说实话,这两年搞软件供应链安全,要是你没听过SBOM,都不好意思跟人打招呼。但我见过太多团队卡在同一个地方:SBOM生成了一大堆,SPDX、CycloneDX格式都有了,然后呢?躺在GitLab里吃灰。真正麻烦的是怎么把这些清单变成能指导修复的安全情报。我自己的经验是,别一上来就上重型商业平台,先用CVE Binary Tool这种轻量开源工具把闭环跑通,比什么都实在。
这篇文章就围绕一个最实际的场景展开:已有或刚生成的SBOM,怎么用CVE Binary Tool快速扫描出已知漏洞。我会把环境准备、SBOM生成、扫描参数、结果解读、误报处理、CI接入整个链路讲透,还会分享一些官方文档里不写、但我实际踩过的坑。看完你直接照着操作,基本就能把这条供应链安全流水线跑起来了。
1. 先搞清楚要解决什么问题
1.1 没有SBOM的时代,漏洞排查有多痛
先花两分钟回忆一下“上古时期”的排查流程。假设线上服务出了个Log4j漏洞,运维和开发的第一反应是什么?打开服务器,逐个目录搜log4j-core的jar包,再对着版本号手工比对公告。运气好,项目规范化,一条find / -name "*.jar"能解决;运气不好,依赖嵌套了三层,同一个组件在多个模块里版本还不一样,那一晚上基本就废了。
SBOM就是干这个的。它把软件里“有哪些组件、什么版本、什么许可证、组件间的依赖关系”全部结构化记录下来,本质上就是你家软件的“配方表”或“购物清单”。无论是NVD披露了新CVE,还是某个组件被爆出供应链攻击,你都可以拿着这张清单快速对照:我有没有用到?用的是哪个版本?需不需要立即处理?
但SBOM只是第一步,它本身不会告诉你“危不危险”。所以需要另一个工具去解读这份清单,把“组件名+版本号”映射到漏洞数据库里,查出对应CVE。这就是CVE Binary Tool干的活。
1.2 CVE Binary Tool这个工具到底干什么
CVE Binary Tool(以下简称cve-bin-tool)是一个开源漏洞扫描器,最早由Red Hat等社区开发者维护,后来独立成项目。它最大的特点是“不挑食”:既能直接扫描二进制文件、源码目录,也能解析现成的SBOM文件,提取里面的组件清单做漏洞匹配。
它底层做的事情其实不复杂:识别目标里每个组件的名称和版本,然后在本地缓存或在线更新的CVE数据库中查找匹配项,最后按CVSS评分排序输出。但这个“不复杂”背后有个很关键的设计——它内置了几百个组件识别器(checkers),可以识别常见的开源库、运行时、工具链的特定版本特征。这意味着哪怕你给我一个没有SBOM的老旧二进制,它也能尽可能猜出里面是什么组件、什么版本,再去查漏洞库。
不过本文重点还是讲SBOM场景,因为SBOM给了它一份“标准答案”,识别准确率会高很多,误报也少。
2. 环境准备与安装,给新手一条明路
2.1 准备运行环境
CVE Binary Tool是Python写的,所以环境要求很直接:Python 3.8及以上,推荐3.10或3.12。Windows、macOS、Linux都能跑,但如果你在公司内网或离线环境使用,建议提前装好Python并配好pip镜像源,后面下载依赖会顺畅很多。
我个人的习惯是给这类工具单独建一个虚拟环境,而不是直接装到系统Python里。因为cve-bin-tool依赖的包不少,包括pip-audit、packaging、rich这些,直接往系统里塞容易跟其他项目冲突。用venv隔离干净,也方便日后整体升级或卸载。
python -m venv cveenv source cveenv/bin/activate # Windows系统是 cveenv\Scripts\activate激活虚拟环境后,顺手把pip升到最新版,避免一些老的安装报错。
2.2 安装方式选择
安装主程序非常简单,一条命令:
pip install cve-bin-tool这个过程会拉取一系列依赖包,包括用于NVD数据同步的库、输出HTML报告用的模板等。如果你公司有内部PyPI源,把pip源指过去即可。
装完可以验证一下版本:
cve-bin-tool --version输出类似CVE Binary Tool vX.Y.Z说明装好了。
我还建议顺手装两个配合工具,后面生成SBOM要用。一个是syft,来自Anchore团队,专门用来扫描容器镜像和文件系统、生成SBOM,支持Syft格式、SPDX、CycloneDX;另一个是trivy,Aqua Security家的,既能扫漏洞也能生成SBOM,功能更全。
# syft 安装(macOS 或 Linux) curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin # trivy 安装(macOS) brew install trivy安装工具这件事,看起来是小事,但很多人就卡在第一步。比如网络代理不通、pip源超时、系统缺少gcc导致某些依赖需要编译……这些我都遇到过。最省事的办法是用官方提供的二进制安装包,或者直接在Docker容器里跑,省去一堆环境问题。如果你只是想在CI里用,后面第六节我会给一个开箱即用的GitHub Actions方案。
3. 手把手:从生成SBOM到扫描漏洞
3.1 先用Syft生成一份CycloneDX格式的SBOM
要扫描SBOM,首先得有一份像样的SBOM。现在市面上生成SBOM的工具很多,Syft、Trivy、SPDX Tools、CycloneDX生成器、甚至pip list都能凑一份。但从“能被CVE Binary Tool好好解析”这个角度出发,我推荐CycloneDX JSON格式,字段规范、版本信息全,工具支持度也最好。
举个例子,假设你有一个Python项目,目录结构大概是这样的:
myapp/ ├── requirements.txt ├── src/ │ └── main.py └── README.md用Syft生成SBOM的命令:
syft dir:./myapp -o cyclonedx-json=myapp.sbom.json这条命令会扫描myapp目录下的所有文件,识别Python依赖(包括requirements.txt里的包)、可能的二进制文件,然后输出一份CycloneDX JSON格式的SBOM。打开看内容,你会发现每个组件都有name、version、type等字段,这些就是后续CVE Binary Tool匹配漏洞的依据。
如果你是扫描容器镜像,命令变成:
syft your-image:latest -o cyclonedx-json=image.sbom.json这种方式对镜像里的系统库、语言依赖识别得更全。生成后建议用jq或编辑器检查一下SBOM里的组件数量——如果只有几个,大概率是识别器漏了东西,得回头看镜像基础镜像或构建方式。
3.2 用CVE Binary Tool扫描这份SBOM
拿到了myapp.sbom.json,下面进入正题——用cve-bin-tool扫它。命令非常直白:
cve-bin-tool --sbom myapp.sbom.json --sbom-type cyclonedx -f json -o myapp_cve_result.json逐项解释一下参数:
--sbom:指定SBOM文件路径。--sbom-type:告诉工具SBOM格式,支持cyclonedx、spdx、swid。这里必须写对,写错了解析直接失败。-f json:输出JSON格式结果,便于后续自动化处理。-o:输出文件路径。
跑起来后,你会看到终端刷出进度信息。第一次运行通常会花费较长时间,因为工具要去同步NVD的CVE数据库。数据同步完成后,它会把数据库默认缓存在用户目录的.cache/cve-bin-tool下,以后扫描就快很多了。
扫描结束,终端会汇总一个漏洞报告:有多少组件、多少CVE、多少高危、多少中危低危。同时会提示输出文件位置。
这里插一个我踩过的坑:SBOM里的组件如果缺少版本号,cve-bin-tool会直接跳过或报warning,而不会去猜版本。生成SBOM时务必确认version字段非空。像syft这种工具偶尔会把某些组件的版本标成unknown,这种情况在扫描结果里是看不到的,但实际风险依然存在。所以拿到SBOM后,先掏一下净值,看看有多少组件“无版本”。
3.3 不依赖SBOM,也能直接扫源码目录
有些老旧项目实在补不出SBOM,没关系,cve-bin-tool并不强制要求SBOM。你可以直接让它扫描源码目录:
cve-bin-tool ./myapp -f csv -o myapp_direct.csv它会通过内置checkers逐个识别目录里的开源组件。比如识别到libcurl的某个版本,就去匹配CVE库。这种模式适合快速摸底,但误报率相对高一些——因为它是根据文件特征猜的,可能有同名干扰。
所以我个人的判断标准是:如果有条件生成SBOM,优先走SBOM路线;实在没有,再用直接扫描兜底。两条路配合,覆盖不同场景。
4. 扫描结果怎么读,漏洞怎么扣
4.1 各种输出格式怎么选
cve-bin-tool支持的输出格式相当丰富,我列个表直观对比一下:
| 格式 | 命令参数 | 适用场景 |
|---|---|---|
| 控制台表格 | 默认 | 临时查看,最适合人肉阅读 |
| CSV | -f csv | Excel处理、快速排序筛选 |
| JSON | -f json | 对接自动化平台、留存原始数据 |
| SARIF | -f sarif | 导入GitHub Advanced Security或VS Code |
| CycloneDX | -f cyclonedx | 生成带漏洞信息的增强版SBOM |
| SPDX | -f spdx | 同上,但用SPDX格式 |
| HTML | -f html | 生成可分享的报告页面 |
我实际用得最多的是JSON和CSV。JSON留给CI脚本去解析,CSV给团队安全负责人做周报。如果你想把漏洞信息直接合并回SBOM里,可以用-f cyclonedx——这样输出的文件既包含原始组件清单,又包含每个组件的漏洞信息,相当于给SBOM做了“染色”,下游工具拿到可以直接消费。
4.2 CVSS评分和严重级别怎么看
扫描结果里每个CVE都会附一个CVSS评分,这是理解漏洞危害的关键。CVSS v3的评分范围是0到10,一般按这个区间分级别:
- 9.0-10.0:严重(Critical),基本意味着远程代码执行级别,必须马上处理。
- 7.0-8.9:高危(High),能造成严重影响的漏洞,需要尽快修复。
- 4.0-6.9:中危(Medium),有条件才能利用,安排正常迭代修复。
- 0.1-3.9:低危(Low),影响有限,可忽略或观察。
实际工作中不能只看分数。比如一个CVSS 9.8的漏洞,如果它影响的组件只在测试环境出现,那优先级就不如一个在公网服务上的CVSS 8.1漏洞。所以我的建议是:先按评分排序,再按资产重要性过滤,最后才决定修复顺序。
cve-bin-tool提供一个很实用的参数--cvss,可以只输出大于等于某个分数的漏洞:
cve-bin-tool --sbom myapp.sbom.json --sbom-type cyclonedx --cvss 7 -f csv -o high_only.csv这样直接筛出高危以上,省得人肉翻。
4.3 剔除干扰项和误报的技巧
SBOM扫描的误报率虽然比二进制扫描低,但还是存在。原因主要有两个:一是SBOM里的组件名和NVD数据库的官方名称对不上,导致匹配错;二是某些CVE只影响特定操作系统或特定使用方式,但SBOM没记录那么细,扫出来算“疑似受影响”。
处理误报我总结了三个步骤:
第一步,利用工具的--exclude参数排除确认无风险的组件。比如某个组件明明是测试专用,被打包进了SBOM,就可以:
cve-bin-tool --sbom myapp.sbom.json --sbom-type cyclonedx --exclude pytest --exclude mock第二步,通过--only-cve-id只关注特定CVE。这个方法适合应急:安全团队通报了一个重大CVE,你只需要确认自己仓里是否踩雷,就跑一次只查这个CVE的扫描。
cve-bin-tool --sbom myapp.sbom.json --sbom-type cyclonedx --only-cve-id CVE-2023-44487第三步,也是最重要的——把扫描结果当线索,不要当结论。cve-bin-tool匹配到漏洞后,你还需要去NVD或厂商公告里确认漏洞影响的具体版本范围、触发条件、修复版本。有这个“确认”动作,才能避免被误报牵着鼻子走,也不会因为工具漏报而完全放松警惕。
5. 常见问题快查表,都是我踩过的坑
5.1 首次扫描特别慢,卡在数据库同步
很多新手第一次运行cve-bin-tool,看到终端半天没动静,以为死机了。其实它在下载NVD的CVE数据,数据量不小,有时候十几个JSON文件要同步几分钟。解决办法是:
- 第一次跑之前,手动执行
cve-bin-tool --update把数据库同步好,后续扫描加--no-update跳过更新,速度飞快。 - 如果网络环境不好,可以设置NVD API密钥环境变量
NVD_API_KEY,能显著提升下载速度、避免限流。 - 离线环境的话,在一台有网的机器上把缓存目录打包,复制到目标机器,并在扫描时指定缓存目录位置。
# 拷贝缓存目录到离线服务器 tar czf cve_cache.tar.gz ~/.cache/cve-bin-tool/5.2 SBOM解析报错,格式明明没问题
我遇到过好几次:--sbom-type cyclonedx写成了CycloneDX,或者JSON文件带BOM头,导致解析失败。这里两个建议:
- 参数值必须用小写:
cyclonedx、spdx。 - 如果工具报JSON解析错误,先检查文件是不是UTF-8编码、有没有多余字符。用
python -m json.tool your.sbom.json校验一下,比肉眼排查快得多。
5.3 扫描结果里组件数量比预期少很多
这种问题大概率出在SBOM生成端,而不是cve-bin-tool。Syft只识别它能识别的语言生态和文件特征,Python项目如果依赖管理混乱(比如有的包是手动pip install后没写进requirements),就可能漏组件。解决思路是:改用trivy fs或syft的更强扫描模式,而且尽量用项目的锁文件(比如poetry.lock、pipfile.lock)作为SBOM生成的权威来源,而不是扫目录。锁文件里的版本信息干净、完整,扫出来的结果也最准。
5.4 扫描提示“no vulnerabilities detected”,是真的安全吗
不一定。cve-bin-tool对照的是NVD数据库,但NVD也不是全知全能的。很多新披露的漏洞、厂商自己公告的漏洞,可能还没进NVD,或者收录有延迟。所以“没扫到”只能说明“按当前数据库没匹配上”,不能等同于“绝对安全”。我一般会再配合厂商自己的安全公告、GitHub Advisory数据库做交叉验证。这也是为什么我强调把工具扫描当线索、别当最终结论。
6. 接入持续集成:让SBOM扫描成为日常
6.1 本地开发阶段:用pre-commit钩子提前拦截
很多漏洞其实在提交代码之前就能拦住。我建议在项目里配置pre-commit钩子,每次git commit前自动跑一次轻量扫描,覆盖变动的依赖文件。
.pre-commit-config.yaml可以参考这样写:
repos: - repo: https://github.com/intel/cve-bin-tool rev: v1.3.2 hooks: - id: cve-bin-tool args: [--sbom, sbom.cyclonedx.json, --sbom-type, cyclonedx, --fail-on, HIGH]其中--fail-on HIGH表示只要出现高危及以上漏洞,commit就直接失败。这样可以逼着开发在提交前把依赖版本升掉,而不是把问题留到上线前。
不过要注意,pre-commit钩子不适合跑全量扫描,因为每次提交都同步数据库会很折腾。建议固定用--no-update,并且提前手动把数据库更新到最新。这样钩子跑起来几秒就出结果,体验好很多。
6.2 GitHub Actions:定时扫描+PR门禁
团队协作场景下,更推荐把SBOM扫描放到CI里。一个比较稳妥的架构是:每天定时跑一次全量扫描,同时每次PR触发一次增量扫描。
PR触发的workflow可以这样写:
name: SBOM Security Scan on: pull_request: branches: [ main ] schedule: - cron: '0 2 * * *' jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Generate SBOM uses: anchore/sbom-action@v0 with: format: cyclonedx-json output-file: sbom.cyclonedx.json - name: Run CVE Binary Tool uses: intel/cve-bin-tool@v1 with: sbom-file: sbom.cyclonedx.json sbom-type: cyclonedx fail-on: HIGH这个workflow里有个很好的设计:每次扫描用的是实时生成的SBOM,不是手工维护的静态文件。这样保证SBOM永远跟代码同步,不会出现“安全部门扫的是上个月的清单”这种情况。
6.3 与Trivy、Syft等工具搭配的更完整工作流
如果你已经有了一套以Syft或Trivy为核心的SBOM生成流水线,CVE Binary Tool完全可以直接对接。我目前比较推荐的工作流是:
- 构建阶段:Syft或Trivy生成SBOM(CycloneDX JSON)。
- 存储阶段:SBOM随镜像或发布包一起归档,同时上传到制品库。
- 扫描阶段:cve-bin-tool每次发布或每日定时扫描归档的SBOM,输出JSON结果。
- 决策阶段:解析JSON结果,自动创建Jira工单或GitHub Issue,分派给对应负责人。
在这个工作流里,cve-bin-tool的定位是深耕CVE匹配和报告生成,而Syft/Trivy负责“食材识别”。组合使用,比单一大而全的工具更灵活,也更符合各自工具的核心优势。
我个人在实际操作中的体会是,整个链路里最花时间的不是扫描本身,而是把扫描结果和“谁负责修”“修哪个版本”打通。很多团队买了商业安全平台,数据很全,但没人跟进修复,漏洞还是一堆。开源的cve-bin-tool反而因为轻量,更容易嵌入到现有研发流程里。如果你正准备在团队里落地SBOM漏洞扫描,我建议先用这套开源方案跑一个月,把团队习惯和处置流程养好,再考虑要不要上重型平台。
最后再分享一个小技巧:cve-bin-tool支持把扫描结果输出成CycloneDX或SPDX格式,这就意味着你可以不断往上叠加漏洞数据,形成一份“带风险信息的SBOM”,传给其他工具做更细粒度的分析。所以别把它当成孤立扫描器,它其实是你整个软件供应链安全体系里一个很关键的“数据加工节点”。配上CI、配上数据库定期更新、配上团队漏洞处置机制,这条链路的威力才会真正释放出来。