【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

admin 2025年2月20日23:31:11评论15 views字数 5220阅读17分24秒阅读模式

前言

随着云计算技术的日益成熟和 DevOps 概念的推广,越来越多的企业选择将其业务上云,基于云计算的容器技术在分布式计算环境中得到广泛部署。然而,容器在其生命周期内会存在多种安全威胁,如恶意镜像、运行时攻击和内核权限提升等。

目前,容器的安全防护主要依赖于 Linux 内核安全机制中的 DAC、MAC 和Namespace 隔离等技术。例如,对于 Ubuntu 系统而言,其会默认开启AppArmor 防护,该防护机制会为 docker 容器生成 docker-default 规则,以对 docker 容器内应用的行为进行限制,进而保障 docker 容器和 Linux 宿主机的安全。本文将从 docker 容器的 CVE-2019-5736 漏洞入手,浅析 AppArmor 对docker容器的实际防护效果,会从 CVE-2019-5736 漏洞概述及复现和探索 Apparmor 防御机制两个方进行介绍。

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

CVE-2019-5736 概述及复现

1 漏洞概述

2019年2月,runC 维护团队公布了影响 Docker、containerd、Podman 和 CRI-O 等默认运行时容器 runC 的严重漏洞 CVE-2019-5736。该漏洞是波兰 CTF 战队Dragon Sector 在CTF赛后对 runC 进行漏洞挖掘成功发现的,其能覆盖宿主机runC 程序完成容器逃逸。该漏洞关键点是在于 runC,docker 在运行 exec 类似功能的命令时,底层实际上是 runC 在执行,即由 runC 在容器内部执行用户指定的程序。

runC 会使用一种特殊的符号链接/proc/[runC-PID]/exe),该链接会指向进程自身对应的本地程序文件,通过它可轻松将宿主机上的 runC 二进制文件覆盖掉。当用户再次调用 runC 执行命令,此时执行的将是攻击者放置的任意恶意命令,实现容器逃逸。

2 漏洞复现概述

2.1  影响版本

docker version <=18.09.2

runC version <=1.0-rc6

2.2  漏洞验证

当使用某开源 POC 执行攻击后,发现宿主机 /tmp 目录下存在创建的“恶意”空文件夹,由此证明漏洞是真实存在的。

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

主要进行的是漏洞的概念性验证,通过一种无损的模式在宿主机指定目录创建了空文件夹runc-pwn-test”。在真实攻击场景中,攻击者可以在 POC 中写入任意恶意命令执行,这将可能带来严重后果。

探索Apparmor防御机制

为深入探索 Apparmor 防御机制,在 docker 不同版本(v17.12 & v18.03)上使用不同 docker 命令进行了一系列实验。

1 预备知识

【AppArmor】

AppArmor(Application Armor)是一种 MAC 机制,在自主访问控制 (DAC)基础上提供强制访问控制(MAC)来进一步保障 Linux 内核安全。不同于其他安全工具,AppArmor 旨在将程序限制在有限的资源集中,其将访问控制属性绑定到某个具体程序而并非系统用户。具体而言,每个进程都相应的有自己的安全配置文件,AppArmor 通过一个配置文件(profile)来指定一个应用程序的相关权限,即以白名单的方式定义该应用程序可以访问的系统资源。

AppArmor 配置文件会有两种工作模式,EnforceComplain

Enforce:此模式下加载的配置文件中定义的策略将强制执行,且会报告违规尝试(syslog/auditd);

Complain:此模式下加载的配置文件中定义的策略不会强制执行,而是仅报告违反策略的尝试;

【docker exec/attach域】

  • 在 docker 17.12 版本中,以 docker start/attach 方式运行的进程受 AppArmor 域的控制(docker-default 文件);而以 docker exec 方式运行的进程则不受 AppArmor 域的控制,其在 AppArmor 看来算作 unconfined 域。

  • 在 docker18.03 版本中,以 docker start/attach 方式和 docker exec 方式运行的进程均受 AppArmor (docker-default 文件)域的控制。

2 实验现象&解释

2.1 显示定义AppArmor 规则

2.1.1 实验方式

通过追踪 POC 运行状态,发现其在运行期间访问了如下路径:

[PATH-A]  /proc/<pid of each process>/cmdline[PATH-B]  /proc/<pid of the runc executed from docker exec>/exe[PATH-C]  /proc/<pid of the runc executed from docker exec>/fd/3

因此,可通过显式地在/etc/apparmor.d/abstractions/base加上下述规则,对AppArmor防御效果进行测试:

audit deny @{PROC}/@{pid}/cmdline rwklx,      #[RULE-A]audit deny @{PROC}/@{pid}/exe  rwklx,        #[RULE-B]audit deny @{PROC}/@{pid}/fd/* rwklx,         #[RULE-C]

2.1.2 实验现象

某公有云主机

    增加 [RULE-A] 后,POC 攻击被拦截,日志有 DENY 信息。

    增加 [RULE-B] 和 [RULE-C],无法拦截 POC 攻击。

本地主机

    增加 [RULE-A] 后,使用 docker attach 或 docker exec 方式运行 POC:

  1. POC 攻击每次都失败;

  2. AppArmor 日志中每次有 DENY持续增加

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

增加 [RULE-B] 和 [RULE-C] 后,无法拦截 POC 攻击。

2.1.3 现象解释

[RULE-A]生效:原因是 cmdline 是一个实际文件(至少不是 symlink)。

[RULE-B]不生效:原因是 PATH-B 指向宿主机 runc,而 AppArmor 只能过滤最终指向的文件的实际路径。

[RULE-C]不生效:原因是 PATH-C 也指向宿主机 runc。

2.2 docker 18.03测试分析

2.2.1 实验方式

鉴于 docker exec 和 docker attach 命令受 AppArmor 域控制不同,将采用以下两种方式进行 CVE-2019-5736 漏洞实验:1)exec 命令运行 POC 和 /bin/sh;2)attach 命令运行 POC,exec 命令运行 /bin/sh。

2.2.2 实验现象

某公有云主机

在 docker-default 规则防御下:i)POC攻击不被拦截;ii)AppArmor 日志中 audit 无对应 DENY 记录。

本地主机

  • 使用 exec 方式运行 POC 和 /bin/shiPOC 攻击不被拦截iiAppArmor日志中 audit 对应 DENY 记录

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

  • 使用 attach 运行POC,exec 方式运行 /bin/sh:i)POC 攻击不被拦截;ii)AppArmor 日志中 audit DENY 随机出现(重复4-5次实验),出现的话只有一条 DENY。

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

注:此处新建 malicious_directory 文件夹,以示与前文基础复现实验的区分。

2.2.3 实验解释

  • POC 攻击成功

    使用相同 exec 命令执行 POC 和 /bin/sh,在 AppArmor 看来属于同一个域,故不会有规则进行拦截。对于 docker 18.03,由于 exec 和 attach 属于 AppArmor 同一个域控制,因此这种方式下 POC 攻击也不会被拦截。

  • exec 攻击无 DENY 出现

    AppArmor <moby>/profiles/apparmor/template.go文件内有“file”,该规则使得任意文件访问默认不被拦截。这使得 POC 在读取 PID 和 fd 时不会被auditd 审计故 AppArmor 日志信息中不会出现 DENY

  • exec/attach 攻击 DENY 随机出现1条

    可能原因未知,暂时无法给出合理解释。

2.3 docker 17.12测试分析

2.3.1 实验方式

实验环境为 docker 17.12 版本,ubuntu 18.04,实验方式同前。

2.3.2 实验现象

某公有云主机

  • 使用 exec 方式运行 POC 和 /bin/shiPOC 攻击不被拦截iiAppArmor日志中 audit 无对应DENY记录

  • 使用 attach 运行 POC,exec 运行 /bin/sh:i)POC 攻击被拦截(POC 攻击程序卡在 open /proc/<runc-pid>/exe);ii)AppArmor 日志中 audit 有对应DENY 记录。

本地主机

  • 使用 exec 方式运行 POC 和 /bin/sh:i)POC 攻击不被拦截;ii)AppArmor日志中 audit 无对应 DENY 记录。

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

  • 使用attach运行POC,exec运行/bin/sh:i)POC每次攻击失败;ii)AppArmor 日志中 audit 有对应 DENY 记录(重复 6-7 次,每次 DENY 有10条,都卡在获取 fd)。

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

2.3.3 现象解释

  • POC攻击成功/失败

    成功使用 exec 命令执行 POC 和 /bin/sh,在 AppArmor 看来属于同一个域,故不会有规则进行拦截,攻击不会被拦截。

    失败对于docker 17.12,exec 和 attach 不属于同一个域控制,AppArmor docker-default中没有对应规则(无此白名单条目),故 POC攻击会被AppArmor 规则拦截导致失败。

  • exec无DENY出现

原因如前 docker 18.03 一节中所述,不再赘述。

  • exec/attach有DENY出现,均为10条

    可能原因是在读取 fd 时出现竞态,即同时有其他进程在读取fd,导致读取一直失败,最终读取次数过多触发 AppArmor 报警机制。

    验证猜想修改 POC 代码,在读取 fd 一定次数后退出循环等待,而不是一直等待。

    结果发现:当读取少量次数(小于1000次)后,未能出发 AppArmor 审计机制,未见 DENY 信息;当读取一定次数(2000)后,AppArmor 审计机制会随机被触发,DENY 信息随机出现;当读取次数达到很大规模(大于10000)后,DENY 信息一定出现。这种现象在一定程度上说明,随着读取次数的增多,与其他进程竞争碰撞的可能性越大,最终导致竞态产生,并触发 AppArmor 报警机制,产生 DENY 信息。

注意,在 docker 17.12 版本中,由于 exec 和 attach 处于不同域的原因,即使读取次数再少,POC 攻击也不会成功。

3 其他发现

除上述与 CVE-2019-5736 漏洞相关的实验现象之外,还有一些其他实验现象的发现。

  • Debian系的操作系统开启了SELinux防护机制,这会导致docker无法正常运行公有云主机和本地主机上的实验现象基本一致,说明该平台云主机并没有使用HIDS进行防护。

  • AppArmor docker-default 文件是 raw_data 格式,其会默认编译到 dockerd二进制里面,无法被逆向出来进行查看和修改。这个问题目前连开发者也无法解决,对常见的云厂商 dockerd 进行逆向后发现,其使用的都是原版 default 文件。

  • AppArmor 日志的 DENY 记录与否,与 audit,deny,allow 有一定关系。值得注意的是,其与攻击成功或失败无直接关联,日志 DENY 记录和攻击成败更像是并行的两条线。

  • Seccomp 和 AppArmor 被绕过机制不同。Seccomp的绕过(攻击者使用syscall int 而非 syscall name),是解析前 syscall 匹配机制出现问题;而AppArmor 绕过(CVE-2019-5736 POC),是解析后 proc/self/exe 链接重定向出现问题。

展望

随着云计算的普及,docker 和 K8s 等云平台工具的使用越来越频繁,与此同时潜在的安全威胁也越来越多。目前 docker 的防护仍高度依赖 Linux 核防护机制,Linux安全大厦看似稳固,近年来相继曝出的一系列 CVE 漏洞却表明,容器云的这种安全防护模式似乎并非牢不可破。

作为云计算安全人员,浅尝辄止地复现 CVE 漏洞仅仅是流于表面,真正需要的是深入研究 CVE 漏洞背后原理,以及思考其给相关云安全防护机制可能带来的负面影响。本文以 CVE-2019-5736 为例,探讨了docker runC漏洞,并测试了AppArmor 的防护效果,最终得出一系列比较有价值的结论。以攻促防,攻防交互,才能更好地全面提升云计算安全,深信服创新研究院云安全研究团队将对此持续探索。

深信服千里目安全实验室

【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

深信服科技旗下安全实验室,致力于网络安全攻防技术的研究和积累,深度洞察未知网络安全威胁,解读前沿安全技术。

● 扫码关注我们

原文始发于微信公众号(深信服千里目安全实验室):【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月20日23:31:11
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【云攻防系列】从CVE-2019-5736漏洞浅析AppArmor防御机制https://cn-sec.com/archives/894415.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息