镜像或者容器中,如果用户是通过包管理软件安装的程序,可以通过包管理软件获取对应的软件信息和版本信息,但是,如果用户自己编译了一个二进制,然后打包到镜像或者通过拷贝命令放到容器中,该如何识别该程序是否有风险呢?
漏洞检测方式有两种:
我们先尝试第一种方式,看能否获取二进制的版本信息(包含二进制使用的开源组件的版本信息)。
SCA是一项对源代码或者二进制进行分析的技术,通过分析软件的一些组成部分和依赖等识别出软件可能包含的漏洞。例如,某个软件在开发过程中使用了一些公开的库,那么这些库可能包含一些漏洞。
Aqua是一家容器安全初创公司,主要的开源产品有:Trivy(容器漏洞扫描)、kube-bench(k8s的CIS安全基准测试)。而Aqua的容器安全平台使用的扫描引擎就是Trivy,而且可以设置选项Scan standalone binaries in images扫描不通过包管理安装的软件(使用开源的Trivy未发现可以扫描二进制,估计是在开源版本上通过plugin机制增加了额外的扫描能力)。
Trivy提供的命令有:
通过对trivy提供的命令以及使用的分析发现,开源的trivy采用的依然是以下三种方式:
Black Duck提供以下几种能力:
Black Duck包含detect和server,detect没有做太多的扫描动作,通常会将数据上传到server执行。
安装detect:bash <(curl -s -L https://detect.synopsys.com/detect7.sh)
。
运行detect:java -jar synopsys-detect-7.13.2.jar --detect.binary.scan.file.path=/usr/bin/ping --blackduck.offline.mode=true --detect.cleanup=false
。
但是detect在运行时一般需要制定server的地址,特别地,对于二进制扫描模式,需要将二进制上传到server进行扫描分析。而在实现原理上,则没有找到更多资料。
腾讯的云产品T-Sec 二进制软件成分分析能够对二进制提供自动化的分析能力,产品提供的功能包括:
腾讯云的二进制软件成分分析产品就是基于科恩的BinaryAI,而BinaryAI就是基于下面两篇论文:
在github上,BinaryAI和BinAbsInspector则都不太活跃。
腾讯的方案,利用AI模型对开源软件的数据进行训练,然后对待检测的二进制进行匹配,找到相似的二进制或者对应的源代码,基本可以确定使用的软件和版本。基于AI模型的方法比较重要的是数据集,BinaryAI每天会自动跟踪开源平台上的项目变化,对数据集进行更新。目前,BinaryAI已经采集全网主流C/C++项目的数万个仓库的上百万个版本,累计百亿C/C++源代码特征文件。
悬镜安全是一家做软件供应链安全的公司,它开源了OpenSCA,根据它所支持的检测能力看,它的实现方式是基于对包管理软件的配置文件的分析。
例如,对于golang,通过分析go.mod和go.sum文件,得出该软件依赖的包和版本,可以看出,这种方案其实还是源代码级别的分析。
基于对上述产品的调研,相对比较公开的SCA实现方式通常是:
而其他的实现方式,例如大数据或者AI,要么比较封闭,查不到太多资料,要么需要利用AI+大数据+算法实现,比较复杂。
容器是基于namespace、cgroup和chroot技术构建成的运行单元,但是多个容器之间依然是共享内核的,容器还是可能逃逸到宿主机,会对其他容器造成安全隐患,因此,通常有两种方式能够提供比原生容器更高的隔离性:
Sandbox是一种更加安全的环境,比虚拟机轻量的同时比容器更加安全,可以在该环境中执行POC测试,从而检测二进制的漏洞。
gVisor通过伪装成内核,对用户程序进行响应,由用户态进程执行系统调用。
gVisor有两个组件:
于是,当容器中的进程执行系统调用时,需要有种机制截获该系统调用,然后转发给Sentry,Sentry在执行时,如果需要IO操作,则转发给Gofer。根据截获系统调用的机制区分,有两种方式:KVM和ptrace。
gVisor的安装以及作为docker的运行时:gVisor Installation
一些重要的选项:
gVisor的一些问题:
kata-containers是一个基于轻量虚拟机实现的容器化技术,它有容器的性能,但是提供比容器更好的隔离性和安全性,可以将它理解为一个经过裁剪的虚拟机。
分别下载containerd和kata:
tar -C / -xf cri-containerd-cni-1.5.2-linux-amd64.tar.gz
tar -C / -xf kata-static-2.5.1-x86_64.tar.xz
cp -f containerd.service /etc/systemd/system/containerd.service
mkdir /etc/containerd
cp -f config.toml /etc/containerd/config.toml
systemctl restart containerd
ctr image pull docker.io/library/busybox:latest
然后运行一个容器:ctr run --runtime "io.containerd.kata.v2" --rm -t docker.io/library/busybox:latest test-kata uname -r
,会发现容器的内核跟宿主机的内核是不一样的,说明它不是传统的容器方式运行。
根据以上的调研,如果使用版本对比的方式得到二进制漏洞,有以下方式:
如果使用POC执行的方式得到二进制漏洞,只能基于一些不会对系统造成影响的环境进行测试,例如,gvisor和kata-containers。