1月6日(金)1、2コマ目

今日、やったこと

バッファオーバーフロー

今日のホワイトボード

バッファオーバーフローとは

バッファオーバーランとも呼ばれる。

メモリ上の確保済みエリアのサイズを超えてデータをコピーすることで、未確保部分にも上書きされること。

図 バッファオーバーフロー

バッファオーバーフローはセキュリティインシデントの要因ナンバー1(と思われる)。

そもそもC言語はメモリ保護がないため、簡単に不具合を作ってしまう。

また、バッファーオーバーフローが特定の場合のみ発生するため、テストで露見しにくい。


メモリは

コンピュータのメモリはプログラム実行時に以下のように3つのエリアで使い分けられる。

図 メモリ


サンプルプログラムでバッファオーバーフロー発生

サンプルプログラム「bof_sample1.c」はstrcpy()でバッファオーバーフローを引き起こし、変数auth_flagの値を書き換えます。

変数auth_flag、password_bufferのアドレス

デバッガでプログラム実行中のメモリの状態(auth_flag、password_buffer)を確認します。

図 auth_flag、password_bufferのアドレス

auth_flag、password_bufferのアドレスから、メモリ上では以下のように配置されていることがわかります。

図 メモリ上でのauth_flag、password_buffer
この位置関係からpassword_bufferからオーバーフローすれば、auth_flagを上書きすることが分かります。

実際にバッファオーバーフローを引き起こしてみます。

バッファオーバーフロー発生時のメモリ[strcpy()前]

メモリは以下のとおり。

図 auth_flag、password_bufferのアドレス

図 strcpy()前のメモリ
password_bufferは初期化していないため、ゴミがあります。
auth_flagは0で初期化しているため、0です。(当然)


バッファオーバーフローでのメモリ[strcpy()後]

strcpy()で引数passwordの値を配列password_bufferにコピーすると、バッファーオーバーフローが発生します。

図 auth_flag、password_bufferのアドレス

図 strcpy()後のauth_flag、password_buffer

まとめ

なにも考えずにstrcpy()を使っていることが原因ですが、それ以外にも不具合の要因はあります。
図 このプログラムの問題点

strcpy()の問題とif()の問題はC言語が持つ問題。
if()の使い方はプログラマの問題。

バッファオーバーフローでリターンアドレス書き換え

バッファオーバーフローを使えば、もっといろいろなことができます。
たとえば、プログラムの実行順を変えることも可能です。
サンプルプログラム「bof_sample2.c」はbof_sample1.cの問題点を修正したものの、根本原因のstrcpy()を使っているため、バッファオーバーフローが発生します。このサンプルプログラムで異なるバッファオーバーフローを引き起こしてみます。

リターンアドレスとは

プログラムを実行すると、実行ファイルがコードエリアにロードされ、順に実行します。
関数を呼び出すと関数実行後は関数呼び出し元に戻ります。
関数呼び出し元に戻る際、コードエリアの戻るべきアドレスをリターンアドレスと呼びます。関数実行時にスタック上にリターンアドレスを記録して、関数を実行します。
図 リターンアドレス

リターンアドレスもローカル変数と同じスタックエリアに書き込まれます。
バッファオーバーフローでリターンアドレスも書き換えができそうです。
図 check()関数でのスタックエリア

次回は

バッファオーバーフローでリターンアドレスを書き換えてプログラムの処理順序を変更します。



 

このブログの人気の投稿

1月24日(火)1、2コマ目

1月17日(火)1、2コマ目