mcpField
A
analyzing-docker-container-forensics

analyzing-docker-container-forensics

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

analyzing-docker-container-forensics について

コンテナやホストのインシデントを扱うセキュリティ調査担当者向けの Docker フォレンジック手順です。証拠保全、イメージレイヤーとファイルシステムの分析、脆弱性スキャン、報告を扱います。

主な機能

  1. 01コンテナ状態と証拠の保全
  2. 02イメージレイヤーとビルド履歴の分析
  3. 03Docker ホストのファイルシステム痕跡の調査
  4. 04実行時のファイルシステム変更の比較
  5. 05イメージの脆弱性スキャンと報告

活用シーン

  1. 01侵害されたコンテナやホストの調査
  2. 02レジストリから取得した悪意あるイメージの分析
  3. 03コンテナエスケープや権限昇格の調査
  4. 04コンテナ環境でのクリプトジャッキング調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill analyzing-docker-container-forensics

インストール後、Claude Code で/analyzing-docker-container-forensicsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

Docker コンテナフォレンジックの分析

使用するタイミング

  • Docker コンテナまたはコンテナホストが侵害された場合の調査
  • レジストリからプルした悪意のある Docker イメージの分析
  • コンテナ化されたアプリケーションの侵害に関するインシデント対応
  • コンテナエスケープの試みや権限昇格の調査
  • コンテナ設定の監査と設定ミスの特定

前提条件

  • フォレンジック用ワークステーションで Docker CLI にアクセスできること
  • Docker ホストのファイルシステム(フォレンジックイメージまたは稼働中の環境)にアクセスできること
  • Docker のレイヤー化ファイルシステム(overlay2、aufs)を理解していること
  • イメージ分析用の dive、docker-explorer、または container-diff
  • Docker デーモンの設定とソケットのセキュリティに関する知識
  • コンテナイメージの脆弱性スキャン用の Trivy または Grype

ワークフロー

ステップ 1:コンテナの状態と証拠を保全する
# List all containers (including stopped)
docker ps -a --no-trunc > /cases/case-2024-001/docker/container_list.txt

# Inspect the compromised container
CONTAINER_ID="abc123def456"
docker inspect $CONTAINER_ID > /cases/case-2024-001/docker/container_inspect.json

# Export container filesystem as tarball (preserves current state)
docker export $CONTAINER_ID > /cases/case-2024-001/docker/container_export.tar

# Create an image from the container's current state
docker commit $CONTAINER_ID forensic-evidence:case-2024-001
docker save forensic-evidence:case-2024-001 > /cases/case-2024-001/docker/container_image.tar

# Capture container logs
docker logs $CONTAINER_ID --timestamps > /cases/case-2024-001/docker/container_logs.txt 2>&1

# Capture running processes (if container is still running)
docker top $CONTAINER_ID > /cases/case-2024-001/docker/container_processes.txt

# Capture network connections
docker exec $CONTAINER_ID netstat -tlnp 2>/dev/null > /cases/case-2024-001/docker/container_network.txt

# Copy specific files from the container
docker cp $CONTAINER_ID:/var/log/ /cases/case-2024-001/docker/container_var_log/
docker cp $CONTAINER_ID:/tmp/ /cases/case-2024-001/docker/container_tmp/
docker cp $CONTAINER_ID:/etc/passwd /cases/case-2024-001/docker/container_passwd

# Hash all exported evidence
sha256sum /cases/case-2024-001/docker/*.tar > /cases/case-2024-001/docker/evidence_hashes.txt
ステップ 2:コンテナイメージのレイヤーを分析する
# Install dive for image layer analysis
wget https://github.com/wagoodman/dive/releases/latest/download/dive_linux_amd64.deb
sudo dpkg -i dive_linux_amd64.deb

# Analyze image layers interactively
dive forensic-evidence:case-2024-001

# Non-interactive layer analysis
dive forensic-evidence:case-2024-001 --ci --json /cases/case-2024-001/docker/dive_analysis.json

# Extract and examine individual layers
mkdir -p /cases/case-2024-001/docker/layers/
tar -xf /cases/case-2024-001/docker/container_image.tar -C /cases/case-2024-001/docker/layers/

# List the image manifest and layer order
cat /cases/case-2024-001/docker/layers/manifest.json | python3 -m json.tool

# Examine each layer for changes
for layer in /cases/case-2024-001/docker/layers/*/layer.tar; do
    echo "=== Layer: $(dirname $layer | xargs basename) ==="
    tar -tf "$layer" | head -20
    echo "..."
done

# Use container-diff to compare with original base image
# Install container-diff
curl -LO https://storage.googleapis.com/container-diff/latest/container-diff-linux-amd64
chmod +x container-diff-linux-amd64

# Compare committed image with original
./container-diff-linux-amd64 diff daemon://nginx:latest daemon://forensic-evidence:case-2024-001 \
   --type=file --type=apt --type=history --json \
   > /cases/case-2024-001/docker/container_diff.json
ステップ 3:Docker ホストのアーティファクトを調査する
# Docker data directory (default: /var/lib/docker/)
DOCKER_ROOT="/mnt/evidence/var/lib/docker"

# Examine overlay2 filesystem layers
ls -la $DOCKER_ROOT/overlay2/

# Find the container's merged filesystem
CONTAINER_HASH=$(docker inspect $CONTAINER_ID --format '{{.GraphDriver.Data.MergedDir}}' 2>/dev/null)
# Or manually from forensic image:
# Look in /var/lib/docker/containers/<container_id>/config.v2.json

# Analyze container configuration files
cat $DOCKER_ROOT/containers/$CONTAINER_ID/config.v2.json | python3 -m json.tool \
   > /cases/case-2024-001/docker/container_config.json

# Check Docker daemon configuration
cat /mnt/evidence/etc/docker/daemon.json 2>/dev/null > /cases/case-2024-001/docker/daemon_config.json

# Examine Docker events log
cat $DOCKER_ROOT/containers/$CONTAINER_ID/*.log > /cases/case-2024-001/docker/container_json_logs.txt

# Check for volume mounts (potential host filesystem access)
python3 << 'PYEOF'
import json

with open('/cases/case-2024-001/docker/container_inspect.json') as f:
    data = json.load(f)

inspect = data[0] if isinstance(data, list) else data

print("=== CONTAINER SECURITY ANALYSIS ===\n")

# Check mounts
print("Volume Mounts:")
for mount in inspect.get('Mounts', []):
    rw = "READ-WRITE" if mount.get('RW') else "READ-ONLY"
    print(f"  {mount.get('Source', 'N/A')} -> {mount.get('Destination', 'N/A')} ({rw})")
    if mount.get('Source') in ('/', '/etc', '/var', '/root') and mount.get('RW'):
        print(f"    WARNING: Sensitive host path mounted read-write!")

# Check privileged mode
host_config = inspect.get('HostConfig', {})
if host_config.get('Privileged'):
    print("\nWARNING: Container was running in PRIVILEGED mode!")

# Check capabilities
cap_add = host_config.get('CapAdd', [])
if cap_add:
    print(f"\nAdded Capabilities: {cap_add}")
    dangerous_caps = ['SYS_ADMIN', 'SYS_PTRACE', 'NET_ADMIN', 'SYS_MODULE']
    for cap in cap_add:
        if cap in dangerous_caps:
            print(f"  WARNING: Dangerous capability: {cap}")

# Check PID namespace
if host_config.get('PidMode') == 'host':
    print("\nWARNING: Container shares host PID namespace!")

# Check network mode
if host_config.get('NetworkMode') == 'host':
    print("\nWARNING: Container shares host network namespace!")

# Check user
user = inspect.get('Config', {}).get('User', 'root (default)')
print(f"\nRunning as user: {user}")

# Check environment variables for secrets
env_vars = inspect.get('Config', {}).get('Env', [])
print(f"\nEnvironment Variables: {len(env_vars)}")
for env in env_vars:
    key = env.split('=')[0]
    if any(s in key.upper() for s in ['PASSWORD', 'SECRET', 'KEY', 'TOKEN', 'CREDENTIAL']):
        print(f"  SENSITIVE: {key}=***REDACTED***")
PYEOF
ステップ 4:コンテナのファイルシステムの変更を分析する
# Compare container filesystem to original image
docker diff $CONTAINER_ID > /cases/case-2024-001/docker/filesystem_changes.txt

# A = Added, C = Changed, D = Deleted
# Analyze changes
python3 << 'PYEOF'
added = []
changed = []
deleted = []

with open('/cases/case-2024-001/docker/filesystem_changes.txt') as f:
    for line in f:
        line = line.strip()
        if line.startswith('A '):
            added.append(line[2:])
        elif line.startswith('C '):
            changed.append(line[2:])
        elif line.startswith('D '):
            deleted.append(line[2:])

print(f"Files Added: {len(added)}")
print(f"Files Changed: {len(changed)}")
print(f"Files Deleted: {len(deleted)}")

# Flag suspicious additions
suspicious = [f for f in added if any(s in f for s in
    ['/tmp/', '/dev/shm/', '/root/', '.sh', '.py', '.elf', 'reverse', 'shell', 'backdoor'])]
if suspicious:
    print(f"\nSuspicious Added Files:")
    for f in suspicious:
        print(f"  {f}")

# Flag suspicious changes
sus_changed = [f for f in changed if any(s in f for s in
    ['/etc/passwd', '/etc/shadow', '/etc/crontab', '/etc/ssh', '.bashrc'])]
if sus_changed:
    print(f"\nSuspicious Changed Files:")
    for f in sus_changed:
        print(f"  {f}")
PYEOF

# Extract and examine the container export
mkdir -p /cases/case-2024-001/docker/container_fs/
tar -xf /cases/case-2024-001/docker/container_export.tar -C /cases/case-2024-001/docker/container_fs/

# Scan for webshells and malicious files
find /cases/case-2024-001/docker/container_fs/tmp/ -type f -exec file {} \;
find /cases/case-2024-001/docker/container_fs/ -name "*.php" -newer /cases/case-2024-001/docker/container_fs/etc/hostname
ステップ 5:脆弱性をスキャンしてレポートを作成する
# Scan the image for known vulnerabilities
trivy image forensic-evidence:case-2024-001 \
   --format json \
   --output /cases/case-2024-001/docker/vulnerability_scan.json

# Scan the exported filesystem
trivy fs /cases/case-2024-001/docker/container_fs/ \
   --format table \
   --output /cases/case-2024-001/docker/fs_vulnerabilities.txt

# Check for secrets in the image
trivy image forensic-evidence:case-2024-001 \
   --scanners secret \
   --format json \
   --output /cases/case-2024-001/docker/secrets_scan.json

主な概念

概念説明
イメージレイヤーコンテナイメージを構成する、積み重ねられた読み取り専用のファイルシステムレイヤー
overlay2レイヤーにユニオンファイルシステムを使用する Docker のデフォルトのストレージドライバー
コンテナの差分実行時のファイルシステム変更と元のイメージとの比較
特権モードホストの機能を全面的に使用できるコンテナ(ほとんどの分離を迂回します)
Docker ソケットDocker デーモンを制御する Unix ソケット(/var/run/docker.sock)
コンテナエスケープコンテナの分離を突破してホストに侵入する手法
ボリュームマウントコンテナ内からアクセスできるホストファイルシステムのパス
イメージ履歴各レイヤーのビルドに使用された Dockerfile 命令の記録

ツールとシステム

ツール用途
docker inspectコンテナの設定と状態に関する詳細情報
docker diff実行中または停止中のコンテナで行われたファイルシステムの変更を表示
diveDocker イメージのレイヤーを対話的に分析するツール
container-diffコンテナイメージの内容を比較する Google のツール
Trivyコンテナイメージとファイルシステムの脆弱性スキャナー
docker-explorerオフラインで Docker アーティファクトを分析するフォレンジックツール
Sysdigコンテナのランタイムセキュリティ監視とフォレンジック
Falcoコンテナと Kubernetes のランタイム脅威検出

よくあるシナリオ

シナリオ 1:Web アプリケーションコンテナの侵害 コンテナのファイルシステムをエクスポートし、Web ルート内の Web シェルを特定して、アクセスログから悪用の試みを分析します。追加されたファイルや変更された設定を確認し、C2 通信のネットワーク接続を調査して、権限昇格につながるコンテナの機能を確認します。

シナリオ 2:悪意のあるイメージによるサプライチェーン攻撃 dive でイメージレイヤーを分析し、悪意のあるコンテンツが追加されたレイヤーを特定します。container-diff で公式ベースイメージと比較し、イメージ履歴に不審な RUN コマンドがないか確認して、埋め込まれたバックドアや暗号通貨マイナーをスキャンし、レジストリログからイメージのプルを追跡します。

シナリオ 3:コンテナエスケープの調査 コンテナが特権モードで実行されていたか、危険な機能を有効にしていたかを確認します。不正アクセスにつながるホストファイルシステムのマウントポイントを調べ、Docker-in-Docker の悪用を可能にする Docker ソケットのマウントを確認します。コンテナエスケープの兆候がないかホストシステムのログを分析し、カーネルエクスプロイトの痕跡を確認します。

シナリオ 4:コンテナ環境でのクリプトジャッキング CPU 使用率の高いコンテナを特定し、コンテナイメージをエクスポートしてマイニング用バイナリを分析します。レジストリ内に未承認のイメージがないか確認し、不正なデプロイがないかコンテナの作成イベントを調べ、マイニングプールとの通信に使われるネットワーク接続を調査します。

出力形式

Docker Container Forensics Summary:
  Container: abc123def456 (nginx-app)
  Image: company/web-app:v2.1
  Status: Running (started 2024-01-10 09:00 UTC)
  Host: docker-host-01.corp.local

  Security Configuration:
    Privileged: No
    Capabilities Added: NET_ADMIN (WARNING)
    Volume Mounts: /var/log -> /host-logs (RW)
    Network Mode: bridge
    User: root (WARNING)

  Filesystem Changes:
    Added: 23 files (5 suspicious)
    Changed: 12 files (2 suspicious)
    Deleted: 0 files

  Suspicious Findings:
    /tmp/reverse.sh - Reverse shell script (Added)
    /var/www/html/.hidden/shell.php - PHP webshell (Added)
    /etc/crontab - Modified (persistence cron entry added)
    /root/.ssh/authorized_keys - Modified (unauthorized key added)

  Vulnerability Scan:
    Critical: 3 (CVE-2024-xxxx in base image)
    High: 12
    Medium: 34

  Evidence: /cases/case-2024-001/docker/

コメント