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()関数実行時に、スタックエリアに記録されている。
![]() |
| 図 戻りアドレス |
次回は
練習問題の解説。
次々回に多分、テストをします。





