红蓝对抗下的lsass护城河:RPC通道与DLL注入的检测和防御
2026/9/15 19:34:37 网站建设 项目流程

前阵子做红蓝对抗复盘,有个测试项特别有意思:目标机器装了卡巴斯基,进攻方想通过RPC通道对lsass发起DLL注入,结果连续几次尝试都被拦了下来。这个案例后来成了我们团队内部讨论的素材,因为“RPC控制lsass注入DLL”这件事,正好踩在Windows安全机制、杀软主动防御、以及红蓝对抗思路的交汇点上。

这篇笔记不谈怎么绕过杀软,那是攻击者的事,我作为防守方也没打算给你整理一份“可用的载荷”。我更想拆解的是:这条路为什么有人想走,卡巴斯基是如何把这条路堵死的,以及作为防守方,我们应该怎么复现攻击链、收集检测规则、加固现有环境。无论你是安全运维、蓝队成员,还是对Windows内部机制感兴趣的朋友,这篇文章应该都能给你一些可落地的参考。

1. 先搞懂攻击者为什么盯上lsass

1.1 lsass在Windows安全体系里的地位

lsass(Local Security Authority Subsystem Service)是Windows系统上处理本地登录、域登录、访问令牌验证、密码策略校验的核心进程。简单说,用户每次输入密码登录,最终都要由lsass来验证凭据是否正确;每次访问资源需要权限检查,也会经过LSA(Local Security Authority)这个逻辑体。

正因为lsass要处理这么多敏感操作,Windows把很多关键凭据材料都放在它的内存空间里:登录会话的NTLM哈希、Kerberos票据、DPAPI主密钥、缓存的域凭据等。攻击者只要能在lsass进程内执行代码,不用碰硬盘上的SAM文件,直接从内存中就能提取出可用于横向移动的凭据材料。这就是所谓的“内存凭据窃取”。

从防守方的角度看,lsass就是Windows凭据体系的心脏。心脏一旦被植入恶意代码,整台机器的身份边界基本就形同虚设。这也是为什么微软从Windows 8.1开始引入LSA保护功能(RunAsPPL),后来又把Credential Guard作为独立方案推向企业环境。

1.2 为什么选择DLL注入,而不是直接读进程内存

很多人会问:不是有mimikatz这类工具可以直接读lsass内存吗?为什么还要折腾DLL注入?

这两条路径的目标并不一样。直接读内存是“旁观者”视角,工具通过打开lsass进程、申请内存读写权限,把目标进程里的明文口令或哈希dump出来。这条路在安装了较新补丁和杀软的环境中越来越难走,因为lsass被标记为受保护进程(PPL)后,普通权限的进程连打开它的句柄都会被拒绝。

DLL注入则是“参与者”视角。攻击者把一段DLL加载到lsass内部,DLL会在lsass进程上下文中执行,等于在心脏里放了个“内鬼”。这种方式可以绕过很多基于句柄权限的访问检查,因为代码已经是lsass自己的一部分了。无论后续要做内联hook、篡改认证逻辑,还是直接内存中搜索凭据,注入后的操作空间都比外部读取大得多。

1.3 站在红蓝对抗视角看待“RPC控制”这个入口

攻击者要在目标机器上触发DLL注入,总得有个“遥控器”。RPC就是很多远程下发任务的首选通道:Windows自带大量RPC接口,系统服务默认开放,而且RPC调用看起来像正常业务流量,不易被网络监测发现。

典型的攻击模型是:攻击者先在目标机上投放一个轻量级服务端组件(可能是DLL,也可能是独立进程),这个组件注册一个RPC接口并持续监听。攻击者从远端调用这个RPC接口,发送“加载某路径的DLL”指令,服务端组件再用本地权限完成注入。整个过程分为两步——先建立通道,再实施注入。通道本身不直接攻击lsass,因此容易被杀软忽略;真正敏感的只有第二步。

我在红蓝对抗中见过不少团队偏好这种“RPC控制+本地执行”的模式。它的优势很明显:远程通道只传递控制指令,网络层看不到明显的恶意特征;载荷留在本地,扫码特征也相对小。但它同样有致命弱点:无论RPC通道包装得多好,最终对lsass的注入动作一定会暴露进程访问痕迹和行为特征,而这正是杀软主动防御的捕捉范围。

2. 拆解注入链条:从RPC指令到lsass进程

2.1 注入动作在RPC服务端如何被触发

从RPC服务端收到指令到真正执行注入,中间通常有几步:反序列化指令、解析目标进程PID/进程名、校验DLL路径、然后调用注入相关的API。这个过程中,服务端进程的权限决定了注入能否成功。

在红蓝对抗测试环境里,攻击者一般会让RPC服务端以SYSTEM权限运行。原因很简单,lsass是受PPL保护的进程,普通管理员权限并不足以打开lsass句柄;SYSTEM权限配合调试特权(SeDebugPrivilege)才有可能。而SYSTEM权限的获取路径包括:Windows服务(以LocalSystem账户注册)、计划任务、服务端组件借壳提权等。

这部分细节点很重要:RPC服务端只负责“传话”,实际的动作发生在本地的OpenProcess调用上。如果服务端权限不够,OpenProcess会直接失败,攻击者就会收到一个类似于“无法打开进程”的RPC错误返回。我在测试环境里见过很多次,RPC调用一直报超时或拒绝访问,这种时候往往不是网络问题,而是服务端进程权限不足。

2.2 教科书式的DLL注入四步法

抛开各种免杀技巧,最基础的DLL注入一定绕不开以下四个API调用链:

  1. OpenProcess:打开目标进程,申请PROCESS_CREATE_THREAD、PROCESS_QUERY_INFORMATION、PROCESS_VM_OPERATION、PROCESS_VM_WRITE、PROCESS_VM_READ等权限。
  2. VirtualAllocEx:在目标进程空间内分配一块内存,用于写入DLL的完整路径字符串。
  3. WriteProcessMemory:把DLL路径写入上一步分配的内存区域。
  4. CreateRemoteThread:在目标进程中创建远程线程,指定入口函数为LoadLibraryW,参数为DLL路径地址。

这四步看着简单,但在有杀软的环境里每一步都可能触发主动防御。卡巴斯基的监控体系会对“高危进程+敏感操作”的组合做行为判定:谁在打开lsass?用什么权限打开的?打开之后是否立刻申请写内存?是否创建远程线程?这些动作单独看可能都是合法API,组合起来就是典型的注入行为,命中规则后直接拦截。

2.3 lsass的PPL保护到底拦住了什么

Windows 8.1之后,lsass可以通过注册表或组策略开启LSA保护(RunAsPPL),让lsass成为受保护进程(Protected Process Light,PPL)。PPL机制的核心是:只有签名级别不低于目标的进程,才能打开受保护进程的句柄。

这意味着,就算攻击者拥有管理员权限,如果没有微软签名的特殊类别驱动程序,也无法对lsass执行打开、读取、写入操作。SYSTEM权限也未必管用,因为PPL检查的是进程签名级别,不是身份级别。

但PPL不是万无一失的。红蓝对抗中,有人利用签名级别漏洞或合法驱动把进程提升到更高PPL级别,再访问lsass。这就是“Bring Your Own Vulnerable Driver”一类攻击的动机。卡巴斯基对这类“修改进程保护级别”的行为也做了专门的监控,一旦发现尝试加载不明驱动或篡改受保护进程配置,就会报警。

2.4 卡巴斯基为什么能识破“RPC+DLL注入”这个套路

卡巴斯基的主动防御体系大致分三层:文件特征扫描、行为流分析、基于内核的回调监控。注入lsass这个行为几乎同时触发这三层。

文件特征层:如果DLL文件本身带有已知恶意特征或壳特征,会在写入磁盘、加载内存前就被拦截。

行为流层:即便DLL没有特征,系统监控组件会记录进程行为,包括进程打开、句柄请求、内存分配、线程创建等。一旦发现lsass出现“目标进程被跨权限访问+远程线程创建”的组合,就会判定为可疑行为。

内核回调层:卡巴斯基驱动注册了进程创建、进程映像加载、句柄操作等内核回调,能够看到比用户态API更底层的信息,攻击者很难通过用户态hook绕过这类监控。

所以,单纯研究“RPC控制”并没有什么高明之处,真正难的是让后面的注入行为看起来像正常行为。而对防守方来说,我们不需要关心攻击者怎么藏,只需要保证这些行为特征能完整被记录、被告警,就已经赢了一半。

3. 卡巴斯基环境下的模拟验证与检测记录

3.1 搭建一个内网隔离测试环境

前面说的都是理论,真正的实战在测试环境里才能得到验证。我建议有条件的团队搭一个隔离的测试域,不要在办公网和生产环境做这类实验。

硬件和系统方面,我测下来比较顺手的组合是:

角色配置
攻击机Windows 10 22H2,安装Python环境和必要的RPC工具链
目标机Windows Server 2019,加入测试域,安装卡巴斯基企业版
域控Windows Server 2016/2019,提供Kerberos认证和组策略下发

测试网络务必与办公网隔离,同时保留一个可抓包端口镜像或网络日志收集节点,方便记录攻击机的RPC通信过程。卡巴斯基需要开启“系统监控”和“应用程序控制”组件,并设置为“交互模式”,这样每一次拦截都会弹出提示,方便实时观察。

3.2 执行一次“被拦截”的注入测试

测试的目的是观察卡巴斯基如何拦截,而不是教大家如何绕过。所以在目标机上,我选择了公开的、已经能被杀软查杀的Demo载荷:一个简单的DLL,导出函数只是弹出消息框,再配合一个通过RPC接口下发加载指令的测试脚本。整个过程刻意不做任何免杀处理,就是为了让卡巴斯基能正常识别。

实际执行时观察到以下现象:

  1. RPC调用本身没有被拦,网络层没有告警。这说明RPC通道的隐蔽性确实高。
  2. 注入动作发起后,卡巴斯基弹出行为告警,提示“进程试图在受保护进程中启动远程线程”,并显示注入方进程路径、目标进程路径、API调用栈。
  3. 点击拦截后,注入失败,DLL没有被加载,lsass进程完好。

这个测试印证了一点:RPC通道能过,但真正“做事”的注入动作一定会在行为监控层面露出马脚。

3.3 卡巴斯基如何记录和分析可疑进程行为

卡巴斯基企业版的“系统监控”会把进程行为记录为事件图,包括进程的父进程、子进程、打开的文件、注册表操作、内存操作、网络连接等。当事件图里出现“一个非系统进程打开lsass句柄并远程写入内存”的路径时,就会生成优先级较高的入侵检测事件。

这类事件不仅包含进程名和路径,还会带上哈希值。如果DLL是本地生成的,哈希值可能查不到签名,那么“未签名/低信誉文件访问受保护进程”也会成为加分告警项。集中管理平台里可以直接搜索事件,也可以导出发给SIEM进一步关联分析。

我整理的排查思路,后面排查环节里还会展开,先记住一个原则:lsass相关进程访问事件要优先看,不要等业务投诉了再看日志。

4. 针对性防御:把lsass变成“刺猬”

4.1 开启Windows原生LSA保护

如果还没开启LSA保护,第一步就是开启它。在注册表位置HKLM\SYSTEM\CurrentControlSet\Control\Lsa下,把RunAsPPL的值设为1,重启后生效。

也可以通过组策略配置“计算机配置-管理模板-系统-本地安全机构-配置LSA保护”,选择“已启用(带UEFI锁)”模式更稳妥。开启成功后,可以运行以下PowerShell命令验证:

$lsa = Get-Process lsass $lsa.PriorityClass # 如果LSA保护生效,可以通过进程模块列表中看到RunAsPPL相关签名状态 # 更直观的方式:通过WinDbg或Process Explorer观察进程保护级别 # 使用微软官方PsExec的-s参数查看进程信息并确认保护级别 # 或者在命令行执行:whoami /priv 查看当前权限

注意,开启PPL之后,普通管理员工具(比如某些解析lsass内存的脚本)都会失效,这是预期效果,不要因为“排查不方便”就关掉保护。

为了降低对运维的影响,建议先在测试域开启,验证业务兼容性之后,再通过组策略分批推广。

4.2 启用Credential Guard进一步隔离凭据

PPL保护的是进程边界,Credential Guard则是把凭据隔离到了虚拟化安全进程(VBS)中,即使lsass被完全攻破,攻击者也拿不到受VBS保护的凭据材料。这是纵深防御里最有效的一层。

在Server 2019/2022和Win10/11企业版中,可以通过“设备安全性-内核隔离-凭据保护”开启。也可以用组策略或以下命令检查状态:

Get-ComputerInfo -Property DeviceGuard*

启用Credential Guard有一点需要特别注意:域环境下的NTLM传统凭据将无法缓存,部分老旧的应用程序或服务如果依赖NTLM就容易出现认证问题。上线前务必做兼容性测试。

4.3 卡巴斯基主动防御的加固配置

卡巴斯基本身的默认防护已经很能打了,但针对lsass注入的专项防护,还可以再拧几颗螺丝:

  • 启用“应用程序控制”中的“受保护进程”规则:把lsass.exe加入受保护列表,禁止任何未知进程读取其内存。
  • 打开“系统监控”中的“远程线程创建”告警开关,并配置为“阻止并记录”。
  • 在“威胁防护”中开启“检测权限滥用”或“利用防护”选项,可以覆盖很多绕过PPL的手法。

这里有一个容易忽略的配置:部分企业版把卡巴斯基配置为“自动选择操作”模式,误报少,但漏报率也会变高。安全要求高的机器,建议对关键服务器设置“交互模式”或“询问模式”,让管理员能够看到每一次可疑行为,再决定是否放行。从我的经验看,宁可前期多一点弹窗,也不要等出事了才后悔没有细粒度日志。

4.4 收敛RPC攻击面

攻击者需要用RPC,我们就应该减少可被利用的RPC入口。以下几个方向可以直接执行:

  1. 删除不再使用的COM/DCOM组件注册信息,尤其是与本地激活相关的组件。
  2. 通过防火墙规则限定RPC动态端口范围,只允许特定源IP访问。
  3. 对于不需要远程管理的机器,禁用远程注册表服务和Remote Procedure Call Locator等不常用服务。
  4. 所在域环境里,尽量启用“身份验证级别”更高的RPC策略,拒绝匿名RPC调用。

RPC不容易被直接关闭,因为Windows核心功能依赖它,所以大原则是“能不开就不开,能限制就限制”。不需要为了安全把RPC服务停掉,那样会造成系统级故障。

5. 检测规则的落地与日志收集

5.1 安装并配置Sysmon,记录进程访问和远程线程

Sysmon是Windows Sysinternals工具,可以记录进程创建、网络连接、进程访问、哈希、驱动加载等高级事件。想要发现lsass注入行为,至少要开启EventID 8(CreateRemoteThread检测)和EventID 10(ProcessAccess检测)。

下面是一份精简的配置示例,把lsass进程访问和远程线程创建都记录为告警:

<Sysmon schemaversion="4.22"> <EventFiltering> <!-- 记录所有进程访问,但只记录目标进程为lsass的事件 --> <ProcessAccess onmatch="include"> <TargetImage name="条件为lsass.exe">lsass.exe</TargetImage> </ProcessAccess> <!-- 记录所有远程线程创建事件 --> <CreateRemoteThread onmatch="include"> <TargetImage name="条件为lsass.exe">lsass.exe</TargetImage> </CreateRemoteThread> <!-- 记录进程创建,过滤一部分系统进程避免日志过于庞大 --> <ProcessCreate onmatch="exclude"> <Image name="排除系统进程">System</Image> <Image name="排除系统进程">svchost.exe</Image> </ProcessCreate> </EventFiltering> </Sysmon>

安装命令参考:

sysmon64 -accepteula -i sysmon-config.xml

配置落地后,如果攻击者尝试注入lsass,Windows日志里会同时出现EventID 10(ProcessAccess)和EventID 8(CreateRemoteThread),配合Sysmon的ProcessGuid关联,可以精准定位是谁、在什么时候、用什么进程打开了lsass。

5.2 建立SIEM检测规则,降低误报

单纯记录还不够,必须有一套可执行的检测逻辑。我常用的检测规则核心逻辑是:如果ProcessAccess事件的TargetImage为lsass.exe,SourceImage不合法,则触发告警。

EventID = 10 TargetImage = lsass.exe SourceImage NOT IN (system, wininit.exe, services.exe, lsass.exe, csrss.exe, svchost.exe) GrantedAccess IN (0x1010, 0x1F0FFF, 0x1FFFFF) # 表示包含VM_READ/WRITE、THREAD_CREATE等危险权限 or EventID = 8 TargetImage = lsass.exe GrantedAccess NOT IN (0x401, 0x1010) # 正常进程访问lsass很少创建远程线程

这套规则在多数企业环境里误报率极低。唯一需要注意的是一些合法的监控软件也会打开lsass句柄做健康检查,需要把监测软件进程加入白名单。

5.3 利用卡巴斯基集中管理平台的事件情报

卡巴斯基管理控制台(KSC)会汇总所有客户端的检测事件,包括“检测到注入代码”、“检测到利用攻击”、“检测到可疑进程操作”等类型。安全运维可以开启“卡巴斯基安全网络”(KSN)的云查询功能,这样卡巴斯基在本地行为分析之外,还能将样本/进程信息匿名上传云端比对。

这个能力在对抗未知DLL时很关键。很多自研DLL没有公开信誉,KSN会根据全球用户的运行统计给出一个信誉分数。分数低的文件即使没有被明确检出,也会被标记为“低信誉”,安全性要求高的机器可以配置为弹出告警。

我习惯的做法是:SIEM负责关联“进程访问”和“远程线程”两个层面的行为,KSC负责提供文件信誉和卡巴斯基自身的检测情报,两边交叉验证,能大幅减少漏报。

5.4 定期复盘和场景化演练

检测规则只有在实战中验证过才算真正生效。我建议每季度做一次场景化演练:在内网隔离区,由蓝队模拟发起一次“RPC控制lsass注入DLL”的测试,检验卡巴斯基的拦截效果、Sysmon日志的完整性、SIEM告警的准确性。

演练结束后的复盘动作包括:

  • 核对告警延迟,确认是在注入前、注入中还是注入后被检测到;
  • 确认事件日志是否被杀毒软件自身的排除项干扰;
  • 检查漏洞利用防护规则是否需要更新;
  • 更新白名单和基线,把演练中出现的合法监控进程加入例外。

这种演练做上两三次,整个团队对“lsass被注入”这个攻击模式的识别能力会有明显提升,比看再多文档都管用。

6. 常见问题与排查技巧实录

6.1 RPC调用超时:cannot finish rpc call in 30 seconds

做RPC下发测试时,攻击端偶尔会收到类似“RPC调用30秒未完成”的错误。这个错误并不一定是注入被拦,也可能是RPC服务端处理逻辑卡住、目标进程句柄没有释放、DLL加载时做了同步初始化导致ReDoS等。排查时先看服务端的日志和事件,再看杀软告警。如果卡巴斯基没有弹窗,大概率是RPC业务逻辑本身的问题,而不是安全拦截。

6.2 DLL加载失败:winerror 1114(初始化失败)

这个错误在DLL注入中很常见,出现的原因通常是DLL入口或依赖库初始化失败。常见诱因包括:目标DLL依赖的第三方库不在系统PATH中、DLL被标记为.NET程序(LoadLibraryW无法直接加载托管DLL)、DLL入口中执行了依赖GUI消息循环的代码。注入到lsass这类非交互进程中时,部分依赖界面组件的DLL就会初始化失败。

排查步骤:先用dumpbin /dependents查看DLL依赖;再用Process Monitor观察失败的加载路径;最后尝试用rundll32在普通环境下手动加载DLL,确认DLL本身是否正常。

6.3 误拦截了合法业务DLL怎么办

企业环境里经常有自研系统往业务进程中注入DLL做监控或热更新,这类行为容易被卡巴斯基误判。解决思路不是关闭杀软,而是把合法DLL加入卡巴斯基“信任程序”列表,同时确保DLL有明确的数字签名。

如果DLL是内部开发的,建议走公司内部的代码签名证书做签名。签名之后,不仅在卡巴斯基里好配信任规则,在Sysmon日志里也能更清晰地识别出“这是内部签名文件”,降低后续误报排查成本。

7. 最后补一句实在话

从那次红蓝对抗复盘到现在,我们内部对“RPC控制lsass注入DLL”的防御已经形成了一套固定打法:Windows原生保护打底,卡巴斯基主动防御做第二道闸门,Sysmon+SIEM做行为层告警。三层配合下来,攻击者即使能走到注入那一步,也会在后续的凭据提取、横向移动阶段暴露行迹。

我个人最大的体会是,不要迷信任何单一防护产品,也不要觉得PPL开了就万事大吉。真正的安全感来自“攻击路径上的每个关键节点都有独立检测能力”。在lsass这个战场上,用户态行为、内核回调、远程通道日志,一个都不能少。后续如果你们团队也在做类似场景的攻防验证,建议先从日志收集开始,这比买新的安全设备更有长期价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询