CTF参加方法とPHPセキュリティ制限の回避テクニック

はじめに

ある日、チームのメンバーからCTFのWeb問題が共有されました。この記事では、その問題を解決する過程で学んだPHPのセキュリティ制限回避技術について解説します。

open_basedirの回避

最初にphpinfo()を実行できることに気づき、eval()関数を使ってシンプルなペイロードを試しました。しかし、/var/www/htmlディレクトリ以外のファイルにアクセスする権限がないことが判明しました。

index.phpを確認すると、GETパラメータ「src」が存在することがわかりました。このパラメータは問題解決に直接役立ちませんでしたが、phpinfoの出力から重要な情報を得ることができました。

open_basedirについて

open_basedirはphp.iniの設定オプションで、ユーザーがアクセスできるファイルの範囲を指定したディレクトリに制限します。例えば、open_basedir=/home/wwwroot/home/web1/:/tmp/の場合、web1経由でサーバーにアクセスするユーザーは、/home/wwwroot/home/web1/と/tmp/以外のファイルにアクセスできなくなります。

この問題ではsystem()やexec()のような関数も無効化されていました。disable_functionsを確認すると、多くの関数がブラックリストに登録されていました。

ここで、海外のセキュリティ研究者が公開したopen_basedirを回避する方法を試しました:

mkdir('/tmp/flag1');chdir('/tmp/flag1');ini_set('open_basedir','..');chdir('..');ini_set('open_basedir','/');print_r(scandir('/'));

このペイロードにより、ルートディレクトリのファイル一覧を取得することができました:

ルートディレクトリに/readflagと/flagファイルが存在することが判明しました。通常であればこれらのファイルを読み取ればフラグを取得できるはずですが、実際にはバイナリファイルとして扱われ、内容を確認できませんでした。

disable_functionsの回避

バイナリファイルの内容を確認するために、このファイルを実行する必要があると判断しました。しかし、disable_functionsの制限を回避する必要がありました。

LD_PRELOADなどの一般的な手法は効果がなかったため、3年前のPHPガベージコレクションの脆弱性を利用したdisable_functions回避のエクスプロイトを使用しました:

GitHubリポジトリ: https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass

エクスプロイトファイルをtmpディレクトリに書き込み、include関数でファイルを読み込むことで、任意のシステムコマンドを実行できるようにしました。

// エクスプロイトファイルの読み込み include('/tmp/exploit.php'); // 任意のコマンドの実行 system('cat /flag');

これにより、フラグを正常に取得することができました。

まとめ

この問題は基本的な知識を試すものでしたが、open_basedirとdisable_functionsの両方を回避する必要があり、興味深い経験となりました。open_basedirの回避原理については、以下の記事を参照してください:

https://skysec.top/2019/04/12/从PHP底层看open-basedir-bypass/

タグ: CTF PHPセキュリティ open_basedir disable_functions Webセキュリティ

6月26日 18:06 投稿