DNS协议是一种请求应答协议,也是一种可用于应用层的隧道技术。虽然DNS流量的异常变化可能会被发现,但是在基于传统socket隧道已经濒临淘汰,TCP、UDP通信大量被安全设备拦截的大背景下,DNS、ICMP、HTTP/HTTPS等难以禁用的协议已经成为攻击者使用隧道的主流选择。
选择DNS协议作为通信隧道的主要优势在于:一方面,DNS是网络环境中必不可少的服务,另一方面,由于防火墙和IDS设备本身较少存在过滤DNS流量的行为,使得DNS报文本身具有了穿越WAF的能力。同时,越来越多的研究数据也证明了DNS隧道在APT攻击和僵尸网络中扮演着重要角色。
DNS隧道原理:
核心思想:端口不和服务绑定,可以传输任何数据。
正常网络之间的通信,是发生在两台机器建立TCP连接之后的,在进行通信时:如果目标是IP,则会直接发送报文,如果是域名,则将域名解析为IP再通信。C&C服务器在建立连接后将指令传递给客户端上的后门程序。
DNS隧道的原理就是:在后门程序进行DNS查询时,如果查询的域名不在DNS服务器本机的缓存中,就会访问互联网进行查询,然后返回结果,如果互联网上有一台攻击者设置的服务器,那么服务器就可以依靠域名解析的响应进行数据包的交换,从DNS协议的角度来看,这样的操作只是反复查询某个或者某些特定的域名并且得到解析结果,但其本质是,DNS预期的返回结果应该是一个IP地址,而事实上不是——返回的可以是任意字符串,包括加密的C&C指令,从而将其他协议封装在DNS协议中进行传输。
DNS隧道木马的通信结构如下:
DNS协议开头为Transaction ID为字段,2字节,用于辨别DNS应答报文是哪个请求报文的响应:
技术要点:
- DNS缓存机制的规避
再使用中继隧道时,如果需要解析的域名在本地的DNS Server中已经有缓存时,本地的DNS Server就不会转发数据包。所以在构造的请求中,每次查询的域名都是不一样的。
- DNS载荷的编码
从高层来看,载荷只是客户端和服务器通信的正常流量。例如客户端发送一个A记录请求给服务器,查询的主机名为2roAUSwVqwOWCaaDC.test.nuoyan.com,其中2roAUSwVqwOWCaaDc则是客户端传递给服务器的信息,这串字符解码后的信息便是DNS隧道。
DNS隧道分类:
DNS隧道攻击分为两种:IP直连型和域名中继型,后面会分别介绍这两种方式的代表工具。
IP直连型:
直连也就是客户端直接和指定的目标DNS Server(Authoritative NS Server)连接,通过将数据编码封装在DNS协议中进行通信,这种方式速度更快,但是隐蔽性较差,容易被WAF或者IDS设备探测到,另外限制比较高,很多实际场景下不允许攻击者来自定义DNS Server,否则很容易被发现。
DNS协议的下层协议为UDP传输协议,这种隧道客户端通常使用UDP socket建立连接,实际上是基于UDP的,但是要利用到53端口。
域名中继型:
通过DNS递归查询实现的中继隧道,比较隐蔽,但同时因为数据包到达目标DNS Server前需要经过多个节点,所以速度上较直连慢很多(其实就类似伪造一台私有DNS Server,当然也许大佬神仙们真有一台权威DNS Server也说不一定哈),同时我们还需要规避本地客户端的DNS缓存,这里可以使用随机域名生成算法(DGA)。很多恶意软件利用该算法生成随机域名,有效绕过黑名单检测,通过轮询的方式尝试连接,寻找C2控制中心。(DGA算法的检测测方法也有不少,这里按下不表)
①受到木马控制的PC将数据封装到DNS数据报文里,向位于内网的本地域名服务器请求查询baidu.com.
②本地域名服务器透过防火墙向根域名服务器发送查询请求
③经过大量的递归重定向,查询请求发到baidu.com的(伪造)权威域名服务器
④baidu.com(伪造)权威域名服务器是在攻击者控制下,解析并发送响应包
⑤dns响应包穿透内网防火墙
⑥进入内网
⑦本地域名服务器将响应包返回给受控客户端
⑧受控客户端解析DNS响应包中的数据,获取指令
几种常见DNS隧道工具流量分析
1、dns2tcp
dns2tcp是一个利用DNS隧道转发TCP连接的工具,是由Olovier Dembour和Nicolas Collignons开发,使用C语言编写。支持DNS协议KEY和TXT类型的请求。使用此工具不需要额外安装TUN/TAP,可用性和实用性很强。
工具使用:
服务器端,默认配置文件
resources里面配置的是dns2tcp供客户端使用的资源。作用是:客户端在本地监听一个端口,并指定使用的资源,当有数据往端口传送后,dns2tcp客户端将数据用DNS协议传动到服务器,然后服务器将数据转发到对应的资源配置的端口中。
启动DNS2TCP客户端的命令如下;
dns2tcpc -c -k pass -l 2222 -d 1 -r ssh -z ns1.abc.com
其中:-c表示启用数据压缩;-d表示启动调试,1为调试等级;-l表示监听本地端口,2222为端口名;-r为使用服务端上的哪个资源,ssh为资源名,可以为http;-z后的ns1.abc.com为前面配置的NS记录的域名。
然后就可以在内网主机192.168.32.132访问本地2222端口,测试成功,可以访问外网主机的ssh资源。
类似的方法,选择http然后将浏览器的代理服务器地址设为127.0.0.1:8118,代理类型为HTTP代理,也可以通过DNS隧道上网了。
流量分析:
请求体与响应体完全一致,响应体多出一段加密的base64的加密流
原理是通过DNS请求头域名的信息的TXT记录加密传输信息,可以看到DNS的查询请求的域名信息test.lab.com前的一串数据,里面就是加密过后的交互数据。DNS隧道建立后,client还是会不断地发包给server心跳包,确认服务器端处于存活状态,保证传输的顺畅。
DNS2TCP使用子域的前4个字节来维护和跟踪相同的会话。通过删除 session-tag,我们可以使用base64解码SSH会话中的实际有效负载
总结:
client通过TXT类型记录的域名前缀来发出数据,采用的是base64加密的方式。
从发包行为上可以发现,在进行传输数据这种大量数据交互操作的情况
2、iodine
与同类工具相比,iodine具有以下特点:
- 下行流量不编码(下行流量是指流出服务器的流量,s to c)
- 强制密码
- 支持同一网段之间的隧道
- 支持多种dns记录格式
Iodine默认使用TXT和NULL类型发送数据,支持NULL,TXT,SRV,MX,CNAME,A等多种查询请求类型。
iodine -fP passwd 96.45.188.252 dnsns.hackbiji.top
-f 前台运行 -D调试级别(输出相关级别日志)
如果发生在内网,你无法访问外网IP(96.45.188.252)的时候,可以去掉IP地址,直接通过内网的DNS服务器帮你请求,依然能达到建立隧道的效果。
iodine -fP hackbjipasswd dnsns.hackbiji.top
原理:
在服务端通过TAP虚拟网卡,在服务端建立一个局域网,彼此之间能ping通那种;
在客户端通过TAP建立虚拟网卡,两者之间通过dns隧道连接,实现出于同一个局域网,客户端会出现一个“dns0”的虚拟网卡。
流量分析:
DNS默认使用数据类型为NULL类型,是一种已经过时的记录类型,现在废弃了。
3、Cobaltstrike DNS beacon
目标靶机的端口开放情况没有变化,隐蔽性高。
CC服务器不容易暴露(因为借用了域名服务器可以使用重定向),蓝队需要递归dns查询反向查找。
可以利用mode命令随时改变数据传输通道,例如mode dns使用A记录传输,mode dns6使用AAAA记录,mode http显而易见使用http通道等等。
profile idle参数可修改teamserver响应IP
流量分析
流量特征:
超长子域名
Dns默认响应值:0.0.0.0
默认使用TXT格式传递base64格式的加密信息