hacktricks/binary-exploitation/heap/unsorted-bin-attack.md

11 KiB

Unsorted Bin Attack

htARTE (HackTricks AWS Red Team 전문가)를 통해 **제로부터 영웅까지 AWS 해킹을 배우세요**!

HackTricks를 지원하는 다른 방법:

기본 정보

unsorted bin이 무엇인지에 대한 자세한 정보는 다음 페이지를 확인하세요:

{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}

정렬되지 않은 목록은 unsorted_chunks (av)의 주소를 청크의 bk 주소에 쓸 수 있습니다. 따라서, 공격자가 정렬되지 않은 bin 내부의 청크에서 bk 포인터의 주소를 수정할 수 있다면, 임의의 주소에 해당 주소를 쓸 수 있어 libc 주소를 노출하거나 일부 방어를 우회하는 데 도움이 될 수 있습니다.

따라서, 기본적으로 이 공격은 임의의 주소를 큰 숫자로 덮어쓸 수 있게 했음을 의미합니다(힙 주소 또는 libc 주소일 수 있는 주소) - 누출될 수 있는 스택 주소 또는 글로벌 변수인 **global_max_fast**와 같은 제한을 우회하여 더 큰 크기의 fast bin bins를 생성할 수 있도록 허용합니다(정렬되지 않은 bin 공격에서 fast bin 공격으로 전환).

{% hint style="success" %} https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle에서 제공된 예제를 살펴보고 0x400과 0x500 대신 0x4000 및 0x5000을 청크 크기로 사용하면(티캐시를 피하기 위해) 현재 오류 **malloc(): unsorted double linked list corrupted**가 트리거되는 것을 볼 수 있습니다.

따라서, 이제 이 unsorted bin 공격은(다른 확인 사항과 함께) 또한 이중 연결 목록을 수정할 수 있어야 하므로 이중 연결 목록이 우회되어야 합니다 victim->bck->fd == victim 또는 victim->fd == av (arena). 즉, 우리가 원하는 주소는 가짜 청크의 주소가 fd 위치에 있어야 하며, 가짜 청크 fd가 아레나를 가리켜야 합니다. {% endhint %}

{% hint style="danger" %} 이 공격은 정렬되지 않은 bin을 손상시킵니다(따라서 작은 크기와 큰 크기 모두). 따라서 이제 이제 fast bin에서만 할당을 사용할 수 있습니다(더 복잡한 프로그램은 다른 할당을 수행하고 충돌할 수 있음) 및 이를 트리거하려면 동일한 크기로 할당해야 합니다.

이 경우 **global_max_fast**를 만드는 것이 도움이 될 수 있으며, fast bin이 모든 다른 할당을 처리할 수 있을 것으로 신뢰할 수 있습니다. 공격이 완료될 때까지. {% endhint %}

guyinatuxedo의 코드는 이를 매우 잘 설명하지만, malloc을 수정하여 tcache에 끝나지 않도록 충분히 큰 메모리를 할당하면 이전에 언급한 오류가 발생하여 이 기술을 방지하는 것을 볼 수 있습니다: malloc(): unsorted double linked list corrupted

Unsorted Bin Infoleak Attack

이것은 실제로 매우 기본적인 개념입니다. 정렬되지 않은 bin의 청크는 bin을 만들기 위해 이중 포인터를 가지게 됩니다. 정렬되지 않은 bin의 첫 번째 청크는 실제로 FDBK 링크가 메인 아레나(libc)의 일부를 가리키게 됩니다.
따라서, unsorted bin에 청크를 넣고 읽거나(사용 후 해제) 다시 할당하여 적어도 1개의 포인터를 덮어쓰지 않고 읽으면 libc 정보 누출을 얻을 수 있습니다.

writeup에서 사용된 유사한 공격은 4개의 청크 구조(A, B, C 및 D - D는 상단 청크와의 통합을 방지하기 위한 것)를 남용하여 B의 널 바이트 오버플로우를 사용하여 C가 B가 사용되지 않았음을 나타내도록 만들었습니다. 또한, B에서 prev_size 데이터가 수정되어 B의 크기가 아닌 A+B의 크기가 되었습니다.
그런 다음 C가 해제되고 A+B와 통합되었지만 B는 여전히 사용 중이었습니다. 크기 A의 새로운 청크가 할당되었고 그런 다음 libc 유출 주소가 B로 쓰여졌습니다.

참고 및 다른 예제

  • https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
  • 글로벌 변수를 4869보다 큰 값으로 덮어쓰기 위한 목표이며, PIE가 활성화되지 않았습니다.
  • 임의의 크기의 청크를 생성할 수 있으며 원하는 크기의 힙 오버플로우가 있습니다.
  • 공격은 3개의 청크를 생성하여 시작됩니다: 오버플로우를 남용하기 위한 청크0, 오버플로우를 받을 청크1 및 이전 청크들이 통합되지 않도록 하는 청크2.
  • 그런 다음, 청크1이 해제되고 청크0이 청크1의 bk 포인터로 오버플로우되어 bk = magic - 0x10을 가리키게 합니다.
  • 그런 다음, 청크3이 청크1과 동일한 크기로 할당되어 정렬되지 않은 bin 공격이 트리거되고 글로벌 변수의 값을 수정하여 플래그를 얻을 수 있게 됩니다.
  • https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
  • 병합 함수는 두 인덱스가 동일한 경우 다시 할당하고 그것을 해제하지만 그 해제된 영역을 사용할 수 있는 포인터를 반환합니다.
  • 따라서, 2개의 청크가 생성됩니다: 자신과 병합될 청크0 및 상단 청크와 통합되지 않도록 하는 청크1. 그런 다음, 청크0으로 병합 함수가 두 번 호출되어 사용 후 해제가 발생합니다.
  • 그런 다음, view 함수가 사용 후 해제된 청크의 인덱스인 2로 호출되어 libc 주소를 누출합니다.
  • 바이너리가 **global_max_fast**보다 큰 크기의 malloc만 허용하는 보호를 가지고 있기 때문에 fastbin을 사용하지 않으므로 unsorted bin 공격이 사용되어 global 변수 global_max_fast를 덮어쓸 수 있습니다.
  • 그런 다음, 사용 후 해제 포인터인 인덱스 2로 편집 함수를 호출하여 bk 포인터를 p64(global_max_fast-0x10)을 가리키도록 덮어쓰고, 이전에 손상된 해제 주소(0x20)를 사용하여 새로운 청크를 만들면 unsorted bin 공격이 트리거되어 global_max_fast를 덮어쓰고 매우 큰 값으로 설정하여 이제 fast bin에 청크를 생성할 수 있습니다.
  • 이제 fast bin 공격이 수행됩니다:
  • 먼저 __free_hook 위치에 크기 200의 fast 청크로 작업할 수 있다는 것을 발견했습니다:
  • gef➤  p &__free_hook
    

$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000

  • 만약 이 위치에 크기가 0x200인 fast chunk를 얻을 수 있다면 실행될 함수 포인터를 덮어쓸 수 있을 것입니다.
  • 이를 위해 크기가 0xfc인 새로운 청크가 생성되고 해당 포인터로 두 번 병합된 함수가 호출되어 fast bin에 크기가 0xfc*2 = 0x1f8인 해제된 청크의 포인터를 얻습니다.
  • 그런 다음, 이 청크에서 fd 주소를 이전 __free_hook 함수를 가리키도록 수정하기 위해 편집 함수가 호출됩니다.
  • 그런 다음, 크기가 0x1f8인 청크가 생성되어 fast bin에서 이전에 쓸모없는 청크를 검색하고, **__free_hook**에 fast bin 청크를 얻기 위해 크기가 0x1f8인 또 다른 청크가 생성되어 system 함수의 주소로 덮어씌웁니다.
  • 마지막으로 /bin/sh\x00 문자열이 포함된 청크가 삭제 함수를 호출하여 해제되고, __free_hook 함수를 트리거하여 /bin/sh\x00을 매개변수로 사용하여 system을 가리키게 됩니다.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • unsorted bin에서 청크를 통합하고 libc 정보 누출을 얻은 다음 malloc 후크를 원 갓젯 주소로 덮어쓰기 위해 fast bin 공격을 수행하는 1바이트 오버플로우를 악용하는 또 다른 예제
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks: