跳到主要内容

注入

很多刚接触 Windows 恶意代码分析的人,看到银狐(Silver Fox / ValleyRAT / Winos)能往系统进程里申请内存、写内存、甚至把代码塞进去运行时,都会下意识觉得这很反常:

系统进程不是权限最高吗?为什么木马还能往里面写?

这个问题本身非常典型,因为它碰到的是 Windows 安全模型里一个很容易被误解的点。

先说结论:

Windows 的保护逻辑并不是:

系统进程
→
任何别的进程都不能碰

而更接近于:

只要当前进程满足访问条件
→
就可以对很多目标进程做跨进程操作

因此,银狐能往一些系统进程里写内存,并不意味着 Windows 完全没有保护;更准确地说,是因为这些目标进程并不一定处在更高等级的受保护状态,而银狐又已经拿到了足够的访问条件。

机制​

很多人第一次看到这些 API,会觉得它们长得就像“恶意接口”。

例如:

OpenProcess()
VirtualAllocEx()
WriteProcessMemory()
CreateRemoteThread()
NtMapViewOfSection()

但这些接口本身并不是专门给木马准备的,而是 Windows 正常提供给调试器、诊断工具、安全产品和分析工具使用的能力。

例如下面这些合法程序,如果完全不能操作别的进程,就很难正常工作:

  • Visual Studio
  • WinDbg
  • x64dbg
  • Process Hacker

因为它们本来就需要:

  • 打开其他进程。
  • 读取和写入目标进程内存。
  • 控制线程。
  • 查看模块、句柄和地址空间。

所以从原理上看:

WriteProcessMemory
≠ 恶意行为本身

它只是会被恶意软件滥用。

流程​

从公开分析和常见家族行为看,银狐的注入并没有特别“神秘”的机制,更多还是沿着常见的 Windows 跨进程操作路径来走。

典型思路通常可以概括为:

获取足够权限
↓
OpenProcess
↓
VirtualAllocEx
↓
WriteProcessMemory
↓
CreateRemoteThread

或者在部分场景下,使用基于节区映射的方式,例如:

NtMapViewOfSection

如果只看抽象过程,它大致做的是:

  1. 先找到一个想利用的目标进程。
  2. 拿到该进程足够强的访问句柄。
  3. 在目标进程地址空间中申请一块内存。
  4. 把要执行的内容写进去,可能是 DLL 路径、shellcode、配置数据或中转代码。
  5. 再让目标进程以某种方式执行那段内容。

所以从行为上看,“注入”不是单一动作,而是一整条组合链。

直接写内存​

这里需要把两个经常被混在一起的问题分开:

NtWriteVirtualMemory 能不能修改目标进程?
能。

NtWriteVirtualMemory 能不能单独让新写入的内容执行?
通常不能。

NtWriteVirtualMemory 的职责是把一段数据复制到目标进程的地址空间。它本身不负责:

  • 在目标进程中申请新的内存区域;
  • 把页面变成可执行;
  • 创建或唤醒执行线程;
  • 修改线程指令指针;
  • 将 APC 排入目标线程。

因此,向新分配的私有内存写入 shellcode 后,通常还需要额外的执行触发步骤。如果没有任何线程、回调或既有执行路径到达这块地址,CPU 不会因为那里出现了数据就自动执行它。

什么时候“只写内存”也可能生效​

“只写内存”可以成立,但这里的“只写”是指远程操作中只观察到内存写入这一类动作,并不代表目标进程完全没有其他前置条件。典型前提包括:

  • 目标位置本来就在原有执行路径上,例如目标进程之后必然会调用的函数、回调或分发表项;
  • 写入位置已经具备合适的写权限,或者此前已经由其他机制准备好;
  • 写入内容能够直接改变既有控制流,且不会破坏指令边界、线程状态或程序所需的数据结构;
  • 目标进程原有线程稍后会自然经过该位置。

概念性例子如下:

目标进程的定时任务
↓
每隔一段时间调用 CheckUpdate()

攻击者对目标进程执行 NtWriteVirtualMemory
↓
修改 CheckUpdate() 的实现或其可写的回调指针
↓
目标进程原有线程下一次执行定时任务
↓
进入被修改后的逻辑

这个例子里,攻击者没有新建远程线程,也没有显式修改线程上下文;执行机会来自目标进程原本就存在的调用路径。类似思路也可能涉及函数指针、回调表、分发表或已加载模块中的控制数据。

但它不是“NtWriteVirtualMemory 天然等于执行”。如果目标代码页不可写,写入可能失败;如果写入的是一块从未被执行流引用的新内存,则仍然需要远程线程、APC、线程劫持、回调触发等后续动作。现代系统的 DEP、CFG、CIG、ACG 等机制也可能进一步影响成功率。

分析时的判断原则​

看到 NtWriteVirtualMemory 后,不要只问“有没有 CreateRemoteThread”,而要继续回答:

  1. 写入的目标地址属于代码页、数据页、私有页还是共享映射?
  2. 该地址是否已经被目标进程的线程、回调或间接调用路径引用?
  3. 写入后是否发生了页面权限变化、线程上下文变化、APC 排队或异常执行?
  4. 写入内容是参数和配置,还是代码、函数指针、回调地址等控制流相关数据?

所以,单独一个 NtWriteVirtualMemory 既不能直接证明注入,也不能因为没有远程线程就排除注入。关键在于写入对象与后续执行证据之间是否能闭合。

经典注入链​

最常被教学材料采用的链路是:

NtOpenProcess
↓
NtAllocateVirtualMemory
↓
NtWriteVirtualMemory
↓
(必要时)NtProtectVirtualMemory
↓
NtCreateThreadEx

每一步承担的职责不同:

阶段解决的问题防守侧要看的重点
NtOpenProcess获取目标进程句柄调用方、目标进程、请求的访问权限和完整性级别
NtAllocateVirtualMemory准备目标地址空间中的存储区域MEM_PRIVATE 区域、初始页面权限和分配时机
NtWriteVirtualMemory把载荷、路径、参数或引导数据写入目标写入地址、大小、内容类型和来源进程
NtProtectVirtualMemory在需要时调整页面保护属性RW → RX、RWX、是否存在合理的 JIT 或兼容性场景
NtCreateThreadEx让目标进程出现新的执行入口线程起始地址是否落在私有可执行页、调用栈和线程归属

高层 Win32 API 的等价抽象通常写成:

OpenProcess
→ VirtualAllocEx
→ WriteProcessMemory
→ VirtualProtectEx(可选)
→ CreateRemoteThread

这里的“等价”是能力层面的对应,不要求每个样本严格按照同样的 API 名称实现。样本也可能用节区映射、线程池、APC 或线程上下文操作替换其中某一环。

为什么要有这么多步骤​

因为经典链路通常面对的是一块目标进程原本没有的全新载荷:

新内存解决“放在哪里”
写入解决“把什么放进去”
权限调整解决“页面能否执行”
线程或其他触发机制解决“谁来执行”

而直接覆盖既有代码或控制数据,依赖目标进程原本就有合适的执行路径,兼容性、稳定性和可控性都更差。目标代码页常常是只读可执行,覆盖后还可能影响正在运行的其他线程;相比之下,准备独立内存并显式安排执行入口,更适合承载较大的独立载荷。

自注入:在自己的进程中执行载荷​

木马进行自注入(Self-Injection),通常是为了实现内存加载、运行时解密、规避静态检测,以及从 Loader 切换到真正的载荷逻辑,不一定是为了隐藏进程。与注入 explorer.exe、svchost.exe 等其他进程不同,自注入操作的是木马当前所在的进程。

这里的“自己”指同一个进程实例,不是“同名 EXE”。一个程序启动另一个同名进程,再向新进程写入代码,仍属于跨进程行为。

为什么已经运行,还要注入自己​

假设 malware.exe 已经运行,它为什么还要向自己的内存写入代码?因为已经运行的可能只是第一阶段 Loader,真正的恶意功能仍以加密、压缩或其他封装形式存放着,还没有进入执行状态。

目的具体原理
规避静态查杀磁盘 PE 中的核心载荷以加密或混淆形式保存,运行时才还原,减少原始恶意字节、字符串和结构的直接暴露
内存加载在本进程内运行还原后的 shellcode,或装载 PE/DLL,不必额外释放一个明文 EXE 或 DLL
分阶段执行第一阶段 Loader 负责取得、还原和装载载荷,第二阶段 Payload 执行真正的恶意功能
解包脱壳运行时解压、解密或解包代码,再将执行流交给还原后的逻辑
改变内存执行位置执行流从原始 PE 映像中的 Loader 转入新分配或准备好的载荷区域,代码仍在同一进程内运行

这些目的可以同时存在。一种典型关系是:

磁盘:Loader + 加密、压缩或封装的 Payload
↓ 启动时先运行 Loader
内存:Loader 还原出真正的载荷
↓ 在本进程中装载并转移执行流
第二阶段 Payload 开始执行恶意功能

加密、混淆解决“如何降低静态可见性”,运行时还原解决“如何得到可执行内容”,自注入解决“如何在当前进程中运行这些内容”。 加密后的字节不能直接作为原始载荷执行;但代码混淆不一定需要解密,有些混淆代码本来就可执行。自注入也可以加载未加密载荷。

加密、编码可能让依赖原始字节或字符串的静态签名漏检,混淆则会增加理解代码的成本,参见 MITRE T1027.013与运行时还原技术 T1140。这并不意味着所有静态分析都会失效:Loader、还原逻辑及封装特征仍可被分析,还原后的内容也能被内存扫描或行为检测发现。

自注入的典型过程​

下面是用于理解样本和遥测的示意流程,不是每个样本必然执行的固定 API 序列:

malware.exe 启动,先运行 Loader
↓
确定操作当前进程(采用带进程参数的接口时可使用自身句柄)
↓
VirtualAlloc / VirtualAllocEx:准备本进程内存区域
↓
在内存中解密、解压或还原内置 Payload
↓
直接写入 / 内存复制 / WriteProcessMemory:填充载荷区域
↓
VirtualProtect / VirtualProtectEx:按需调整为可执行权限
↓
当前线程转入载荷,或由 CreateThread 等方式安排执行
↓
第二阶段 Payload 运行

自注入不一定需要 WriteProcessMemory 或 CreateRemoteThread。 进程可以直接访问自己有权限操作的内存,因此也可能观察到 VirtualAlloc → 内存复制(如 memcpy)→ VirtualProtect → CreateThread 这样的本地加载行为。载荷也可以直接在目标区域被解密出来,无需单独复制;执行流可以来自既有线程或回调,无需新建线程。

VirtualAllocEx、WriteProcessMemory、VirtualProtectEx 等带目标进程参数的接口,不能仅凭名称判断为远程注入;要检查句柄实际指向谁。类似地,看到 CreateRemoteThread 或 NtCreateThreadEx 时,也应核实目标进程身份。微软的 VirtualAllocEx和 CreateRemoteThread文档说明了目标进程参数的含义。

分配、写入和执行是不同阶段:没有线程或回调到达相关地址,就不能仅凭“写入成功”认定载荷已经执行。页面权限转换也不是必备的独立步骤,实际行为取决于原有权限、映射方式和进程缓解策略。

自注入与远程进程注入的区别​

对比维度自注入远程进程注入
目标进程Loader 当前所在进程另一个进程实例
是否跨进程否是,即使进程名相同
常见目的内存加载、载荷解密、解包、阶段切换借用其他进程的执行上下文、隐藏后续行为等
是否需要远程进程句柄不需要,部分接口可使用自身句柄常见实现需要相应目标句柄或其他跨进程访问条件
是否必须创建远程线程否否,也可能使用 APC、既有线程或其他触发方式
对静态检测的影响配合加密、混淆与内存加载,可能降低载荷静态检出率取决于载荷保存形式与实现,跨进程操作本身不保证规避静态检测
能否隐藏原来的恶意进程通常不能,独立恶意 EXE 仍是原进程可能借用正常宿主,但原进程是否退出需另行取证
是否自动提权或持久化否否,取决于访问条件和后续动作

若 Loader 已经通过侧加载在合法进程中运行,自注入可以延续该宿主上下文;如果它原本就是单独的 malware.exe,向自身加载代码不会把它变成合法进程。自注入改变的是代码的存储位置和执行方式,不代表恶意行为对 EDR 不可见。

自注入不等于进程镂空​

自注入通常在同一个进程内加载并执行另一段代码;进程镂空(Process Hollowing,也称进程空洞化)通常创建一个挂起的进程,替换其原有映像或执行内容,再恢复执行。后者关注的是另一个进程实例及映像替换,参见 MITRE T1055.012。即使新进程与 Loader 来自同一个 EXE,也不能因为名称相同就称为自注入。

本进程反射 DLL 加载、直接 shellcode 执行和托管程序集内存加载,都可能呈现同进程加载行为;具体归类仍需区分装载机制,详见反射加载及 MITRE T1620。

如何防范与检测​

阻止不可信 Loader 或侧载 DLL 获得执行机会,是第一道防线:维护软件补丁,限制用户可写目录中的程序与插件执行,并按环境部署应用控制。最小权限能限制载荷后果,但不能阻止普通用户进程在自身内存中运行代码。

对适用程序评估 DEP、ACG、CFG 和代码完整性策略。DEP 阻止执行未标记为可执行的页面;ACG 进一步限制动态代码的可执行内存分配和权限转换;CFG 约束受保护的间接调用目标。它们各有覆盖边界,ACG 等设置还可能影响 JIT,应按程序验证兼容性后部署,不能理解成一个全局开关解决所有自注入。参见微软的利用防护参考。

检测重点应从“谁写入另一个进程”扩展为“同一进程怎样从数据走到代码”:关联输入来源、异常可执行区域、实际执行地址与网络或持久化行为。具体观察方法、误报边界和响应步骤见内存执行:自注入的检测与处置。

针对加密载荷,防守侧应同时检查磁盘上的 Loader 与运行时还原后的内容:在受控分析环境中关联解码前后的数据、内存内容和执行流,避免只对加密容器做一次静态扫描就结束研判。高熵或存在解密逻辑只能作为线索,合法压缩包、加密数据与软件保护也可能出现这些特征。

条件​

问题的关键在于:

SYSTEM 进程
≠
受保护进程

这是最容易被混淆的地方。

Windows 中有大量进程运行在:

NT AUTHORITY\SYSTEM

上下文里,例如:

  • svchost.exe
  • services.exe
  • spoolsv.exe
  • taskhostw.exe

这些进程权限确实高,但它们并不一定属于:

Protected Process
Protected Process Light (PPL)

如果恶意程序已经拿到了:

管理员权限
+
SeDebugPrivilege

它就往往有机会对这些非 PPL 的 SYSTEM 进程申请较强访问权限,然后做跨进程内存操作。

所以真正决定“能不能碰”的,不只是目标是不是 SYSTEM,更要看:

  • 当前进程权限够不够。
  • SeDebugPrivilege 是否已启用。
  • 目标进程是不是受更高等级保护。
  • 系统是否还有额外的代码完整性和执行保护。

宿主​

从公开报告和常见现象看,银狐常见的目标可能包括:

  • svchost.exe
  • explorer.exe
  • dllhost.exe
  • RuntimeBroker.exe
  • msedge.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.exe
  • MsMpEng.exe
  • 某些场景下的 csrss.exe

CFG​

CFG 用来限制异常控制流跳转。

它不会让“所有注入”瞬间消失,但会提高下面这类行为的成功门槛:

  • 远程线程落点异常。
  • shellcode 跳转。
  • 部分控制流劫持链。

CIG​

CIG 更偏向限制代码完整性相关的加载行为。

它对某些 DLL 注入路径会形成额外限制,尤其是在依赖 LoadLibrary 的注入思路里更值得关注。

ACG​

ACG 主要限制动态生成和执行可执行代码。

从攻击角度看,它会压缩这些空间:

  • 直接申请 RWX 内存。
  • 临时拼接并执行 shellcode。
  • 在受限进程里动态创建可执行页面。

Chrome、Edge 这类高价值宿主经常会结合这些机制提高攻击难度。

VBS​

VBS 涉及的能力更广,例如:

  • Credential Guard
  • HVCI

它并不是专门只针对注入,但会从凭据保护、内核完整性和隔离执行环境等角度整体提高攻击成本。

环境因素​

一个很现实的原因是,很多企业环境本身就给它留出了成功空间。

常见情况往往是:

用户是本地管理员
↓
UAC 配置较弱或被关闭
↓
SeDebugPrivilege 可被启用
↓
目标进程不是 PPL

在这种前提下,下面这条链就更容易成立:

OpenProcess
↓
VirtualAllocEx
↓
WriteProcessMemory
↓
CreateRemoteThread

所以很多时候,银狐成功率高,并不一定是因为它用了特别罕见的技巧,而是因为环境本身就满足了它完成注入的条件。

检测​

在进入具体检测前,可以先把常见注入手法按“载荷如何进入目标地址空间”和“执行流如何被触发”拆开。这样比只记 API 名更容易还原攻击链。

常见手法对比​

手法地址空间变化执行触发防守侧关键观察点
自注入 / 同进程内存加载载荷留在 Loader 自身地址空间当前线程、本地线程或回调进入载荷同一进程内的数据来源、内存变化与执行证据,不能依赖跨进程告警
直接写内存 / 执行流篡改修改既有代码、函数指针、回调或分发表;也可能写入已准备好的区域目标进程原有线程自然经过被修改的位置写入地址的内存类型与权限、是否属于控制流数据、写入后是否出现异常执行
远程线程注入在目标进程中分配、写入新内存创建远程线程或等价线程对象跨进程句柄、远程写入、线程起始地址位于私有内存
APC 注入通常先向目标进程写入载荷把回调排入目标线程的 APC 队列跨进程写入后紧跟 APC 排队,回调地址不属于正常模块
线程劫持向目标写入载荷或复用已有内存暂停线程、修改上下文、恢复线程线程暂停与上下文修改成组出现,指令指针跳入私有页
进程空洞化创建合法映像后替换或重映射其主要代码恢复主线程或修改入口点映像路径正常,但内存映像与磁盘文件不一致
节区映射注入同一节区被映射到本地和目标进程远程线程、APC 或线程劫持跨进程共享节区、可执行映射、异常线程落点
DLL 注入让目标加载磁盘上的 DLL调用系统加载器非标准路径 DLL、父子签名与路径错配、异常模块加载
反射加载 / 手工映射在私有内存中自行完成映像装载本地或远程执行流跳转内存中存在 PE 结构却没有对应模块记录和磁盘文件
模块覆盖借已加载模块的部分内存承载新代码劫持已有导出或线程入口已签名模块的内存页与磁盘内容不一致,页面权限异常

这里的分类不是互斥的。一次攻击可能用节区完成载荷传递,再用 APC 触发;也可能先空洞化启动器,随后从被替换的进程继续注入另一个长期驻留进程。

需要特别区分:直接写内存是一个动作,注入链是多个动作的组合。如果写入的只是配置、参数或进程间通信数据,它未必构成注入;只有当写入内容改变了目标进程的代码、控制流或执行相关数据,并且后续确实被目标进程使用时,才更接近“通过内存写入实现注入或执行流篡改”。

抽象案例​

合法进程外观与内存身份不一致​

一个来自用户下载目录的安装器创建了挂起状态的常见系统辅助进程。新进程的磁盘路径、图标和签名都正常,但恢复运行后出现三个异常:

  • 主映像的内存代码与磁盘文件不一致。
  • 主线程入口附近落在私有可执行内存,而不是原映像的代码段。
  • 随后由该进程发起与其职责不符的公网通信。

这类组合更符合进程空洞化,而不能因为进程名和签名正常就判定安全。签名只证明磁盘上的原始文件;它不能替内存中后来被替换的内容背书。

没有远程线程也可能完成注入​

某个高完整性进程先打开长期驻留的系统宿主,随后出现远程内存写入,但没有创建远程线程。短时间后,目标进程已有线程的执行地址跳到无文件映射的内存,并开始产生异常网络行为。

这种情况下应继续检查 APC、线程上下文修改、节区映射和回调劫持,不能把“没有 CreateRemoteThread”理解为“没有注入”。

看似注入,实际是进程内寄生​

如果一个合法宿主自己按照插件、安装包或扩展机制加载了恶意模块,就不需要任何跨进程写入。日志里可能只有模块加载,甚至只剩下宿主进程执行异常行为。

这类情况应与注入严格区分,典型例子包括 DLL 侧加载、插件滥用和 MSI CustomAction。共同点是:

合法宿主主动加载不可信内容
≠
攻击进程把内容写进合法宿主

两者都能形成“白进程干坏事”的外观,但证据链、检测点和处置方式不同。

内存证据​

分析注入时,建议同时回答下面四个问题:

  1. 谁取得了谁的句柄:调用方、目标进程、访问权限和完整性级别是否合理。
  2. 内容怎样进入内存:远程写入、共享节区、映像替换,还是目标进程主动加载。
  3. 执行流怎样到达载荷:新线程、APC、线程上下文、回调、导出函数或主入口。
  4. 载荷由什么支撑:正常映像、已删除文件、私有内存,还是被覆盖的模块页面。

高价值内存信号通常包括:

  • 线程起始地址或当前指令指针位于 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。
  • 在目标没有更高保护边界时,常见注入链就可能成功走通。

因此更准确的理解应该是:

银狐能做注入
不是因为“系统进程不设防”
而是因为“它已经满足了访问这些目标进程的条件”

参考资料​

  1. Solutions Against In-The-Wild Attacks From The New Variant of Sly Silver Fox - Sangfor Technologies
  2. Silver Fox Expands Winos 4.0 Malware Targets Southeast Asia With Privilege Escalation - Intertec Systems
  3. Looking for the ‘Sliver’ lining: Hunting for emerging command-and-control frameworks - Microsoft Security Blog