4、指纹采集技术(上):操作系统层采集
操作系统层的指纹采集,说白了就是跟系统内核“要数据”。Windows 有注册表,Linux 有 /proc 文件系统。这两个东西,是设备指纹最底层的“矿藏”。
我刚开始做资产盘点的时候,也试过用各种 Agent 去扫。后来发现,很多关键信息其实操作系统自己就记着,只是你没找对地方。今天咱们就把这两个“数据源”彻底聊透。
4.1 Windows 注册表:系统的“记忆宫殿”
Windows 注册表,你可以把它想象成一个巨大的树形数据库。从硬件配置到软件安装,从用户设置到网络参数,全在里面。指纹采集,就是从这个“宫殿”里提取关键特征。
4.1.1 注册表结构速览
注册表分五大根键,咱们做指纹采集,重点关注这几个:
| 根键 | 缩写 | 采集价值 |
|---|---|---|
| HKEY_LOCAL_MACHINE | HKLM | 硬件、系统、安全信息(核心) |
| HKEY_CURRENT_CONFIG | HKCC | 当前硬件配置文件 |
| HKEY_CLASSES_ROOT | HKCR | 文件关联、COM 组件(辅助) |
4.1.2 关键采集路径
我个人总结了几个“必采”路径,你在项目里可以直接套用:
- CPU 信息:
HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
取ProcessorNameString和Identifier。注意,Identifier 里包含步进和修订版本,是区分同型号 CPU 的关键。 - 主板/BIOS:
HKLM\HARDWARE\DESCRIPTION\System\BIOS
BaseBoardManufacturer、BaseBoardProduct、SystemSerialNumber。序列号是硬指纹,但有些组装机是空值,要做好容错。 - 网卡 MAC:
HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}
遍历子项,找NetCfgInstanceId和MACAddress。这里有个坑,虚拟网卡和 VPN 网卡也会出现,需要过滤。 - 磁盘序列号:
HKLM\SYSTEM\MountedDevices
或者通过 WMI 转储到注册表。磁盘序列号是唯一性很高的指纹因子。
4.1.3 采集代码示例(PowerShell)
我建议用 PowerShell 做原型验证,它原生支持注册表操作,写起来很快。
# 采集 CPU 信息
$cpuPath = "HKLM:\HARDWARE\DESCRIPTION\System\CentralProcessor\0"
$cpuInfo = Get-ItemProperty -Path $cpuPath
$fingerprint = @{
CPUName = $cpuInfo.ProcessorNameString
CPUIdentifier = $cpuInfo.Identifier
}
# 采集 BIOS 序列号
$biosPath = "HKLM:\HARDWARE\DESCRIPTION\System\BIOS"
$biosInfo = Get-ItemProperty -Path $biosPath
$fingerprint.BIOSSerial = $biosInfo.SystemSerialNumber
# 输出 JSON 格式指纹
$fingerprint | ConvertTo-Json
这段代码跑完,你会得到一个 JSON 对象。这就是最原始的“操作系统层指纹片段”。
4.2 Linux /proc 文件系统:内核的“实时快照”
Linux 下没有注册表,但 /proc 文件系统更强大。它不是一个真正的文件系统,而是内核数据结构的运行时接口。你读 /proc 下的文件,其实就是在内核里查表。
你想想看,/proc 里的文件大多是 0 字节,但 cat 一下却能输出一堆信息。为什么?因为它不是静态文件,是内核动态生成的。
4.2.1 核心采集文件
| 文件路径 | 采集内容 | 指纹价值 |
|---|---|---|
| /proc/cpuinfo | CPU 型号、核心数、标志位 | 高(含 vendor_id、model name、flags) |
| /proc/meminfo | 内存总量、内存分区 | 中(MemTotal 可用于辅助校验) |
| /proc/diskstats | 磁盘设备号、读写统计 | 中(设备号可映射到具体磁盘) |
| /proc/net/arp | IP 与 MAC 对应表 | 高(采集本机 MAC 的可靠来源) |
| /proc/version | 内核版本、GCC 版本 | 低(变化快,但可做环境校验) |
4.2.2 采集代码示例(Shell)
Linux 下我习惯用 Shell 脚本 + awk 处理。简单、高效、依赖少。
#!/bin/bash
# 采集 CPU 指纹
CPU_MODEL=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | sed 's/^ //')
CPU_CORES=$(grep "cpu cores" /proc/cpuinfo | head -1 | awk '{print $4}')
CPU_FLAGS=$(grep "flags" /proc/cpuinfo | head -1 | cut -d: -f2 | sed 's/^ //')
# 采集 MAC 地址(从 ARP 表取本机)
MY_IP=$(hostname -I | awk '{print $1}')
MAC_ADDR=$(grep "$MY_IP" /proc/net/arp | awk '{print $4}')
# 采集磁盘序列号(通过 udev 或 smartctl,/proc 本身不直接提供)
# 这里用 /proc/diskstats 获取设备名
DISK_DEV=$(grep "sd" /proc/diskstats | head -1 | awk '{print $3}')
echo "{\"cpu_model\":\"$CPU_MODEL\",\"cpu_cores\":\"$CPU_CORES\",\"mac\":\"$MAC_ADDR\",\"disk_dev\":\"$DISK_DEV\"}"
4.3 操作系统层指纹的“稳定性”与“可变性”
采集到数据只是第一步。你得知道哪些指纹是“死”的,哪些是“活”的。我把它分成三类:
- 硬指纹(高稳定): CPU ID、主板序列号、磁盘序列号。只要硬件不换,这些值不变。
- 软指纹(中稳定): MAC 地址、主机名、内核版本。重装系统或更换网卡会变。
- 动态指纹(低稳定): 内存大小、IP 地址、启动时间。每次重启都可能变。
做资产台账时,我建议用“硬指纹 + 软指纹”组合成主键。动态指纹只做辅助校验,不要用它做唯一标识。
4.4 知识体系总览
下面这张图,是我梳理的操作系统层指纹采集的核心逻辑。你可以把它当作本章的“地图”。
4.5 本章小结
操作系统层采集,是设备指纹的“地基”。Windows 靠注册表,Linux 靠 /proc。两者思路一致:从系统核心数据结构中,提取那些“换了机器就会变”的特征。
我个人建议,你在做采集引擎时,先把 Windows 和 Linux 的采集模块分开写。不要试图用一个万能脚本兼容两个系统。分开写,维护成本反而更低。