House of Roman

HackTricks 지원하기

기본 정보

이 기법은 가짜 fastbins, unsorted_bin 공격 및 상대적 덮어쓰기를 통해 누출 없이 RCE를 가능하게 했던 매우 흥미로운 기법이었습니다. 그러나 패치되었습니다.

코드

목표

  • 상대적인 포인터를 악용하여 RCE

요구 사항

  • fastbin 및 unsorted bin 포인터 편집

  • 작동 확률이 0.02%인 12비트의 무작위성 브루트 포스

공격 단계

파트 1: Fastbin 청크가 __malloc_hook을 가리키도록 함

여러 청크 생성:

  • fastbin_victim (0x60, 오프셋 0): 나중에 힙 포인터를 LibC 값으로 가리키도록 나중에 편집할 UAF 청크

  • chunk2 (0x80, 오프셋 0x70): 좋은 정렬을 위해

  • main_arena_use (0x80, 오프셋 0x100)

  • relative_offset_heap (0x60, 오프셋 0x190): 'main_arena_use' 청크의 상대적 오프셋

그런 다음 free(main_arena_use)를 하면 이 청크가 unsorted 목록에 배치되어 fdbk 포인터 모두에서 main_arena + 0x68을 가리키는 포인터를 얻게 됩니다.

이제 fdbk 포인터에서 main_arena + 0x68을 가리키는 fake_libc_chunk(0x60)이 할당됩니다.

그런 다음 relative_offset_heapfastbin_victim을 해제합니다.

/*
Current heap layout:
0x0:   fastbin_victim       - size 0x70
0x70:  alignment_filler     - size 0x90
0x100: fake_libc_chunk      - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main        - size 0x20
0x190: relative_offset_heap - size 0x70

bin layout:
fastbin:  fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
  • fastbin_victimrelative_offset_heap을 가리키는 fd를 가지고 있습니다.

  • relative_offset_heapfake_libc_chunk로부터의 거리 오프셋이며, main_arena + 0x68을 가리키는 포인터를 포함합니다.

  • fastbin_victim.fd의 마지막 바이트를 변경함으로써 fastbin_victimmain_arena + 0x68을 가리키도록 만들 수 있습니다.

이전 동작을 위해 공격자는 fastbin_victimfd 포인터를 수정할 수 있어야 합니다.

그런 다음, main_arena + 0x68은 그다지 흥미로운 것이 아니므로 포인터가 **__malloc_hook**을 가리키도록 수정합니다.

__memalign_hook은 일반적으로 0x7f로 시작하고 그 앞에는 0으로 채워지므로, 0x70 fast bin의 값으로 가짜로 만들 수 있습니다. 주소의 마지막 4비트는 랜덤이므로 원하는 위치를 가리키도록 끝을 맞출 수 있는 가능성은 2^4=16입니다. 따라서 여기서 BF 공격이 수행되어 청크가 다음과 같이 끝나도록 합니다: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(나머지 바이트에 대한 자세한 내용은 how2heap의 설명을 확인하십시오. BF가 작동하지 않으면 프로그램이 중단됩니다 (작동할 때까지 다시 시작하십시오).

그런 다음, 처음 2개의 fast bin 청크를 제거하기 위해 2개의 malloc이 수행되고, 세 번째 malloc이 수행되어 **__malloc_hook:**에서 청크를 얻습니다.

malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

파트 2: Unsorted_bin 공격

더 많은 정보를 원하시면 확인하세요:

Unsorted Bin Attack

하지만 기본적으로 이는 chunk->bk에 지정된 위치로 main_arena + 0x68를 쓸 수 있게 합니다. 그리고 우리는 공격에 __malloc_hook을 선택합니다. 그런 다음, 덮어쓴 후에 상대적 덮어쓰기를 사용하여 one_gadget을 가리키게 할 것입니다.

이를 위해 청크를 가져와 unsorted bin에 넣기 시작합니다:

uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate

puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);

이 청크에서 UAF를 사용하여 unsorted_bin_ptr->bk__malloc_hook 주소로 지정합니다(이전에 우리는 이를 무차별 대입했습니다).

이 공격은 unsorted bin을 손상시키므로 이제 빠른 bin에서 할당만 사용할 수 있습니다 (더 복잡한 프로그램은 다른 할당을 수행하고 충돌할 수 있음), 이를 트리거하기 위해 동일한 크기로 할당해야 합니다.

따라서, __malloc_hookunsorted_bin_ptr->bk에 설정한 후에 main_arena + 0x68에 쓰기를 트리거하기 위해 우리는 단순히 **malloc(0x80)**을 수행해야 합니다.

단계 3: __malloc_hook을 시스템으로 설정

첫 번째 단계에서 __malloc_hook을 포함하는 청크를 제어하게 되었고(변수 malloc_hook_chunk), 두 번째 단계에서 여기에 main_arena + 0x68을 쓸 수 있었습니다.

이제, malloc_hook_chunk에서 부분적 덮어쓰기를 악용하여 거기에 쓴 libc 주소(main_arena + 0x68)를 사용하여 one_gadget 주소를 지정합니다.

여기서 12비트의 무작위성을 무차별 대입해야 합니다(how2heap예시에서 자세한 정보 확인).

마지막으로, 올바른 주소가 덮어쓰여지면 malloc을 호출하고 one_gadget을 트리거합니다.

참고 자료

HackTricks 지원

Last updated