分析 Windows 注册表以提取痕迹(取证)
何时使用
- 在事件响应中调查 Windows 系统上的用户活动时
- 识别恶意软件使用的自启动/持久化机制
- 追溯已安装软件、USB 设备和网络连接
- 在内部人员威胁调查中重建用户操作
- 将注册表时间戳与其他取证痕迹关联
前提条件
- 取证镜像或提取的注册表配置单元文件
- RegRipper、Registry Explorer (Eric Zimmerman) 或 python-registry
- 访问注册表配置单元位置(SAM、SYSTEM、SOFTWARE、NTUSER.DAT、UsrClass.dat)
- 理解 Windows 注册表结构(配置单元、键、值)
- SIFT 工作站或取证分析环境
工作流程
第 1 步:从取证镜像中提取注册表配置单元
# 以只读方式挂载取证镜像
mkdir /mnt/evidence
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/evidence.dd /mnt/evidence
# 复制系统注册表配置单元
cp /mnt/evidence/Windows/System32/config/SAM /cases/case-2024-001/registry/
cp /mnt/evidence/Windows/System32/config/SYSTEM /cases/case-2024-001/registry/
cp /mnt/evidence/Windows/System32/config/SOFTWARE /cases/case-2024-001/registry/
cp /mnt/evidence/Windows/System32/config/SECURITY /cases/case-2024-001/registry/
cp /mnt/evidence/Windows/System32/config/DEFAULT /cases/case-2024-001/registry/
# 复制用户特定的配置单元
cp /mnt/evidence/Users/*/NTUSER.DAT /cases/case-2024-001/registry/
cp /mnt/evidence/Users/*/AppData/Local/Microsoft/Windows/UsrClass.dat /cases/case-2024-001/registry/
# 复制事务日志(用于脏配置单元恢复)
cp /mnt/evidence/Windows/System32/config/*.LOG* /cases/case-2024-001/registry/logs/
# 对所有提取的配置单元计算哈希值
sha256sum /cases/case-2024-001/registry/* > /cases/case-2024-001/registry/hive_hashes.txt
第 2 步:使用 RegRipper 进行自动化痕迹提取
# 安装 RegRipper
git clone https://github.com/keydet89/RegRipper3.0.git /opt/regripper
# 对 NTUSER.DAT(用户配置文件)运行 RegRipper
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/NTUSER.DAT \
-f ntuser > /cases/case-2024-001/analysis/ntuser_report.txt
# 对 SYSTEM 配置单元运行
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SYSTEM \
-f system > /cases/case-2024-001/analysis/system_report.txt
# 对 SOFTWARE 配置单元运行
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SOFTWARE \
-f software > /cases/case-2024-001/analysis/software_report.txt
# 对 SAM 配置单元运行(用户帐户)
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SAM \
-f sam > /cases/case-2024-001/analysis/sam_report.txt
# 运行特定插件
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/NTUSER.DAT \
-p userassist > /cases/case-2024-001/analysis/userassist.txt
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SYSTEM \
-p usbstor > /cases/case-2024-001/analysis/usbstor.txt
第 3 步:提取持久化和自动运行条目
# 使用 python-registry 进行针对性提取
pip install python-registry
python3 << 'PYEOF'
from Registry import Registry
# 打开 SOFTWARE 配置单元
reg = Registry.Registry("/cases/case-2024-001/registry/SOFTWARE")
# 检查 Run 键(自启动)
autorun_paths = [
"Microsoft\\Windows\\CurrentVersion\\Run",
"Microsoft\\Windows\\CurrentVersion\\RunOnce",
"Microsoft\\Windows\\CurrentVersion\\RunServices",
"Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run",
"Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"
]
for path in autorun_paths:
try:
key = reg.open(path)
print(f"\n=== {path} (最后修改时间: {key.timestamp()}) ===")
for value in key.values():
print(f" {value.name()}: {value.value()}")
except Registry.RegistryKeyNotFoundException:
pass
# 检查已安装的服务
key = reg.open("Microsoft\\Windows NT\\CurrentVersion\\Svchost")
print(f"\n=== Svchost 组 ===")
for value in key.values():
print(f" {value.name()}: {value.value()}")
PYEOF
# 检查 NTUSER.DAT 中的用户特定自动运行
python3 << 'PYEOF'
from Registry import Registry
reg = Registry.Registry("/cases/case-2024-001/registry/NTUSER.DAT")
user_autorun = [
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run"
]
for path in user_autorun:
try:
key = reg.open(path)
print(f"\n=== {path} (最后修改时间: {key.timestamp()}) ===")
for value in key.values():
print(f" {value.name()}: {value.value()}")
except Registry.RegistryKeyNotFoundException:
pass
PYEOF
第 4 步:分析用户活动痕迹
# 提取 UserAssist 数据(程序执行历史,使用 ROT13 编码)
python3 << 'PYEOF'
from Registry import Registry
import codecs, struct, datetime
reg = Registry.Registry("/cases/case-2024-001/registry/NTUSER.DAT")
ua_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist"
key = reg.open(ua_path)
for guid_key in key.subkeys():
count_key = guid_key.subkey("Count")
print(f"\n=== {guid_key.name()} ===")
for value in count_key.values():
decoded_name = codecs.decode(value.name(), 'rot_13')
data = value.value()
if len(data) >= 16:
run_count = struct.unpack('<I', data[4:8])[0]
focus_count = struct.unpack('<I', data[8:12])[0]
timestamp = struct.unpack('<Q', data[60:68])[0] if len(data) >= 68 else 0
if timestamp > 0:
ts = datetime.datetime(1601,1,1) + datetime.timedelta(microseconds=timestamp//10)
print(f" {decoded_name}: 运行次数={run_count}, 聚焦次数={focus_count}, 最后时间={ts}")
else:
print(f" {decoded_name}: 运行次数={run_count}, 聚焦次数={focus_count}")
PYEOF
# 提取最近文档 (MRU 列表)
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/NTUSER.DAT \
-p recentdocs > /cases/case-2024-001/analysis/recentdocs.txt
# 提取已输入的 URL(浏览器)
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/NTUSER.DAT \
-p typedurls > /cases/case-2024-001/analysis/typedurls.txt
# 提取 Explorer 中输入的路径
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/NTUSER.DAT \
-p typedpaths > /cases/case-2024-001/analysis/typedpaths.txt
第 5 步:提取系统和网络信息
# 从 SYSTEM 配置单元获取计算机名和操作系统版本
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SYSTEM \
-p compname > /cases/case-2024-001/analysis/system_info.txt
# 网络接口和配置
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SYSTEM \
-p nic2 >> /cases/case-2024-001/analysis/system_info.txt
# 无线网络历史记录
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SOFTWARE \
-p networklist > /cases/case-2024-001/analysis/network_history.txt
# 时区配置
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SYSTEM \
-p timezone > /cases/case-2024-001/analysis/timezone.txt
# 关机时间
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SYSTEM \
-p shutdown > /cases/case-2024-001/analysis/shutdown.txt
# 从 Uninstall 键获取已安装软件
perl /opt/regripper/rip.pl -r /cases/case-2024-001/registry/SOFTWARE \
-p uninstall > /cases/case-2024-001/analysis/installed_software.txt
关键概念
| 概念 | 描述 |
|---|---|
| 注册表配置单元 (Registry hive) | 存储注册表某一部分的二进制文件(SAM, SYSTEM, SOFTWARE, NTUSER.DAT) |
| MRU(最近使用的) | 跟踪最近访问的文件、命令和搜索词的列表 |
| UserAssist | 使用 ROT13 编码的注册表条目,跟踪程序执行并包含时间戳 |
| ShimCache | 应用程序兼容性缓存,记录已执行过的程序 |
| AmCache | 详细的执行历史记录,包含可执行文件的 SHA-1 哈希值 |
| BAM/DAM | 后台/桌面活动调节器,在 Windows 10+ 中跟踪程序执行 |
| 最后写入时间 (Last Write Time) | 注册表键上的时间戳,指示其最后修改时间 |
| 事务日志 (Transaction logs) | 日志文件,允许在异常关闭后恢复注册表状态 |
工具与系统
| 工具 | 用途 |
|---|---|
| RegRipper | 基于插件架构的自动化注册表痕迹提取工具 |
| Registry Explorer | Eric Zimmerman 开发的交互式注册表分析 GUI 工具 |
| python-registry | 用于编程式注册表配置单元解析的 Python 库 |
| RECmd | Eric Zimmerman 开发的命令行注册表分析工具 |
| yarp | 另一个基于 Python 的注册表解析器 (Yet Another Registry Parser) |
| AppCompatCacheParser | 专用的 ShimCache/AppCompatCache 解析器 |
| AmcacheParser | 专用的 AmCache.hve 分析工具 |
| ShellBags Explorer | 专门用于分析 ShellBag 痕迹的工具 |
常见场景
场景 1:恶意软件持久化调查 提取 SOFTWARE 和 NTUSER.DAT 配置单元,检查所有 Run/RunOnce 键中是否存在未授权条目,检查服务中是否存在可疑添加项,检查计划任务注册表键,将自动运行时间戳与恶意软件执行时间线关联。
场景 2:用户活动重建 分析 UserAssist 获取程序执行历史,检查 RecentDocs 获取已访问文件,检查 TypedPaths 获取 Explorer 导航记录,提取 ShellBags 获取文件夹访问模式,构建事件窗口期间的用户活动时间线。
场景 3:未授权软件检测 解析 Uninstall 键以获取所有已安装应用程序,与批准的软件基线进行比较,检查 BAM/DAM 以获取最近执行但不在批准列表中的程序,检查 AppCompatCache 以获取即使已卸载也能找到的执行证据。
场景 4:USB 数据泄露调查 从 SYSTEM 配置单元中提取 USBSTOR 条目以获取已连接的设备,将设备序列号与 MountedDevices 关联,检查 NTUSER.DAT 中的 MountPoints2 以获取用户对可移动介质的访问记录,检查 SetupAPI 日志以获取首次连接时间戳。
输出格式
注册表分析摘要:
系统: DESKTOP-ABC123 (Windows 10 Pro Build 19041)
时区: 东部标准时间 (UTC-5)
最后关机: 2024-01-18 23:45:12 UTC
自动运行条目:
HKLM Run: 5 条目 (1 条可疑: "updater.exe" -> C:\ProgramData\svc\updater.exe)
HKCU Run: 3 条目 (均合法)
服务: 142 条目 (2 条未知: "WinDefSvc", "SysMonAgent")
用户活动 (NTUSER.DAT):
UserAssist 程序: 234 条目
最近文档: 89 条目
已输入 URL: 45 条目
已输入路径: 12 条目
连接的 USB 设备:
- Kingston DataTraveler (序列号: 0019E06B4521) - 首次连接: 2024-01-10, 最后连接: 2024-01-18
- WD My Passport (序列号: 575834314131) - 首次连接: 2024-01-15, 最后连接: 2024-01-15
已安装软件: 127 个应用程序
可疑发现: 3 项标记待审查