使用 RPC 检测恶意攻击
Windos 中利用 RPC 检测恶意攻击
前置知识
- RPC(Remote Procedure Call)原理
- ETW(Event Tracing for Windows)
背景
RPC 是 Windows 的一种 IPC(Inter-Process Communication,进程间通信)机制,可以用于同一台机器上的进程通信,也可以与远程机器上的进程通信,是许多 Windows 功能和第三方工具的基础。例如计划任务(at、schtasks)和 sc、wmi、psexec 等。这些工具也常被攻击者使用。既然这些工具都使用了 RPC 作为底层技术,我们自然可以通过检测 RPC 的方式来检测这些攻击方式。
监控 RPC 行为的方法
本文中会介绍两种检测 RPC 的方法:抓包和使用 ETW。
- 抓包:抓取 RPC Client 和 Server 端的通信。使用此方法需要确保能拦截到 Client 和 Server 通信的流量。本文中演示了物理机攻击虚拟机的过程,使用 Wireshark 拦截虚拟网卡,同时 Wireshark 提供了默认的过滤器 dcerpc,可以方便地观察 RPC 通信内容。
- 使用 ETW:Windows 中存在一个 ETW Provider,Microsoft-Windows-RPC.xml,其中提供了关于 RPC 调用的事件,与使用抓包方式获取的信息基本相同。使用 ETW 的优势在于只需在靶机上捕捉事件,在实际检测中比较合理。
如无特殊说明,实验环境为:
Vmware 靶机 Win 10,192.168.3.131。
物理机 IP 192.168.3.1。
检测计划任务
Windows 中提供了两个管理计划任务的工具,At 和 Schtasks。At 自 Win 8 起弃用,因此我们首先从 Schtasks 开始。Windows 中使用了一种基于 RPC 的协议来管理计划任务,MS-TSCH。
注意,对于检测计划任务来说,使用 ETW Provider Microsoft-Windows-TaskScheduler 也许是更好的方式,这里只为演示如何检测基于 RPC 的行为。
Schtasks
在目标机器上启动事件记录,并启动 Wireshark 抓取 Vmware NAT 网卡上的流量。
1 | logman create trace rpc -p Microsotf-Windows-RPC -ets |
进行攻击
1 | # 目标机器运行以下命令,授予 Administrator 和 SYSTEM 对 task 目录的完全访问权限 |
停止记录
1 | logman stop rpc -ets |
结束后我们就得到了事件文件 rpc.etl 和使用 dcerpc 过滤后的 schtasks.pcapng。
抓包
首先来看 schtasks.pcapng,显示了调用的过程:
3 号包,Client 向 EndPoint Manager 查询希望使用的 RPC 接口的 UUID 为
86d35949-83c9-4044-b424-db363231fd0c
,希望获得对应 RPC Server 运行的端口4 号包,EPM 回应,该 Server 运行在 TCP 19667
5、6、7 号包,Client 连接指定的端口,并进行认证
8 号包开始,Client 调用该接口的方法,可以看到 OpNum,即调用的方法在接口中的顺序。例如 8 号包中,OpNum 为 0,可知调用的是接口中的第一个方法,查询接口的定义(SchRpc.idl 或 在 RPC interfaces RS5 中搜索对应的接口)可知调用的 OpNum 为 0 的方法是 SchRpcHighestVersion,由名可知是个查询版本的方法。
附件的包可能由于过滤后保存的包不全的原因没有最后一个对 OpNum 为 1 的方法调用,在保存完整的包中可以看到,读者可自行实验。
ETW
第二种方式是使用 ETW,Microsoft-Windows-RPC中包含了 Provider 的定义,由于我们是做检测,是在服务端捕获日志,因此我们重点关心 Event ID 6,即 RpcServerCallStart,该事件包含了以下信息:
1 | <template tid="RpcClientCallStartArgs_V1"> |
可以看到其中包含了许多有效的信息,其中 ProcNum 就是抓包中的 OpNum。使用 Powershell 提取 rpc.etl 中的信息:
1 |
由于 Microsoft-Windows-RPC 会产生大量事件,我们只筛选出我们关心的事件,即 Event Id 为 6,UUID 为 86d35949-83c9-4044-b424-db363231fd0c,Protocol 为 1(TCP,数字与协议的对应关系为 1 - TCP,2 - NamedPipe,3 - ALPC),查看这些事件调用的方法(ProcNum):
1 | > foreach($e in $events){ |
由此可知调用的顺序是 0(SchRpcHighestVersion),7(SchRpcEnumTasks),1(SchRpcRegisterTask)。其中最重要的是 SchRpcRegisterTask。因此进行检测时,调用 86d35949-83c9-4044-b424-db363231fd0c 接口 OpNum 为 1 的方法的行为即为注册计划任务的行为。
At
根据上面对 Schtasks 进行研究的过程进行总结,可以发现对于基于主机的检测来说,使用 ETW 是更好的方案,研究时也比较方便。在研究 At 时使用类似于 Schtasks 的 ETW 方法,具体过程略,结果是使用 At 添加计划任务时调用的是接口1FF70682-0A51-30E8-076D-740BE8CEE98B
OpNum 为 0 的方法 NetrJobAdd。
检测服务创建
创建服务的常用方式包括 sc、wmi、psexec 等,研究方法也与 Schtasks 类似。与计划任务相比,服务创建这一部分体现了利用 RPC 进行检测的一个优势,即可以从更底层获得不同创建服务方式的共同点,从而帮助检测。创建服务时,Windows 使用的是另一个基于 RPC 的协议MS-SCMR Service Control Manager Remote Protocol。
类似于计划任务,ETW Provider Microsoft-Windows-Service 也提供了服务相关的事件。但是该 Provider 不提供服务创建时的事件,可以与 RPC 结合判断。
SC
具体过程略,我们关注的还是 Microsoft-Windows-RPC 的 Event ID 为 6 的方法,同时我们在 MS-SCMR 协议中找到了接口定义,UUID 为 367ABB81-9844-35F1-AD32-98F038001003
,据此我们可以得知调用函数的顺序:15(ROpenSCManagerW),12(RCreateServiceW),0(RCloseServiceHandle)。这其中最重要的一步应该是 12 CreateService。在查阅该接口时,发现还有一些其他的创建服务的函数,24 RCreateServiceA,44 RCreateServiceWOW64A,45 RCreateServiceWOW64W,这几个函数从函数名上就可以知道它们的不同,在检测服务创建行为时应该一并检测。
PsExec
PsExec 是 Sysinternals 中的工具,渗透中十分常用。基本原理是:首先将 PsExec.exe 通过文件共享发送到目标机器,然后启动服务,通过服务执行操作,最后删除服务。其与服务有关的操作也是通过同样的接口367ABB81-9844-35F1-AD32-98F038001003
实现的,执行函数的顺序为 12 RCreateServiceW,29 RStartServiceW,1 RControlService,2 RDeleteService。可以看到 PsExec 与 Sc 使用了相同的接口和相同的方法(RCreateSeerviceW)。
另外一个特征是,Psexec 会比较快地执行上面四个步骤。
WMI
WMI 用于管理服务的类是 Win32_Service 类,该类有 Create 和 Start 方法用于创建和启动服务。有多种方式与 WMI 进行交互,实验时使用 Powershell。WMI 使用的协议是 MS-WMI。
使用 Powershell 创建服务:
1 | Invoke-CimMethod -ClassName Win32_Service -MethodName create -Arguments @{PathName=C:\Windows\System32\calc.exe; DisplayName=evilservice DesktopInteract=true; StartName="NT AUTHORITY\SYSTEM"; StartPassword=""; ErrorControl=3; LoadOrderGroup=""; LoadOrderGroupDependencies=""; Name=evilservice; ServiceDependencies=""; ServiceType=16; StartMode=Manual;} |
由于 WMI 包含的接口较多,Full IDL,找到其中用于执行 WMI 方法的接口和方法IWbemServices::ExecMethod
,UUID 为 9556dc99-828c-11cf-a37e-00aa003240c7
,可以看到 OpNum 为 21 即 ExecMethod 的方法。但受限于 RPC Provider 提供的信息不够,只知道执行了某个 WMI 类的某个方法,但并不能知道是哪个类的哪个方法。因此使用 RPC Provider 很难发现使用 WMI 创建服务的性行为。
对于 WMI 创建服务的行为,需要特定于 WMI 的监控方式来实现,或者仍使用 Microsoft-Windows-Services。
使用 RPC 检测恶意攻击