tcachebins & arena free chunk and libc leak

우리가 free로 메모리를 해제할때 기본적으로 arena라는 개념을 써왔다.

그런데 특정 libc 버젼 부터는 tcachebins 를 더 빠른 할당을 위해 사용한다.

이때 특정 크기로 tcachebins에 못가는데 그 기준이 바로 0x408 (1032 bytes) 이다.

또한 tcachebins 에 있는 chunk랑 arena에 있는 청크랑 다르다.

what is Heap & how it work - unsorted bin 글을 읽고 오면 이해가 더 쉽다.

기본적으로 tcache에 들어가지 못하는 크기를 free를 하면 unsorted bin 으로 들어간다.

이후 malloc 등으로 탐색이 일어나면 이 이후에 large bin 같은 다른 large bin으로 정렬 되는 방식이다.

일반적인 bin은 위와 같은 chunk를 따르는데 unsorted bin에 들어가 있을 때는 약간 다르다.

C
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555603840
Size: 0x2d1
fd: 0x7ffff7dcdca0
bk: 0x7ffff7dcdca0



pwndbg> vmmap 0x7ffff7dcdca0
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
             Start                End Perm     Size Offset File
    0x7ffff7dcd000     0x7ffff7dcf000 rw-p     2000 1eb000 /lib/x86_64-linux-gnu/libc-2.27.so +0xca0

다음과 같이 fd 와 bk에 heap 영역이 아닌 libc의 특정 부분을 가리키고 있다. 즉, 이 주소를 잘 노출시키면 libc_leak 이 가능하다는 소리이다. 그럼 저 주소는 뭘까?

unsortedbin은 main_arena.unsorted_bins라는 더블 링크드 리스트에 연결되어 있는데 그 링크드 리스트의 가상 노드가 main_arena+0x60 근처를 가리킨다. 따라서,

C
pwndbg> p &main_arena
$1 = (struct malloc_state *) 0x7ffff7dcdc40 <main_arena>

main_arena의 특정 노드의 주소를 담고 있는 것이다.