前言
最近搭建了隧道的实验环境,想研究一下各种协议隧道通讯的记录情况,在某些环境下企业限制内网机器访问外部资源但放行了DNS流量,黑客会使用DNS隧道来传输数据和执行命令,这次我们先看看DNS隧道使用过程中的数据包情况。
准备工作
前两天我使用iodine先建立了DNS隧道通讯的环境,环境搭建的方法可以参考:https://rosetscmite.github.io/2018/12/13/%E5%9F%BA%E4%BA%8Eiodine%E5%BB%BA%E7%AB%8BDNS%E9%9A%A7%E9%81%93/
问题1:DNS隧道建立后有哪些特征
DNS隧道建立后依靠不断发送query信息来判断隧道存活性
问题2:DNS隧道传输时有哪些特征
通过DNS隧道传输时,客户端将数据编码后作为主机名向DNS服务器提交,DNS服务端解码后读取数据
主机名的长度可以通过iodine的参数来调节默认的长度为255,可以通过调短主机名长度来提高隐蔽性,下图与上图为同一个操作,把iodine的主机名长度设置为100后,FQDN的长度明显缩短,但请求次数会增加,因为传输的数据量不变
iodine可以不发送标准的DNS报文,直接发送特定畸形的DNS报文来传输数据,这种传输方式规避了特定的记录和主机名,由于数据包非标准格式,流量检测设备也无法解析,对溯源造成困扰
问题3:DNS隧道client端是如何接受命令的
在隧道服务端向客户端发送命令,通过查看DNS记录可以发现服务端通过回复心跳记录将命令编码后放在Answers字段发送给客户端,客户端解码后读取命令并执行,将回显信息通过Query请求出去,服务端解码后读取回显信息
问题4:DNS隧道传输文件时是否会记录再一条flow日志中
通过标准DNS数据包记录传输数据时,数据通过主机名和Answers进行传递,每一组DNS请求与回应记录到一条flow
通过畸形DNS数据包传输数据时,由于数据包畸形没有解析到DNS记录,传输数据时记录到一条flow日志中
实验结论:
从实验结果看出,DNS隧道主要分为两种模式一是将数据编码通过主机名进行传递,一是通过畸形DNS数据包进行传递,检测方法如下:
将数据编码通过主机名进行传递的方式:
- 检测每个域的主机名数:因为绕过DNS记录缓存,DNS隧道发送的记录都是不同的(包括心跳包),所以可以检测窗口时间内同一个域下的主机名数量来判断异常
- 检测DNS域名长度:通过DNS隧道传输数据时,FQDN长度一般会较长与正常域名
- 检测DNS不常见记录类型:统计窗口时间内同一个域下不常见的记录类型数量
通过畸形DNS数据包进行传递的方式:
- 单个DNS flow的数据包较大
- 单个IP时间窗口内检测到较多畸形DNS数据包
通用检测方式:
- 每个IP地址的DNS流量异常
- DNS服务器的地理位置异常
- 访问非受信的DNS服务器