注入
很多刚接触 Windows 恶意代码分析的人,看到银狐(Silver Fox / ValleyRAT / Winos)能往系统进程里申请内存、写内存、甚至把代码塞进去运行时,都会下意识觉得这很反常:
系统进程不是权限最高吗?为什么木马还能往里面写?
这个问题本身非常典型,因为它碰到的是 Windows 安全模型里一个很容易被误解的点。
先说结论:
Windows 的保护逻辑并不是:
系统进程
→
任何别的进程都不能碰
而更接近于:
只要当前进程满足访问条件
→
就可以对很多目标进程做跨进程操作
因此,银狐能往一些系统进程里写内存,并不意味着 Windows 完全没有保护;更准确地说,是因为这些目标进程并不一定处在更高等级的受保护状态,而银狐又已经拿到了足够的访问条件。
机制
很多人第一次看到这些 API,会觉得它们长得就像“恶意接口”。
例如:
OpenProcess()
VirtualAllocEx()
WriteProcessMemory()
CreateRemoteThread()
NtMapViewOfSection()
但这些接口本身并不是专门给木马准备的,而是 Windows 正常提供给调试器、诊断工具、安全产品和分析工具使用的能力。
例如下面这些合法程序,如果完全不能操作别的进程,就很难正常工作:
Visual StudioWinDbgx64dbgProcess Hacker
因为它们本来就需要:
- 打开其他进程。
- 读取和写入目标进程内存。
- 控制线程。
- 查看模块、句柄和地址空间。
所以从原理上看:
WriteProcessMemory
≠ 恶意行为本身
它只是会被恶意软件滥用。
流程
从公开分析和常见家族行为看,银狐的注入并没有特别“神秘”的机制,更多还是沿着常见的 Windows 跨进程操作路径来走。
典型思路通常可以概括为:
获取足够权限
↓
OpenProcess
↓
VirtualAllocEx
↓
WriteProcessMemory
↓
CreateRemoteThread
或者在部分场景下,使用基于节区映射的方式,例如:
NtMapViewOfSection
如果只看抽象过程,它大致做的是:
- 先找到一个想利用的目标进程。
- 拿到该进程足够强的访问句柄。
- 在目标进程地址空间中申请一块内存。
- 把要执行的内容写进去,可能是 DLL 路径、shellcode、配置数据或中转代码。
- 再让目标进程以某种方式执行那段内容。
所以从行为上看,“注入”不是单一动作,而是一整条组合链。
条件
问题的关键在于:
SYSTEM 进程
≠
受保护进程
这是最容易被混淆的地方。
Windows 中有大量进程运行在:
NT AUTHORITY\SYSTEM
上下文里,例如:
svchost.exeservices.exespoolsv.exetaskhostw.exe
这些进程权限确实高,但它们并不一定属于:
Protected Process
Protected Process Light (PPL)
如果恶意程序已经拿到了:
管理员权限
+
SeDebugPrivilege
它就往往有机会对这些非 PPL 的 SYSTEM 进程申请较强访问权限,然后做跨进程内存操作。
所以真正决定“能不能碰”的,不只是目标是不是 SYSTEM,更要看:
- 当前进程权限够不够。
SeDebugPrivilege是否已启用。- 目标进程是不是受更高等级保护。
- 系统是否还有额外的代码完整性和执行保护。
宿主
从公开报告和常见现象看,银狐常见的目标可能包括:
svchost.exeexplorer.exedllhost.exeRuntimeBroker.exemsedge.exe
它选择这些进程,通常不是因为“它们一定权限最高”,而是因为这些进程更适合隐藏。
常见原因包括:
- 这些名字很常见,出现在主机上不突兀。
- 它们本来就可能长期驻留。
- 某些进程本来就会联网、加载 DLL 或维持复杂线程活动。
- 在日志里看起来更像正常程序,而不是孤零零的陌生木马进程。
因此,银狐注入的目的很多时候不是单纯为了“拿更高权限”,而是为了:
- 隐藏自己。
- 降低被简单杀软发现的概率。
- 借正常进程外壳维持执行。
- 让后续持久化和通信更不显眼。
前置权限
这里要和 SeDebug 连起来看。
在银狐链路里,SeDebugPrivilege 通常不是“注入动作本身”,而是注入前的重要准备条件之一。
它的作用可以理解成:
让木马更容易打开高权限进程
↓
让 OpenProcess 更容易成功
↓
让后续 VirtualAllocEx / WriteProcessMemory / CreateRemoteThread 更容易成立
所以银狐很多时候并不是“直接就能注入”,而是先走这样一条顺序:
UAC Bypass
↓
管理员
↓
Enable SeDebugPrivilege
↓
OpenProcess
↓
内存操作
↓
注入
这也是为什么在检测里,单看某一次 WriteProcessMemory 价值还不够大,而把它和前面的权限变化连起来看,信号会更强。
特殊目标
很多人看到“管理员 + SeDebugPrivilege 可以操作很多进程”,就会自然推导出:
那是不是任何 SYSTEM 进程都能被注入?
答案仍然不是。
例如 lsass.exe 在现代 Windows 中经常会开启:
RunAsPPL
这会让它进入:
Protected Process Light
状态。
一旦目标进入 PPL,即使当前进程已经是管理员,甚至启用了 SeDebugPrivilege,也仍然可能在:
OpenProcess(PROCESS_VM_WRITE)
WriteProcessMemory
这些步骤上直接失败,返回:
Access Denied
这也是为什么很多更高阶样本,或者一些后渗透工具,在面对 lsass.exe、安全产品进程等高保护目标时,会继续引入:
BYOVD- 驱动提权
PPL Bypass
保护边界
从防守角度看,真正需要关注的不是“是不是系统进程”这么粗糙的问题,而是它有没有额外保护边界。
PPL
这是最重要的一层之一。
一旦目标进程处在 PPL 状态,普通管理员态进程就很难像对普通 SYSTEM 进程那样随意读写内存或做注入。
常见会被提到的例子包括:
lsass.exeMsMpEng.exe- 某些场景下的
csrss.exe
CFG
CFG 用来限制异常控制流跳转。
它不会让“所有注入”瞬间消失,但会提高下面这类行为的成功门槛:
- 远程线程落点异常。
- shellcode 跳转。
- 部分控制流劫持链。
CIG
CIG 更偏向限制代码完整性相关的加载行为。
它对某些 DLL 注入路径会形成额外限制,尤其是在依赖 LoadLibrary 的注入思路里更值得关注。
ACG
ACG 主要限制动态生成和执行可执行代码。
从攻击角度看,它会压缩这些空间:
- 直接申请
RWX内存。 - 临时拼接并执行 shellcode。
- 在受限进程里动态创建可执行页面。
Chrome、Edge 这类高价值宿主经常会结合这些机制提高攻击难度。
VBS
VBS 涉及的能力更广,例如:
Credential GuardHVCI
它并不是专门只针对注入,但会从凭据保护、内核完整性和隔离执行环境等角度整体提高攻击成本。
环境因素
一个很现实的原因是,很多企业环境本身就给它留出了成功空间。
常见情况往往是:
用户是本地管理员
↓
UAC 配置较弱或被关闭
↓
SeDebugPrivilege 可被启用
↓
目标进程不是 PPL
在这种前提下,下面这条链就更容易成立:
OpenProcess
↓
VirtualAllocEx
↓
WriteProcessMemory
↓
CreateRemoteThread
所以很多时候,银狐成功率高,并不一定是因为它用了特别罕见的技巧,而是因为环境本身就满足了它完成注入的条件。
检测
在进入具体检测前,可以先把常见注入手法按“载荷如何进入目标地址空间”和“执行流如何被触发”拆开。这样比只记 API 名更容易还原攻击链。
常见手法补充
| 手法 | 地址空间变化 | 执行触发 | 防守侧关键观察点 |
|---|---|---|---|
| 远程线程注入 | 在目标进程中分配、写入新内存 | 创建远程线程或等价线程对象 | 跨进程句柄、远程写入、线程起始地址位于私有内存 |
| APC 注入 | 通常先向目标进程写入载荷 | 把回调排入目标线程的 APC 队列 | 跨进程写入后紧跟 APC 排队,回调地址不属于正常模块 |
| 线程劫持 | 向目标写入载荷或复用已有内存 | 暂停线程、修改上下文、恢复线程 | 线程暂停与上下文修改成组出现,指令指针跳入私有页 |
| 进程空洞化 | 创建合法映像后替换或重映射其主要代码 | 恢复主线程或修改入口点 | 映像路径正常,但内存映像与磁盘文件不一致 |
| 节区映射注入 | 同一节区被映射到本地和目标进程 | 远程线程、APC 或线程劫持 | 跨进程共享节区、可执行映射、异常线程落点 |
| DLL 注入 | 让目标加载磁盘上的 DLL | 调用系统加载器 | 非标准路径 DLL、父子签名与路径错配、异常模块加载 |
| 反射加载 / 手工映射 | 在私有内存中自行完成映像装载 | 本地或远程执行流跳转 | 内存中存在 PE 结构却没有对应模块记录和磁盘文件 |
| 模块覆盖 | 借已加载模块的部分内存承载新代码 | 劫持已有导出或线程入口 | 已签名模块的内存页与磁盘内容不一致,页面权限异常 |
这里的分类不是互斥的。一次攻击可能用节区完成载荷传递,再用 APC 触发;也可能先空洞化启动器,随后从被替换的进程继续注入另一个长期驻留进程。
抽象案例
合法进程外观与内存身份不一致
一个来自用户下载目录的安装器创建了挂起状态的常见系统辅助进程。新进程的磁盘路径、图标和签名都正常,但恢复运行后出现三个异常:
- 主映像的内存代码与磁盘文件不一致。
- 主线程入口附近落在私有可执行内存,而不是原映像的代码段。
- 随后由该进程发起与其职责不符的公网通信。
这类组合更符合进程空洞化,而不能因为进程名和签名正常就判定安全。签名只证明磁盘上的原始文件;它不能替内存中后来被替换的内容背书。
没有远程线程也可能完成注入
某个高完整性进程先打开长期驻留的系统宿主,随后出现远程内存写入,但没有创建远程线程。短时间后,目标进程已有线程的执行地址跳到无文件映射的内存,并开始产生异常网络行为。
这种情况下应继续检查 APC、线程上下文修改、节区映射和回调劫持,不能把“没有 CreateRemoteThread”理解为“没有注入”。
看似注入,实际是进程内寄生
如果一个合法宿主自己按照插件、安装包或扩展机制加载了恶意模块,就不需要任何跨进程写入。日志里可能只有模块加载,甚至只剩下宿主进程执行异常行为。
这类情况应与注入严格区分,典型例子包括 DLL 侧加载、插件滥用和 MSI CustomAction。共同点是:
合法宿主主动加载不可信内容
≠
攻击进程把内容写进合法宿主
两者都能形成“白进程干坏事”的外观,但证据链、检测点和处置方式不同。
内存证据
分析注入时,建议同时回答下面四个问题:
- 谁取得了谁的句柄:调用方、目标进程、访问权限和完整性级别是否合理。
- 内容怎样进入内存:远程写入、共享节区、映像替换,还是目标进程主动加载。
- 执行流怎样到达载荷:新线程、APC、线程上下文、回调、导出函数或主入口。
- 载荷由什么支撑:正常映像、已删除文件、私有内存,还是被覆盖的模块页面。
高价值内存信号通常包括:
- 线程起始地址或当前指令指针位于
MEM_PRIVATE可执行页。 - 页面从可写变为可执行,且附近没有合理的 JIT 运行时。
- 内存中存在完整或残缺的 PE 头,但模块列表中没有对应项。
- 已加载模块的代码页与磁盘基线不一致。
- 调用栈出现从私有内存直接进入网络、凭据或持久化相关 API 的情况。
- 目标进程的实际行为与其正常职责明显冲突。
JIT、浏览器、.NET、Java、安全软件和某些防作弊组件也会产生私有可执行内存,所以内存属性不能单独定性,应与来源进程、签名、路径、调用栈和后续行为关联。
如果你在做 EDR Hunting、Sysmon 分析或主机排查,最值得关注的往往不是某一个孤立 API,而是整条注入链是否形成。
比较典型的链路是:
AdjustTokenPrivileges(SeDebugPrivilege)
↓
OpenProcess
↓
VirtualAllocEx
↓
WriteProcessMemory
↓
CreateRemoteThread
这条链通常就已经非常接近:
MITRE ATT&CK T1055
Process Injection
如果它前面还出现:
OpenProcess(winlogon.exe)
DuplicateTokenEx
ImpersonateLoggedOnUser
那就说明它很可能已经不是单纯的注入,而是进入了:
Token Theft
→
SYSTEM
→
Process Injection
的组合链路。
小结
银狐之所以能往很多系统进程里申请内存、写内存甚至注入代码,并不是因为 Windows 对系统进程完全没有保护,而是因为:
- Windows 本来就允许满足条件的进程做跨进程操作。
- 很多 SYSTEM 进程并不是
PPL。 - 银狐常常已经先获得管理员权限,并启用了
SeDebugPrivilege。 - 在目标没有更高保护边界时,常见注入链就可能成功走通。
因此更准确的理解应该是:
银狐能做注入
不是因为“系统进程不设防”
而是因为“它已经满足了访问这些目标进程的条件”
参考资料
- Solutions Against In-The-Wild Attacks From The New Variant of Sly Silver Fox - Sangfor Technologies
- Silver Fox Expands Winos 4.0 Malware Targets Southeast Asia With Privilege Escalation - Intertec Systems
- Looking for the ‘Sliver’ lining: Hunting for emerging command-and-control frameworks - Microsoft Security Blog