[pwnable.xyz] Heap - House of Force 복습 (note v3)
Wargame/pwnable.xyz

[pwnable.xyz] Heap - House of Force 복습 (note v3)

🧡 note v3 binary

House of Force 복습 문제 😍

void make_note(void)

{
  size_t __nbytes;
  undefined4 *puVar1;
  void *__buf;
  ssize_t sVar2;
  uint local_24;
  
  local_24 = 0;
  while( true ) {
    if (9 < local_24) {
      puts("Notebook full");
      return;
    }
    if (*(long *)(notes + (long)(int)local_24 * 8) == 0) break;
    local_24 = local_24 + 1;
  }
  printf("Size: ");
  __nbytes = readint();
  puVar1 = (undefined4 *)malloc(__nbytes + 0x10);
  __buf = malloc(0x20);
  if ((puVar1 != (undefined4 *)0x0) && (__buf != (void *)0x0)) {
    printf("Title: ");
    read(0,__buf,0x20);
    *(void **)(puVar1 + 2) = __buf;
    printf("Note: ");
    sVar2 = read(0,puVar1 + 4,__nbytes);
    *puVar1 = (int)sVar2;
    *(undefined4 **)(notes + (long)(int)local_24 * 8) = puVar1;
    return;
  }
  puts("Error");
                    /* WARNING: Subroutine does not return */
  exit(1);
}
void edit_note(void)

{
  undefined4 *puVar1;
  ulong uVar2;
  ssize_t sVar3;
  
  printf("Note: ");
  uVar2 = readint();
  if ((uVar2 < 10) && (*(long *)(notes + uVar2 * 8) != 0)) {
    printf("Data: ");
    puVar1 = *(undefined4 **)(notes + uVar2 * 8);
    sVar3 = read(0,(void *)(*(long *)(notes + uVar2 * 8) + 0x10),
                 (ulong)**(uint **)(notes + uVar2 * 8));
    *puVar1 = (int)sVar3;
  }
  else {
    puts("Error");
  }
  return;
}

이 문제에 특징은 heap을 free 할 수 없다. heap을 free 할 수 없는 heap 문제? House of Force~

먼저 설명을 알아 듣기 쉽게 이번 문제에서 생성되는 Heap 구조를 그려봤다.

대충 이렇게 생겼고, 이번 문제에서는 Heap overflow를 이용한 House of Force에 대해 알아볼 것이다.

🧡 Attack Vector

먼저 make_note 함수에 있는 *puVar1  = read(0,puVar1 + 4,__nbytes); 부분에서 취약점이 발생한다. __nbyte는 우리가 입력하는 입력 값인데, 이 입력 값에 -1과 같이 적절한 음수를 입력하게 되면 heap은 정상적으로 할당되나, read에서 입력 받는 size가 음수이므로 -1을 return 하게 된다. 즉, heap의 길이가 0xffffffff가 되어 edit_note 함수로 heap overflow를 발생시킬 수 있다.

 

🧡 House of Force

House of Force는 heap의 top chunk를 조작하여 사용자가 원하는 메모리를 top chunk로 조작하는 기법이다. 


/*
   sysmalloc handles malloc cases requiring more memory from the system.
   On entry, it is assumed that av->top does not have enough
   space to service request for nb bytes, thus requiring that av->top
   be extended or replaced.
 */
/* finally, do the allocation */
  p = av->top;
  size = chunksize (p);
  /* check that one of the above allocation paths succeeded */
  if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
    {
      remainder_size = size - nb;
      remainder = chunk_at_offset (p, nb);
      av->top = remainder;
      set_head (p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0));
      set_head (remainder, remainder_size | PREV_INUSE);
      check_malloced_chunk (av, p, nb);
      return chunk2mem (p);
    }

top chunk로 바꿀 heap을 0x602010, 현재 top chunk를 0x602060, size를 0xffffffffffffffff로 조작했다고 가정하고 설명해보도록 하겠다.

 

코드를 설명하자면, size에 현재 top chunk에 chunk size가 저장된다. malloc 요청이 들어왔을 때, size가 충분하다면 그냥 heap을 할당해주지만 만약 size가 부족하다면 remainder_size를 (size - nb) | PREV_INUSE 로 조정하여 새로운 top chunk에 할당한다. top chunk는 [조작할 chunk] - [0x10] - [top chunk] - [0x10]로 계산할 수 있다.

 

🧡 Scenario

그래서 결국, 저 문제는 edit_note 함수로 top chunk를 조작하고 heap base를 leak하여 fake chunk의 주소를 계산한 다음, GOT Overwrite를 해주면 해결되는 문제다.

'Wargame > pwnable.xyz' 카테고리의 다른 글

[pwnable.xyz] All Clear  (0) 2021.07.17
[pwnable.xyz] fishing - thread  (0) 2021.07.12
[pwnable.xyz] executioner v2 삽질  (2) 2021.07.03
[pwnable.xyz] executioner trick(?)  (2) 2021.07.01
[pwnable.xyz] Free spirit trick 소개  (2) 2021.06.26