Python网络安全工具高级开发(二十九):威胁检测之EDR端点行为监控

摘要:在本文中,我们将着手构建一个EDR(端点检测与响应)工具的核心——端点行为监控器(Sensor)。我们将深入探讨现代EDR是如何超越传统杀毒软件(AV),从“静态文件扫描”进化到“实时行为分析”的。为了绕过AV,攻击者越来越多地使用“就地取材(Living off the Land, LotL)”技术(如利用PowerShell、WMI等系统自带工具)。本文将利用强大的跨平台库
psutil
,构建一个Python“传感器”守护进程,它能够持续监控
端点上的进程创建事件,并重点分析父子进程关系(例如,检测
WINWORD.EXE
启动
powershell.exe
这样的典型恶意行为),从而捕获传统AV无法识别的威胁。

关键词:Python, EDR, 端点安全,
psutil
, 进程监控, 行为分析, 威胁狩猎, LotL


正文

1. EDR的诞生:当AV“失明”时

传统AV(杀毒软件):像一个“文件扫描仪”。它主要依赖签名来识别已知的恶意文件(如病毒、木马)。

AV的“盲点”

内存马/无文件攻击:恶意代码只在内存中运行,从不落地为文件,AV无法扫描。

就地取材(LotL)攻击:这是现代攻击者最爱的技巧。他们不再使用自定义的恶意程序,而是利用Windows系统自带的、合法的工具(如
powershell.exe
,
bitsadmin.exe
,
wmic.exe
,
rundll32.exe
)来执行恶意操作(如下载Payload、横向移动)。

EDR的“视野”:EDR不(仅仅)关心文件是什么,它更关心进程做了什么。它是一个行为录像机分析师

EDR的核心逻辑是:“一个合法的程序(如PowerShell)在错误的时间(凌晨3点)、由错误的发起者(如Adobe Reader)、执行了错误的操作(如发起网络连接到某个俄罗斯IP),那么它就是恶意的。”

2. EDR“传感器”:
psutil

要实现行为监控,我们的EDR工具必须有一个“传感器”来收集端点上的遥测(Telemetry)数据。
psutil
(Python System and Process Utilities)是实现这一目标的完美跨平台库。它能让我们访问到:

进程列表

每个进程的详细信息:PID、名称、命令行、父进程ID(PPID)、网络连接、打开的文件…

环境准备

Bash


pip install psutil

3. 监控的核心:父子进程关系

在所有行为中,进程创建链(Process Tree)是最重要的入侵指标(IoC)之一。一个合法的
powershell.exe
,其父进程通常是
explorer.exe
(用户启动)或
svchost.exe
(计划任务)。

高危警报(Red Flag)


WINWORD.EXE
(Word) ->
cmd.exe
->
powershell.exe

分析:这几乎100%是恶意宏在执行命令。


apache.exe
(Web服务器) ->
cmd.exe

分析:WebShell在执行系统命令。


services.exe
->
powershell.exe

分析:可能是一个恶意的持久化服务。

我们的第一个EDR传感器,就要专注于实时捕获新创建的进程及其父进程

4. 代码实现 (
edr_sensor.py
)

我们将编写一个守护进程,它会定期(例如每秒)扫描当前进程列表,并与上一秒的“快照”进行对比,从而找出所有新创建的进程,并对其进行分析。

Python



# edr_sensor.py
import psutil
import time
import sys
import argparse
from datetime import datetime
 
# --- 规则引擎 (简化版) ---
# 定义高危的“父进程 -> 子进程”组合
SUSPICIOUS_PARENT_CHILD_MAP = {
    # 父进程列表 (小写)
    'winword.exe': ['cmd.exe', 'powershell.exe', 'cscript.exe', 'wscript.exe'],
    'excel.exe': ['cmd.exe', 'powershell.exe'],
    'powerpnt.exe': ['cmd.exe', 'powershell.exe'],
    'acrord32.exe': ['cmd.exe', 'powershell.exe'],
    # Web服务器
    'apache.exe': ['cmd.exe', 'powershell.exe', '/bin/sh', '/bin/bash'],
    'nginx.exe': ['cmd.exe', 'powershell.exe', '/bin/sh', '/bin/bash'],
    'httpd.exe': ['cmd.exe', 'powershell.exe', '/bin/sh', '/bin/bash'],
}
 
def get_process_info(proc: psutil.Process):
    """
    安全地获取进程的详细信息。
    (psutil在访问已死亡的进程时会抛出异常)
    """
    try:
        pid = proc.pid
        ppid = proc.ppid()
        name = proc.name()
        cmdline = ' '.join(proc.cmdline())
        username = proc.username()
        
        # 获取父进程信息
        parent_proc = proc.parent()
        parent_name = parent_proc.name() if parent_proc else "N/A"
        
        return {
            "pid": pid, "ppid": ppid,
            "name": name, "cmdline": cmdline,
            "username": username, "parent_name": parent_name
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied):
        return None
 
def check_rules(proc_info: dict):
    """
    对新进程应用我们的安全规则。
    """
    if not proc_info:
        return
 
    p_name = proc_info['name'].lower()
    parent_name = proc_info['parent_name'].lower()
    
    # 规则1: 检查父子进程组合
    if parent_name in SUSPICIOUS_PARENT_CHILD_MAP:
        if p_name in SUSPICIOUS_PARENT_CHILD_MAP[parent_name]:
            log_alert(
                "HIGH", 
                "可疑的进程创建链 (LotL)!",
                f"父进程 '{proc_info['parent_name']}' (PID: {proc_info['ppid']}) 启动了子进程 '{proc_info['name']}' (PID: {proc_info['pid']})",
                f"命令行: {proc_info['cmdline']}"
            )
 
    # 规则2: 检查可疑的命令行 (例如,powershell base64编码)
    if p_name == "powershell.exe" and "encodedcommand" in proc_info['cmdline'].lower():
        log_alert(
            "MEDIUM",
            "检测到PowerShell编码命令",
            f"进程: {proc_info['name']} (PID: {proc_info['pid']})",
            f"命令行: {proc_info['cmdline'][:100]}..." # 截断
        )
 
def log_alert(level, title, description, details):
    """格式化并打印告警。"""
    print("
" + "="*60)
    print(f"[!!!] {level} 威胁警报 [!!!]")
    print(f"  时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print(f"  标题: {title}")
    print(f"  详情: {description}")
    print(f"  证据: {details}")
    print("="*60 + "
")
 
 
def main_loop(poll_interval):
    """EDR传感器的
    主循环。"""
    print(f"[*] EDR端点传感器已启动。监控间隔: {poll_interval}秒...")
    
    # 获取启动时的进程PID快照
    known_pids = {p.pid for p in psutil.process_iter()}
    
    try:
        while True:
            time.sleep(poll_interval)
            
            current_pids = set()
            new_processes = []
            
            # 遍历当前所有进程
            for proc in psutil.process_iter():
                current_pids.add(proc.pid)
                if proc.pid not in known_pids:
                    # 发现新进程!
                    new_processes.append(proc)
            
            # 更新已知的PID列表
            known_pids = current_pids
            
            if new_processes:
                print(f"[*] 检测到 {len(new_processes)} 个新进程...")
                for proc in new_processes:
                    info = get_process_info(proc)
                    # 对新进程进行规则检查
                    check_rules(info)
 
    except KeyboardInterrupt:
        print("
[*] EDR传感器正在关闭...")
 
def main():
    parser = argparse.ArgumentParser(description="一个基础的EDR端点进程监控传感器。")
    parser.add_argument("-i", "--interval", type=int, default=2, help="轮询间隔时间(秒)。")
    args = parser.parse_args()
    
    main_loop(args.interval)
 
if __name__ == "__main__":
    if sys.platform == "win32" and not 'ADMIN' in os.environ.get('USERNAME', '').upper():
         pass # 在Windows上,非管理员权限可能无法获取所有进程信息
    main()

5. 如何测试

运行EDR传感器: 在一个终端中启动传感器(在Windows上,最好以管理员身份运行以获取所有进程信息)。

Bash


python edr_sensor.py

模拟攻击(良性): 打开一个新的终端,简单地运行
powershell

观察结果: EDR传感器会立即检测到这个新进程,但由于其父进程可能是
explorer.exe

cmd.exe
(由你手动启动),这不会触发我们的高危规则。

模拟攻击(恶意)(这是一个非恶意的模拟,它不会伤害你的电脑) 打开一个Word文档,按下
Alt + F11
打开VBA编辑器,插入一个新模块,并粘贴以下代码:

VBA



Sub Auto_Open()
    Shell "powershell.exe -e WwB...[base64_string]...", vbHide
End Sub

当你(在受控的VM中!)重新打开这个带有宏的文档时,Word(
WINWORD.EXE
)会启动一个隐藏的
powershell.exe
进程。

观察告警: 我们的EDR传感器会立刻捕获到这个事件,并打印出一个高危告警,因为它命中了
'winword.exe' -> 'powershell.exe'
这条规则。

总结

我们成功地利用
psutil
构建了一个基础的EDR传感器的“大脑”——进程行为监控器。它通过分析进程创建链这一核心指标,已经能够检测到大量基于LotL的、AV无法察觉的恶意活动。

一个完整的EDR系统,还需要:

监控网络连接文件修改(同样可通过
psutil
实现)。

将这些遥测数据实时地大规模地发送到一个中央分析平台(我们之前设计的Kafka + Elasticsearch)。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
聚沙成塔的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容