Investigates malware persistence mechanisms on Windows and Linux systems by enumerating registry keys, services, autoruns, scheduled tasks, and rootkits for incident response, threat hunting, and forensics.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 调查恶意软件如何在系统重启后维持存在时
Investigates malware persistence mechanisms on Windows and Linux systems using Autoruns, registry analysis, scheduled tasks, and Python scripts. For incident response, threat hunting, and remediation verification.
Investigates malware persistence on Windows and Linux via registry analysis, Autoruns, scripts, and YARA. For incident response, threat hunting, and remediation verification.
Hunts attacker persistence mechanisms in Windows endpoints covering registry Run keys, services, startup folders, and WMI event subscriptions. For threat hunting and incident response.
Share bugs, ideas, or general feedback.
# 从取证镜像中提取注册表 hive
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/evidence.dd /mnt/evidence
# 关键注册表持久化位置
python3 << 'PYEOF'
from Registry import Registry
import json
results = {'registry_persistence': []}
# SYSTEM hive 分析
system_reg = Registry.Registry("/cases/case-2024-001/registry/SYSTEM")
select = system_reg.open("Select")
current = select.value("Current").value()
cs = f"ControlSet{current:03d}"
# 服务(非常常见的持久化方式)
services = system_reg.open(f"{cs}\\Services")
for svc in services.subkeys():
try:
start_type = svc.value("Start").value()
image_path = ""
try:
image_path = svc.value("ImagePath").value()
except:
pass
# 启动类型:0=Boot, 1=System, 2=Auto, 3=Manual, 4=Disabled
if start_type in (0, 1, 2) and image_path:
svc_type = svc.value("Type").value() if svc.values() else 0
results['registry_persistence'].append({
'location': f'HKLM\\SYSTEM\\{cs}\\Services\\{svc.name()}',
'type': '服务',
'value': image_path,
'start_type': start_type,
'timestamp': str(svc.timestamp())
})
except Exception:
pass
# SOFTWARE hive 分析
sw_reg = Registry.Registry("/cases/case-2024-001/registry/SOFTWARE")
# 机器 Run 键
run_keys = [
"Microsoft\\Windows\\CurrentVersion\\Run",
"Microsoft\\Windows\\CurrentVersion\\RunOnce",
"Microsoft\\Windows\\CurrentVersion\\RunServices",
"Microsoft\\Windows\\CurrentVersion\\RunServicesOnce",
"Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run",
"Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
"Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
]
for key_path in run_keys:
try:
key = sw_reg.open(key_path)
for value in key.values():
results['registry_persistence'].append({
'location': f'HKLM\\SOFTWARE\\{key_path}',
'type': 'Run Key',
'name': value.name(),
'value': str(value.value()),
'timestamp': str(key.timestamp())
})
except Exception:
pass
# NTUSER.DAT 分析
import glob
for ntuser in glob.glob("/cases/case-2024-001/registry/NTUSER*.DAT"):
try:
user_reg = Registry.Registry(ntuser)
user_run_keys = [
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
]
for key_path in user_run_keys:
try:
key = user_reg.open(key_path)
for value in key.values():
results['registry_persistence'].append({
'location': f'HKCU\\{key_path}',
'type': '用户 Run Key',
'name': value.name(),
'value': str(value.value()),
'timestamp': str(key.timestamp()),
'hive': ntuser
})
except Exception:
pass
except Exception:
pass
print(f"注册表持久化条目总数:{len(results['registry_persistence'])}")
for entry in results['registry_persistence']:
print(f" [{entry['type']}] {entry.get('name', '')} -> {entry.get('value', '')[:100]}")
with open('/cases/case-2024-001/analysis/registry_persistence.json', 'w') as f:
json.dump(results, f, indent=2)
PYEOF
# 从取证镜像中提取计划任务
mkdir -p /cases/case-2024-001/persistence/tasks/
cp -r /mnt/evidence/Windows/System32/Tasks/* /cases/case-2024-001/persistence/tasks/ 2>/dev/null
# 解析计划任务 XML 文件
python3 << 'PYEOF'
import os, xml.etree.ElementTree as ET
tasks_dir = '/cases/case-2024-001/persistence/tasks/'
suspicious_tasks = []
for root_dir, dirs, files in os.walk(tasks_dir):
for fname in files:
fpath = os.path.join(root_dir, fname)
try:
tree = ET.parse(fpath)
root = tree.getroot()
ns = {'t': 'http://schemas.microsoft.com/windows/2004/02/mit/task'}
actions = root.findall('.//t:Exec', ns)
for action in actions:
command = action.find('t:Command', ns)
args = action.find('t:Arguments', ns)
cmd_text = command.text if command is not None else ''
args_text = args.text if args is not None else ''
# 标记可疑命令
suspicious_indicators = [
'powershell', 'cmd.exe', 'wscript', 'cscript', 'mshta',
'regsvr32', 'rundll32', 'certutil', 'bitsadmin',
'/c ', '-enc', '-e ', 'hidden', 'bypass', 'downloadstring',
'invoke-', 'iex', '/tmp/', 'appdata', 'programdata',
'temp\\', '.ps1', '.vbs', '.hta', 'base64'
]
is_suspicious = any(s in (cmd_text + ' ' + args_text).lower() for s in suspicious_indicators)
task_info = {
'name': fname,
'path': fpath.replace(tasks_dir, ''),
'command': cmd_text,
'arguments': args_text,
'suspicious': is_suspicious
}
if is_suspicious:
suspicious_tasks.append(task_info)
print(f"可疑任务:{fname}")
print(f" 命令:{cmd_text}")
print(f" 参数:{args_text}")
print()
except Exception as e:
pass
print(f"\n可疑计划任务总数:{len(suspicious_tasks)}")
PYEOF
# 检查 WMI 事件订阅(常见的 APT 持久化方式)
# WMI 库:C:\Windows\System32\wbem\Repository\
cp -r /mnt/evidence/Windows/System32/wbem/Repository/ /cases/case-2024-001/persistence/wmi/ 2>/dev/null
# 使用 PyWMIPersistenceFinder 解析 WMI 持久化
python3 << 'PYEOF'
import os, re
# 在 WMI OBJECTS.DATA 中搜索事件订阅
wmi_db = '/cases/case-2024-001/persistence/wmi/OBJECTS.DATA'
if os.path.exists(wmi_db):
with open(wmi_db, 'rb') as f:
data = f.read()
# 搜索 EventFilter 字符串
filters = re.findall(b'__EventFilter.*?(?=\x00\x00)', data)
consumers = re.findall(b'CommandLineEventConsumer.*?(?=\x00\x00)', data)
bindings = re.findall(b'__FilterToConsumerBinding.*?(?=\x00\x00)', data)
print("=== WMI 持久化 ===")
print(f"事件过滤器:{len(filters)}")
print(f"命令消费者:{len(consumers)}")
print(f"过滤器-消费者绑定:{len(bindings)}")
for consumer in consumers:
decoded = consumer.decode('utf-8', errors='ignore')
print(f" 消费者:{decoded[:200]}")
else:
print("WMI 库未找到")
PYEOF
# 启动文件夹
echo "=== 启动文件夹内容 ===" > /cases/case-2024-001/analysis/startup_items.txt
ls -la "/mnt/evidence/ProgramData/Microsoft/Windows/Start Menu/Programs/Startup/" \
>> /cases/case-2024-001/analysis/startup_items.txt 2>/dev/null
for userdir in /mnt/evidence/Users/*/; do
username=$(basename "$userdir")
echo "--- 用户:$username ---" >> /cases/case-2024-001/analysis/startup_items.txt
ls -la "$userdir/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/" \
>> /cases/case-2024-001/analysis/startup_items.txt 2>/dev/null
done
# 检查 DLL 搜索顺序劫持位置
echo "=== DLL 劫持检查 ===" > /cases/case-2024-001/analysis/dll_hijack.txt
# 检查应用程序目录中只应存在于 System32 的 DLL
find /mnt/evidence/Program\ Files/ /mnt/evidence/Program\ Files\ \(x86\)/ \
-name "*.dll" -newer /mnt/evidence/Windows/System32/ntdll.dll 2>/dev/null \
>> /cases/case-2024-001/analysis/dll_hijack.txt
# 检查 COM 对象劫持
python3 << 'PYEOF'
from Registry import Registry
reg = Registry.Registry("/cases/case-2024-001/registry/SOFTWARE")
# 检查可疑的 CLSID 条目
try:
clsid = reg.open("Classes\\CLSID")
for key in clsid.subkeys():
try:
server = key.subkey("InprocServer32")
dll_path = server.value("(default)").value()
if any(s in dll_path.lower() for s in ['temp', 'appdata', 'programdata', 'downloads', 'tmp']):
print(f"可疑 COM:{key.name()} -> {dll_path}")
except:
pass
except:
pass
PYEOF
# 检查引导配置是否存在 bootkit
# BCD(启动配置数据)
ls -la /mnt/evidence/Boot/BCD 2>/dev/null
# 检查 bootmgr 或 winload.exe 是否被修改
sha256sum /mnt/evidence/Windows/System32/winload.exe 2>/dev/null
# 如果分析 Linux 系统
LINUX_ROOT="/mnt/evidence"
echo "=== Linux 持久化检查 ===" > /cases/case-2024-001/analysis/linux_persistence.txt
# Cron 任务
echo "--- Cron 任务 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
cat $LINUX_ROOT/etc/crontab >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
ls -la $LINUX_ROOT/etc/cron.d/ >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
cat $LINUX_ROOT/etc/cron.d/* >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
cat $LINUX_ROOT/var/spool/cron/crontabs/* >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# Systemd 服务
echo "--- 自定义 Systemd 服务 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
find $LINUX_ROOT/etc/systemd/system/ -name "*.service" -not -type l \
>> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# SSH 授权密钥
echo "--- SSH 授权密钥 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
find $LINUX_ROOT/home/ $LINUX_ROOT/root/ -name "authorized_keys" -exec cat {} \; \
>> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# Init 脚本和 rc.local
echo "--- RC 脚本 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
cat $LINUX_ROOT/etc/rc.local >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# Shell profile 脚本
echo "--- Profile 脚本 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
cat $LINUX_ROOT/etc/profile.d/*.sh >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# LD_PRELOAD
echo "--- LD_PRELOAD ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
cat $LINUX_ROOT/etc/ld.so.preload >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
grep -r "LD_PRELOAD" $LINUX_ROOT/etc/ >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# 内核模块
echo "--- 已加载的内核模块 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
cat $LINUX_ROOT/etc/modules-load.d/*.conf >> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# PAM 后门
echo "--- PAM 配置 ---" >> /cases/case-2024-001/analysis/linux_persistence.txt
find $LINUX_ROOT/etc/pam.d/ -exec grep -l "pam_exec\|pam_script" {} \; \
>> /cases/case-2024-001/analysis/linux_persistence.txt 2>/dev/null
# 生成全面的持久化报告
python3 << 'PYEOF'
import json
with open('/cases/case-2024-001/analysis/registry_persistence.json') as f:
reg_data = json.load(f)
report = """
恶意软件持久化调查报告
==========================================
发现的持久化机制:
1. 注册表 RUN 键:
"""
run_keys = [e for e in reg_data['registry_persistence'] if 'Run' in e.get('type', '')]
for entry in run_keys:
report += f" [{entry['timestamp']}] {entry.get('name', 'N/A')} -> {entry.get('value', '')[:100]}\n"
services = [e for e in reg_data['registry_persistence'] if e.get('type') == '服务']
report += f"\n2. 服务({len(services)} 个自启动服务):\n"
for entry in services[:20]:
report += f" {entry['location'].split(chr(92))[-1]}:{entry['value'][:100]}\n"
report += """
3. 计划任务:[见计划任务分析]
4. WMI 订阅:[见 WMI 分析]
5. 启动文件夹:[见 startup_items.txt]
6. COM 劫持:[见 COM 分析]
需要调查的可疑条目:
"""
# 标记可疑条目
for entry in reg_data['registry_persistence']:
value = str(entry.get('value', '')).lower()
suspicious_indicators = ['powershell', 'cmd /c', 'wscript', 'certutil',
'programdata', 'appdata\\local\\temp', 'base64',
'.ps1', '.vbs', '.hta', '/tmp/', 'hidden']
if any(s in value for s in suspicious_indicators):
report += f" 可疑:{entry.get('name', 'N/A')} -> {entry.get('value', '')[:100]}\n"
with open('/cases/case-2024-001/analysis/persistence_report.txt', 'w') as f:
f.write(report)
print(report)
PYEOF
| 概念 | 描述 |
|---|---|
| Run 键(Run keys) | 在用户登录时执行程序的注册表键(HKLM 和 HKCU) |
| 计划任务(Scheduled tasks) | 在触发器(时间、事件、登录)上执行的 Windows 任务计划条目 |
| WMI 事件订阅 | 触发操作的持久性 WMI 查询(隐蔽持久化) |
| COM 劫持(COM hijacking) | 重定向 COM 对象加载以执行恶意 DLL |
| DLL 搜索顺序劫持 | 在 System32 之前被搜索的目录中放置恶意 DLL |
| 服务持久化(Service persistence) | 安装随系统自动启动的 Windows 服务 |
| 引导级持久化(Boot-level persistence) | 修改引导配置或 MBR/VBR 以在操作系统前执行 |
| 离地攻击(Living-off-the-land) | 使用合法系统工具(PowerShell、WMI、certutil)进行持久化 |
| 工具 | 用途 |
|---|---|
| Autoruns | Sysinternals 全面的自启动枚举工具 |
| RegRipper | 自动化注册表持久化制品提取 |
| KAPE | 自动化持久化制品收集和分析 |
| Velociraptor | 具有持久化狩猎制品的端点 Agent |
| OSQuery | 基于 SQL 的系统查询,用于持久化枚举 |
| PersistenceSniper | 用于 Windows 持久化检测的 PowerShell 工具 |
| RECmd | Eric Zimmerman 的注册表命令行分析工具 |
| Volatility | 用于内存中持久化的内存取证工具 |
场景 1:初始入侵后的 APT 持久化 检查所有注册表 Run 键,枚举包含编码 PowerShell 命令的计划任务,检查 WMI 事件订阅中的事件触发执行,检查 COM 对象注册是否存在被劫持的 CLSID,审查最近安装的具有可疑映像路径的服务。
场景 2:加密前的勒索软件持久化 识别勒索软件如何维持访问以进行重新加密或监控,检查会重新启动加密的计划任务,检查勒索软件操作者安装的服务,在宣告修复完成前验证不存在额外的后门持久化。
场景 3:无文件恶意软件持久化 重点关注将有效载荷存储在注册表值中的持久化,检查从事件触发器执行 PowerShell 的 WMI 订阅,检查使用编码命令参数的计划任务,检查加载远程内容的基于 mshta/rundll32 的持久化。
场景 4:修复后验证 运行 Autoruns 与已知良好基线的比对,验证所有已识别的持久化机制已被删除,检查可能被遗漏的额外持久化,确认服务、任务和注册表条目已清理,监控再次感染指标。
持久化调查摘要:
系统:DESKTOP-ABC123(Windows 10 Pro)
分析日期:2024-01-20
发现的持久化机制:
注册表 Run 键(HKLM):5 条(1 条可疑)
注册表 Run 键(HKCU):3 条(1 条可疑)
服务(自启动): 142 条(2 条可疑)
计划任务: 67 条(3 条可疑)
WMI 订阅: 1 条(可疑)
启动文件夹: 4 项(1 项可疑)
COM 对象: 0 条被劫持条目
DLL 劫持: 0 条检测到
可疑条目:
1. HKCU\Run\WindowsUpdate -> powershell -ep bypass -e <base64>
时间戳:2024-01-15 14:35:00
操作:编码的 PowerShell 下载执行
2. 服务:WinDefenderUpdate -> C:\ProgramData\svc\update.exe
时间戳:2024-01-15 14:40:00
操作:ProgramData 中的未知可执行文件
3. 任务:\Microsoft\Windows\Maintenance\SecurityUpdate
命令:cmd.exe /c powershell -w hidden -e <base64>
触发:系统启动时
4. WMI:__EventFilter "ProcessStart" -> CommandLineEventConsumer
操作:WMI 事件触发时执行 C:\Windows\Temp\svc.exe
需要修复:4 个持久化机制待删除
报告:/cases/case-2024-001/analysis/persistence_report.txt