1月19日(月)2コマ目
今日、やったこと
[やってみよう 解説]バッファオーバーフロー
今日のホワイトボード
[やってみよう 解説]バッファオーバーフロー
バッファオーバーフローの脆弱性をついて、関数のリターンアドレスを書き換える。
main()関数をアセンブラに
gdbのdisasコマンドでmain()関数をアセンブラに。
![]() |
| 図 disasコマンドでmain()関数をアセンブラに |
今回は43行目のprintf()がどこにロードされるかを調べたい。
![]() |
| 図 43行目のprintf() |
hasUpperCase()関数をアセンブラに
同じようにhasUpperCase()関数もアセンブラにしてみる。
![]() |
| 図 hasUpperCase()関数をアセンブラに |
![]() |
| 図 hasUpperCase()関数をアセンブラに |
このとき、hasUpperCase()関数呼び出し時にスタックに書き込まれたリターンアドレスを参照する。
コードエリアにロードされたmain()関数、hasUpperCase()関数は下図のような感じ。
![]() |
| 図 コードエリア上のmain()関数、hasUpperCase()関数 |
hasUpperCase()関数のローカル変数
hasUpperCase()関数のstrcpy()実行後にメモリがどのようになっているか確認。
まず、hasUpperCase()関数のローカル変数がメモリ上(スタックエリア)にどのようにエリアが確保されるか確認。
![]() |
| 図 3つのローカル変数のメモリ番地 |
配列buffの先頭から64バイト分のメモリの様子を調べると以下のようになる。
![]() |
| 図 配列buffの先頭から64バイトの内容 |
配列buffの先頭から41バイト目からリターンアドレスが書き込まれていることがわかる。
バッファオーバーフローの脆弱性を使って、ここに飛ばしたいアドレスを書き込めばいい。
![]() |
| 図 3つの変数とリターンアドレス |
次回は
テストをします。







