1月19日(月)2コマ目

今日、やったこと

[やってみよう 解説]バッファオーバーフロー

今日のホワイトボード

[やってみよう 解説]バッファオーバーフロー

バッファオーバーフローの脆弱性をついて、関数のリターンアドレスを書き換える。

main()関数をアセンブラに

gdbのdisasコマンドでmain()関数をアセンブラに。

図 disasコマンドでmain()関数をアセンブラに

今回は43行目のprintf()がどこにロードされるかを調べたい。

図 43行目のprintf()

hasUpperCase()関数をアセンブラに

同じようにhasUpperCase()関数もアセンブラにしてみる。
図 hasUpperCase()関数をアセンブラに
hasUpperCase()関数は0x00…400666番地からロードされていることがわかる。

図 hasUpperCase()関数をアセンブラに
0x00…40073a番地のretqで呼び出し元に帰る。
このとき、hasUpperCase()関数呼び出し時にスタックに書き込まれたリターンアドレスを参照する。

コードエリアにロードされたmain()関数、hasUpperCase()関数は下図のような感じ。
図 コードエリア上のmain()関数、hasUpperCase()関数

hasUpperCase()関数のローカル変数

hasUpperCase()関数のstrcpy()実行後にメモリがどのようになっているか確認。

まず、hasUpperCase()関数のローカル変数がメモリ上(スタックエリア)にどのようにエリアが確保されるか確認。
図 3つのローカル変数のメモリ番地
3つのローカル変数のうち、配列buffが一番若いアドレスからはじまる。

配列buffの先頭から64バイト分のメモリの様子を調べると以下のようになる。
図 配列buffの先頭から64バイトの内容

配列buffの先頭から41バイト目からリターンアドレスが書き込まれていることがわかる。
バッファオーバーフローの脆弱性を使って、ここに飛ばしたいアドレスを書き込めばいい。
図 3つの変数とリターンアドレス

次回は

テストをします。








このブログの人気の投稿

1月13日(火)3コマ目

2月2日(月)4コマ目

2月10日(火)3コマ目