sysmalloc mmap을 통한 libc leak

msh1307·2022년 10월 17일
1

etc

목록 보기
1/21

sysmalloc_mmap

static void *
sysmalloc_mmap (INTERNAL_SIZE_T nb, size_t pagesize, int extra_flags, mstate av)
{
  long int size;

  /*
    Round up size to nearest page.  For mmapped chunks, the overhead is one
    SIZE_SZ unit larger than for normal chunks, because there is no
    following chunk whose prev_size field could be used.

    See the front_misalign handling below, for glibc there is no need for
    further alignments unless we have have high alignment.
   */
  if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ)
    size = ALIGN_UP (nb + SIZE_SZ, pagesize);
  else
    size = ALIGN_UP (nb + SIZE_SZ + MALLOC_ALIGN_MASK, pagesize);

  /* Don't try if size wraps around 0.  */
  if ((unsigned long) (size) <= (unsigned long) (nb))
    return MAP_FAILED;

  char *mm = (char *) MMAP (0, size,
                            mtag_mmap_flags | PROT_READ | PROT_WRITE,
                            extra_flags);
  if (mm == MAP_FAILED)
    return mm;

#ifdef MAP_HUGETLB
  if (!(extra_flags & MAP_HUGETLB))
...

malloc 할 때 일반적으로 큰 사이즈를 요청하면, brk나 sbrk로 program break를 쭉 늘리거나 감당할만하면, 탑 청크에서 떼주는데, malloc(0x200000) 이런 식으로 엄청 크게 줘버리면, 위 sysmalloc_mmap을 통해 mmap syscall을 부른다.

이때 커널에서 리턴받은 메모리와 libc가 로드된 주소와의 오프셋이 일정하다는 특징을 통해 libc leak이 가능하다.
libc 바로 앞에 딱 달라붙어있는게 mmap으로 할당받은 곳이다.

profile
https://msh1307.kr

0개의 댓글