본문 바로가기
Pwnable/Techniques

_int_malloc

by Anatis 2021. 2. 22.

_int_malloc과 _int_free는 개발자의 실수, 악의적인 행위 등으로 힙이 정상적으로 동작하지 않는 것을 방지하기 위해 검증 코드가 존재한다.

 

검증 코드를 이해하고 있다면 익스플로잇을 할 때 이를 우회하여 공격할 수 있다.

 

_int_malloc과 _int_free 코드를 보면서 어떠한 검증이 있는지 확인해보자.

 

malloc(): memory corruption (fast)

#define fastbin_index(sz) \
  ((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)

idx = fastbin_index (nb);
if (victim != 0)
{
    if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
    {
        errstr = "malloc(): memory corruption (fast)";
       errout:
        malloc_printerr (check_action, errstr, chunk2mem (victim), av);
        return NULL;
    }
}

_int_malloc에서 fastbin 크기의 힙이 할당될 때 호출되는 검증 코드이다.

 

할당하려는 fastbin의 크기와 할당될 영역의 크기를 구한 후 두 크기가 같은 bin에 속하는지 검증한다.

같은 bin에 속하는 크기라면 정상적으로 할당될 것이고 아니라면, malloc(): memory corruption (fast) 에러를 출력하고 비정상 종료를 한다.

 

m_error1.c

/*
    Fastbin
    gcc -o m_error1 m_error1.c
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main()
{
    uint64_t *ptr, *ptr2;
    
    ptr = malloc(0x20);
    ptr2 = malloc(0x20);

    free(ptr);
    free(ptr2);

    fprintf(stderr, "ptr2 fd: %p: %p\n", ptr2, ptr2);
    *(uint64_t *)ptr2 = *(uint64_t *)ptr2 + 0x100;
    fprintf(stderr, "ptr2 fd: %p: %p\n", ptr2, ptr2);

    malloc(0x20);
    malloc(0x20);
}

m_error1.c는 ptr2의 FD를 힙 청크가 존재하지 않는 영역의 주소로 조작해 검증 에러를 발생시키는 코드이다.

 

메모리의 상태는 다음과 같다.

해제된 ptr2의 FD를 올바르지 않은 0x602100 주소로 조작된 것을 확인할 수 있다.

0x062100 주소는 같은 bin의 크기를 가지고 있지 않기 때문에 에러가 발생한다.

 

malloc(): memory corruption

while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
{
  bck = victim->bk;
  if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)
      || __builtin_expect (victim->size > av->system_mem, 0))
    malloc_printerr (check_action, "malloc(): memory corruption",
        chunk2mem (victim), av);

unsorted bin 힙의 BK가 main_arena의 unsorted bin의 주소인지 확인한다.

다른 값일 때, 할당하는 힙의 크기가 2 * SIZE_SZ 보다 작거나 av->system_mem 보다 크면 에러를 출력하고 비정상 종료를 한다.

 

m_error2.c

// gcc -o m_error2 m_error2.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main()
{
    uint64_t *ptr, *ptr2, *ptr3;

    ptr = malloc(0x100);
    ptr2 = malloc(0x100);
    
    free(ptr);

    fprintf(stderr, "BK: %p\n", ptr[1]);
    ptr[1] += 0x40;
    fprintf(stderr, "Corrupted BK: %p\n", ptr[1]);

    malloc(0x21000);
}

m_error2.c 코드는 바로 위에서 언급한 memory corruption 에러를 발생시키는 코드이다.

 

메모리의 모습이다.

unsorted bin의 BK를 다른 값으로 조작하고 av->system_mem 보다 큰 값을 할당하였다.

unsorted bin의 BK가 small bin의 주소를 가리키고 있기 때문에 에러가 발생한다.

 

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

Double Free Bug  (0) 2021.02.23
_int_free  (0) 2021.02.22
ptmalloc2 allocator  (0) 2021.02.21
_IO_FILE vtable check  (0) 2021.02.06
_IO_FILE  (0) 2021.02.03

댓글