y0u_bat

[heap] fastbin fd control 본문

System

[heap] fastbin fd control

유뱃 2016. 10. 7. 00:32

fastbin fd control

먼저 청크 구조부터 설명하면,

----------------------------
size of previous chunk
----------------------------
size of chunk  | M | P |   |
----------------------------
        using_data      
----------------------------


Free Chunk

-----------------------------------
       size of previous chunk
-----------------------------------
forward pointer to next chunk
-----------------------------------
back pointer to previous chunk
-----------------------------------
            Unused space 
-----------------------------------

malloc으로 할당된 청크들은 free를 통해 bin이라는 구조로 관리가 된다.
bin은 double-linked-list 구조로 되어있다.
chunk size에 따라 나눠지는데 small bin, large bin, fastbin small bin는 512byte 이하, large bin는 그 이상이다.
small bin에서 72byte 이하의 size를 가지는 chunk는 fastbin이라고 한다.

fastbin같은 경우는 속도를 높히기 위해 single-linked-list로 구현으며, 스택와 같은 방식으로 동작한다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main(int argc, char *argv[])
{
   char *mol1;
   char *mol2;
   char *mol3;

   mol1 = malloc(20);
   mol2 = malloc(20);
   mol3 = malloc(20);

   strcpy( mol1 , argv[1] );
   strcpy( mol2 , argv[2] );
   strcpy( mol3 , argv[3] );

   free(mol1);
   free(mol2);
   free(mol3);

   mol1 = malloc(20);
   mol2 = malloc(20);

   strcpy( mol2 , argv[4] );
}

fastbin은 stack와 같은 방식으로 돌아간다. 그래서 제일 처음으로 free된건 제일 마지막으로 재할당을 하고 늦게 free된것은 제일 처음으로 할당된다.

그리고 fastbin은 다른bin들과 다르게, 자기크기와 정확히 맞는 free chunk가 있을때, 그공간을 재할당을 한다.

free 이전 heap

0x804b004:  0x00000019  0x61616161  0x00000000  0x00000000
0x804b014:  0x00000000  0x00000000  0x00000019  0x62626262
0x804b024:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b034:  0x00000019  0x63636363  0x00000000  0x00000000
0x804b044:  0x00000000  0x00000000  0x00020fb9  0x00000000

free(mod1)

0x804b004:  0x00000019  0x00000000  0x00000000  0x00000000
0x804b014:  0x00000000  0x00000000  0x00000019  0x62626262
0x804b024:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b034:  0x00000019  0x63636363  0x00000000  0x00000000
0x804b044:  0x00000000  0x00000000  0x00020fb9  0x00000000

free(mod2)

0x804b004:  0x00000019  0x00000000  0x00000000  0x00000000
0x804b014:  0x00000000  0x00000000  0x00000019  0x0804b000
0x804b024:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b034:  0x00000019  0x63636363  0x00000000  0x00000000
0x804b044:  0x00000000  0x00000000  0x00020fb9  0x00000000

free(mod3)

0x804b004:  0x00000019  0x00000000  0x00000000  0x00000000
0x804b014:  0x00000000  0x00000000  0x00000019  0x0804b000
0x804b024:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b034:  0x00000019  0x0804b018  0x00000000  0x00000000
0x804b044:  0x00000000  0x00000000  0x00020fb9  0x00000000

fastbin 구조
free(mod3) --- fd: (&mod2) bk: NULL
free(mod2) --- fd: (&mod1) bk: NULL
free(mod1) --- fd: NULL bk: NULL

아까전부터 말했듯이 fastbin는 stack구조라서 나중에 free한 청크가 먼저 재할당 된다. 그리고 single-linked-list 구조라 BK는 안쓴다.

mol1 = malloc(20); ---> EAX: 0x804b038 --> 0x804b018 --> 0x0
mod3 위치에 할당된다.

mod3의 fd가 mod2의 힙 시작 주소이다. fd는 다음청크주소를 가지고 있는데,

mod2 = malloc(20); --> mod3의 fd에 있는주소에 재할당 될것이다.

그러므로 mod3에 있는 fd를 조작해보았습니다. 0x0804b018 -> 0x0804b0b0

size도 맞쳐줘야 되기때문에 0x0804b0b4에 0x00000019으로 gdb에서 임의적으로 변경 했습니다.

실제로는 오버플로우를 일으켜서 조작하거나, 0x19가 있는 곳을 찾아서 그부분을 주의해서 fd를 조작 해야됩니다. 만약에 size를 제대로 맞추지 않을경우 malloc corruption이 뜨는것을 볼 수 있습니다.

0x804b004:  0x00000019  0x00000000  0x00000000  0x00000000
0x804b014:  0x00000000  0x00000000  0x00000019  0x0804b000
0x804b024:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b034:  0x00000019  0x0804b0b4  0x00000000  0x00000000
0x804b044:  0x00000000  0x00000000  0x00020fb9  0x00000000
0x804b054:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b064:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b074:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b084:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b094:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b0a4:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b0b4:  0x00000000  0x00000019  0x00000000  0x00000000

mod2 = malloc(20); --> EAX: 0x804b0bc --> 0x0

0x0804b0b0부터 청크가 시작하며, 0x0804b0bc부터는 우리가 쓸 청크공간이다.

| 이전 청크 사이즈|
| 현재 청크 사이즈|
|우리가 쓸 청크공간|

이처럼 fd을 조작하고 size를 맞춰주어, 원하는주소에 할당을 받을수있게 됬다.

0x804b0a4:  0x00000000  0x00000000  0x00000000  0x00000000
0x804b0b4:  0x00000000  0x00000019  0x61616161  0x00000000
0x804b0c4:  0x00000000  0x00000000

그뒤에 strcpy를 실행해보면, 그주소에 write가 된걸 볼수있다.(write-anything-anywhere)

'System' 카테고리의 다른 글

[heap] fastbin_dup_into_stack.c  (0) 2016.11.02
[heap] how2heap first_fit.c  (0) 2016.10.20
QEMU-MIPS 환경 구축  (1) 2016.09.14
해킹캠프 13회 - equations 풀이  (0) 2016.02.28
Alphanumeric Shellcode (ascii shellcode) 작성  (0) 2016.02.19
Comments