徳丸日記の問題を解いてみる初級編①:環境構築

セキュリティ

先日徳丸さんの日記やツイッターで、CSRFの問題を出していました。

以下リンクになっていますので、参照ください。

問題:間違ったCSRF対策~初級編~

解説はまだ出ていないのでまだ記載しませんが、環境構築にいて記事にしていきます。
※なお、本当に初心者向けでの解説をしていきますので、ご理解のほどよろしくお願いいたします。

環境構築

OSコマンドインジェクションのデモで使用した環境があるので、そちらを使用します。

まずはPHPのバージョンを確認しましょう。

$ php -v
PHP 7.2.10-0ubuntu0.18.04.1 (cli) (built: Sep 13 2018 13:45:02) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.10-0ubuntu0.18.04.1, Copyright (c) 1999-2018, by Zend Technologies

PHPは上記に記載のとおり、7.2.10を使用します。

まずはカレントディレクトリまで移動し、置いてあるファイルを確認します。

$ cd /var/www/html/
#カレントディレクトリまで移動
$ ls
#該当ディレクトリにあるファイルを確認
index.html  nslookup.php  test.php
$ rm test.php

test.phpについてはいらないので消します。他についてはOSコマンドインジェクションのデモ用のソースなのでそのままにしておきます。

では、さっそく環境を作りましょう。

$ nano mypage.php
#ログインしたことにする確認用のスクリプトの作成、以下をコピペして「Ctrl+o」で保存します。
<?php // mypage.php : ログインしたことにする確認用のスクリプト
session_start();
if (empty($_SESSION['id'])) { // ログインしたことにしてメールアドレスも初期化
$_SESSION['id'] = 'alice';
$_SESSION['mail'] = 'alice@example.com';
}
?><body>
ログイン中(id:<?php echo
htmlspecialchars($_SESSION['id'], ENT_QUOTES, 'UTF-8'); ?>)<br>
メールアドレス:<?php echo
htmlspecialchars($_SESSION['mail'], ENT_QUOTES, 'UTF-8'); ?><br>
<a href="chgmailform.php">メールアドレス変更</a><br>
</body>

同じような感じで残りも作成しましょう。

$ nano chgmailform.php
#メールアドレス変更フォーム(chgmailform.php)。CSRF対策用のワンタイムトークンを生成してhiddenパラメータtokenにセット。以下をコピペして「Ctrl+o」で保存します。
<?php
session_start();
if (empty($_SESSION['id'])) {
die('ログインしてください');
}
$token = bin2hex(random_bytes(24)); // ワンタイムトークン生成
$_SESSION['token'] = $token;
?><body>
<form action="chgmail.php" method="POST">
メールアドレス<input name="mail"><BR>
<input type=submit value="メールアドレス変更">
<input type="hidden" name="token" value="<?php
echo htmlspecialchars($token, ENT_COMPAT, 'UTF-8'); ?>">
</form>
</body>
$ nano chgmail.php
#メールアドレス変更プログラム(chgmail.php)。ワンタイムトークン確認の後、メールアドレスを変更(実際にはセッション変数のみ変更)する。以下をコピペして「Ctrl+o」で保存します。
<?php
session_start();
if (empty($_SESSION['id'])) {
die('ログインしてください');
}
$id = $_SESSION['id']; // ユーザIDの取り出し
if ($_POST['token'] !== $_SESSION['token']) { // ワンタイムトークン確認
die('正規の画面からご使用ください');
}
unset($_SESSION['token']); // 使用済みトークンの削除
$mail = $_POST['mail'];
$_SESSION['mail'] = $mail;
?>
<body>
<?php echo htmlspecialchars($id, ENT_COMPAT, 'UTF-8'); ?>さんのメールアドレスを<?php
echo htmlspecialchars($mail, ENT_COMPAT, 'UTF-8'); ?>に変更しました<br>
<a href="mypage.php">マイページ</a>
</body>

これで準備はOKです。早速動作を確認してみましょう。

ブラウザからアクセスしてみましょう。
※アクセス例:http://192.168.70.139/mypage.php

動作していますね。では画面上のリンクにアクセスし次の画面へ遷移してみましょう。

ちゃんとメールアドレス変更フォームが表示されます。

では適当なメールアドレスを入力して、「メールアドレス変更」ボタンを押してみましょう。

ちゃんと、入力したメールアドレスに変更されている動作になっていますね。

ただ、セッションIDに挿入するだけなので、セッションIDを再発行すれば同じ動作を確認することができます。

これで準備はOKですね。(コピペしただけですが・・・)

最後に

徳丸さんの問題の検証環境を構築しました。

以下の設問個所については、答えというかどうすれば実行可能かについては検証も含め出来ています。

設問
利用者(被害者)がmypage.phpを閲覧した状態(ログイン中を想定)で、罠ページを閲覧させることにより、CSRF攻撃でメールアドレスを変更してください。この攻撃を実現する罠ページのPoC(概念実証コード)が解答になります。

ただし、回答が公開されるまでは記事にしませんので、週明けの回答をお待ちください。

不明点や要望やこういったこともやって欲しいとの要望があれば、お問い合わせページやコメント、ツイッターからでも結構ですので、気軽にご連絡ください。

コメント