【安全】容器中二进制漏洞检测方案

1 背景

镜像或者容器中,如果用户是通过包管理软件安装的程序,可以通过包管理软件获取对应的软件信息和版本信息,但是,如果用户自己编译了一个二进制,然后打包到镜像或者通过拷贝命令放到容器中,该如何识别该程序是否有风险呢?

漏洞检测方式有两种:

  • 版本对比:将软件的版本跟漏洞库中影响的版本进行匹配,如果匹配上,说明有对应的漏洞,有一定的误报,而且需要先识别出软件名称和版本
  • POC脚本执行:执行漏洞POC,查看是否有漏洞上报,准确率高,但是有些漏洞没有POC,而且这种方式可能对正在运行的系统造成影响

我们先尝试第一种方式,看能否获取二进制的版本信息(包含二进制使用的开源组件的版本信息)。

2 SCA(Software Composition Analysis)

SCA是一项对源代码或者二进制进行分析的技术,通过分析软件的一些组成部分和依赖等识别出软件可能包含的漏洞。例如,某个软件在开发过程中使用了一些公开的库,那么这些库可能包含一些漏洞。

2.1 AquaSecurity

Aqua是一家容器安全初创公司,主要的开源产品有:Trivy(容器漏洞扫描)、kube-bench(k8s的CIS安全基准测试)。而Aqua的容器安全平台使用的扫描引擎就是Trivy,而且可以设置选项Scan standalone binaries in images扫描不通过包管理安装的软件(使用开源的Trivy未发现可以扫描二进制,估计是在开源版本上通过plugin机制增加了额外的扫描能力)。

Trivy提供的命令有:

  • trivy image:扫描镜像,通过分析操作系统的包管理器的配置文件得到安装的软件包和版本,然后通过软件包和版本得到对应的漏洞数据
  • trivy fs:扫描本地文件系统的语言包和配置文件
  • trivy rootfs:扫描rootfs,相当于扫描容器,扫描的方式跟镜像类似
  • trivy repository:扫描远程的仓库
  • trivy server:以server模式运行,然后提供接口
  • trivy config:扫描配置文件中的密码和token等信息,例如:Dockerfile、k8s的yaml、cloudformation、Terraform
  • trivy kubernetes:扫描k8s的漏洞

通过对trivy提供的命令以及使用的分析发现,开源的trivy采用的依然是以下三种方式:

  • 通过操作系统包管理器(apt、yum)获取安装的软件信息,然后根据软件版本信息分析出漏洞
  • 通过分析语言包的依赖库,以及依赖库的漏洞信息,得出整个软件的漏洞数据
  • 扫描相关的配置文件(Dockerfile、yaml、Terraform)中的敏感信息(passwd、key、token)
2.2 Synopsys Black Duck

Black Duck提供以下几种能力:

  • 程序分析:依赖分析(显然,也是通过分析配置文件)、码纹分析(可以识别C/C++开发的应用中使用的开源和第三方组件)、二进制分析、许可证分析
  • 漏洞扫描

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进行扫描分析。而在实现原理上,则没有找到更多资料。

2.3 腾讯

腾讯的云产品T-Sec 二进制软件成分分析能够对二进制提供自动化的分析能力,产品提供的功能包括:

  • 开源组件识别
  • 敏感信息扫描
  • 漏洞扫描

腾讯云的二进制软件成分分析产品就是基于科恩的BinaryAI,而BinaryAI就是基于下面两篇论文:

  • 基于图神经网络的二进制代码分析:判断两个二进制是否是同一份源代码编译出来的。那么,在对待检测而进制而言,如果可以找到同一份源代码编译出来的其他二进制,那么他们应该就是从同一份源代码编译出来的,就可以得到待检测的二进制使用的软件和版本信息。当然,不同版本的软件可能修改的代码不是太多,可能造成版本识别不正确
  • 基于跨模态检索的二进制代码-源代码匹配:在给定二进制的情况下,匹配出对应的源代码。那么,在对待检测的二进制而言,如果可以找到对应的源代码,也就可以知道对应的软件和版本,即便是通过不同参数编译而成的。

在github上,BinaryAIBinAbsInspector则都不太活跃。

腾讯的方案,利用AI模型对开源软件的数据进行训练,然后对待检测的二进制进行匹配,找到相似的二进制或者对应的源代码,基本可以确定使用的软件和版本。基于AI模型的方法比较重要的是数据集,BinaryAI每天会自动跟踪开源平台上的项目变化,对数据集进行更新。目前,BinaryAI已经采集全网主流C/C++项目的数万个仓库的上百万个版本,累计百亿C/C++源代码特征文件。

2.4 悬镜安全

悬镜安全是一家做软件供应链安全的公司,它开源了OpenSCA,根据它所支持的检测能力看,它的实现方式是基于对包管理软件的配置文件的分析。

例如,对于golang,通过分析go.mod和go.sum文件,得出该软件依赖的包和版本,可以看出,这种方案其实还是源代码级别的分析。

2.5 小结

基于对上述产品的调研,相对比较公开的SCA实现方式通常是:

  • 分析操作系统的包管理软件
  • 分析语言包的配置文件

而其他的实现方式,例如大数据或者AI,要么比较封闭,查不到太多资料,要么需要利用AI+大数据+算法实现,比较复杂。

3 Sandbox

容器是基于namespace、cgroup和chroot技术构建成的运行单元,但是多个容器之间依然是共享内核的,容器还是可能逃逸到宿主机,会对其他容器造成安全隐患,因此,通常有两种方式能够提供比原生容器更高的隔离性:

  • 基于虚拟机,例如KVM或者Xen,在虚拟机之上搭建用户内核,各虚拟机之间完全隔离,但是这种方式的缺点在于,启动时间较长、消耗的资源更多
  • 基于规则,例如Seccomp、SELinux和AppArmor,通过限定用户程序能够执行的操作达到隔离,缺点在于,规则比较复杂,而且内核依然是共用的

Sandbox是一种更加安全的环境,比虚拟机轻量的同时比容器更加安全,可以在该环境中执行POC测试,从而检测二进制的漏洞。

3.1 gVisor(Google)

gVisor通过伪装成内核,对用户程序进行响应,由用户态进程执行系统调用。

gVisor有两个组件:

  • Sentry:用户态的应用程序内核,本身运行在用户态,而且使用Seccomp限制了操作,当应用程序执行系统调用时,Sentry会收到请求,它自身会处理一些逻辑,无法执行的操作会通过9P协议转发给Gofer。
  • Gofer:Gofer是个运行在宿主机的进程,当Gofer收到请求后,会处理所有对资源的访问,当然,也会提供额外的隔离。

于是,当容器中的进程执行系统调用时,需要有种机制截获该系统调用,然后转发给Sentry,Sentry在执行时,如果需要IO操作,则转发给Gofer。根据截获系统调用的机制区分,有两种方式:KVM和ptrace。

gVisor的安装以及作为docker的运行时:gVisor Installation

一些重要的选项:

  • --platform=kvm/ptrace:默认使用ptrace,使用kvm时,宿主机需要加载kvm模块
  • --overlay:默认情况下,在容器中读写文件,操作的还是宿主机上面的文件,如果想要完全隔离,可以设置该参数
  • --network=sandbox/host/none:默认使用sandbox网络,容器和宿主机可以通信,并做转发;如果设置为host时,则使用宿主机的网络;如果设置为none时,容器中则只有loopback,容器不能与宿主机通信
  • --debug:启用debug
  • --debug-log=/tmp/runsc/:debug日志路径

gVisor的一些问题:

  • 本身对内核版本要求高(使用了user namespace,3.8开始引入,3.10需要修改配置/proc/sys/user/max_user_namespaces)
  • Sentry没有实现所有的系统调用,部分程序可能无法运行
  • 没有在大规模场景下使用过,可能有很多潜在的bug
3.2 kata-containers

kata-containers是一个基于轻量虚拟机实现的容器化技术,它有容器的性能,但是提供比容器更好的隔离性和安全性,可以将它理解为一个经过裁剪的虚拟机。

分别下载containerd和kata:

shell 复制代码
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,会发现容器的内核跟宿主机的内核是不一样的,说明它不是传统的容器方式运行。

4 总结

根据以上的调研,如果使用版本对比的方式得到二进制漏洞,有以下方式:

  • 基于包管理的软件清点,包括操作系统(yum、apt)和应用软件(pip等)
  • 采集DockerHub中的主流软件的主程序的哈希值,形成知识库,然后用哈希值对比的方式获取软件信息
  • 利用gVisor在沙箱中运行容器中的主程序的命令,得到应用的版本号,可以优化现有的容器进程的软件版本清点的卡死、影响业务的问题
  • 基于腾讯开源的BinaryAI库或者BinAbsInspector建立自己的知识库(成本较高)

如果使用POC执行的方式得到二进制漏洞,只能基于一些不会对系统造成影响的环境进行测试,例如,gvisor和kata-containers。

相关推荐
用户962377954481 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主2 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954484 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954484 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star4 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954485 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher6 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行9 天前
网络安全总结
安全·web安全