Heap Overflow

HackTricks 지원

기본 정보

힙 오버플로우는 힙에서 발생하는 스택 오버플로우와 유사합니다. 기본적으로 힙에 데이터를 저장할 공간이 예약되었지만 저장된 데이터가 예약된 공간보다 큰 경우를 의미합니다.

스택 오버플로우에서는 몇 가지 레지스터(명령 포인터 또는 스택 프레임과 같은)가 스택에서 복원될 것이며 이를 악용할 수 있다는 것을 알 수 있습니다. 힙 오버플로우의 경우, 힙 청크에는 기본적으로 민감한 정보가 저장되어 있지 않습니다. 그러나 민감한 정보나 포인터가 될 수 있으므로 이 취약점의 중요성은 무엇이 덮어쓰여질 수 있는지 및 공격자가 이를 어떻게 악용할 수 있는지에 따라 달라집니다.

오버플로우 오프셋을 찾기 위해 스택 오버플로우에서와 같은 패턴을 사용할 수 있습니다.

스택 오버플로우 vs 힙 오버플로우

스택 오버플로우에서는 취약점이 트리거될 때 스택에 존재하는 데이터 및 배열이 상당히 신뢰할 수 있습니다. 이는 스택이 선형이며 충돌 메모리에서 항상 증가하며, 프로그램 실행 중 스택 메모리의 특정 위치에는 일반적으로 유사한 종류의 데이터가 저장되며 각 함수에서 사용하는 스택 부분 끝에 일부 포인터가 있는 특정 구조를 가지고 있기 때문입니다.

그러나 힙 오버플로우의 경우, 사용된 메모리는 선형이 아니지만 할당된 청크는 일반적으로 메모리의 분리된 위치(서로 옆에 위치하지 않음)에 있습니다. 이는 크기에 따라 할당을 분리하는 bins 및 zones로 인해 그리고 이전에 해제된 메모리가 새로운 청크를 할당하기 전에 사용되기 때문입니다. 어떤 객체가 오버플로우될 것인지 알아내는 것은 복잡합니다. 따라서 힙 오버플로우를 발견하면 원하는 객체가 오버플로우될 수 있는 메모리에서 다음에 위치하도록 하는 신뢰할 수 있는 방법을 찾아야 합니다.

이를 위해 사용되는 기술 중 하나는 Heap Grooming입니다. 이 기술은 예를 들어 이 게시물에서 사용됩니다. 이 게시물에서는 iOS 커널에서 메모리를 저장할 공간이 부족해지면 커널 페이지로 확장되고, 이 페이지는 예상 크기의 청크로 분할되어 사용됩니다(9.2 버전 이전까지는 이러한 청크가 이러한 공격의 어려움을 위해 무작위로 사용됩니다).

따라서 힙 오버플로우가 발생하는 이전 게시물에서 오버플로우된 객체가 희생자 순서와 충돌하도록 강제하려면 여러 kallocs가 여러 스레드에 의해 강제로 실행되어 모든 빈 청크가 채워지고 새 페이지가 생성되도록 해야 합니다.

특정 크기의 객체로 이 채움을 강제하기 위해 iOS mach port와 관련된 out-of-line 할당이 이상적인 후보입니다. 메시지 크기를 조정함으로써 kalloc 할당의 크기를 정확히 지정할 수 있으며 해당 mach port가 파괴되면 해당 할당은 즉시 kfree로 반환됩니다.

그런 다음 이러한 플레이스홀더 중 일부를 해제할 수 있습니다. kalloc.4096 free list는 후입선출 순서로 요소를 해제하므로 일부 플레이스홀더가 해제되고 악용이 가능한 객체를 할당하려는 동안 오버플로우될 객체를 할당하려는 시도가 있으면 이 객체가 희생자 객체 뒤에 따르게 될 가능성이 높습니다.

예시 libc

이 페이지에서는 이전 청크의 prev in use 비트와 prev size의 위치를 덮어쓰는 것으로 사용 중인 청크를 통합할 수 있고, 그런 다음 다시 할당하여 다른 포인터에서 사용 중인 데이터를 덮어쓸 수 있는 기본적인 힙 오버플로우 에뮬레이션을 찾을 수 있습니다.

protostar heap 0의 다른 예시는 힙 오버플로우를 악용하여 승자 함수를 호출하여 플래그를 획득할 수 있는 CTF의 매우 기본적인 예시를 보여줍니다.

protostar heap 1의 예시에서는 버퍼 오버플로우를 악용하여 사용자로부터의 임의 데이터가 쓰일 주소가까운 청크에 덮어쓰는 것이 가능한 방법을 볼 수 있습니다.

예시 ARM64

https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ 페이지에서는 실행될 명령이 오버플로우된 청크에서 저장되는 힙 오버플로우 예시를 찾을 수 있습니다. 따라서 쉬운 악용을 통해 실행될 명령을 덮어쓰는 것이 가능합니다.

python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt

다른 예시

  • 우리는 정수 오버플로 취약점을 사용하여 힙 오버플로우를 얻습니다.

  • 우리는 오버플로된 청크의 struct 내부의 함수에 대한 포인터를 손상시켜 system과 같은 함수를 설정하고 코드 실행을 얻습니다.

HackTricks 지원

Last updated