3. 硬件物料清单(HBOM)与软件物料清单(SBOM)工程
在IoT设备供应链安全中,HBOM与SBOM是两条并行的“成分账本”。HBOM记录设备中所有物理物料——主控芯片、无线模组、传感器、Flash、电源管理IC、连接器,甚至外壳与PCB的层压材料;SBOM记录固件与操作系统中所有软件组件——内核、驱动、协议栈、第三方库、配置文件与构建脚本。两者共同回答一个核心问题:这台设备到底由什么构成,每个成分来自哪里,存在哪些已知漏洞。
HBOM与SBOM并非简单的清单罗列,而是需要与供应链、漏洞库、构建系统形成可追溯的关联。对于IoT设备,硬件与软件高度耦合:一颗Wi-Fi模组的固件版本可能决定其协议栈是否受某个CVE影响;一颗MCU的ROM bootloader可能无法升级,从而形成永久性风险。因此,HBOM与SBOM必须能够通过“设备型号—批次—固件版本—组件版本”这条链路进行联合查询。
数据格式:SPDX与CycloneDX的工程选择
当前主流的SBOM格式是SPDX与CycloneDX。SPDX由Linux基金会维护,强调许可证合规与文件级溯源,适合需要严格许可证审计的场景;CycloneDX由OWASP社区推动,原生支持漏洞(VEX)、服务与硬件描述,更适合安全漏洞追溯与IoT设备。两者都支持JSON、XML等序列化方式,但字段模型不同。
以CycloneDX 1.5为例,一个最小SBOM片段如下:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"metadata": {
"component": {
"type": "firmware",
"name": "iot-gateway-fw",
"version": "2.3.1"
}
},
"components": [
{
"type": "library",
"name": "mosquitto",
"version": "2.0.11",
"purl": "pkg:github/eclipse/mosquitto@2.0.11",
"bom-ref": "pkg:github/eclipse/mosquitto@2.0.11"
},
{
"type": "library",
"name": "openssl",
"version": "1.1.1k",
"purl": "pkg:generic/openssl@1.1.1k",
"bom-ref": "pkg:generic/openssl@1.1.1k"
}
]
}
其中purl(Package URL)是跨格式的组件唯一标识,bom-ref用于在依赖关系与漏洞声明中引用该组件。SPDX则使用SPDXID与PackageName、PackageVersion、ExternalRef等字段表达类似信息。工程上建议:若下游漏洞平台支持CycloneDX,优先使用CycloneDX;若需要与许可证扫描工具链深度集成,可同时输出SPDX。
生成工具:Syft与Tern的定位差异
Syft是Anchore开源的SBOM生成器,擅长从容器镜像、文件系统、目录中提取软件包信息,支持APK、DEB、RPM、Go模块、Python包、npm包等多种生态,输出SPDX与CycloneDX。Tern则更聚焦于容器镜像与固件镜像的分层分析,能够识别Dockerfile层、文件系统层,并生成更细粒度的组件清单。对于IoT固件,常见做法是先用binwalk解包固件,再用Syft扫描解包后的根文件系统。
一个典型的固件SBOM生成流程如下:
# 1. 解包固件
binwalk -e firmware.bin
# 2. 定位根文件系统
ls _firmware.bin.extracted/squashfs-root/
# 3. 使用Syft生成CycloneDX SBOM
syft dir:_firmware.bin.extracted/squashfs-root/ -o cyclonedx-json > sbom.json
# 4. 使用Grype进行漏洞匹配
grype sbom:sbom.json -o table
这里的关键是:Syft扫描的是解包后的文件系统,而不是原始固件二进制。对于没有文件系统的裸机固件,则需要结合字符串提取、符号表分析与组件指纹库进行识别,此时SBOM的完整性会下降,需要在HBOM中标注“软件成分不可完全枚举”的风险。
HBOM与SBOM在IoT固件中的集成方法
HBOM与SBOM的集成不是简单地把两个JSON文件放在一起,而是要在构建与发布流程中建立关联。推荐的做法是:在CI/CD流水线中,每次固件构建时同时生成SBOM,并将SBOM的哈希值写入HBOM的扩展字段;在设备出厂时,将HBOM与SBOM的引用写入设备的安全存储或OTA元数据中。这样,当某个CVE爆发时,可以通过“CVE→组件→SBOM→固件版本→HBOM→设备批次”快速定位受影响设备。
下图展示了HBOM、SBOM、固件构建与漏洞追溯之间的数据流关系:
漏洞追溯实战:从CVE到设备批次
假设某日公开了CVE-2023-0286,影响OpenSSL 1.1.1k及更早版本。追溯过程如下:
- 在漏洞库中确认受影响组件为
openssl@1.1.1k,purl为pkg:generic/openssl@1.1.1k。 - 在SBOM仓库中检索包含该purl的SBOM文件,得到固件版本
2.3.1。 - 通过HBOM中记录的“SBOM哈希”字段,确认该SBOM对应硬件批次
LOT-2024-11,设备型号GW-200。 - 查询生产数据库,得到该批次已出货设备序列号范围,输出受影响设备清单。
- 根据VEX声明判断该漏洞在设备上下文中是否可利用:若OpenSSL仅用于已禁用的调试接口,则标记为
not_affected;若用于MQTT over TLS,则标记为affected,触发OTA修复。
这个闭环的关键在于:SBOM必须与固件版本绑定,HBOM必须与批次绑定,且两者之间通过哈希或引用建立可验证的关联。如果SBOM是构建后补录的,或者HBOM没有记录SBOM引用,追溯就会断裂。
HBOM/SBOM工程检查要点
| 检查项 | 合格标准 | 常见问题 |
|---|---|---|
| SBOM格式 | CycloneDX 1.4+ 或 SPDX 2.3+,含purl与bom-ref | 仅输出组件名称,无版本与唯一标识 |
| HBOM字段 | 含型号、批次、固件版本、SBOM哈希 | 缺少批次与固件版本映射 |
| 生成时机 | CI/CD构建阶段自动生成,与固件同版本 | 发布后手工补录,与二进制不一致 |
| 漏洞匹配 | 使用Grype/OSV-Scanner对SBOM自动扫描 | 仅依赖人工比对CVE列表 |
| VEX声明 | 对每个受影响组件给出可利用性判断 | 所有CVE一律标记为affected,造成告警疲劳 |
对于IoT设备,HBOM与SBOM的工程化不是一次性任务,而是贯穿需求、选型、构建、测试、发布、运维的持续过程。只有把物料清单变成构建流水线的“副产品”而非“额外文档”,才能真正支撑供应链漏洞的快速追溯与精准响应。