CSRF(弊研究室の某課題について考える19日目)

はじめに

この記事は弊研究室の某課題について考える19日目の記事です

今日はCSRFの話、正直言葉は知ってる人多いと思うけど内容知らない人が多そうだと思ったので記事にします。CSRF自体の解説は他のサイトでもいっぱいされているのでそっちを見てもよし!

CSRFとは

CSRFとはクロスサイトリクエストフォージェリ(cross-site request forgeries)の略称でありWebアプリケーションの脆弱性の一つ、もしくはそれを利用した攻撃を指します。

具体的な被害としては以下のものが挙げられます

  • データ漏洩
  • 意図しないコードの実行
  • 権限の取得
  • なりすまし
  • アプリケーションデータの読み取り

こんな感じでしっかりと対策を行うべき脆弱性です。

CSRFは以下の状況で発生します

  • クッキーのみでセッション管理が行われているサイト
  • HTTP認証、SSLクライアント証明書、携帯電話の携帯IDのみで利用者の識別が行われているサイト

CSRFの例

docker-composeで手元でも確認できる環境を用意しました!やったね!!手元確認しない人用に重要な部分のソースコードは載せます。

Docker環境

先に書きます。徳丸本を参考にしてます

パスワード変更のサンプル(passwd.php)

<?php
        function h($str){
                return htmlspecialchars($str, ENT_NOQUOTES, 'UTF-8');
        }
        session_start();
        // ログイン確認---省略
        $id = $_SESSION['id'];
?>
<!DOCTYPE HTML>
<html>
        <head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <meta http-equiv="Content-Security-Policy" contents="default-src 'self'; script-src 'self';">
                <title>Login form</title>
                <link rel="stylesheet" type="text/css" href="report.css">
        </head>
<body>
<div class="top19">
        <div class="box19">
        <h1>Password Change</h1>
        <form action="passchange.php" method="POST">
                新パスワード : <input name="pwd" type="password"><br>
                <input type="submit" value="パスワード変更">
        </form>
        </div>  <!-- box19 -->
</div>
</body>
</html>

POST送信の先(passchange.php)

<?php
        function h($str){
                return htmlspecialchars($str, ENT_NOQUOTES, 'UTF-8');
        }
        session_start();
        $id = $_SESSION['id'];
        // ログイン確認---省略
        $pwd = $_POST['pwd'];
        // パスワード変更処理
?>
<!DOCTYPE HTML>
<html>
        <head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <meta http-equiv="Content-Security-Policy" contents="default-src 'self'; script-src 'self';">
                <title>Login form</title>
                <link rel="stylesheet" type="text/css" href="report.css">
        </head>
<body>
<div class="top19">
        <div class="box19">
        <h1>Password Change</h1>
        <?php echo h($id); ?>さんのパスワードを<?php echo h($pwd); ?>に変更しました!
        </div>  <!-- box19 -->
</div>
</body>
</html>

この一連のページはパスワードの変更を行うものである。パスワード変更の流れは

  1. POSTメソッドでpasschange.phpがリクエストされる
  2. ログインを確認する
  3. POSTパラメータのpwdのパスワードに変更する

となっているが、2つめのログインを確認する場面を正しく行わないとCSRFが発生する。

対策方法は後で述べるとして攻撃方法を示す。

上のページにアクセスした後にcrack.htmlにアクセスするとpasswordがcrackedに変更されたメッセージが確認できると思います

<body onload="document.forms[0].submit()" >
<form action="http://[hostname]:4455/passchange.php" method="POST">
<input type="hidden" name="pwd" value="cracked">
</form>
</body>

上記例においてCSRFが発生する状況

ログイン確認の部分を記述していませんがここをしっかりすれば上の状況でもCSRFは発生しません。

ログイン確認の部分に固定の値ではなく乱数を含めたセッションidを用いればよいのです(セッションidは一定時間で変更するとなおよし)

<input type="hidden" name="sessionid" value="セッションidのもの">

送信されてきたセッションidと通信しているセッションidが同じであれば本人の通信であるという保証が得られます。

CSRFの対策

基本的には利用者の操作とアクセスが一致しているかどうかを確認することに尽きると思います。

もっと知りたい方は徳丸本を買いましょう。そして徳丸本は6月に改訂されるらしいです

ハッシュ関数(弊研究室の某課題について考える23日目)

はじめに

この記事は弊研究室の某課題について考えるの23日目の記事です。

今日はハッシュ関数について簡単な解説をします。

ハッシュ関数とは

あるデータが与えられた場合にそのデータを代表する数値を得る操作、または、その様な数値を得るための関数のことを指します。HashMap関数とかSHA1とかに代表されるようなやつらです。

国の識別にJPとか使いますがこれはJapanとわかるので一種のハッシュ値と言えるでしょう

ハッシュ関数の用途

ハッシュの用途としては以下のような感じです

  • ハッシュテーブル
  • キャッシュ
  • 重複レコードの検出
  • 類似レコードの探索
  • 幾何学的ハッシュ
  • 改ざんの検出

この記事では改ざんの検出に扱われるハッシュについて焦点をあて記述していきます

改ざんの検出

ファイルの信頼性を確かめる際に,同じファイルを比較するのは(ファイルにもよりますが)コストが重くなります。そこで元のファイルのハッシュを計算しておき,そのハッシュ値と比較したいファイルのハッシュ値を比較することでファイルの信頼性を保証できます。ハッシュ値を計算するハッシュ関数は高速なためファイル同士を比較するよりも高速に検証可能です。

改ざんの検出を行う際は簡単なハッシュ関数であると,同じハッシュ値を求めることが可能なため,安全なハッシュ関数を用いる必要があります。

ハッシュの特性

ハッシュ関数が安全であるかは以下の特性が守られているかにかかっています。

  • 原像計算困難性
  • 弱衝突耐性(第2原像計算困難性)
  • 強衝突耐性(衝突困難性)

それぞれは原像計算困難 ⊃ 弱衝突耐性 ⊃ 強衝突耐性な関係性です

原像計算困難性

定義:ハッシュ値Hに対してH=h(m)となるmを求められない

これは単純であるハッシュ値がわかったときにそのハッシュ値と同じになるmを求められてはいけないということです。

弱衝突耐性

定義:h(m)からh(m)=h(n)を満たすnを求められない

弱衝突耐性がないと下の画像にある?を求められるということになります。

f:id:kataware8136:20180305150332p:plain

強衝突耐性

定義:h(m)≠h(n)となるmnを求められない

強衝突性がないとmとnを見つけられる。作れるということになります。

f:id:kataware8136:20180305150909p:plain

よく知られているハッシュ関数

このうち推奨暗号なのはsha2だけです。新しくシステム実装する際に使うときには基本的にsha2を使いましょう。

Shattered Attack (蛇足)

蛇足です。去年Googleが公開したSHA1脆弱性の話ですね!

今までさんざん危ない危ない言われてたけど衝突性は破られていなかったSHA1の強衝突耐性が破られたという話です。

これを利用した問題がSECCONで出ました。まぁ仕組みに関しては昔私がLTで話したので読んでね(露骨なアクセス数稼ぎ)

www.slideshare.net

Length Extention Attack

レングスエクステンションアタックとは攻撃者があるハッシュ値を入手した際に元のメッセージに任意のメッセージを付与したハッシュ値を導出可能という攻撃方法です。

ちなみにこの攻撃方法は反復型ハッシュ関数の、H(M||M')H(M)M'から計算できるという性質を利用する攻撃です。

md5sha1,sha2といったMerkle-Damgård構造のハッシュ関数は反復型ハッシュ関数であるため攻撃可能なケースが存在します。

HashPumpというツールがあります。このツールではMD5,SHA1,SHA256,SHA512に対応しています。オリジナルのハッシュ関数は自力で攻撃コードを書く必要があります

Androidの証明書関連のお話(弊研究室の某課題について考える6日目)

はじめに

この記事は弊研究室の某課題について考える6日目の記事です

本来はパーミッションの話をする予定でしたが,学内CTFの問題にならないので変えました

Androidの証明書

Androidのアプリケーションの実体はAPKファイルなのですがこのAPKファイルに署名をしないと端末にインストールすることはできません。

証明書がどのような役割を持っているかですが、APK内にあるファイルが改ざんされていないかを確認することができます。

4日目に書きましたがMETA-INFディレクトリ以下に署名関連のファイルは存在します。その中でも重要となるのはMETA-INF/MANIFEST.MFというファイルです。

以下に私が作成したテストアプリのマニフェストファイルとそのディレクトリ構成を示します。

Manifest-Version: 1.0
Created-By: 1.8.0_161 (Oracle Corporation)

Name: res/drawable-xhdpi-v4/ic_launcher.png
SHA-256-Digest: N32Dm15hayJA533LvqCbKTjB2VKktf8s07k5/GsrcSY=

Name: AndroidManifest.xml
SHA-256-Digest: TZXq3N83t1tAAfKW2Msiqf61rlc52yCRG0xnViSz6qQ=

Name: res/drawable-hdpi-v4/ic_launcher.png
SHA-256-Digest: wFAEDtDl2JOrQllos6kANCnFUUeuQYLRxBxZ4rPQT44=

Name: res/layout/activity_main.xml
SHA-256-Digest: ZfSju9DUI4erELJwRPGT/4quaScbbcc/sNZxzBoDn8U=

Name: resources.arsc
SHA-256-Digest: 5xEbB46maGyhMKqlKNX/E2CcJWus2fp9XE5Pci1b/Ek=

Name: res/drawable-mdpi-v4/ic_launcher.png
SHA-256-Digest: oDeveiogn/RmjjLSWBqGIkEm00m9vvxVI2A4iyG9hq8=

Name: classes.dex
SHA-256-Digest: mwFrI/cqNGVZeSHxWO2kzM7F/Xa/YBpfxRcG8M9OnM4=

Name: res/drawable-xxhdpi-v4/ic_launcher.png
SHA-256-Digest: 9tez3E9oIUiz8dzaZvZBX44SD3jDbVjG7AcunU5NOQ8=

Name: res/menu/main.xml
SHA-256-Digest: JmNDf4y9RNEWeRvzDM9HrKBucRjxYfJ0TQ7zkoB3uzw=
$ tree ./

./
├── AndroidManifest.xml
├── classes.dex
├── res
│   ├── drawable-hdpi-v4
│   │   └── ic_launcher.png
│   ├── drawable-mdpi-v4
│   │   └── ic_launcher.png
│   ├── drawable-xhdpi-v4
│   │   └── ic_launcher.png
│   ├── drawable-xxhdpi-v4
│   │   └── ic_launcher.png
│   ├── layout
│   │   └── activity_main.xml
│   └── menu
│       └── main.xml
└── resources.arsc

APKファイル内の全てのハッシュ値がMANIFEST.MFに記述されています。この値とファイルのハッシュ値を比較すれば改ざんされているかを確認できます。

ファイルのハッシュ値計算方法

ファイルのハッシュ値ですが,ファイルのハッシュダイジェストの20バイトのバイナリ長で返されたものをbase64エンコードしたものとなります。

ハッシュアルゴリズムに関してはMANIFEST.MFに書いてあるのでそれで計算します。今回は上のclasses.dexのハッシュ値を確認します。

phpでのハッシュ確認

$ php -r "echo base64_encode(hash_file('sha256','classes.dex',true));"
mwFrI/cqNGVZeSHxWO2kzM7F/Xa/YBpfxRcG8M9OnM4=%

という感じで計算できているのが確認できます。hash_file関数の最後にtrueを指定しないと16進で値が返ってきてしまいますので結果が変わってしまうので気をつけてください。

pythonでのハッシュ確認

>>> import hashlib
>>> import base64
>>> f = open("./classes.dex","rb")
>>> content = f.read()
>>> print(base64.b64encode(hashlib.sha256(content).digest()))
mwFrI/cqNGVZeSHxWO2kzM7F/Xa/YBpfxRcG8M9OnM4=

こんな感じですね、Pythonのほうが特に気をつけることもなくて楽ですね

おわりに

弊研究室のB4課題の知識としては上のことを知ってれば解けるはず、もっと詳しく知りたい方は参考文献を見る。もしくはAndroid Developerを見に行く等ですね

参考文献