1月13日(火)3コマ目

今日、やったこと

バッファオーバーフロー2(戻りアドレス書き換え)

今日のホワイトボード

前回はバッファオーバーフローの脆弱性を使って、関数の戻り値を変更した。

今回はバッファオーバーフローの脆弱性を使って、関数の戻りアドレスを変更する。

そもそもプログラムは

コンパイルしてできた実行ファイルはメモリ上のコードエリアにロードされる。

関数を呼び出すと、コードエリアにロードされた命令を1つずつ、順に実行していく。

関数内の変数や引数のためのエリアは、関数呼び出し時にスタックエリア上に確保される。

サンプルプログラム2を実行する

前回のサンプルプログラム1の問題点を修正したサンプルプログラム2を実行する。

コマンドライン引数は、バッファオーバーフローが発生して、変数auth_flagのエリアを上書きしてしまう”12345678901234567890123456789"。

〇strcpy()実行前

変数auth_flagと配列pass_buffの位置を確認。

図 strcpy()実行後

〇return auth_flag実行前

前回のプログラムでは、変数auth_flagが上書きされているが、プログラムを修正したため、0になっている。
図 return auth_flag実行前

プログラムの実行コードを確認

デバッガのdisasコマンドを使って、実行ファイルからmain()関数をアセンブラに変換。
図 disasコマンドでアセンブラに変換

check()関数を呼び出す、main()関数に戻る

関数を呼び出す=関数がロードされている位置から実行する。
アセンブラで確認すると、main()関数でcheck()関数の呼び出すと、callqコマンドでcheck()関数がロードされているアドレスに移動している。
check()関数の実行が終わると、再びcallqコマンドの次のコマンドから順に実行する。
ここに戻ってこれるように、スタックエリアに戻るべきアドレス番地が記録されている。
これが戻りアドレス。
図 check()関数呼び出し、main()関数に戻る


戻りアドレスを書き換える

main()関数にて、check()関数の戻り値に関わらず、下図のように別に位置から実行させたい。
図 check()関数から戻る位置を変える

check()関数から戻る位置

下図のようにcheck()関数実行時に、スタックエリアに記録されている。
図 戻りアドレス
バッファオーバーフローの脆弱性を使えば、戻りアドレスの内容も書き換えることができる。

次回は

練習問題の解説。
次々回に多分、テストをします。





このブログの人気の投稿

2月2日(月)4コマ目

2月10日(火)3コマ目