
Crystal Palace 库,用于通过线程池代理 Nt API 调用。已针对调用 gadgets 进行更新。
这是 https://github.com/AlmondOffSec/LibTPLoadLib 的泛化版本,用于代理具有任意数量(实际上最多 11 个,但已经够用)参数的 API。以 Crystal Palace 共享库的形式提供。API 与 @rasta-mouse 的 LibTP 兼容,方便通过 spec 文件切换。提供了一些钩子,用于展示最新的 Crystal Palace 特性。
警告 ⚠️ :本项目不能原样直接使用。我没有提供一个用于查找 call gadget 的模块。你需要自己寻找。阅读博客文章了解更多信息。
注意 :由于能够传递 11 个参数(其中 7 个会被压入栈),call gadget 必须位于具有足够大栈帧的函数中。寻找 add rsp 至少为 0x68 的代码。
警告 ⚠️ :由于此技术的内部工作原理,无法获取被代理函数的返回值。代理 NTAPI 通常更实用,因为它们的返回值“只是”NTSTATUS。不过这也使得难以判断函数是否真的成功执行了 🙃。
在目标上可用的模块中找到一个可用的 gadget。在 src/tp_gadget.c 中,将其名称补丁到 LoadLibraryA 调用中,并修改 GetCallGadgetAddress 函数以获取其地址。如有必要,修补汇编存根(sub rsp 的值、gadget 将调用的寄存器)。
编译项目:make。输出为 Crystal Palace 共享库 libtp_gadget.x64.zip。
编译示例 COFF(该示例只会加载 wininet.dll,然后本地分配并执行 shellcode):make -C example_print。输出为 COFF 文件 example_print.x64.o。
创建一个 Crystal Palace spec 文件,指示链接器在 DFR 上使用我们的钩子:使用 Tradecraft Garden 的 Simple PIC spec 文件,并在 mergelib "../libtcg.x64.zip" 和 export 之间添加以下行:
mergelib "../libtp_gadget.x64.zip"
attach "KERNEL32$LoadLibraryA" "H_LoadLibraryA"
optout "ProxyNtApi" "H_LoadLibraryA"
attach "NTDLL$NtOpenProcess" "H_NtOpenProcess"
attach "NTDLL$NtAllocateVirtualMemory" "H_NtAllocateVirtualMemory"
attach "NTDLL$NtWriteVirtualMemory" "H_NtWriteVirtualMemory"
attach "NTDLL$NtProtectVirtualMemory" "H_NtProtectVirtualMemory"
attach "NTDLL$NtFreeVirtualMemory" "H_NtFreeVirtualMemory"
attach "NTDLL$NtClose" "H_NtClose"
attach "NTDLL$NtCreateThreadEx" "H_NtCreateThreadEx"
attach "NTDLL$NtOpenThread" "H_NtOpenThread"
attach "NTDLL$NtSuspendThread" "H_NtSuspendThread"
attach "NTDLL$NtResumeThread" "H_NtResumeThread"
attach "NTDLL$NtGetContextThread" "H_NtGetContextThread"
attach "NTDLL$NtSetContextThread" "H_NtSetContextThread"
attach "NTDLL$NtWaitForSingleObject" "H_NtWaitForSingleObject"
使用 Crystal Palace 链接整个工程以生成 PIC shellcode:path/to/crystalpalace/link simplepic_modified/loader.spec example_print/example_print.x64.o out.bin。
使用任意加载器运行 shellcode。