容器镜像静态扫描原理
前言
有这样一个工具, 可以对镜像进行扫描, 拿出其中包含的软件包、lib库(pip包等)、危险文件等, 并能够识别出哪些包是存在漏洞的. 比如trivy
工具. 那么他们是如何做到这件事情的呢?
正好最近在研究这块, 索性就简单谈一谈(其实原理很简单).
获取包含内容
对于镜像的存储, 层之间的关系, 以及如何将多层数据进行聚合, 可以看之前的这篇文章.
扫描单层软件包#
扫描单层的数据, 说白了就是文件扫描. 比如:
- 获取系统版本
- 从
etc/os-release
文件获取系统版本 - 从
etc/debian_version
文件获取debian
的版本 - 从
etc/lsb-release
文件获取ubuntu
版本 - 从
etc/alpine-release
文件获取alpine
的版本
- 从
- 获取系统包
- 从
lib/apk/db/installed
文件获取安装的所有apk
包 - 从
var/lib/dpkg/status
文件获取安装的所有dpkg
包
- 从
- 获取依赖库
- 依据
.jar
后缀拿到所有jar
包 - 依据
go.mod
文件名获取依赖的库 - 从
requirements.txt
文件拿到依赖的pip
库
- 依据
- 获取风险文件
- 通过一些文件识别的扫描库, 可实现对恶意文件的识别. 比如yara
通过对本层所有文件的扫描, 就能够将当前层包含的信息全部拿到了.
多层合并#
在拿到每一层的数据之后, 接下来就是将多层的数据进行聚合了. 软件包的聚合规则与文件的聚合规则相同. 可以回这篇文章复习一下文件是如何聚合的.
- 覆盖: 对于单文件内容, 上层覆盖下层, 比如:
- 系统包.
apk/dpkg
等, 在信息修改后, 其对应的单位件会覆盖
- 系统包.
- 合并: 将多层内容进行合并. 比如:
jar
文件, 每层增加一个, 在最后将所有jar
包合并到一起
- 移除: 之前说过, 当文件删除的时候, 会保留一个
without
文件. 因此, 当上层将下层内容删除时, 需要在最终聚合的时候去掉.
经过以上步骤, 整个镜像的完整信息就已经拿到了.
识别漏洞
如何识别漏洞呢? 就更简单了, 在本地数据库中维护一份漏洞库, 标识了某个系统的某个软件的某个版本, 存在某个漏洞. 然后拿着匹配到的结果一个一个找就行了.
总结
以上, 就是镜像的静态扫描原理了. 看完之后是不是发现特别的简单?
但其实写起来并没有想象中那么简单, 比如合并的操作就比较繁琐. 不过这里只介绍原理, 知道是怎么回事就行了.
还有一些扫描是动态扫描, 会将镜像启动, 然后通过攻击行为来判断是否存在某种漏洞. 不在本文的说明范围内.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Blazor Hybrid适配到HarmonyOS系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 解决跨域问题的这6种方案,真香!
· 分享4款.NET开源、免费、实用的商城系统
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
2019-06-11 docker常用命令