0%
毅种循环

模块 49 - 进程参数伪装 (2)

恶意软件开发课程 - 进程参数伪装 (2)


模块 49 - 进程参数伪装 (2)#

[!IMPORTANT] 本知识库声明

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

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

进程参数伪装 (2)#

简介#

在上一模块中,我们成功欺骗了 Procmon,使其记录了哑元(Dummy)命令行参数。然而,同样的技术在面对一些工具(如 Process Hacker)时效果并不理想。下图显示了上一模块的技术在 Process Hacker 中的显示结果。

图片
图片

可以看到,真实的参数被暴露了出来,同时还带着一截残留的哑元参数。本模块将分析为什么会发生这种情况,并提供解决方案。

分析问题#

为了更好地理解为什么真实参数会被暴露,我们将哑元参数设置为 powershell.exe AAAAAAA...

图片
图片

再次检查 Process Hacker,发现真实参数和哑元参数片段都被记录了。

图片
图片

💡 初学者提示:快照 vs 实时查询

  • Procmon:它就像一个交警,记录下车辆(进程)进入路口(启动)时那一瞬间的样子。所以它记录的是我们最初传入的“假参数”。
  • Process Hacker:它就像一个随时能够透视车辆内部的雷达。即使在车辆行驶过程中(运行时),它也可以通过特定的系统调用(如 NtQueryInformationProcess)去查看进程内存中的 PEB。

当 Process Hacker 查询 PEB 时,它会读取 CommandLine.Buffer。因为我们已经在内存里把它改成了真参数,Process Hacker 就能实时看到真相。

解决方案#

这些工具读取 CommandLine.Buffer 时,读取的字节数是由 CommandLine.Length 成员指定的。它们并不依赖于字符串的空终止符(Null-terminator),因为微软在 UNICODE_STRING 文档 中明确说明,该结构体的 Buffer 可能没有空终止符。

简而言之,为了防止在没有空终止符的情况下读取到额外的垃圾数据,这些工具限定了只读取 CommandLine.Length 指定长度的字节。

图片
图片

因此,我们可以通过将 CommandLine.Length 设置为小于实际 Buffer 大口的值来欺骗这些工具。这允许我们控制 CommandLine.Buffer 中的 Payload 被外界工具看到的程度。我们可以通过修补远程进程中 CommandLine.Length 的地址来实现这一点。

修补 CommandLine.Length#

下面的代码片段修补了 PEB->ProcessParameters.CommandLine.Length,使 Process Hacker 只能读取到 powershell.exe 部分。它的工作原理是:先按照常规方法伪装参数,然后再将长度修补为 sizeof(L"powershell.exe")

// 我们希望外部工具认为命令行只有 "powershell.exe" 这么长
DWORD dwNewLen = sizeof(L"powershell.exe");

// 定位并修补远程进程中的 CommandLine.Length
// 注意:Length 是一个 USHORT,但在此示例中使用 DWORD 写入前 4 字节(覆盖 Length 和 MaximumLength)
// 或者你可以更精确地只定位 Length 地址进行写入
if (!WriteToTargetProcess(Pi.hProcess, ((PBYTE)pPeb->ProcessParameters + offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine.Length)), (PVOID)&dwNewLen, sizeof(DWORD))){
  return FALSE;
}
c

演示#

Process Hacker 视图(现在只显示 powershell.exe):

图片
图片

Procmon 视图(仍然保留着最初的哑元参数 Totally Legit Argument):

图片
图片

通过这种结合手段,我们成功地在不同层面的监控工具面前都实现了伪装!


🎯 总结#

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

  1. UNICODE_STRING 的关键性:理解了 Length 成员如何决定外部工具读取的内容多少。
  2. 二次欺骗:学习了如何针对实时查询类工具(Process Hacker)进行补丁。
  3. 完美伪装:通过同时操作 Buffer(覆盖真命令)和 Length(截断显示),达到了在所有监控手段下都保持隐蔽的效果。

💡 关键要点

  • 长度修补:通过缩小 Length,我们可以让外部工具只看到进程名,而看不到后面的任何参数。
  • 实战建议:在红队行动中,这种“双重修补”是对抗专业防御者的必修课。

📚 下一步学习

完成了参数伪装后,我们已经掌握了非常进阶的进程欺骗技巧。在接下来的章节中,我们将学习更多关于 PE 结构解析和手动映射等更底层的对抗技术!