4、进程与线程监控:进程创建与终止、线程注入检测、父子进程关系分析
进程和线程,是EDR系统最核心的监控对象。说白了,操作系统里的一切恶意行为,最终都要落到进程或线程上。你想想看,一个病毒要执行代码,它总得有个进程吧?一个勒索软件要加密文件,它也得跑在某个进程里。所以,搞懂进程与线程监控,你就抓住了EDR的命门。
我个人习惯把这块内容分成三个层面:进程的生死(创建与终止)、线程的异常(注入检测)、进程的家族史(父子关系)。咱们一个一个来拆。
4.1 进程创建与终止:EDR的第一道防线
进程创建,是操作系统最频繁的操作之一。正常软件要运行,就得CreateProcess。但恶意软件也要CreateProcess。怎么区分?
EDR通常会在内核层挂钩NtCreateUserProcess或CreateProcess的调用链。每次有新进程诞生,EDR都能第一时间拿到通知。拿到的信息包括:
- 进程ID(PID):唯一标识
- 父进程ID(PPID):谁生了它
- 命令行参数:启动时带了什么参数
- 镜像路径:可执行文件在哪
- 用户SID:以哪个用户身份运行
- 创建时间戳:精确到微秒
我在项目中遇到过一种情况:某款正常软件,每次启动都会生成一个临时进程,然后立即结束。EDR一开始报了警,后来发现是软件自身的更新机制。所以,光看创建还不够,还得结合终止行为一起分析。
关键点:进程终止监控同样重要。恶意软件经常采用"启动-执行-自毁"的模式。比如一个无文件攻击,它可能创建一个进程执行payload,执行完立刻自杀。如果你只监控创建,不监控终止,就会漏掉这个攻击链。
EDR记录进程终止时,会捕获:
- 退出码:正常退出是0,异常退出可能是-1或其它值
- 终止时间:进程存活了多久
- 终止方式:是自己退出的,还是被TerminateProcess杀掉的
避坑指南:我曾经遇到过一个案例,攻击者用CreateProcess创建了一个隐藏窗口的进程,然后立刻调用TerminateProcess结束它。你以为它死了?其实它在结束前已经完成了注册表修改。所以,进程终止事件不能只看结果,要看它在存活期间做了什么。
4.2 线程注入检测:藏在合法进程里的幽灵
线程注入,是恶意软件最爱的技术之一。为什么?因为它可以借壳生蛋。攻击者把自己的恶意代码,塞进一个合法的进程(比如explorer.exe、svchost.exe)里,然后以这个合法进程的身份执行。
常见的线程注入手法有:
- CreateRemoteThread:在目标进程中创建远程线程
- SetWindowsHookEx:通过全局钩子注入DLL
- APC注入:利用异步过程调用队列
- Process Hollowing:进程空洞,替换合法进程的内存
- Reflective DLL Injection:反射式DLL注入,不落盘
EDR怎么检测?核心思路是监控跨进程操作。具体来说:
| 检测维度 | 监控点 | 告警条件 |
|---|---|---|
| 句柄操作 | OpenProcess 获取目标进程句柄 | 非父子进程间获取PROCESS_ALL_ACCESS权限 |
| 内存操作 | VirtualAllocEx 在目标进程分配内存 | 分配的内存带有PAGE_EXECUTE_READWRITE属性 |
| 线程创建 | CreateRemoteThread 在目标进程创建线程 | 线程起始地址不在合法模块范围内 |
| DLL加载 | LoadLibrary 在目标进程加载DLL | DLL路径异常或签名无效 |
嗯,这里要注意:不是所有的跨进程操作都是恶意的。比如调试器、杀毒软件、输入法,它们都会做跨进程操作。EDR需要建立白名单机制。
警告:千万别以为检测到CreateRemoteThread就一定是攻击。我记得有一次,某款游戏的反作弊系统大量使用远程线程注入,结果被EDR误报成恶意行为。最后我们不得不把游戏进程加入白名单。所以,上下文分析比单一事件检测更重要。
我个人比较推崇的检测方法是行为序列分析。单个API调用可能是正常的,但如果你看到:
- OpenProcess → VirtualAllocEx → WriteProcessMemory → CreateRemoteThread
这个序列,几乎可以100%确定是线程注入。EDR应该把这个序列建模成一个攻击模式。
4.3 父子进程关系分析:谁是谁的爹
父子进程关系,是EDR分析中最容易被忽视、但又最有价值的信息。你想想看,一个正常的Word进程,它生出来的子进程应该是谁?应该是它自己的插件或者打印驱动。但如果Word生出了一个cmd.exe,那就有问题了。
这就是著名的"子进程异常"检测模型。常见的异常父子关系包括:
- Office应用生成Shell进程:winword.exe → cmd.exe(宏病毒典型行为)
- 浏览器生成Shell进程:chrome.exe → powershell.exe(钓鱼攻击)
- PDF阅读器生成Shell进程:acrobat.exe → wscript.exe(漏洞利用)
- 系统进程生成可疑子进程:svchost.exe → rundll32.exe(横向移动)
EDR在记录父子关系时,会构建一个进程树。这个树形结构能直观地展示攻击链。比如:
explorer.exe (PID: 1234)
├── chrome.exe (PID: 5678)
│ └── cmd.exe (PID: 9012) ← 异常!浏览器生出了命令行
│ └── powershell.exe (PID: 3456) ← 下载恶意载荷
│ └── rundll32.exe (PID: 7890) ← 执行恶意DLL
看到这个进程树,你就能还原整个攻击过程:用户通过浏览器访问了恶意网站 → 触发了下载 → 执行了PowerShell脚本 → 最终加载了恶意DLL。
核心观点:父子进程关系分析,本质上是信任链分析。你信任父进程,不代表你该信任它的所有子进程。每个子进程的诞生,都应该有合理的业务解释。没有解释的,就是可疑的。
我曾经处理过一个案例:某台服务器上,svchost.exe频繁生成wmic.exe进程。一开始以为是正常的管理操作,后来发现是攻击者利用WMI进行横向移动。如果没有父子进程关系分析,这种隐蔽的横向移动很难被发现。
4.4 知识体系总览
下面这张图,是我自己总结的进程与线程监控知识体系。你可以把它当作本章的思维导图:
这张图把本章的三个核心模块串起来了。你可以看到,进程创建与终止是基础监控,线程注入检测是深度分析,父子进程关系是关联分析。三者缺一不可。
个人建议:在实际部署EDR时,优先开启进程创建和终止的监控。这两个事件的数据量最大,但也最有价值。线程注入检测可以放在第二阶段,因为它需要更多的计算资源。父子进程关系分析,建议作为事后回溯的主要手段,而不是实时告警的依据。
好了,关于进程与线程监控,我就讲这么多。记住一句话:监控进程的生死,检测线程的异常,理清进程的家族关系。这三板斧用好了,大部分恶意行为都逃不过你的眼睛。
公众号:蓝海资料掘金营,微信deep3321