Unsorted Bin Attack
Last updated
Last updated
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
정렬되지 않은 빈에 대한 더 많은 정보는 이 페이지를 확인하세요:
정렬되지 않은 리스트는 청크의 bk
주소에 unsorted_chunks (av)
의 주소를 쓸 수 있습니다. 따라서 공격자가 정렬되지 않은 빈 내의 청크에서 bk
포인터의 주소를 수정할 수 있다면, 그는 그 주소를 임의의 주소에 쓸 수 있게 되어 Glibc 주소를 유출하거나 일부 방어를 우회하는 데 도움이 될 수 있습니다.
기본적으로 이 공격은 임의의 주소에 큰 숫자를 설정할 수 있게 합니다. 이 큰 숫자는 주소로, 힙 주소 또는 Glibc 주소일 수 있습니다. 일반적인 목표는 **global_max_fast
**로, 더 큰 크기의 빠른 빈을 생성할 수 있게 하며 (정렬되지 않은 빈 공격에서 빠른 빈 공격으로 넘어갈 수 있습니다).
https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle에서 제공된 예제를 살펴보면, 청크 크기로 0x400과 0x500 대신 0x4000과 0x5000을 사용하면 (Tcache를 피하기 위해) 현재 오류 **malloc(): unsorted double linked list corrupted
**가 발생하는 것을 볼 수 있습니다.
따라서 이 정렬되지 않은 빈 공격은 이제 (다른 검사와 함께) 이중 연결 리스트를 수정할 수 있어야 하며, 이는 victim->bk->fd == victim
또는 victim->fd == av (arena)
가 성립하지 않아야 함을 의미합니다. 즉, 우리가 쓰고자 하는 주소는 가짜 청크의 fd
위치에 가짜 청크의 주소를 가져야 하며, 가짜 청크의 fd
는 아레나를 가리켜야 합니다.
이 공격은 정렬되지 않은 빈을 손상시킵니다 (따라서 작은 빈과 큰 빈도 마찬가지입니다). 따라서 우리는 이제 빠른 빈에서 할당만 사용할 수 있습니다 (더 복잡한 프로그램은 다른 할당을 수행하고 충돌할 수 있습니다), 이를 트리거하기 위해서는 같은 크기를 할당해야 하며, 그렇지 않으면 프로그램이 충돌합니다.
**global_max_fast
**를 덮어쓰는 것이 이 경우 도움이 될 수 있으며, 빠른 빈이 익스플로잇이 완료될 때까지 모든 다른 할당을 처리할 수 있다고 믿어야 합니다.
guyinatuxedo의 코드는 이를 매우 잘 설명하고 있지만, mallocs를 수정하여 Tcache에 도달하지 않도록 충분히 큰 메모리를 할당하면 앞서 언급한 오류가 발생하여 이 기술을 방지합니다: malloc(): unsorted double linked list corrupted
사실 이것은 매우 기본적인 개념입니다. 정렬되지 않은 빈의 청크는 포인터를 가질 것입니다. 정렬되지 않은 빈의 첫 번째 청크는 실제로 **fd
**와 bk
링크가 주 아레나(Glibc)의 일부를 가리킵니다.
따라서 청크를 정렬되지 않은 빈에 넣고 읽거나 (free 후 사용) 포인터 중 적어도 하나를 덮어쓰지 않고 다시 할당하여 읽으면, Glibc 정보 유출을 얻을 수 있습니다.
이 글에서 사용된 유사한 공격은 4개의 청크 구조(A, B, C 및 D - D는 상위 청크와의 통합을 방지하기 위해서만 존재)를 악용하여 B에서 널 바이트 오버플로우를 사용하여 C가 B가 사용되지 않았음을 나타내도록 했습니다. 또한 B에서 prev_size
데이터를 수정하여 크기가 B의 크기 대신 A+B가 되도록 했습니다.
그런 다음 C가 해제되고 A+B와 통합되었지만 B는 여전히 사용 중이었습니다. 크기 A의 새 청크가 할당된 후, 유출된 libc 주소가 B에 기록되었습니다.
목표는 4869보다 큰 값으로 전역 변수를 덮어쓰는 것이므로 플래그를 얻을 수 있으며 PIE는 활성화되지 않습니다.
임의 크기의 청크를 생성할 수 있으며 원하는 크기로 힙 오버플로우가 발생합니다.
공격은 3개의 청크를 생성하는 것으로 시작됩니다: 오버플로우를 악용하기 위한 chunk0, 오버플로우될 chunk1, 이전 청크와 통합되지 않도록 하는 chunk2.
그런 다음 chunk1이 해제되고 chunk0이 chunk1의 bk
포인터를 가리키도록 오버플로우됩니다: bk = magic - 0x10
그런 다음 chunk3가 chunk1과 동일한 크기로 할당되어 정렬되지 않은 빈 공격이 트리거되고 전역 변수를 수정하여 플래그를 얻을 수 있게 됩니다.
병합 함수는 두 인덱스가 동일할 경우 재할당하고 해제하여 해제된 영역에 대한 포인터를 반환하므로 취약합니다.
따라서 2개의 청크가 생성됩니다: chunk0는 자신과 병합되고 chunk1은 상위 청크와 통합되지 않도록 합니다. 그런 다음 chunk0에 대해 병합 함수가 두 번 호출되어 free 후 사용이 발생합니다.
그런 다음 view
함수가 인덱스 2(사용 후 해제된 청크의 인덱스)로 호출되어 libc 주소가 유출됩니다.
바이너리가 **global_max_fast
**보다 큰 크기만 malloc하도록 보호되어 있으므로 빠른 빈이 사용되지 않고, 정렬되지 않은 빈 공격이 사용되어 전역 변수 global_max_fast
를 덮어씁니다.
그런 다음 인덱스 2(사용 후 해제된 포인터)로 edit 함수를 호출하고 bk
포인터를 p64(global_max_fast-0x10)
을 가리키도록 덮어씁니다. 그런 다음 새 청크를 생성하면 이전에 손상된 해제 주소(0x20)가 사용되어 정렬되지 않은 빈 공격이 트리거되어 global_max_fast
를 매우 큰 값으로 덮어씁니다. 이제 빠른 빈에서 청크를 생성할 수 있습니다.
이제 빠른 빈 공격이 수행됩니다:
우선 __free_hook
위치에서 크기 200의 빠른 청크로 작업할 수 있다는 것이 발견됩니다:
$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의 빠른 청크를 얻으면 실행될 함수 포인터를 덮어쓸 수 있습니다.
이를 위해 크기 0xfc
의 새 청크가 생성되고 병합 함수가 해당 포인터로 두 번 호출되어 빠른 빈에서 크기 0xfc*2 = 0x1f8
의 해제된 청크에 대한 포인터를 얻습니다.
그런 다음 이 청크에서 edit 함수를 호출하여 이 빠른 빈의 fd
주소를 이전 __free_hook
함수로 가리키도록 수정합니다.
그런 다음 크기 0x1f8
의 청크가 생성되어 빠른 빈에서 이전의 쓸모없는 청크를 가져오고, 또 다른 크기 0x1f8
의 청크가 생성되어 **__free_hook
**에서 빠른 빈 청크를 가져오고, 이 청크는 system
함수의 주소로 덮어씌워집니다.
마지막으로 문자열 /bin/sh\x00
을 포함하는 청크가 delete 함수를 호출하여 해제되어 __free_hook
함수가 호출되고, 이 함수는 /bin/sh\x00
을 매개변수로 하여 system을 가리킵니다.
정렬되지 않은 빈에서 청크를 통합하고 libc 정보 유출을 얻기 위해 1B 오버플로우를 악용한 또 다른 예제이며, 이후 malloc 훅을 하나의 가젯 주소로 덮어쓰는 빠른 빈 공격을 수행합니다.
우리는 0x100
보다 큰 크기의 청크만 할당할 수 있습니다.
정렬되지 않은 빈 공격을 사용하여 global_max_fast
를 덮어씁니다 (ASLR로 인해 1/16의 확률로 작동하며, 12비트를 수정해야 하지만 16비트를 수정해야 합니다).
전역 청크 배열을 수정하기 위한 빠른 빈 공격. 이는 임의의 읽기/쓰기를 가능하게 하여 GOT를 수정하고 일부 함수를 system을 가리키도록 설정할 수 있습니다.
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)