1. 杨CC有话说

无痕注入,不使用任何进程句柄的注入技术原理分析。
文章来源: 冲鸭安全

2. 无痕注入-不使用任何进程句柄的注入技术原理分析

破碎攻击(Shatter Attack)

概念来源

所谓 Shatter Attack 是一种早期(主要在 Windows NT、Windows 2000、Windows XP 时代被关注)的本地特权提升攻击方式。它利用的是 Windows 消息机制(Windows Messages)在同一桌面(desktop)环境下没有足够的安全隔离这一漏洞。

Windows 消息机制的背景

在 Windows 图形界面系统里,GUI 线程之间可以通过 SendMessage / PostMessage 等 API 发送消息。

这些消息(WM_XXX)会被目标窗口的回调过程(WindowProc 或过程函数)处理。

在设计上,所有同一交互会话中的应用程序都可以给彼此发送消息——包括输入消息、控制消息、甚至某些带有内存指针的结构(如 WM_TIMER、WM_COPYDATA、WM_SETTEXT)。如果目标进程是一个高权限进程(例如以管理员账户运行的 GUI 程序),而攻击者的低权限进程能向它发送精心构造的消息,就有可能诱使目标进程执行任意代码。

攻击原理

攻击者写一个低权限程序,找到同一桌面上运行的高权限进程窗口句柄(比如系统配置工具、服务管理器 GUI)。

利用 Windows 消息机制,向窗口过程发送带有指针的消息,让高权限进程执行某种动作(如调用回调函数、写入/读出内存)。

因为消息处理代码是在目标进程的上下文中执行的,这会让攻击者的代码在高权限进程里运行,从而提升权限。

使用的漏洞点

当时的核心问题:
高权限 GUI 程序与低权限 GUI 程序运行在同一个交互桌面 (interactive desktop) 上。
Windows 消息机制在用户模式下允许跨进程发送,并且缺乏足够的权限检查。
这种情况就被形象地称为 “Shatter”(打碎安全界限)攻击,因为它“打碎”了权限隔离的边界。

影响与修复

微软在后续更新(尤其是 Windows XP SP2 以后)中,加强了对 SendMessage 等 API 的检查,限制不同安全级别进程之间的消息交互。

从 Windows Vista 开始,引入了 “用户界面特权隔离” (User Interface Privilege Isolation, UIPI) / 低完整性级别机制,阻止低权限程序向高权限程序发送某些危险消息。

现代复兴

  • 这个跟Storm-0978的利用路线一样,我们先说一下时间线:
  • 深度研究APT组织Storm0978的高级注入技术StepBear
  • 2017年最开始被人拿去在CSGO上搞外挂,因为这是一种不用进程句柄的远程进程读写技术
  • 2022年又被提出来了一次
  • 2024年就看到毛子APT在大规模滥用了
  • 再然后,这种东西就跟VMP3源码一样,传来传去,到最后免费送了, 所以到现在,被开源了,那也没什么好藏着掖着的了,直接来介绍这块吧.
  • 这项技术的优点是:
    1. 不需要进程句柄,因此可以绕过一些进程访问控制机制。
    1. 很难进行行为检测,恶意软件利用基本能实现断链.
  • 缺点:
    1. 开了CFG拉闸
    1. 很多窗口默认都开了CFG, 所以一般游戏用得多.但是对于安全领域,总有些窗口是没CFG的
  • 没开CFG的窗口

核心原理介绍

让AI复习一下setwindowshook的工作原理

任意代码执行

SetWindowsHookEx负责设置要执行的位置,而我们还需要执行的代码,而SendMessage是非常好的执行的API,但是我们依然要找个gate,来把 msg->wparam、msg->lparam 和 msg->id 反序列化到三个不同的寄存器,然后通过 JMP [RAX] 调用 msg->lparam
所以作者准备了两个gate,作为布局,分别是RtlpFcChangeRegistrationCallback和_PsxaCallOwner
而毛子的APT组织用的是I_RpcFreePipeBuffer

整个流程如下

1
2
3
4
5
6
7
8
9
 SendMessageA(hwnd, WM_APPCOMMAND, wparam, lparam)
      ↓
  SetWindowsHookEx的 WH_SHELL Hook 被触发,执行 w (write gadget)
      ↓
  w 读取 wparam 结构体中的 function_ptr (即 t)
      ↓
  t (trampoline) 解析参数,调用 memcpy 字段指向的实际函数
      ↓
  实际目标函数执行 (RtlCopyString, malloc, 或任意函数)

第一个gate

这个代码里面,作者第一个gate是
RtlpFcChangeRegistrationCallback
一旦发送消息后,目标进程就会执行
gate_one(nCode, wParam, lParam)
而这个地方长这样:

1
2
3
4
5
6
__int64 __fastcall RtlpFcChangeRegistrationCallback(__int64 a1, __int64 a2)
{
  RtlAcquireSRWLockExclusive(a2 + 0x20);
  (*(void (__fastcall **)(_QWORD))(a2 + 0x10))(*(_QWORD *)(a2 + 0x18));
  return RtlReleaseSRWLockExclusive(a2 + 32);
}
  • 他会执行wParam+0x10的代码,并且把0x18当作参数1传入到里面,也就是开始执行第二个gate

第二个gate

  • 第二个gate在shell32里面,叫做_PsxaCallOwner,参数1成了前一个gate写的wpawn + 0x18了
    而参数2,rdx成了之前的wpawn的0+0x8了:

总结

让AI画了个图

3. 检测

他不是完全不能检测,如果EDR采集了窗口数据源,或者像xxx一样有核晶或者infinityhook的话,就非常容易检测了,所幸,win32k数据源,hypervisor,infinityhook这三个已经成为大部分安全软件的基础设施组件了.所以检测起来不难.就拿EDR来说,他的检测结果跟之前的APT的检测结果完全一样,就是因为EDR采集了win32k数据源

4. 源码

本人以及公众号并非作者,不对它具有任何法律责任
https://github.com/waryas/WaryasSWHE

5. 结束语

  • CTRl+D 将本网站:ycc77.com添加到书签栏哦~
  • 需要资源,记得将ycc77.cn 添加到书签栏哦~
  • QQ交流群:660264846(满)
  • QQ交流群2:721170435
  • B站: 疯狂的杨CC
  • 抖音: 疯狂的杨CC
  • 快手: 疯狂的杨CC
  • 公众号:SGY安全
  • 91: 疯狂的杨CC
  • p站: 疯狂的杨CC