一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

SilentMoonwalk:实践指南

时间:2026-09-11 16:20:01 编辑:袖梨 来源:一聚教程网

如果把SilentMoonwalk放进候选清单,不能只看热度;它的定位是PoC 完全动态调用堆栈欺骗的实现。实际做日常自动化时,经常会碰到输入边界、依赖和失败处理如果不清楚就很难稳定复用,所以功能列表并不能代替验证。先用一项范围明确的真实任务完成最小试跑更稳妥;过程中要观察配置时间、输出质量、异常信息和维护痕迹,失败也应能解释原因。我会把它列入愿意先做小范围验证并复查原始文档的团队的候选清单,而不是仅凭项目介绍直接纳入生产。

# SilentMoonwalk

PoC 完全动态调用堆栈欺骗的实现

TL;DR

SilentMoonwalk 是完全动态调用堆栈欺骗程序的 PoC 实现,实现了一种从调用堆栈中删除原始调用者的技术, 使用 ROP 使展开与控制流不同步。

概述

此存储库演示了 PoC 实现,用于在调用任意 Windows APIs 时欺骗调用堆栈。

这一尝试的灵感来自于 这个 Twitter 帖子 和 这个 Twitter 帖子,其中老师 namazso 展示并建议 使用 ROP 链扩展堆栈展开方法,使展开与实际控制流不同步并恢复 之后的原始堆栈。

这个PoC尝试做与上面类似的事情,并使用一个desync堆栈来完全隐藏原始的 调用堆栈,还从中删除 EXE 映像库。返回后,调用 ROP 小工具来恢复原始堆栈。 在代码中,这个过程在循环中重复 10 次,每次迭代使用不同的帧,以证明稳定性。

支持的模式

该工具目前支持 2 种模式,其中一种实际上是对已识别的非工作流行 RBP 帧的错误修补,它通过移动当前的 RSP 并向调用堆栈添加两个假帧。由于它使用合成框架运行,我将此模式称为“SYNTHETIC”。

当选择通过从堆栈中弹出 RBP 寄存器来展开的帧时,该工具可能会选择不合适的帧,从而突然结束 剪切调用堆栈,如下所示。

综合调用堆栈模式

该问题的一个愚蠢的解决方案是创建两个假框架并将它们链接回剪切调用堆栈。这将创建一种明显合法的调用堆栈, 即使没有合适的框架来展开调用 POP RBP,但是:

  • 您将失去异步技术的优势
  • 堆栈仍然是不可展开的
  • 乍一看,生成的调用堆栈似乎是合法的,但它可能不会通过严格的检查

_synthetic 欺骗的结果如下图所示:

图 1:Windows 10 - 显然是合法的、不可撤销的调用堆栈,其中 EXE 模块已被完全删除(调用无参数函数 getchar)

注:此操作模式默认禁用。要启用此模式,请将 CALLSTACK_TYPE 更改为 1

异步堆栈模式

这种模式是上述问题的正确解决方案,即用另一个合适的框架简单地替换不合适的框架。

图 2:Windows 10 - 合法、不可破坏的调用堆栈,其中 EXE 模块被完全删除(调用 4 个参数函数 MessageBoxA)

实用性

在存储库中,您还可以找到一些用于检查运行时函数的实用程序,这对于分析运行时函数条目可能很有用。

UnwindInspector.exe -h

 Unwind Inspector v0.100000

 Mandatory args:
   -m <module>: Target DLL
   -f <function>: Target Function
   -a <function-address>: Target Function Address

示例输出:

UnwindInspector.exe -m kernelbase -a 0x7FFAAE12182C
[*] Using function address 0x7ffaae12182c

  Runtime Function (0x000000000000182C, 0x00000000000019ED)
  Unwind Info Address: 0x000000000026AA88
    Version: 0
    Ver + Flags: 00000000
    SizeOfProlog: 0x1f
    CountOfCodes: 0xc
    FrameRegister: 0x0
    FrameOffset: 0x0
    UnwindCodes:
    [00h] Frame: 0x741f - 0x04  - UWOP_SAVE_NONVOL     (RDI, 0x001f)
    [01h] Frame: 0x0015 - 0x00  - UWOP_PUSH_NONVOL     (RAX, 0x0015)
    [02h] Frame: 0x641f - 0x04  - UWOP_SAVE_NONVOL     (RSI, 0x001f)
    [03h] Frame: 0x0014 - 0x00  - UWOP_PUSH_NONVOL     (RAX, 0x0014)
    [04h] Frame: 0x341f - 0x04  - UWOP_SAVE_NONVOL     (RBX, 0x001f)
    [05h] Frame: 0x0012 - 0x00  - UWOP_PUSH_NONVOL     (RAX, 0x0012)
    [06h] Frame: 0xb21f - 0x02  - UWOP_ALLOC_SMALL     (R11, 0x001f)
    [07h] Frame: 0xf018 - 0x00  - UWOP_PUSH_NONVOL     (R15, 0x0018)
    [08h] Frame: 0xe016 - 0x00  - UWOP_PUSH_NONVOL     (R14, 0x0016)
    [09h] Frame: 0xd014 - 0x00  - UWOP_PUSH_NONVOL     (R13, 0x0014)
    [0ah] Frame: 0xc012 - 0x00  - UWOP_PUSH_NONVOL     (R12, 0x0012)
    [0bh] Frame: 0x5010 - 0x00  - UWOP_PUSH_NONVOL     (RBP, 0x0010)

构建

为了构建 POC 并观察与图中类似的行为,请确保:

  • 禁用 GS (/GS-)
  • 禁用代码优化(/Od
  • 禁用整个程序优化(删除/GL
  • 禁用大小和速度首选项(删除 /Os/Ot
  • 启用内在如果未启用(/Oi

以前的工作

值得一提的是之前在这个主题上所做的工作,它奠定了这项工作的基础。

  • 返回地址欺骗: Original 技术和想法,作者:Namaszo。我所知道的所有其他 PoC 都是在此之上构建的。
  • YouMayPasser: This Arash 的出色工作是 Namaszo 的返回地址欺骗 PoC 的第一个正确完成的扩展。
  • VulcanRaven: A 调用堆栈欺骗程序,通过综合创建一个镜像另一个真实调用堆栈的线程堆栈来进行欺骗。
  • Unwinder: A 非常好的 Rust PoC 调用堆栈欺骗器的实现,它通过解析展开代码信息来替换调用堆栈中的帧进行操作。

注释

  • [SYNTHETIC STACK ONLY]: For 我定位小工具的方式有限制,目前参数的最大数量是 8(修改和添加更多参数是 TRIVIAL,但我懒得打扰)。
  • [DSESYNC STACK ONLY]: For 我如何设置欺骗程序的限制,目前支持的最大参数数量为 4。
  • 对这个的测试非常有限。可能存在我目前不知道的例外情况。
  • 未测试涉及 128 位寄存器的展开。
  • 官方不支持调用使用 128 位寄存器的函数。

热门栏目