Reflective call stack detections and evasions

Reflective call stack detections and evasions

In a blog published this March, we explored reflective loading through the lens of an offensive security tool developer, highlighting detection and evasion opportunities along the way. This time we are diving into call stack detections and evasions, and how BokuLoader reflectively loads call stack spoofing capabilities into beacon.
在今年三月发布的一篇博客中,我们通过攻击性安全工具开发人员的视角探讨了反射加载,强调了在此过程中的检测和规避机会。这次我们将深入探讨调用堆栈检测和逃避,以及 BokuLoader 如何反射性地将调用堆栈欺骗功能加载到信标中。

We created this blog and public release of BokuLoader during Dylan’s summer 2023 internship with IBM X-Force Red. While researching call stack spoofing for our in-house C2, this was one of the techniques identified — the X-Force Adversary Services team’s private C2 has much stealthier techniques implemented. The call stack evasion techniques that have been integrated into BokuLoader are not novel and are publicly disclosed. While these techniques are available to security vendors, detections for these evasions may not be present.
我们在 Dylan 2023 年夏季在 IBM X-Force Red 实习期间创建了这个博客和 BokuLoader 的公开版本。在为我们的内部 C2 研究调用堆栈欺骗时,这是确定的技术之一 — X-Force 对手服务团队的私人 C2 实施了更隐蔽的技术。已集成到BokuLoader中的调用堆栈规避技术并不新颖,并且是公开披露的。虽然安全供应商可以使用这些技术,但可能不存在对这些逃避的检测。

In this post, we have created hypothetical detections that could be implemented to detect publicly disclosed active call stack evasion techniques. Each detection has exceptions. Significant tuning would be required before they are deployed into customer environments.

While sharing call stack evasions from the perspective of an offensive operator, our intention is to equip threat hunters and detection engineers with knowledge on how to detect advanced malware from call stack traces.

Call stack detections and evasions

Call stack detection #1 — Return address hunting
调用堆栈检测 #1 — 返回地址搜寻

When analyzing a call stack, verify that the caller’s return address resolves to a loaded module. Unresolved addresses could hint to shellcode and be flagged as malicious. This detection exists in some form within most modern security solutions.

Reflective call stack detections and evasions

Diagram of detecting shellcode by checking caller’s return address

In this call stack below, a sleeping beacon’s return address is exposed.
在下面的调用堆栈中, 显示睡眠信标的返回地址.

Reflective call stack detections and evasions

Default beacon with return address exposed in call stack while executing Sleep API
执行睡眠 API 时在调用堆栈中公开返回地址的默认信标

Evading call stack detection #1 — Return address spoofing
逃避调用堆栈检测 #1 — 返回地址欺骗

One way to evade this detection is saving beacon’s return address in a non-volatile register before calling an API, then returning to beacon through a ROP gadget in a trusted DLL. Since non-volatile registers are restored by the called API, we can rely on their values persisting through the call.
逃避此检测的一种方法是在调用 API 之前将信标的返回地址保存在非易失性寄存器中,然后通过受信任 DLL 中的 ROP 小工具返回到信标.由于非易失性寄存器是由被调用的 API 恢复的,因此我们可以依靠它们的值在调用中持续存在。

While checking the return address of the caller, security solutions may be fooled into thinking our stack frame belongs to a trusted DLL API. When our thread finishes executing the called API, it takes a different path than the stack walker. Our thread returns to the gadget, and the gadget jumps our thread back home to beacon.
在检查调用方的返回地址时,安全解决方案可能会被愚弄,认为我们的堆栈帧属于受信任的 DLL API。当我们的线程完成执行调用的 API 时,它会采用与堆栈步行器不同的路径。我们的线程返回到小工具, 小工具将我们的线程跳回信标.

Reflective call stack detections and evasions

Diagram of evading caller return address detection using return address spoofing

This clever trick was popularized by Namazso in a game hacking forum and then by Kyle Avery in his AceLdr reflective loader project, which he presented at DEFCON 2022.
这个聪明的技巧由 Namazso 在一个游戏黑客论坛上推广,然后由 Kyle Avery 在他的 AceLdr 反射加载器项目中推广,他在 DEFCON 2022 上展示。

Like BokuLoader, AceLdr adds call stack spoofing capabilities to beacon by reflectively hooking imported APIs. Before the hook passes execution to the API, beacon’s return address is stored on the stack. This stack address is saved into the nonvolatile RBX register and a jmp [rbx] gadget replaces the caller’s return address. To avoid a return address to the hook being pushed onto the stack, the AceLdr hook jumps to the API instead of calling it.
与BokuLoader一样,AceLdr通过反射性挂钩导入的API将调用堆栈欺骗功能添加到信标中。在钩子将执行传递给 API 之前, 信标的返回地址存储在堆栈上.此堆栈地址保存在非易失 RBX 寄存器中, jmp [rbx] 小工具替换调用方的返回地址。为了避免钩子的返回地址被推送到堆栈上,AceLdr 钩子跳转到 API 而不是调用它。

Reflective call stack detections and evasions

In the call stack below, we see the gadget’s return address which resolves to the WININET module, instead of a return address to our beacon shellcode.
在下面的调用堆栈中,我们看到小工具的返回地址解析为 WININET 模块,而不是我们的信标外壳代码的返回地址。

Reflective call stack detections and evasions

AceLdr beacon call stack with return address spoofing of InternetConnectA API
AceLdr 信标调用堆栈,具有 InternetConnectA API 的返回地址欺骗

While examining the AceLdr call stack above, we see it ends prematurely after the gadget stack frame. This is because the return address of the next stack frame is 0. Stack walkers typically walk down the call stack until the next stack frame has a return address of 0.
在检查上面的 AceLdr 调用堆栈时,我们看到它在小工具堆栈帧之后过早结束。这是因为下一个堆栈帧的返回地址为 0。堆栈步行者通常沿着调用堆栈向下走,直到下一个堆栈帧的返回地址为 0。

Call stack detection #2 — Truncated call stack
调用堆栈检测 #2 — 截断的调用堆栈

When analyzing a call stack, verify the call stack traces down to common thread start APIs such as BaseThreadInitThunk & RtlUserThreadStart. Call stack traces that end prematurely are suspicious and could be flagged for further investigation.
分析调用堆栈时,验证调用堆栈跟踪到常见的线程启动 API,例如 BaseThreadInitThunk & RtlUserThreadStart 。过早结束的调用堆栈跟踪是可疑的,可能会被标记以供进一步调查。

Reflective call stack detections and evasions

Diagram of a suspicious call stack that uses the call stack truncation evasion.

Evading call stack detection #2 — Synthetic frames
逃避调用堆栈检测 #2 — 合成帧

To evade this call stack tracing detection we can extend the first evasion by pushing fake thread start API frames to the stack. As long as we allocate memory on the stack for our fake frames, we can continue to add frames and avoid overwriting beacon’s real call stack.
为了逃避此调用堆栈跟踪检测,我们可以通过将假线程启动 API 帧推送到堆栈来扩展第一次逃避。只要我们在堆栈上为假帧分配内存, 我们可以继续添加帧并避免覆盖信标的真实调用堆栈.

Reflective call stack detections and evasions

Diagram of evading call stack tracing detections using synthetic frames

Synthetic frames are used in the SilentMoonwalk project as the non-default option and are also used in the Vulcan Raven project.
合成帧在SilentMoonwalk项目中用作非默认选项,也用于Vulcan Raven项目。

Call stack detection #3 — Hunting for the thread start frame
调用堆栈检测 #3 — 搜寻线程开始帧

When analyzing a call stack, verify that the third stack frame from the bottom is a return address to the thread’s start address function. If the call stack does not align with the thread’s start function, this may be suspicious and warrant further investigation. This detection technique could be leveraged to detect both modes of the SilentMoonwalk project and the new release of BokuLoader.

Reflective call stack detections and evasions

Detecting suspicious call stack due to thread start address frame missing (Desynchronization technique — left, Synthetic Frame technique — right)
检测由于线程开始地址帧丢失而导致的可疑调用堆栈(去同步技术 — 左,合成帧技术 — 右)

In the below screenshot we see a thread of OneDrive.exe has a start address, which aligns with the third lowest frame in the thread’s call stack.
在下面的屏幕截图中,我们看到一个 OneDrive.exe 线程具有开始地址,该地址与线程调用堆栈中倒数第三的帧对齐。

Reflective call stack detections and evasions

The symbol from a thread’s Start Address is normally present on its call stack

This detection will likely result in a lot of false positives if implemented without proper tuning. While typical user programs launched from the desktop follow this pattern, there are many service and background processes that do not. Regardless of the noise, threat hunters and detection engineers may find this detection technique useful while investigating call stack traces.

Call stack detection #4 — Hunting for gadgets
调用堆栈检测 #4 — 搜寻小工具

All the evasion techniques we have described depend on a jmp [rbx] gadget to restore execution to a handler that returns to beacon. However, it is possible to also use other nonvolatile registers such as rsi and rdi.
我们描述的所有规避技术都依赖于一个小 jmp [rbx] 工具来恢复对返回信标的处理程序的执行.但是,也可以使用其他非易失性寄存器,例如 rsi 和 rdi 。

Bokuloader integration 博库装载机集成

For the public BokuLoader project, we have incorporated the call stack spoofing capabilities of the LoudSunRun project by Dylan Tran. Dylan’s project is derived from the SilentMoonwalk and the Vulcan Raven projects. In this release of BokuLoader synthetic stack frames are used to evade call stack detections. The detection methods described in this post should be able to detect a BokuLoader beacon.
对于公共BokuLoader项目,我们整合了Dylan Tran的LoudSunRun项目的呼叫堆栈欺骗功能。迪伦的项目来源于SilentMoonwalk和Vulcan Raven项目。在此版本的 BokuLoader 中,合成堆栈帧用于逃避调用堆栈检测。这篇文章中描述的检测方法应该能够检测到 BokuLoader 信标.

Active call stack spoofing has been applied to all WININET APIs imported by the Cobalt Strike HTTPS beacon. A hashing method has been included in the BokuLoader project and replaces the previously used string encryption method. This was done to save memory on the stack and avoid potential stack overflows which would crash beacon.
主动调用堆栈欺骗已应用于钴攻击 HTTPS 信标导入的所有 WININET API。BokuLoader项目中包含一个哈希方法,并取代了以前使用的字符串加密方法。这样做是为了节省堆栈上的内存并避免潜在的堆栈溢出,从而导致信标崩溃.

Reflective call stack detections and evasions

Hook call stack spoof implementation for InternetOpenA
用于 InternetOpenA 的钩子调用堆栈欺骗实现

Some direct syscalls in BokuLoader have been replaced by spoofed indirect syscalls. To determine the syscall number, the HalosGate technique is still used. A simple gadget hunter has been added which searches for a syscall gadget within the executable section of the NTDLL module.
BokuLoader 中的一些直接系统调用已被欺骗性的间接系统调用所取代。为了确定系统调用号码,仍然使用HalosGate技术。添加了一个简单的小工具猎人,用于在 NTDLL 模块的可执行部分中搜索系统调用小工具。

Reflective call stack detections and evasions

Executing NtProtectVirtualMemory NTAPI via spoofed indirect syscall
通过欺骗性间接系统调用执行 NtProtectVirtualMemory NTAPI。

Closing thoughts 结语

We hope you found this post helpful and learned something new about call stack detections and evasions. If you are interested in learning more, check out Dylan’s recently released blog post “An Introduction into Stack Spoofing.” Stay tuned for our next post!
我们希望你觉得这篇文章对你有帮助,并学到了一些关于调用堆栈检测和逃避的新知识。如果您有兴趣了解更多信息,请查看 Dylan 最近发布的博客文章“堆栈欺骗简介”。请继续关注我们的下一篇文章!

References and resources

原文始发于securityintelligence:Reflective call stack detections and evasions

版权声明:admin 发表于 2023年10月10日 上午10:38。
转载请注明:Reflective call stack detections and evasions | CTF导航