初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

バッファ・オーバーフローとクリックジャッキング

 バッファ・オーバーフローとクリックジャッキングについて勉強しました。本記事はこれらの攻撃についてまとめています。なお、私はセキュリティに関してはずぶの素人で本記事にも誤りが含まれているかもしれません。その際はコメントでご指摘いただけると幸いです。

バッファ・オーバーフロー

どんな攻撃

 あらかじめ確保したスタック領域のメモリサイズを超える入力値を入れることで、WEBサーバの動作を停止させたり、不正な動作をさせる攻撃です。

 変数val_1とval_2を格納するスタック領域があるとします。このスタック領域では、val_1に2バイト割り当てられており、外部から値を入力することができます。また、val_2にはint型の数値がデフォルトで入っているとします。

 このような設定のもとで、外部からval_1に3バイトの入力値abcを与えたとします。このとき、val_1は2バイトしか確保されていないので、あふれた1バイト分がval_2を上書きしてしまいます。val_2はint型であるにもかかわらず、char型で上書きされたのでWEBサーバ上で実行エラーが発生します(図1)。

図1:バッファー・オーバフローが発生する仕組み

 このようにあらかじめ確保していたメモリ領域を超える入力値を与えることで、他の変数を上書きするなどの攻撃をすることをバッファ・オーバーフローといいます。

どんな影響があるの?

 AppGoatによれば、下記の影響があります。

  • プログラムが異常終了させられる
  • 外部から任意のマシンコードが実行される

対策例

 C言語の文字列をコピーする関数にstrcpyとstrncpyがあります。strcpyにはバッファー・オーバフローの危険性があり、strncpyにはその危険性がありません。 したがって、文字列のコピーをする際にstrncpyを使用することで、バッファー・オーバフローを防ぐことができます。

 strncpyを利用することでバッファー・オーバーフローを防ぐことができる理由について述べます。下記はstrcpyとstrncpyの挙動の違いを説明するコードです。

char s1[4] = {'a', 'b', 'c', 'd'};
char s2[4] = {'a', 'b', 'c', 'd'}; 

// バッファー・オーバーフローが発生
strcpy(s1, '12345'); // s1 = {'1', '2', '3', '4', '5'} ← s1のもとの大きさを超えている

// バッファー・オーバーフローが発生しない
strncpy(s2, '12345', 4); // s1 = {'1', '2', '3', '4'} ← s2のもとの大きさを超えていない

 ポイントは、strncpyには第三引数としてコピーする文字の長さを指定できるという点です。これにより、確保したメモリよりも大きい文字列が外部から入力された場合でも、メモリがあふれることがありません。

クリックジャッキング

どんな攻撃

 罠サイトに透明な正規サイトを被せ、ユーザの意図しないリクエストを送ることを誘導する攻撃です。といっても、これだとどんな攻撃かわかりにくいと思います。 順を追って説明します。

罠サイトに透明な正規サイトを被せる

 HTMLタグの一つにiframe(インラインフレーム)というものがあります。iframeとは、あるWEBサイトに別のWEBサイトを被せることができるHTMLタグです。 例えば、WEBサイトにGoogleマップが載っていたりしますが、iframeを使っている場合があります。*1このiframeを利用することで、罠サイトに透明な正規サイトを被せることができます。

意図しないリクエストを送る

 ユーザは、罠サイトに透明な正規サイトを被せられていることに気付かず、罠サイトに載っている文言を信じてクリック等の操作をしてしまいます。このとき、ユーザの知らないところで正規サイトの操作が行われ、意図しないリクエストがWEBサーバに送られてしまいます。このような攻撃をクリックジャッキングと言います(図2)。

図2:クリックジャッキング

どんな影響があるの?

 AppGoatによれば、下記の影響があります。

  • ログイン後の利用者のみが可能なサービスの悪用
  • ログイン後の利用者のみが編集可能な設定の変更

対策例

 対策はシンプルです。iframeタグ等による別サイトの読み込みを制限することで、クリックジャッキングを防ぐことができます。ifrmaタグ等による別サイトの読み込みの制限は、HTTPヘッダのX-Frame-OptionsヘッダフィールドにDENYもしくは、SAMEORIGINを設定することで実現します。PHPであれば下記のように書けばOKです。*2

header("X-Frame-Options:DENY")
// もしくは
header("X-Frame-Options:SAMEORIGIN")

まとめ

 今回はバッファ・オーバフローとクリックジャッキングについてまとめました。  バッファ・オーバフローはバイト数の大きい入力値を入れることでメモリをあふれさせる攻撃でした。また、クリックジャッキングは罠サイトに透明な正規サイトを被せることでユーザが意図しない行動を誘導する攻撃でした。

*1:詳しくは、こちらのページに詳しく書いてありました。

*2:ちなみに、DENYの場合、全てのWEBページに対してフレーム内の表示を禁止します。一方で、SAMEORIGINについては同一オリジンのWEBページのみフレーム内の表示を許可します。