11 KiB
Unsorted Bin Attack
htARTE (HackTricks AWS Red Team 전문가)를 통해 **제로부터 영웅까지 AWS 해킹을 배우세요**!
HackTricks를 지원하는 다른 방법:
- 회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하려면 SUBSCRIPTION PLANS를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 Discord 그룹 또는 텔레그램 그룹에 가입하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
기본 정보
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의 첫 번째 청크는 실제로 FD 및 BK 링크가 메인 아레나(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:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.