一.漏洞简述
1.snap简述
ubuntu官方对snap的解释:https://cn.ubuntu.com/blog/what-is-snap-application
Snap是Canonical为使用Linux内核的操作系统开发的软件打包和部署系统。这些包(称为 snaps)和使用它们的工具 snapd 可在一系列 Linux 发行版中工作。
Canonical科能软件有限公司(主业FOSS开源项目的):
https://zh.wikipedia.org/wiki/Canonical
https://canonical.com/
Snap可包含一个或多个服务,支持cli(命令行)应用,GUI图形应用以及无单进程限制。因此,你可以单个snap下调用一个或多个服务。对于某些多服务的应用来说,非常方便。snap间相互隔离,可以通过interface(接口)定义来做资源交换。interface被用于让snap可访问OpenGL加速,声卡播放、录制,网络和HOME目录。Interface由slot和plug组成即提供者和消费者。
ubuntu机器下查询下snap是啥,可以看到有许多*.snap结尾的文件
归纳下,snap文件路径默认在以下三个路径
代码语言:javascript复制/var/lib/snapd/snaps
/var/lib/snapd/seed
/tmp/snap.docker/tmp
2.snap-confine简述
snap-confine(安装的一个 SUID-root 程序) 默认情况下在 Ubuntu 上。Snap 是由适用于使用 Linux 内核的操作系统的规范。称为 snaps,以及使用它们的工具 snapd,工作跨一系列 Linux 发行版并允许上游软件。开发人员将他们的应用程序直接分发给用户。快照是在沙箱中运行的独立应用程序访问主机系统。
snap-confine 是 snapd 内部使用的一个程序,用于构建snap 应用程序的执行环境。”(man snap-confine)
发现和利用 snap-confine 中的漏洞已经极具挑战性(尤其是在默认安装的 Ubuntu 中), 因为 snap-confine 使用了一种非常防御性的编程风格,AppArmor 配置文件、seccomp 过滤器、挂载命名空间和两个 Go 帮助程序。 最终,我们发现了两个漏洞:
总结下snap-confine文件路径
代码语言:javascript复制/var/lib/snapd/apparmor/snap-confine
/usr/lib/snapd/snap-confine
/snap/snapd/12398/usr/lib/snapd/snap-confine
/snap/snapd/12398/var/lib/snapd/apparmor/snap-confine
/snap/snapd/12159/usr/lib/snapd/snap-confine
/snap/snapd/12159/var/lib/snapd/apparmor/snap-confine
/snap/core20/1026/var/lib/snapd/apparmor/snap-confine
/snap/core/11316/usr/lib/snapd/snap-confine
/snap/core/11316/var/lib/snapd/apparmor/snap-confine
/snap/core/11187/usr/lib/snapd/snap-confine
/snap/core/11187/var/lib/snapd/apparmor/snap-confine
代码语言:javascript复制snap command:
列出已经安装的snap包
sudo snap list
搜索要安装的snap包
sudo snap find <text to search>
安装一个snap包
sudo snap install <snap name>
更新一个snap包,如果你后面不加包的名字的话那就是更新所有的snap包
sudo snap refresh <snap name>
把一个包还原到以前安装的版本
sudo snap revert <snap name>
删除一个snap包
sudo snap remove <snap name>
二.影响版本:
1.漏洞披露先后:
代码语言:javascript复制CVE-2021-44731 snap-confine 的 setup_private_mount() 中的竞争条件
CVE-2021-44730 snap-confine 的 sc_open_snapd_tool() 中的硬链接攻击
CVE-2021-3996 util-linux 的 libmount 中未经授权的卸载
CVE-2021-3995 util-linux 的 libmount 中未经授权的卸载
CVE-2021-3998 来自 glibc 的 realpath() 的意外返回值
CVE-2021-3999 glibc 的 getcwd() 中的一个缓冲区溢出/下溢
CVE-2021-3997 systemd 的 systemd-tmpfiles 中不受控制的递归的挖掘
竞争条件
代码语言:javascript复制 竞争条件发生在当多个进程或者线程在读写数据时,其最终的的结果依赖于多个进程的指令执行顺序。
例如:考虑下面的例子
假设两个进程P1和P2共享了变量a。在某一执行时刻,P1更新a为1,在另一时刻,P2更新a为2。
因此两个任务竞争地写变量a。在这个例子中,竞争的“失败者”(最后更新的进程)决定了变量a的最终值。
多个进程并发访问和操作同一数据且执行结果与访问的特定顺序有关,称为竞争条件。
对应时间线的挖洞大佬
代码语言:javascript复制James Troup 发现 snap 没有正确管理
snap 目录的权限。本地攻击者可能会利用此问题来暴露
敏感信息。( CVE-2021-3155 )
Ian Johnson 发现 snapd 没有正确验证内容界面
和布局路径。本地攻击者可能会利用此问题注入
任意 AppArmor 策略规则,从而绕过预期的访问
限制。( CVE-2021-4120 )
Qualys 研究团队发现 snapd 没有正确验证
snap-confine 二进制文件的位置。本地攻击者可能会使用此
问题来执行其他任意二进制文件并提升权限。
( CVE-2021-44730 )
Qualys 研究团队在为snap 准备私有挂载命名空间时发现 snapd snap-confine 二进制文件中存在竞争条件。
本地攻击者可能会使用此问题来提升权限并执行
任意代码。( CVE-2021-44731 )
2.受影响版本
代码语言:javascript复制该漏洞目前主要影响范围为ubuntu发行版:
Ubuntu 21.10 snapd/snap-confine < 2.54.3 21.10.1
Ubuntu 20.04 LTS snapd/snap-confine < 2.54.3 20.04
Ubuntu 18.04 LTS snapd/snap-confine < 2.54.3 18.04
Ubuntu 16.04 ESM 待官方更新
3.不受影响版本
代码语言:javascript复制安全版本
Ubuntu 21.10 snapd/snap-confine >= 2.54.3 21.10.1
Ubuntu 20.04 LTS snapd/snap-confine >= 2.54.3 20.04
Ubuntu 18.04 LTS snapd/snap-confine >= 2.54.3 18.04
Ubuntu 16.04 ESM 待官方更新
三.漏洞分析
1.反向分析(补丁版本 snap-confine 2.54.3),先了解snap-confine的大致结构:
核心分析/usr/lib/snapd/snap-confine文件,该文件是一个二进制文件,搞成文本下来看下:
代码语言:javascript复制xxd snap-confine > snap-confine.txt
(1)file查看文件类型
代码语言:javascript复制root@VM-0-5-ubuntu:/usr/lib/snapd# file snap-confine
snap-confine: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f946d2d193895203adbd114d6b9aad311a211a46, for GNU/Linux 3.2.0, stripped
(2)ldd查看调用库关系
代码语言:javascript复制root@VM-0-5-ubuntu:/usr/lib/snapd# ldd snap-confine
linux-vdso.so.1 (0x00007ffd1cca9000)
libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007f513097a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5130974000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5130951000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f513075f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f51309e3000)
(3)ltrace查看函数调用关系
代码语言:javascript复制root@VM-0-5-ubuntu:/usr/lib/snapd# ltrace /usr/lib/snapd/snap-confine
Usage: snap-confine <security-tag> <executable>
application or hook security tag was not provided
(4)readelf查看elf信息
代码语言:javascript复制root@VM-0-5-ubuntu:/usr/lib/snapd# readelf -h snap-confine
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x60c0
Start of program headers: 64 (bytes into file)
Start of section headers: 140776 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29
(5)objdump从对象文件中显示信息
代码语言:javascript复制root@VM-0-5-ubuntu:/usr/lib/snapd# objdump -d snap-confine | head
snap-confine: file format elf64-x86-64
Disassembly of section .init:
0000000000004000 <.init>:
4000: f3 0f 1e fa endbr64
4004: 48 83 ec 08 sub $0x8,%rsp
4008: 48 8b 05 c9 ef 01 00 mov 0x1efc9(%rip),%rax # 22fd8 <__gmon_start__>
(6)strace:
代码语言:javascript复制root@VM-0-5-ubuntu:/usr/lib/snapd# strace -f /usr/lib/snapd/snap-confine
execve("/usr/lib/snapd/snap-confine", ["/usr/lib/snapd/snap-confine"], 0x7fffa6ec0368 /* 21 vars */) = 0
brk(NULL) = 0x560d7306f000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe7b9f6ae0) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=87696, ...}) = 0
mmap(NULL, 87696, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fda927f9000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libudev.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF211 3 >