hacktricks/binary-exploitation/libc-heap/house-of-orange.md

9.4 KiB

House of Orange

{% hint style="success" %} AWS 해킹 학습 및 실습:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 학습 및 실습: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

기본 정보

코드

목표

  • malloc_printerr 함수 남용

요구 사항

  • 최상위 청크 크기 덮어쓰기
  • Libc 및 힙 누출

배경

이 예제의 주석에서 필요한 일부 배경:

과거의 libc 버전에서 malloc_printerr 함수가 호출될 때 _IO_list_all에 저장된 _IO_FILE 구조체 목록을 반복하고 실제로 그 구조체 내의 명령 포인터를 실행했습니다.
이 공격은 우리가 _IO_list_all에 쓸 가짜 _IO_FILE 구조체를 조작하고 malloc_printerr가 실행되도록 만들 것입니다.
그런 다음 우리는 _IO_FILE 구조체의 점프 테이블에 저장된 주소를 실행하고 코드 실행을 얻을 것입니다.

공격

공격은 unsorted bin 내부에 top chunk을 가져오는 것으로 시작합니다. 현재의 최상위 청크 크기보다 크지만 mmp_.mmap_threshold (기본값은 128K)보다 작은 크기로 malloc을 호출하여 이루어집니다. 최상위 청크 크기가 수정될 때마다 top chunk + 해당 크기가 페이지에 맞추어지고 prev_inuse 비트가 항상 설정되어 있는지 확인하는 것이 중요합니다.

unsorted bin 내부에 top chunk을 얻으려면 최상위 청크를 만들기 위해 청크를 할당하고 최상위 청크 크기를 변경해야 합니다 (할당된 청크에서 오버플로우). 그래로 top chunk + 크기가 페이지에 맞추어지고 prev_inuse 비트가 설정되어야 합니다. 그런 다음 새로운 최상위 청크 크기보다 큰 청크를 할당합니다. 최상위 청크를 unsorted bin으로 가져오기 위해 free가 호출되지 않는다는 점을 주목하세요.

이제 이전 최상위 청크는 unsorted bin에 있습니다. 이를 통해 데이터를 읽을 수 있다고 가정하면 (오버플로우를 일으킨 취약점 때문에 가능할 수 있음), libc 주소를 누출하고 _IO_list_all의 주소를 얻을 수 있습니다.

unsorted bin 공격은 오버플로우를 악용하여 topChunk->bk->fwd = _IO_list_all - 0x10를 쓰는 것으로 수행됩니다. 새로운 청크가 할당되면 이전 최상위 청크가 분할되고 unsorted bin에 대한 포인터가 **_IO_list_all**에 쓰입니다.

다음 단계는 이전 최상위 청크의 크기를 작은 bin에 맞게 줄이는 것을 포함합니다. 특히 크기를 0x61로 설정합니다.

  1. Small Bin 4에 삽입: malloc이 unsorted bin을 스캔하고 이 청크를 볼 때 크기가 작기 때문에 이를 small bin 4에 삽입하려고 시도합니다. 이로 인해 이 청크는 small bin 4 목록의 헤드에 놓이게 되며 이는 우리가 unsorted bin 공격을 통해 **_IO_list_all**의 청크의 FD 포인터 위치에 가까운 주소를 썼기 때문입니다.
  2. Malloc 확인 트리거: 이 청크 크기 조작은 malloc이 내부적인 확인을 수행하도록 만듭니다. 거짓 앞쪽 청크의 크기를 확인할 때 (이는 0이 될 것입니다), 오류가 발생하고 malloc_printerr가 호출됩니다.

작은 bin의 조작을 통해 청크의 전방 포인터를 제어할 수 있습니다. _IO_list_all과의 중첩은 가짜 _IO_FILE 구조체를 조작하는 데 사용됩니다. 이 구조체는 libc에서 내부 확인을 통과하는 값으로 설정된 _IO_write_base_IO_write_ptr와 같은 주요 필드를 포함하도록 주의 깊게 제작됩니다. 또한 가짜 구조체 내에 점프 테이블이 생성되며 명령 포인터가 임의의 코드 (예: system 함수)가 실행될 수 있는 주소로 설정됩니다.

기술의 나머지 부분을 요약하면:

  • 이전 최상위 청크 축소: 이전 최상위 청크의 크기를 0x61로 조정하여 작은 bin에 맞춥니다.
  • 가짜 _IO_FILE 구조체 설정: 이전 최상위 청크와 중첩된 가짜 _IO_FILE 구조체를 설정하고 흐름 제어를 탈취합니다.

다음 단계는 현재 unsorted bin에 있는 이전 최상위 청크와 중첩되는 가짜 _IO_FILE 구조체를 조작하는 것입니다. 이 구조체의 처음 바이트는 조심스럽게 제작되어야 하며 실행될 명령 (예: "/bin/sh")을 가리키는 포인터를 포함해야 합니다.

가짜 _IO_FILE 구조체의 주요 필드인 _IO_write_base_IO_write_ptr와 같은 필드는 libc에서 내부 확인을 통과하는 값으로 설정됩니다. 또한 가짜 구조체 내에 점프 테이블이 생성되며 명령 포인터가 임의의 코드가 실행될 수 있는 주소로 설정됩니다. 일반적으로 이는 system 함수의 주소 또는 쉘 명령을 실행할 수 있는 다른 함수의 주소일 것입니다.

공격은 malloc 호출이 조작된 _IO_FILE 구조체를 통해 코드 실행을 트리거할 때 완료됩니다. 이를 통해 임의의 코드 실행이 가능해지며 일반적으로 쉘이 생성되거나 다른 악성 페이로드가 실행됩니다.

공격 요약:

  1. 최상위 청크 설정: 청크를 할당하고 최상위 청크 크기를 수정합니다.
  2. 최상위 청크를 unsorted bin으로 강제 이동: 더 큰 청크를 할당합니다.
  3. libc 주소 누출: unsorted bin에서 읽기 위해 취약점 사용.
  4. unsorted bin 공격 수행: 오버플로우를 사용하여 _IO_list_all에 쓰기.
  5. 이전 최상위 청크 축소: 작은 bin에 맞게 크기 조정.
  6. 가짜 _IO_FILE 구조체 설정: 제어 흐름을 탈취하기 위해 가짜 파일 구조체 조작.
  7. 코드 실행 트리거: 공격을 실행하고 임의의 코드 실행.

이 접근 방식은 free를 직접 호출하지 않고도 코드 실행을 달성하기 위해 힙 관리 메커니즘, libc 정보 누출 및 힙 오버플로우를 악용합니다. 가짜 _IO_FILE 구조체를 주의 깊게 제작하고 올바른 위치에 배치하여 표준 메모리 할당 작업 중에 제어 흐름을 탈취할 수 있습니다. 이를 통해 임의의 코드 실행이 가능해지며 일반적으로 쉘 또는 다른 악성 활동이 실행됩니다.

참고 자료

{% hint style="success" %} AWS 해킹 학습 및 실습:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 학습 및 실습: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원
{% endhint %}