背景介绍
各种 Shell 都有它自己的优点和缺点,采用 TCP 和 UDP 的虽然功能强大,但是却受到了防火墙和杀毒软件的严格监控,Ruby 和 Java 写成的又不一定有相应的运行环境。 主角登场我们今天介绍一个利用 DNS 协议进行通信的反弹 Shell,和 ICMP 反弹 Shell 的原理几乎相同,只是传输的协议变为了 DNS。 使用 DNS 请求来伪装通信进行命令控制带来的好处不言而喻,不管你做了多么严格的网络控制,你也要满足至少对一个服务器发起的 DNS 查询请求,那么就可以被攻击者恶意利用。利用 DNS 的想法并不新奇,在黑帽大会上也多次提到过 DNS 隧道,之前的 DNS 域传送漏洞也是一个利用方法,今天我们选取一个开源的工具进行学习–DNShell 。 有关于 DNS 的相关细节不再赘述,有想了解详细内容的移步相关的 RFC 文档,如 RFC 4034、RFC 3755等等。 准备工作如作者所说,这是一个使用 Python 编写的、利用 DNS 作为命令控制信道的反弹 Shell。对于 Python 库的准备就不再多说了,依赖的环境应该是 Python 2.7,因为其在服务器端的代码中使用了 raw_input 和 .format() 。众所周知, raw_input 函数在 Python3 中被砍掉了,而 str.format() 则是在 Python 2.6 才加入的函数。 上图是我的 Package 页 from Crypto.Cipher import AES 引入错误,如果在装了 Crypto 后还是错误,就需要装pycrypto 这个库。 如果想修改代码到 Python3 下运行,遇到 import dns.resolver 引入错误,是需要装dnspython3 的。 DNS 查询简单介绍一下如何利用 Python 来进行 DNS 查询,这也是核心的方法,DNS 作为信道进行隐蔽通信的核心就是把要传递的数据作为 DNS 请求的 hostname 部分。
先创建一个实例,然后查询 Google.com 的 A 记录。以同样的方式,我们可以执行对 MX 和NS 的查询,只需要改动 A 的那部分就可以了,很简单。 当用它来进行反向 DNS 查找(主机名到 IP) 时,就不是简单的输入 IP 地址直接执行 A 记录查找。我们需要执行 PTR 查找,查找时要将待查找的 IP 地址逆向书写,并将 “.in addr.arpa”追加到它后面。 例如,为解析 IP 地址为 114.124.134.3 的主机名,我们使用的代码是:
DNS 解析程序也给我们指定我们自己的域名服务器的选项。这可以通过使用:
这里也引出了一种对抗的方法,我们将在后面进行说明。 分析与问题上图将 DNShell 的一次命令控制过程进行了展示,由于两个文件代码量并不大,我们不进行逐段的详细解释和分析了,只对一些地方进行简要阐述,想彻底弄懂或者改写代码的请自行研究。 先运行服务器端,再执行被控制端,这一点在 GitHub 的项目主页上作者也有提醒。 Python 有两个内建的模块用于处理命令行参数,一个是 getopt 另一个是 optparse ,作者在这个代码中使用的是 optparse 模块用来解析命令行参数。 监听的端口是常见的 DNS 服务器端口 53,如果你的服务器恰好搭建了 DNS 服务,或者有程序占用这个端口,你就无法对这个端口进行监听了,必须先停止占用端口的程序。 程序使用了 base64 进行编码解码,使用 AES 进行加密解密,在程序两端都要更改密钥和向量来保证加密的安全性。 NXT 资源记录通过在域中创建所有字面上的所有者名称链,指出某个名称在域中不存在。它们同时也指出,一个已有名称当前有什么资源记录类型。 在加解密的时候,因为 AES 是分块加密的,在加解密时作者使用 lambda 表达式这种匿名函数来实现,十分简洁。 执行命令用的传统 subprocess 子进程的方法,如果要改进代码的话,这里还有提升空间可以解决很多问题,比如执行命令时的权限问题、 Windows 和 Linux 的命令不尽相同的问题等。 如果被控制端需要放在 Windows 上运行,不仅要考虑到其没有 Python 运行环境是否打包成exe 文件才能运行的问题、是否触发 UAC 的验证引起用户警觉,还有应该使用加壳、加密等手段来绕过像管家、360 等杀软的问题。 Nullege 是一个查询源代码和文档的好地方,和谷歌配合使用疗效显著。如果你对其中的某些函数感到陌生或者困惑,不但可以查官方文档,也可以在这里查找很多示例的源代码增进理解。 实际部署服务器端放在了一台 VPS 上,如上图所示。 在被控制端脚本执行后,服务器端会出现一个 SHELL 的提示行,我们在这里输入命令
在被控制端,我们可以清楚的看到,经过解码和解密,已经成功得到了 ipconfig -all 这个命令,(需要注意的是,我对代码进行了些微的改动,可能导致行号和作者版本的行号不相同,不过这并不影响什么) 在调试器中查看执行命令的 stdout 可以看到
我们再输入退出的指令 quit 来测试一下 被控制端直接退出了,也完成了远程的命令。接着我们用 Wireshark 进行抓包 可以看到这条发送出去的 DNS 请求 返回的响应中,我们也确实看到了携带的数据 对抗方法在 DNS 查询小节中,我们讲到了在查询时指定域名服务器的方法。这也是对抗使用 DNS 请求作为隐蔽通信信道的方法,在可能的情况下,使用自己搭建的 DNS 服务器,这样就可以直接得出:除了这一台 DNS 服务器要与外界进行 DNS 请求交互,其余服务器任何试图与外界DNS 服务器发起的请求都是恶意的。 *本文原创作者:ArkTeam 楚子航,本文属FreeBuf原创奖励计划,未经许可禁止转载 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|