ほとんどの侵入者は、暗号の脆弱性をテストすることはほとんどないようです。私はいつも暗号技術に非常に興味があり、ウェブ・アプリケーション開発者による暗号アルゴリズムの誤用と、これらの脆弱性がどのように悪用されるかについて調べることにしました。
メッセージ認証コード 101
def create_mac(key, fileName)
return Digest::SHA1.hexdigest(key + fileName)
End結果のURLは次のようになります:
http://.com/download?file=.pdf&mac=563162c9c71a17367d44c165b84b85ab59d036f9ユーザーがファイルのダウンロード要求を開始すると、以下の関数が実行されます:
def verify_mac(key, fileName, userMac)
validMac = create_mac(key, filename)
if (validMac == userMac) do
initiateDownload()
else
displayError()
end
Endこの方法では、サーバーは、ユーザーが許可なくファイル名を変更していない場合にのみ、 initiateDownload()を実行してダウンロードを開始します。実際、この方法でMACを生成すると、攻撃者がファイル名にカスタム文字列を追加できる可能性があります。
延長攻撃、シンプルに
説明
MD5、SHA1、SHA2などのハッシュ・ダイジェスト・アルゴリズムは、Merkle-Damgård構造に基づいています。このタイプのアルゴリズムには興味深い問題があります。メッセージとMACがわかっていれば、キーの値がわからなくても、キーの長さをもう一度知るだけで、メッセージの後に情報を追加し、対応するMACを計算することができます。
例:メッセージ+パディング+エクステンション
上記の例に引き続き、ファイルダウンロード機能に対して長さ拡張攻撃が実行されます:
http://.com/download?file=
report.pdf%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%A8/../
../../../../../../etc/passwd&mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5長さ 延長 深さ
この攻撃を理解するためには、まずハッシュ関数の内部を理解する必要があります。
ハッシュアルゴリズムの仕組み
ハッシュ関数はブロック単位でデータを操作します。例えば、MD5、SHA1、SHA256のブロック長は512ビットです。ほとんどのメッセージはハッシュ関数のブロック長で正確に割り切れません。この場合、メッセージはブロック長の整数倍にパディングされなければなりません。前のファイルダウンロードのMACの例を使うと、パディングされたメッセージは次のようになります:
xxxxxxxxxxxreport.pdf\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\xA8この例で使われているSHA1アルゴリズムでは、ハッシュ値は5組の整数で構成されます。よく見られるのは、これら5つの整数を16進数に変換し、それらを連結したものです。アルゴリズムが実行されると、初期値はこのような数値の集合に設定されます: 67452301, EFCDAB89、
98BADCFE、10325476、C3D2E1F0。 その直後、メッセージが満たされ、512ビットのブロックに分割されます。アルゴリズムは各ブロックを順番に操作し、一連の計算を行い、レジスタを更新します。これらの操作が完了すると、レジスタの値が最終的なハッシュ値となります。
延長の計算
拡張子の値を計算する最初のステップは、新しいMACを作成することです。まず、拡張子の値:上記の例では「/...」を扱います。/.../.../.../.../.../.../etc/passwd'でハッシュダイジェスト。しかし、ダイジェストを行うには、レジスタの初期値を元のメッセージのMACに設定します。これは、サーバー上で実行された関数が終了したところから、SHA1関数を続行できるようにすると考えることができます。
攻撃者のMAC = SHA1(拡張+パディング) <- レジスターの初期値を上書き
この攻撃には前提条件があり、サーバのハッシュ関数に渡される際、拡張された値が別のブロックに存在しなければなりません。そのため、第2段階として、キー+メッセージ+パディング=512ビットの整数倍となるようなパディング値を計算します。この場合、キーは11文字です。つまり、パディング後のメッセージは以下のようになります:
report.pdf\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA8サーバーと新しいMACに送信されるパディングと拡張後のメッセージ:
download?file=.pdf
%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%A8/../../../../../../../etc/
passwd&mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5攻撃者がサーバーにダイジェスト処理を実行させるために改ざんしたメッセージは以下の通り:
secret + message + padding to the next block +extension + padding to the end of that block.サーバーが計算したハッシュはee40aa8ec0cfafb7e2ec4de20943b673968857a5となり、拡張文字列を追加してレジスタの初期値を上書きして計算したものと全く同じになります。これは、攻撃者のハッシュ計算処理が、その直後に行われるサーバーからの計算処理の半分に相当するためです。
攻撃の進め方
簡単のため、この例では鍵の長さを11ビットとします。現実的な攻撃環境では、攻撃者は鍵の長さを知ることができず、鍵の長さを推測する必要があります。
例の続きで、脆弱なサイトがMAC認証に失敗したときにエラーメッセージを返すとします。認証は成功したがファイルが存在しない場合、エラーメッセージも返されます。これら2つのエラーメッセージが同じでない場合、攻撃者はそれぞれ異なる鍵長に対応する異なる拡張子を計算し、それぞれをサーバに送信することができます。サーバーがファイルが存在しないことを示すエラーメッセージを返した場合、長さの拡張子攻撃が存在することになり、攻撃者は自由に新しい拡張子を計算し、サーバーから不正な機密ファイルをダウンロードすることができます。
この」攻撃に対する防御法
この脆弱性の解決策は、HMACアルゴリズムを使用することです。このアルゴリズムは大まかに次のようなものです: MAC =
ハッシュ(キー + ハッシュ(キー + メッセージ)) を使用する代わりに、キーとメッセージを連結した後の値のダイジェストをハッシュするだけです。
HMACの正確な仕組みは少し複雑ですが、大まかなイメージはつかめるでしょう。HMACは1996年に初めて発表され、それ以来ほとんどのプログラミング言語の標準ライブラリに追加されています。
概要
いまだに独自の暗号化アルゴリズムを書くクレイジーな人間がいる一方で、大半の人々は徐々に、独自の暗号化アルゴリズムを書くことは良い考えではないことに気づいてきました。しかし、一般に公開されている暗号化アルゴリズムを単純に適用するのではなく、正しく使用できるのであれば、それはそれでよいのです。使っている暗号化アルゴリズムの原理を完全に理解し、その正しい使い方を知っているのでなければ、専門家レベルで吟味されたアルゴリズムの高度なライブラリを使う方が安全です。





