0%
毅种循环

模块 29 - 进程注入 - Shellcode 注入

恶意软件开发课程 - 进程注入 - Shellcode 注入


模块 29 - 进程注入 - Shellcode 注入#

[!IMPORTANT] 本知识库声明

本知识库由本人整理自互联网 MalDev Academy 泄露资源,并由本人手动翻译为中文,过程中增加了大量关键技术提示实践心得

  1. 内容完整性:并未修改任何核心代码与技术逻辑,仅做汉化与注释加强。
  2. 版权归属:原始知识产权归原作者/官方所有。
  3. 支持正版:本仓库仅供内部学习交流,如果您有经济能力,请务必支持正版课程
  4. 权利申诉:如相关内容侵犯了您的权益,请联系我,我将立即核实并删除。

进程注入 - Shellcode 注入#

简介#

本模块将与之前的 DLL 注入模块类似,只有细微的变化。Shellcode 进程注入将使用几乎相同的 Windows API 来执行任务:

💡 初学者提示:API 的 “Ex” 后缀

你会发现很多 API 都有个 “Ex” 版本(如 VirtualAlloc vs VirtualAllocEx)。

  • 无后缀(如 VirtualAlloc):通常只操作当前进程
  • Ex 后缀(如 VirtualAllocEx):Extended(扩展)版本,通常接受一个 hProcessHandle 参数,允许操作指定进程(本地或远程)。
  • 例外:有些 Ex 函数只是增加了额外参数(如 VirtualFreeEx),功能本质不变但作用域变了。

枚举进程#

与前一个模块类似,进程注入从枚举进程开始。下面显示的进程枚举代码片段已在前一个模块中解释过。

Shellcode 注入#

要执行 Shellcode 注入,将使用 InjectShellcodeToRemoteProcess 函数。该函数接受 3 个参数:

  1. hProcess - 已打开的远程进程的句柄。
  2. pShellcode - 去混淆后的 Shellcode 的基地址。Shellcode 在注入之前必须是明文,因为一旦进入远程进程就无法编辑它(实际上可以但很麻烦)。
  3. sSizeOfShellcode - Shellcode 的大小。

Shellcode 注入 - 代码片段#

📚 知识扩展:为什么在远程进程中执行 Shellcode?

  • 无文件落地:Shellcode 直接写入内存,不需要像 DLL 注入那样在磁盘上放一个 .dll 文件。
  • 更难检测:没有文件 I/O 操作供 AV 扫描。
  • 更灵活:可以注入任何代码,不仅仅是加载 DLL。
  • 执行步骤
    1. VirtualAllocEx (RW) -> 申请内存
    2. WriteProcessMemory -> 写入代码
    3. VirtualProtectEx (RX/RWX) -> 改为可执行
    4. CreateRemoteThread -> 执行 这个 “Alloc -> Write -> Protect -> Exec” 模式是所有代码注入的基石。

释放远程内存#

VirtualFreeEx 是一个用于释放远程进程中先前分配的内存的 WinAPI。此函数应仅在 Payload 完全执行完毕后调用,否则可能会释放 Payload 的内容并导致进程崩溃。

BOOL VirtualFreeEx(
  [in] HANDLE hProcess,
  [in] LPVOID lpAddress,
  [in] SIZE_T dwSize,
  [in] DWORD  dwFreeType
);
c

VirtualFreeEx 接受与 VirtualFree WinAPI 相同的参数,唯一的区别是 VirtualFreeEx 接受一个额外的参数(hProcess),该参数指定内存区域所在的驻留进程。

调试#

在本节中,使用 xdbg 调试器调试实现,以进一步了解底层发生的情况。

本演练将 Shellcode 注入到 Notepad 进程中,因此首先打开 Notepad 并将 x64 xdbg 调试器附加到它。下图显示该进程的 PID 为 22992

图片
图片

运行 RemoteShellcodeInjection.exe,提供 notepad.exe 作为参数。二进制文件将开始搜索 Notepad 的 PID,它应该与 xdbg 调试器中显示的 PID 相同,在本例中为 22992

图片
图片

接下来,二进制文件将解密 Payload。请注意,尝试访问内存地址将导致错误。发生这种情况是因为调试器附加到了 notepad.exe 进程,而去混淆过程发生在本地进程 RemoteShellcodeInjection.exe 中。

图片
图片

要查看去混淆的 Payload,必须打开一个新的 xdbg 实例并将其附加到 RemoteShellcodeInjection.exe 进程。

图片
图片

回到 Notepad 调试器实例,下一步是内存分配。将写入 Payload 的基地址是 0x0000021700230000。调试器显示分配的内存区域已归零。

图片
图片

然后将去混淆的 Payload 写入远程进程中分配的内存区域。

图片
图片

分析本地进程,Payload 已成功归零,因为不再需要它。

图片
图片

最后,Payload 在远程进程的新线程内执行。

图片
图片


🎯 总结#

在本模块中,我们学习了:

  1. 远程 Shellcode 注入:如何在不使用 DLL 的情况下将代码注入另一个进程。
  2. 核心 APIVirtualAllocEx -> WriteProcessMemory -> VirtualProtectEx -> CreateRemoteThread
  3. 调试跨进程注入:如何使用 x64dbg 分别调试注入器(Injector)和目标进程(Target)。

💡 关键要点

  • Shellcode 注入 vs DLL 注入:Shellcode 更隐蔽(内存中执行,无文件),但开发 Shellcode 比编写 DLL 更难。
  • 内存清理:在将 Shellcode 写入远程进程后,立即在本地进程中擦除明文 Shellcode 是良好的 OpSec 习惯。
  • CreateRemoteThread:依然是最大的检测指标。后续模块将学习如何避免使用它。

📚 下一步学习

下一个模块将介绍 Payload Staging(恶意载荷分段)。我们不再将整个 Payload 硬编码在二进制文件中,而是从网络服务器下载!