0%
毅种循环

模块 38 - 线程劫持 - 远程线程枚举

恶意软件开发课程 - 线程劫持 - 远程线程枚举


模块 38 - 线程劫持 - 远程线程枚举#

[!IMPORTANT] 本知识库声明

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

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

线程劫持 - 远程线程枚举#

简介#

本模块介绍如何使用 CreateToolhelp32Snapshot 枚举远程进程的线程。对上一模块中展示的 GetLocalThreadHandle 函数进行了少量修改,使其可以针对远程线程工作。

逻辑保持不变,即使用 CreateToolhelp32SnapshotThread32FirstThread32Next 来枚举目标进程的线程。针对远程进程时的区别在于,主线程也是劫持的有效目标。

💡 初学者提示:为什么远程主线程可以劫持?

在本地进程中,我们不能劫持自己的主线程,因为主线程负责运行代码。如果主线程挂起自己,它就无法再运行 SetThreadContextResumeThread 来完成劫持过程。

但在远程进程中,被劫持的线程和我们(注入者)所在的线程是相互独立的。我们可以放心地挂起远程的主线程,修改它的状态,然后再把它恢复,这不会影响我们自己程序的执行。

远程线程枚举函数#

GetRemoteThreadhandle 将枚举远程进程的线程。它需要 3 个参数:

  • dwProcessId - 这是目标进程的 PID。
  • dwThreadId - 指向将接收目标进程线程 ID 的 DWORD 的指针。
  • hThread - 指向将接收远程线程句柄的 HANDLE 的指针。

GetRemoteThreadhandle 函数实现的一个额外区别是需要提供目标 PID。当针对本地进程时,这是不需要的,因为 GetCurrentProcessId WinAPI 会检索本地进程的 PID。

远程线程劫持函数#

这部分类似于以前模块中看到的劫持函数。检索远程进程句柄,将 Payload 注入到远程进程中,最后劫持线程。

演示#

获取目标进程的 PID。在本例中,目标进程为 Notepad.exe

图片
图片

注入 Payload 并劫持线程 ID 7136。线程堆栈显示 Payload 的地址是下一个待执行的任务。

图片
图片

最后,Payload 被成功执行。

图片
图片


🎯 总结#

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

  1. 远程线程发现:使用 CreateToolhelp32Snapshot 发现属于特定远程 PID 的线程。
  2. 获取远程句柄:通过 OpenThread 获得对这些线程的完全控制权。
  3. 万物皆可劫持:在远程场景下,即使是正在运行的主线程也是劫持的好对象。

💡 关键要点

  • 劫持远程现有线程不需要创建新进程 (Module 36),因此更加低调。它利用的是目标进程已有的资产。
  • 风险与挑战:如果该线程正处于关键的系统调用或者持有某个锁,强制跳转到我们的 Payload 可能导致目标进程死锁或崩溃。在实际应用中,劫持那些处于可警报状态 (Alertable state) 或者不怎么活跃的后台线程会更安全。

📚 下一步学习

下一个模块将介绍 APC Injection (异步过程调用注入)。这是一种更优雅、更不容易被察觉的注入技术,它不需要手动修改线程上下文,而是直接向线程的队列中“派单”!