DNS 隧道通信特征与检测

DNS 隧道技术解析

一、DNS 隧道技术解析

1.1 DNS协议解析过程

DNS协议解析过程分为两种,迭代查询和递归查询。

1.1.1 迭代查询

本地域名服务器向根域名服务器发送请求报文,根域名服务器要么给出ip地址要么告诉本地域名服务器下一步应该去查询另一个域名服务器(假设这个域名服务器为A)。本地域名服务器会向A域名服务器发送请求报文,A域名服务器要么给出ip地址要么告诉本地域名服务器下一步应该去查询B域名服务器。过程以此类推,直到查找到ip地址为止。

 

1.1.2 递归查询

客户机像本地域名服务器查询,如果本地服务器的缓存中没有需要查询的ip地址,那么本地域名服务器会以客户机的身份(代替本机查询),向根域名服务器发送请求报文。。

递归查询返回的结果要么是查询到的ip地址,要么报错。

客户端只发一次请求,要求对方给出最终结果。

本机查询本地域名服务器,这部分属于递归查询。

本地域名服务器查询根域名服务器,这部分属于迭代查询。

 

1.2 DNS隧道

DNS隧道是隐蔽信道的一种,通过将其他协议封装在DNS协议中进行通信。封装由客户端完成,将DNS流量还原成正常的流量由服务器完成。

 

1.2.1 DNS隧道攻击实现流程

大多数防火墙和入侵检测设备对DNS流量是放行的。

而隧道攻击正式利用了放行的特点以及协议解析流程来实现的。

 

IP直连型DNS隧道:

直连也就是客户端直接和指定的目标DNS Server(Authoritative NS Server)连接,通过将数据编码封装在DNS协议中进行通信,这种方式速度快,但是隐蔽性比较弱,很容易被探测到,另外限制比较高,很多场景不允许自己指定DNS Server。

客户端使用UDP socket建立连接,实际上是基于UDP的,但是利用53端口

 

域名型DNS隧道(中继):

通过DNS迭代查询实现的中继隧道,比较隐蔽,但同时因为数据包到达目标DNS Server前需要经过多个节点,所以速度上较直连慢很多。

(图 1-2)

此时PC是攻击者已经控制了,被植入了木马

aaa.com权威域名服务器也是在攻击者的控制之下,aaa.com域名也是攻击者的。

 

Step 1:受控PC机将数据封装进DNS数据包里,像局域网内部的本地域名服务器请求查询aaa.com

Step 2:本地域名服务器透过防火墙向根域名服务器发送查询请求

Step 3:经过大量重定向,查询请求最终要aaa.com的权威域名服务器

Step 4:aaa.com权威域名服务器是在攻击者的控制下,解析发送过来的DNS数据包并发送回应包

Step 5:DNS回应包穿透防火墙

Step 6::DNS回应包进入内网

Step 7:本地域名服务器将回应包返回给受控PC机

Step 8:受控PC机解析DNS回应包里的数据,得到新的指令

 

1.2.2 典型恶意程序

Trojan.Win32.Ismdoor.gen:使用了多层C&C通信协议结构,使用了DNS隧道技术,C&C服务器的命令会被协议为IPv6地址

Backdoor.Win32.ClIEcker:允许恶意程序从服务器接收随机类型的DNS数据包,该木马没有逻辑上的子协议,只有发送和接收数据包的请求。

Backdoor.Win32.Denis:该恶意程序只使用一个DNS格式的数据包与DNS服务器通信,这种格式汇总,回应的大小被限制为只有4个字节,这只是一个常规的木马下载器,而且下载文件的速度很慢。

PlugX远控变种: 该后门木马结合DNS隧道传输技术和PlugX远控程序,通过建立的DNS隧道进行攻击控制。利用DNS请求应答机制作为攻击渗透的命令控制通道,把C&C服务器指令封装到DNS相应报文中,以此控制被控端主机。并且依托DNS协议的特性,该木马可以有效穿透防火墙,躲避常规的安全检测。

 

1.2.3 经典的攻击事件

2016年5月,Palo Alto曝光了一起APT攻击,Webky团队利用DNS请求应答作为攻击渗透的命令控制通道。攻击者把CC服务器的指令封装在DNS响应报文里

2017年3月,思科Talos团队发现一起名为DNSMessenger的攻击,该恶意软件的所有命令与控制通信都经过DNS TXT类型查询和响应。以此来躲避检测

早在2012的RSA会议上,基于DNS协议的远程控制恶意软件就被视为未来六种最危险的攻击之一。

 

二、DNS隧道攻击实现以及流行工具展示

DNS隐蔽隧道主要是封装其他协议流量来完成传输。

从2004年Dan Kaminsky在Defcon大会上发布的基于NSTX的DNS隐蔽隧道工具,目前来看,基于DNS隧道的木马分成两种类型:IP Over DNS(允许通过隐蔽隧道传输IP数据包)和TCP Over DNS(提供单一的TCP通信的隐蔽隧道)两大类。

IP Over DNS 是将IP数据包封装到DNS报文的构造技术,在构建DNS隐蔽隧道时,通信双方需要解决数据分片,封装,重组等问题。IP Over DNS通用使用TUN/TAP设备(操作系统内核中的虚拟网络设备)将数据包重定向到指定的虚拟网卡中来解决发送端数据分片和接受数据的问题。

DNS域名中的字符限定在字母a-z,A-Z,0-9以及’-’共63个字符,一般采用base32,base64来封装要传输的信息,域名长度最大为255。每一个子域最长为63个字符。发送端将隐蔽数据信息切分并且编码后封装到DNS报文域名中进行传输,接收端收到DNS报文后提取域名中的隐蔽信息字段进行解码重组还原得到IP报文。主要的工具有DNSCat,Iodine等。

TCP Over DNS只有将TCP作为传输协议封装在隐蔽隧道中。由于DNS采取的是不可靠的UDP协议,为了保证传输过程中的数据不丢失不乱码,还要兼顾传输效率,保证通道稳定可用。一般利用SSH的端口重定向技术或者SOCKS代理技术将TCP信道重定向到DNS通道中来。除此之外,TCP Over DNS涉及的编码,数据分割,重组和IP Over DNS类似。主要的工具有OzyManDNS,DNS2TCP等。

 

2.1 测试平台

客户端:本地虚拟机 kali x64

服务器:vps(香港)

本地域名服务器:公司内部DNS服务器

公网域名:xxx.xxx.xxx.xx

 

2.2 dns2tcp

dns2tcp是由Olovier Dembour和Nicolas Collignons开发,使用C语言编写。支持DNS协议KEY和TXT类型的请求。使用此工具不需要额外安装TUN/TAP,可用性和实用性很强。

 

2.2.1 dns2tcp建立隧道流程

首先在vps上配置好dns2tcp。

打开dns2tcp的配置文件,更改后的配置文件如图所示:

启动命令,搭建dns隧道,此时dns2tcp服务端已经准备就绪

再来看看客户端,我这里使用的是kali,因为kali直接预装了dns2tcp

(图 2-3)

Dns2tcp的客户端命令如图2-3所示。

使用命令创建隧道,并且发送数据,如图2-4所示

(图 2-4)

再用服务端像客户端发送数据,如图所示

可以看到,客户端传输的aaa.txt,以及服务端传输的test.txt

传输完成,成功使用了dns2tcp建立隧道传输数据

 

2.2.2 dns2tcp数据包分析

通过wireshark抓包

随机找一个数据包,细看下dns协议内容

type我使用的是TXT来传输,dns2tcp只可以选择两种type,分别是TXT和KEY,默认是TXT。

如果类型变化,base64+域名这样的格式不会变化。

域名前的是通过隧道加密传输的数据,使用了base64加密。

DNS隧道传输数据时,会将数据切成若干个小单元依次发出,时间间隔非常小,当没有数据交互的时候,隧道两端仍然会发包保持通信状态,大概0.6s发出一个数据包,最大是3s可以设置。

dns2tcp这个工具建立隧道发送的数据包特征非常明显。

请求包和回应包的内容基本一致,除了回应包比请求包多了一串base64加密后的数据。

(图 2-8)

 

2.2.3 总结

clent通过TXT类型记录(类型可以使用dns2tcp参数更改)的域名前缀来发出数据,域名前缀和回应内容均加密,采用的是base64加密的方式。

从发包行为上可以发现,在进行传输数据这种大量数据交互操作的情况

 

2.3 iodine

iodine是目前比较活跃,知名度比较大的一个dns tunneling实现工具,平台覆盖范围广,它可以运行在Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD 和 Windows上,甚至还有android客户端,不过它需要安装TUN/TAP。官方称上行速度最大680 kbit/s,下行速度上限可以达到2.3Mbit/s。

 

2.3.1 iodine建立隧道流程

首先添加一条NS 记录

这里设置的是ns.xxx.xxx指向www.xxx.xxx。想要解析ns.xxx.xxx这个子域名就要去访问www.xxx.xxx这个域名服务器

服务端启动命令如下所示

Iodine提供了一个很不错的功能,可以在线查询建立的隧道是否有效。

服务端的隧道建立完毕

这个时候会生成一个名为dns0的虚拟网卡。

客户端输入命令建立隧道

再看看CC服务器,此时已经有数据传输

Iodine隧道建立完毕

 

2.3.2 iodine数据包分析

通过抓包分析一下

Iodine默认使用TXT和NULL类型发送数据,支持NULL,TXT,SRV,MX,CNAME,A等多种查询请求类型

随机找一个请求包

查看它的queries字段

发现ns.xxx.xxx前面是加密的数据,Iodine支持base32,base64,base128等多种编码规范。使用了NULL类型传递

再通过ID查看它的回应包

可以发现这个数据包里,iodine使用了NULL类型来回应,这里是我们传递的加密数据

Iodine的性能还是非常好的,速度十分快。查看了下官方文档的说明,可见测试的结果也十分让人欣喜,单位是kbit / s

 

2.3.3 总结

Iodine与dns2tcp非常类似,其实这些DNS隧道工具都大同小异。抓包分析可以看到,dns隧道的内容加密,并且上传下载频率高。

iodine的可移植性比较强,在许多不同的类UNIX系统和Win32上运行。都可以在两台主机之间建立隧道。

Iodine操作方便,自动处理接口上的IP号,最多16个用户可以同时共享一台服务器。

 

2.4 Dnscat2

Dnscat2的定位是一个封装在DNS协议中加密的命令与控制(C&C)信道。它同样是C/S架构,Client位于感染主机,而Server位于权威域名服务器上。

 

2.4.1 Dnscat2 建立隧道流程

Dnscat2服务端的是交互模式,作者说采用这种设计是受metasploit和meteprete的启发。而服务端的使用方法也确实和metasploit和meteprete的使用方法类似。

首先,服务器创建隧道。可以发现dnscat2打印了一堆东西,其中还有提示客户端建立隧道的命令

使用客户端敲命令建立DNS隧道

可以看到Session established。隧道已经建立成功。

再反观服务器,成功建立了隧道(窗口1)

我们再vps上敲命令session查看这个隧道的情况

使用help命令查看dnscat2工具自带的功能

我们先试用session –i 1,创建新的命令窗口,再使用ping命令,来测试下。

可以看到返回了Pong!,代表成功执行。

再回头看看客户端

可以看到有数据显示。

 

2.4.2 Dnscat2 数据包分析

通过抓包分析一下

随机找一个数据包,查看它的请求包

再查看下queries字段

可以看到dnscat2加密后的域名开头有dnscat的样式。此数据包使用的是CNAME的类型

再看下同一个id的回应包

其中answers字段的内容是

 

2.4.3 总结

dnscat2与其他DNS隧道工具不太一样,它提供了命令,并且以窗口的形式,来执行各种命令。

通过数据包可以发现,dnscat2通过加密的手段隐蔽了CC服务器的域名。隐蔽性做的更好。

 

三、检测DNS隧道木马

将通过3个通信行为分析DNS隧道木马会话。

 

3.1 DNS会话中数据包的总数

正常DNS会话比较简短,随着一次DNS解析任务结束而结束。

DNS隧道木马的会话随着木马的生命周期结束而结束,但在整个木马的生命周期里会向CC服务器发送心跳包,传输信息,资源文件等行为。CC服务器也会发送控制指令。所以在DNS隧道木马的会话中DNS报文数量大。

 

3.2 隧道消息类型

在正常的DNS流量中。A记录类型的流量占20%-30%,CNAME记录为38%-48%,AAAA记录占25%,NS记录只有5%,TXT记录只有1%-2%。然而为了获取更高的带宽,一部分的DNS隐蔽信道工具如Iodine。在默认配置下会使用TXT或NULL等不常用的记录类型。

 

3.3 域名固定部分不变

在DNS隧道的报文中,我们可以看到变化的都是子域名

但是Dnscat2,根域名也加密了并且一直变化,但是有一个显著的标志。

Spread the word. Share this post!

Meet The Author

Leave Comment