这年头,连DNS隧道都被玩坏了( 三 )


三、实践DNS Tunneling从提出到现在已经有了很多的实现工具,历史比较早的有NSTX,Ozymandns,目前比较活跃的有iodine,dnscat2,其他的还有DeNise,dns2tcp,Heyoka等 。不同工具的核心原理相似,但在编码,实现细节和目标应用场景方面存在一定的差异性 。
目前已经提出了多种检测技术,例如通过请求和相应包的大小进行监测,通常dns tunneling为了取得较大的带宽,会选择构造尽量大的dns请求和响应 。还可以通过分析一定时间窗口内所产生的FQDN数,通常DNS Tunneling的FQDN数在一定时间窗口内会远高于正常的DNS流量 。另外在Detecting DNS Tunnels Using Character Frequency Analysis论文中,证明了还可以通过词频的检测识别DNS Tunneling的流量 。根据Zipf定律,在自然语言的语料库里,一个单词出现的次数与它在频率表里的排名成反比 。正常的域名也符合这个定律 。而在这篇论文中,证明了DNS Tunneling中由于域名做了编码,不符合Zipf定律,整个分布趋于平稳 。另外很多DNS Tunneling使用TXT记录类型发送请求和响
应,而在正常的DNS网络流量中,TXT记录的比例可能只有1%-2%,如果时间窗口内,TXT记录的比例激增,那么也意味着存在异常 。
权威DNS Server配置采用中继模式工作,所有工具的基础是需要配置一台权威DNS Server 。如果没有公网域名可以从freedns注册三级域名,不过有的地区好像不可用 。
注册完域名后,我们需要配置一个A记录和一个NS记录(也可以配置多个NS记录) 。
1.Dns2tcp
dns2tcp是一个利用DNS隧道转发TCP连接的工具,支持KEY和TXT类型的请求,用C语言开发 。它分为两个部分,服务端和客户端,服务端运行在linux服务器上,客户端可以运行在linux和windows上(其他平台没有测试过),编译完成后在服务端上的可执行文件名称为dns2tcpd,在客户端(linux)上的名称为dns2tcpc,kali默认安装了二者 。下述为主要参数及解释,详情请参考手册 。
dns2tcpd

-F 强制在在台运行,默认在后台
-i IP address
监听ip,默认0.0.0.0
-f 配置文件
指定使用的配置文件路径
-d debug level
指定调试级别,输出相关级别日志,默认为1,2,3
dns2tcpc
-c : 启用压缩
-z <domain> : 指定所使用的域名
-d <1|2|3> : 调试级别 (1, 2 or 3)
-r <resource> : 访问的目标资源
-f <filename> : 配置文件路径
-l <port|-> : 本地监听端口
-T <TXT|KEY> : DNS请求类型,默认为TXT
配置文件
为了避免运行时指定太多的参数,可以通过指定配置文件来启动服务端 。示例如下:
listen = 0.0.0.0
port = 53
user = nobody
chroot = /tmp
domain = <domain.com>
resources = ssh:127.0.0.1:22,socks:127.0.0.1:1082,http:
127.0.0.1:3128,nc:127.0.0.1:2222
其中resource这个参数稍作解释:
格式:<name>:<ip>:<port>
其中name为自定义标识,通常为本地开启的目标服务名称,ip如果是本机为127.0.0.1,端口则为目标服务所监听的端口,或者说服务端通过该端口将流量转发给目标服务 。例如希望在服务端和客户端用nc来进行对接传输文件,我可以自定义nc:127.0.0.1:2222 。
在客户端不指定resource这个参数的时候,会列出对应server可以接受的资源 。
服务端
dns2tcpd -f /etc/dns2tcpd.conf -d 3
nc -l 2222 > test.txt
客户端
dns2tcpc -r nc -d 3 -z <domain.com> <server ip> -l 8888
nc 127.0.0.1 8888 < test.txt
在服务端开启dns2tcp服务,强制在前台运行,并设置调试级别,从而能比较清楚的看到服务端的日志 。同时使用nc 在2222端口开启监听,将数据重定向输出到test.txt文件 。
客户端通过制定nc资源,所使用的域名,目标dns server的ip,以及指定本地的8888监听端口与dns server建立通信连接,同时也用nc访问本地8888端口,并用test.txt进行重定向输入 。
通过在服务端和客户端使用nc进行双向对接,我们可以利用dns2tcp完成文件传输 。
初步分析
通过抓包提取dns协议里的附件字段或者直接查看在客户端打出的log,可以发现clent通过TXT类型记录的域名前缀来发出数据,通过DNS RR中的TXT记录来附加回应的内容 。域名前缀和回应内容均采用base64编码,如果提取单条数据,进行base64解码,即可看到传输的内容 。
从发包行为上可以发现,如果在进行传输数据这种大量数据交互操作的情况,dns2tcp会将数据切分成若干个小单元,依次发出,时间间隔非常小,而当无数据交互,空闲时,两端仍然通过发包维持通信状态,客户端大约每隔0.6s发出一个状态包 。


推荐阅读