セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

GOT Overwrite - %hhnを使ってみる

//

GOT Overwrite

以下の二つを満たすと、ライブラリの関数アドレスを保存するGOT領域が書き込み可能となっているらしい

  • 実行ファイルがライブラリと動的リンクされている
  • No RELRO もしくは Partial RELRO



準備

strlenのアドレスが書き込まれる場所を探します。今回は0x0804a01cだとします。

$ readelf -r got

次にSystem関数のアドレスを探します。ASLR条件下と仮定して、以下のコマンドで調べます。今回は0xf7e52e70だとします。

$ gdb -q got
gdb_peda$ b main
gdb_peda$ r
gdb-peda$ p system 

次は入力がどのいちに反映されるか確認します。

f:id:thinline196:20180712223719p:plain

7個目ですね。%nは指定されたアドレスを4バイト分と見てprintfが出力している文字数をそこに書き込んでくれます。また%7$nとすれば、先ほどの7番目のアドレスに対して書き込んでくれるという優れもの。%?xとすると?分の文字を出力したと同じ効果があるものも一緒に使用します。

今回は%hhnを使用するということで、1バイト分ずつ書き込んでいこうと思います。ちなみに%hnは2バイト分。

やってみる


0x0804a01c~0x0804a01f(strlenのアドレスが入っていることろ)にSystem関数のアドレス0xf7e52e70を書き込むということで、

  • 0x0804a01c には 0x70
  • 0x0804a01d には 0x2e
  • 0x0804a01e には 0xe5
  • 0x0804a01f には 0xf7

を書き込みます。(リトルエンディアン)


で、文字数ですが、
・始めのアドレスを描く部分で16バイト使用します。
・次に、0x70を書き込みために、文字数を112にします。すでに16バイト(0x10)あるので、0x70-0x10=0x60 で%96xでok(注意として、%?xは10進数)これを7番目にhhnで書き込むので、%7$hhn
・次、2eを書き出したいが、すでに文字数が0x70。実はオーバーフロー分は無視されるらしいので、0x12eを目指せばOK。3桁目の1が無視されて書き出される。
・あとは、手作業で。。。


・最後、fgetsの入力は改行でストップするため、2個目のfgetsに入れたいもの(System関数の引数になる)の前に¥nを挟むこと。

結果

f:id:thinline196:20180712225818p:plain

しっかりlsコマンドを使用できているので、eipを奪えています。




何が言いたかったかというと、%hhnを使用するときのオーバーフロー分の計算は16進数で求めて、最後に必要な文字数を10進数で表したほうがわかりやすいよ