原文视频地址:https://www.bilibili.com/vIDEo/BV1FL4y1A73V
开源项目地址:https://Github.com/murphysecurity/murphysec
本文内容较长,阅读时长约15分钟~
6月29日至30日墨菲安全受邀参与小米IoT安全峰会,本次由墨菲安全联合创始人、墨菲安全实验室负责人、软件供应链安全开源项目murphysecurity主要贡献者欧阳强斌带来分享,智能汽车行业的软件供应链安全威胁与解决方案。
智能汽车涉及的三类供应链风险的场景一、开源软件服务的风险过去有数据统计,过去的这个 10 年的这些攻击事件,41%都是来自于云端。那么在云端有大量的服务、数据统计,有78% 的项目都涉及到开源软件开源组件。这里面包含 log4j 这样的开源组件,也有像 Grafana 这样的开源应用,还有像 emqx 这样的 IoT 设备用得比较多的消息队列服务。
那它带来的风险是什么呢?如果有开源软件服务暴露在外网,攻击者通过很多公开漏洞,相对来说能够比较轻易的拿到服务权限,然后作为跳板去进行渗透,包括控制云端的这些 OTA 的服务数据库,以及说这个固件存储的 S3 的这种服务。当它控制了这些 OTA 的基础设施之后,它就可以给车辆下发这种升级指令去更新一个恶意的固件。这样的云端的攻击成本是很低的,而风险比较高,所以我们需要首先去关注开源软件服务的风险。
二、供应商的风险
供应商例如一些电池的管理系统,充电桩的管理的平台,或者是一些和客户代理商相关的管理系统,通常这些系统它不会直接和车辆进行交互,它是不能控制车辆的。但是比较大的风险是由于这些系统存储了车主用户的信息,容易导致车辆的用户信息轨迹、隐私数据泄露。供应商被攻击之后会导致泄露对应的用户隐私数据。
事件案例:去年,由于奥迪和大众的供应商被攻击,导致 350 万的用户数据泄露,这是关于这个供应商的风险场景的场景之一。
三、车身联网的风险
第三类风险在车身上面,车身涉及超过 100 个的 ecu 和 1 亿行的代码,其实中有 80% 的硬件,包括它配套的固件都是由供应商提供的。这里供应商又分了不同的层级,比如说 tier-1 它是提供系统的,然后 tier-2 是给这个 tier-1 去提供物料的。还有像芯片厂商,它既给 tier-1 提供芯片,它也提供给整车厂。
事件案例:最早大家关注车联网的安全,源于 15 年查理米勒演示了他通过右边这个哈曼的 ivi ,也就这个车机信息娱乐系统,去远程控制了汽车的转向制动。因为哈曼是这个克莱斯勒的 tier-1 的供应商,所以最后克莱斯勒召回了 140 万的配备 uconnet 系统的汽车。
所以我们可以看到在智能汽车这个场景里面有几个特点:1、车身涉及 200 多个供应商,其中任何一个出现问题都有可能影响到车辆安全;像芯片厂商,它传统的是属于tier-2,但现在整个已经形成了供应网;像去年英伟达的芯片出现漏洞,会影响到整车厂,也会影响tier-1。那当上下游都使用这个供应件的时候,你要完全的去替换它,成本就很高了。
然后普通的安全攻击事件,更多是给我们带来经济上的损失。但是由于车辆的安全会涉及到人身的安全,所以在这个场景下,大家其实对车的安全的容忍度是比较低的。同时国内外的一些制度标准也对安全有明确的要求,整个法规的要求还是比较高的。那这是我们看到的关于漏洞的一些风险。那除了漏洞以外,其实还有关于这个知识产权的风险在最近这几年也是受到关注。
事件案例:特斯拉在 2018 年开源了辅助驾驶平台的 Linux 内核和引导程序的代码。这背后其实是由于这些开源项目都用到了 GPL 的许可证。那 GPL 的许可证就要求说,你对这个源码做了修改,再去发布的时候,你是需要提供相应的源码的。所以这个 SFC 软件自由保护协会,他们经过长达五年的努力,最终是推动了特斯拉去做这样的一个开源。
事件案例:去年在国内,从法律的这个角度上去明确了许可证对应的法律效力。这就意味着开源的许可证合规,不再是一个君子协定。这些都是一些关于软件供应链的风险。
软件供应链安全解决方案一、智能汽车软件供应链安全治理参考现在主要的一些法规和标准,我们可以从以下的几个方面去展开治理。
1、首先是供应链的安全需要安全要求,需要覆盖软件产品的全生命周期,从整个设计开发到运行上
2、其次是在流程制度上要覆盖整体的管理要求,针对开源闭源软件的这些治理的机制,对风险的进行分类分级,并且持续的跟踪。
3、还需要有相应的协同应急处置的机制,当出现问题的时候,会需要及时的这种情报的信息漏洞分析和处置的工具,以及和供应商的协同处置的能力。
因为风险是不断变化的,所以对历史漏洞和恶意组件的这种投毒的情况,我们需要持续的去监测。
二、企业治理落地
从管理上的话,主要是对漏洞的管理,对供应商能力的评估。
识别:这里面涉及到的关键技术包括各个形态的软件资产的识别,缺陷的检测。比如判断是不是真的受到漏洞的影响,这样的技术可能会主要靠静态分析去实现。
修复:在缺陷修复上,主要考虑怎么能够更低成本的帮助开发者去修复。比如说有很多间接依赖的漏洞,我们要怎么样去修复。
漏洞挖掘与分析:这是对数据对知识的一个持续运营,是一个大的框架。具体来说,企业治理的核心是管理加上配套的工具能力,这里面核心数据是 SBOM 和知识库。
SBOM 是所有软件的资产清单,知识库指的是各类的风险信息形成的一个知识的聚合。从整个扫描能力上,核心是需要和研发的各个流程去做结合,构建对应场景的识别和解决的能力。包括像 IDE 的插件代码入库的扫描;项目在构建过程的扫描;针对容器的镜像、制品、二进制等不同的发布形态的扫描。在这之上可以去构建管理控制的能力,包括 SBOM 资产管理黑白名单的策略的限制,哪些组件可引入,哪些是不允许引入的。
然后我们可以去构建溯源查询的能力,能够支撑查询某一个风险,它引入的整个依赖的链条、它的时间点以及对应的具体的人员;还有整个的风险的视图,用来支撑体现整体的风险治理的状况。这些能力适用于支撑事前-事中-事后的这些治理的动作。所以风险前置解决是很重要的,因为越往后识别的难度越大,修复的成本也会越高。
所以对于研发工程师来说,应该从选行就开始考虑开源软件的安全,包括这个组件有没有漏洞,许可证是什么样的,流行度是什么样,版本之间是否是兼容等等。开发者或者开发团队对项目的维护频率是不是足够高,所以需要知识库来提供这些信息给研发工程师做参考。
三、开源软件风险治理前置
大部分的开发者都会使用 IDE 进行开发,所以在开发的过程中可以基于 IDE 的插件去实施检测依赖的变化,并且帮助开发者一键的去修复安全风险。如果研发工程师不使用 IDE 或者在开发过程中没有去解决风险,我们还可以在代码推送到代码仓库的时候去做强制的检查,去限制代码的合并。这些都是开源软件风险治理前置的一些做法。
这里面会涉及到一些技术点,比如说很多的代码可能是 C 写的,那我们要怎么去识别这里面的依赖?这里大概会分成两类:第一类是说基于这个依赖管理的文件去识别。比如说conan是一个比较现代化的依赖管理工具,它直接声明了依赖的这些组件静态、动态链接库的名称和版本。那如传统一点的像 make file 也会声明它的链接库,但是我们需要对文件做进一步的查找,才能够去进行判断。第二类是对于有源码的情况,我们可以通过文件的哈希和云端构建的组件版本特征库进行关联。当然这就会依赖云端,要提前计算好大量的特征。
另外很多比较简短的代码,比如说我们看到很多 base64 计算的函数,这样的代码可能非常短,开发者可能不会单独的通过一个文件去引入。它可能看到这一段代码写得不错,然后直接复制粘贴到了它的代码当中。这样的话我们就需要去识别说它是不是引入了一个代码片段或者是抄袭了某一段的代码片段,可以基于 N 行的代码进行匹配,比如说八行、十行,但是这样带来的问题就是误报率会比较高。如果以这个函数作为单位进行识别,这样的准确率会更高一些。
四、漏洞风险应急处置
以上提及了风险的治理前置,那如果业务在上线之后出现了新的漏洞呢?首先是可以根据预警信息——风险预警的情报信息,对资产清单进行排查,由识别受影响的项目,然后根据项目找到并通知对应的研发工程师进行修复,然后可以在构建的环节进行检查和阻断,禁止这种受影响的风险软件在再增量的去引入。
那这里面关于漏洞的这些知识数据怎么能够更全呢?比较理想的一个模式,首先是需要大量的数据源作为输入,包括像官方的这种CVE/CNVD的漏洞库、 Github 之类的第三方的漏洞库、开源代码库的所有的变更、开发者的各种通告、技术博客的文章、推特社交媒体,以及社区的白帽子的输入等等。有了这些数据输入之后,可以进行相应的数据清洗,然后由模型进行识别分类。比如说识别哪篇文章是描述某个漏洞,那这个漏洞是严重还是不严重?然后再经过一些策略的处理,主要是针对一些已知的场景的做相对比较确定性的规则,最后由专家团队进行校验,输出到漏洞知识库。
数据量上一些字段大家比较关注,包括说漏洞是怎么触发的,通过什么样的代码写法或者是什么样的配置才能触发;然后漏洞的利用条件是什么,有没有 POC 或者是在野利用的真实影响,有没有修复兼容性的问题。这些字段其实都会影响到大家对漏洞的判断。
五、漏洞尽早发现
从一般的漏洞公开时间线来看,从安全人员发现漏洞,到开发者收到反馈进行修复发版,然后安全通告到 CVE 公开这样的过程。大家越往后关注度越高,但是越往后面的两个环节之间留给大家的时间也越短。所以如果想要提前发现漏洞,那么就需要关注前面的一些环节。那基于这样的一些理念去实践的话,我们在最近这几个月也是提前发现了不少的漏洞。
六、组件投毒识别
除了漏洞,近几年投毒的事件也非常多。针对组件的投毒,目前大家研究的主要是集中在 Node 、Python、Ruby这几种动态类型的语言。当然在其他语言中我认为也会有相应的投毒存在,主要因为这几种语言的包名相对比较简单,所以就比较容易混淆,再加上安装脚本可以自定义,所以很多时候这个投毒的行为就发生在安装的过程里面,它加入了一些像下图中这样的信息收集的恶意的代码,从识别方式上看的话,主要有这几类。
第一类可以去判断这个包名它是不是容易混淆的。比如说通过新发的包名和存量的这些包名去计算它的编辑距离,看是不是相近相似。第二类从代码的静态分析上去判断,通常这种会有敏感函数的调用,有这个数据外发的异常。然后很多可能会有一些混淆的场景,这样的话可以去计算代码的熵值。
第三类从动态的行为上看,恶意的行为主要涉及到非预期的文件操作系统调用,还有外联网络的行为,这些都可以作为特征去进行识别。当然说检测其实它还是比较偏下游的,从上游来看,Sigstore 项目是比较值得大家去关注的,它的核心是期望通过签名和校验去实现供应链的信任。上游的软件开发者对发布的这个软件制品可以做签名,下游的这个使用者就可以对他拿到的制品去验证它的来源。
七、供应商安全能力评估
这套方案我们预计今年会走向成熟,像 kubernetes 这样的环境已经集成了,包括像 Openssf 基金会,他们也在推动主要语言的包管理器去使用这套签名验证的机制。
刚才我们讲云端的东西讲的比较多,讲自研的东西比较多。我们也提到了说供应商的准入,那怎么去评估一个供应商他的安全能力?
我们想大概可能会有这么几个维度是可以去评估的。
- 第一个是供应商的实力背景,比如说它是一个机构在维护,还是个人在维护,有没有相关的一些资质。
- 第二个是它的服务存在什么样的漏洞,包括合规上的一些风险。
- 第三个是它这个软件是在持续的维护还是处在一个长期不迭代的状况。
- 第四个是当初见问题后,它的响应处置的能力。
- 第五个是在供应商内部,是不是有安全管理体系。
这是关于供应商的能力评估的一些维度,还有像车身或者 IoT 的设备,会涉及到比较多的二进制或者固件的交付的场景。
总结
关于软件供应链安全,整体认为是处在一个风险和关注度都比较高的状态。可预见的是在接下来的一段时间风险还会持续。想要高效的去解决这些风险,核心依赖的是能够支撑各个场景的这种检测和修复的工具,以及说像漏洞组件这样丰富的知识库数据。在 IOT 领域,尤其需要关注风险的前置解决,否则整个治理的效果效率会比较低,成本也会比较高。
,