CVE-2019-16884:apparmor绕过

前置知识

apparmor

apparmor 可以让管理员通过程序的配置文件限制程序的功能,其本身作为一个内核模块集成在 Linux 内核中(可能发现 lsmod 里面并没有 apparmor,这是因为 lsmod 展示的是所有动态加载的内核模块,通过 ls /sys/module/ 就可以看到所有的内核模块包括系统中内置的),因此其通过内核提供强访问控制。

漏洞原理

  • 这个漏洞的根源在 libcontainer/rootfs_linux.go 文件中的 checkMountDestination 函数。 这个函数的本意是防止容器将目录挂载到 /proc 上,以确保后续写入 /proc/self/attr/exec 的操作能真正加载 AppArmor 策略到内核。但函数实现中存在一个逻辑缺陷——它检查了挂载到 /proc 子目录的情况,却遗漏了对挂载目标刚好是 /proc 本身的检查*。更糟糕的是,这个错误在测试代码中也被复制了(把 == 写成了 !=),导致测试阶段都没能发现

假设我们可以成功挂载/proc卷,那么我们就可以自定义/proc里面的内容,这样我们就可以使得/proc/self/attr/exec可控,因此就会使得相关的apparmor安全策略无法加载

漏洞复现

确认 AppArmor 已启用image-20260906143145664

创建一个规则来阻止对 /flag 文件的读取

image-20260906143221477

创建一个flag文件

image-20260906143251152

使用 apparmor_parser 工具加载我们刚刚创建的规则

image-20260906143329516

启动一个正常的容器,并应用 no_flag 安全策略,然后尝试读取 /flag 文件

image-20260906144842362

创建恶意镜像所需的目录结构和一些“诱饵”文件。关键在于创建一个虚假的 /proc 目录

image-20260906144931023

创建一个 Dockerfile,用于构建恶意镜像

image-20260906145011208

这个 Dockerfile 的关键是 VOLUME /proc 指令,它声明将容器的 /proc 目录挂载为一个卷。

使用刚才编写的 Dockerfile 构建镜像,并命名为 apparmor-bypass

image-20260906145046259

最后,运行这个恶意镜像,并尝试读取被保护的 /flag 文件

由于环境问题,没能实现,但思路是没问题的TvT

标签: none

添加新评论

邮箱仅用于识别回复,不会在页面公开。提交后请等待页面确认结果。

文章图片预览