ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BlackHat Heap] Allocate a block
    Hack/Pwnable 2016. 11. 30. 01:37

    [ Allocate a fastbin chunk ] 


    할당된 Chunk가 fastbin Chunk 사이즈 내에 있으면, fastbin 크기에 대한 인덱스를 얻고, fastbin ptr은 그 인덱스를 현재의 아레나 내의 fastbin array의 오프셋을

    얻어 초기화한다.

    반환된 포인터가 NULL이 아니고 할당 된 청크가 그 크기에대한 fastbin single linked list의 첫번째 블록에 할당 될 때 'victim' 이란 변수가 반환되도록 한다.

    이 청크가 실제로 fastbin에 있어야 하는것을 확인하기 위해 보안 검사가 수행된다. 검사를 통과하면, fastbin 배열에 대한 포인터가 list의 다음 청크에 할당이 된다.

    check_remalloced_chunk()에 대한 호출이 이루어졌지만 MALLOC_DEBUG가 정의되어있다면 do_check_remalloced_chunk() _only_로 정의되어 컴파일된다.

    그리고, 사용자에게 반활 될 메모리 부분에 대한 포인터를 가져오고, 이전에 할당된경우엔 perturb byte가 설정되고 마지막으로 메모리에 대한 포인터가 public_malloc()에 반환된다.



    [ Allocate a small normal bin chunk ]


    fastbin 청크 크기보다 크고 512바이트보다 작은 경우 small normal bin 청크로 할당된다.

    해당 사이즈 내에 있으면 할당한 크기의 인덱스를 가져와서 arena의 normal bin배열에 대한 인덱스로 사용해 올바른 bin에 대한 포인터를 얻는다.

    그리고 victim 변수가 bin의 마지막 청크에 할당된다. 이 포인터가 bin자체를 가리키지않으면 ( list에 청크가 없음을 나타냄 ) NULL이 아닌지를 확인한다.

    위는 malloc_consolidate()에 대한 호출인 경우이다.


    malloc_consolidate()는 주석에서 variant of free()'로 설명되어있는 함수이다.

    free()가 되어있는 fastbin 청크가 있는지 검사하고, unsorted chunk와 가장 큰 fastbin list에 대한 포인터를 얻는다. 

    청크가 NULL을 가리키지않고 원본 포인터가 NULL을 가리키도록 셋팅될경우 포인터는 이 fastbin 청크로 초기화한다.

    다음 list에 다음 청크가 얻어지고, 이전 청크가 사용중이 아니라면, 이전 청크의 크기를 현재 청크의 크기와 더한다음 현재 청크의 크기를 추가해 현재 청크로 병합한다.

    그리고 현재 청크에대한 포인터가 이전 청크를 가리키도록 한다.

    그 후 다음 청크가 맨위 청크인지 확인하고 그렇지 않으면 현재 청크와 unlink()로 병합된다.

    그리고 unsorted chunk list에 추가된다. 이 프로세스들은 fastbin 인덱스에 대한 모든 블록이 적용되고, fastbin list에 대해 모든 fastbin 청크를 병합하여 unsorted bin list에 배치하고 마지막으로 리턴된다.


    victim 포인터가 NULL이고, malloc_consolidate()가 호출된 경우, 큰 normal chunk 할당 작업이 계속된다.

    victim 포인터가 NULL이 아니라면, victim의 back link가 얻어지고 bin의 back link가 할당된다. 

    victim 청크는 이전에 사용된 비트 셋을 가지고, victim 청크 forward link는 bin에 할당된다. 


    [ Allocate a lagre normal bin chunk ] 


    fastbin의 청크 범위와 small normal 청크 범위를 벗어나는 사이즈를 할당하려고하면, large normal bin으로 할당된다.

    청크가 small normal bin 청크 사이즈를 벗어났다면, 할당 된 첫번째는 해당 사이즈의 bin 색인을 얻는것이고 arena에  fastbin 청크가 있으면 malloc_consolidate()에 대한 호출이 이루어진다. 


    small normal 청크의 사이즈고, malloc_consolidate()가 할당 시도할경우, 이 단계는 이미 통합 된 fastbin 청크로 인해 건너뛴다!

    할당자는 for(;;) 루프를 입력해 while 루프에서 unsorted chunk index를 가리키고 청크가 발견될때까지 계속된다.

    victim의 backwards link에 대한 포인터가 얻어지고, victim size에 대한 검사가 이루어져 가능한 small chunk size보다 작은지 확인한다. 

    그리고ㅏ서 청크의 크기가 최종적으로 얻어진다.


    * chunk가 main_arena 에 없을시에 NON_MAIN_ARENA 비트가 1로 셋팅된다.



    [ Allocate a large chunk ]


    할당을 하고, 위의 모든 메소드가 bin list에서 적절한 청크를 찾지 못하거나 top chunk를 분할하지 못하면, sysmalloc() 함수로 끝난다. 이 함수는 mmap() 청크에 대한 새로운 영역 또는 top chunk를 확장한다. 

    요청 된 크기가 최대 mmap() 임계 값보다 작고 메모리 맵핑된 섹션이 너무 많지 않은 경우 할당시 overhead를 포함하도록 크기가 채워지고 mmap()을 통해 새 메모리 섹션이 확보 된다. 이렇게 할당이 된다면, 정렬은 잠재적으로 고정되고 메모리의 사용자에 대한 포인터는 public_malloc에 리턴된다.


    mmap()에 대한 호출이 실패하면 이미 너무 많은 메모리 맵핑이 되었거나, 크기가 mmap() 임계 값보다 큰 경우 top chunk를 확장하려고 시도한다.


    * 크기 조절이 실패하면 new_heap()을 호출해 새 힙을 요청함. 이 호출이 실패하거나 arena가 main_arena일 경우, 요청한 크기가 음수가 아닌경우 조정된 크기에 대해 MORECORE() 함수가 호출된다. MORECORE() 함수는 프로세스 데이터 세그먼트를 확장하는 sbrk()를 기본값으로 사용한다.


    * 위 호출이 실패하지 않으면 __after_morecore_hook()을 호출하여 잠재적인 콜백이 발생한다. 이 변수는 ptmalloc으로 할당이 불가함






    'Hack > Pwnable' 카테고리의 다른 글

    [BlackHat Heap] Traditional double free() exploitation  (0) 2016.11.30
    [BlackHat Heap] Free a chunk  (0) 2016.11.30
    [BlackHat Heap] Binning  (0) 2016.11.29
    [BlackHat Heap] Chunks of memory  (0) 2016.11.29
    [BlackHat Heap] malloc_state structure  (0) 2016.11.29

    댓글

Designed by Tistory.