BOFの勉強中に発生したスタックセグメントの謎(CentOS6.3 + gcc 4.4.6)

本当は、前回に引き続き、こちらの参考書のバッファオーバーフローに関してを個人的に復習してまとめるために書こうと思ったんですが、再現の過程で、なんかよくわからない問題にぶつかったのでメモメモ。

前回はpassword_bufferの後に、auth_flagがメモリ上に確保されており、password_bufferを単純に配列より大きい文字列を与えたことによって、auth_flagの領域まで上書きしてしまう、というところまで再現しました。

今回はこちらのコードをBOFさせ、不正に認証処理を回避していきます。 コードはこちら

前回からの変更点は一箇所だけです。password_bufferを先に宣言してから、auth_flagを宣言しています。まずはこのコードを通常実行させた場合のメモリの状態を見ていきます。前回結構詳細まで書いたので、gdbデバッガのオプションとかの説明は省略いたします。

Screen Shot 2013-02-27 at 20.46.37

前回と同じ箇所にブレイクポイントを設定しておきます

Screen Shot 2013-02-27 at 20.47.32後ろに豪快に、twitterとか、ブラウザが映り込んでしまっていますが、まぁいいでしょう(笑)これで準備OKです。

実際に動かしてみます。

ここで問題発生・・・前回のサンプルを動作させたCentOS 6.2とgcc4.4.6だと変数の宣言位置を変えてもメモリの位置関係が変わらない・・・orz

書きなおしてもchar型配列のpassword_buffer[]がauth_flagの前にきちゃう・・・

Screen Shot 2013-02-28 at 13.57.58

gccの「最適化しない」オプションの”-O0″(大文字のOに数字の0)を付けてコンパイルしても結果は同じ・・・どういうこっちゃ・・・

Screen Shot 2013-02-28 at 14.01.01結局原因がわからないので、ちょっとしたテストしてみました。コードはこちら

いろんな型を適当な順番に宣言して、メモリ上にどのように確保されるのか、を環境ごとにチェックしていきます。(ブログの内容から少しづれちゃってるので、今度別の記事にまとめるかもしれません。)手元にある環境がCentOS6.2 , MacOSX MountainLion, Ubuntu7.0.4 なので、それぞれ比較してみたいと思います。

 

ごめんなさい、見づらいと思うんですが、どの環境でもちゃんとスタック状に詰まれてるんですよね・・・じゃぁなぜあの問題が起きるのか・・・申し訳ないです、結局特定はできていません・・・。ちなみに、以下のコードをCentOS でコンパイルしてgdbデバッグでメモリ確認すると、メモリの位置関係がスタック状ではなくなっていることが再現できました。

こちらをデバッグしてみると

Screen Shot 2013-02-28 at 16.09.20

宣言された順番にアドレス値を確認しているので、通常通りスタックに詰まれていけばアドレス値は小さくなるはずなんですが、メモリには

  1. password_buffer2
  2. password_buffer1
  3. auth_flag1
  4. auth_flag2

の順番に詰まれていることがわかります・・・これは一体・・・ 。

とりあえずわかったこと

  1. MacOSX Mountain Lion + gcc 4.2.1 と、Ubuntu7.0.2 + gcc3.3.6は、上記3つのコードとも、通常通り、宣言された順番でスタックに詰まれていく
  2. CentOS 6.3 + gcc 4.4.6は、2つ目のサンプル(色々な型をごちゃごちゃに宣言したもの)は通常通り、宣言された順番でスタックに詰まれていく
  3. CentOS 6.3 + gcc 4.4.6は、char型配列とint型を宣言するとchar型配列が優先されてスタックに詰まれている(ように現状見える)
  4. ついでだけど、MacOSX Mountain Lion + gcc 4.2.1とCentOS 6.3 + gcc 4.4.6では初期化されてない整数型、浮動小数点型は自動で初期化されるっぽい(何度やってもaとbは0クリアされてる。でもMacのほうは2つ目のfloatは初期化されない)※これは「そうなってるのかー」と解っただけで、自分でプログラム書く時初期化なしでもゼロとして使ってOKという訳では絶対ない(笑)念のため
  5. あと、基本的な見落としがあるのかもしれないけど、char型[16]の配列を宣言すると、MacOSXは16byte確保するのに対して、CentOS6.3とUbuntu7.0.2は28byte確保している。(なんじゃこりゃ)

原因わかる方・・・アドバイスくだしあ・・・・涙

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です