mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
76 lines
7.3 KiB
Markdown
76 lines
7.3 KiB
Markdown
# House of Orange
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Basic Information
|
|
|
|
### Code
|
|
|
|
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c)에서 예제를 찾으세요.
|
|
- 이 [patch](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0)에서 취약점이 수정되었으므로 더 이상 작동하지 않습니다 (2.26 이전에서 작동).
|
|
- [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)에서 **더 많은 주석이 있는** 동일한 예제를 확인하세요.
|
|
|
|
### Goal
|
|
|
|
- `malloc_printerr` 함수 악용
|
|
|
|
### Requirements
|
|
|
|
- 상위 청크 크기 덮어쓰기
|
|
- Libc 및 힙 누수
|
|
|
|
### Background
|
|
|
|
[**이 예제**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**에서 필요한 배경:**
|
|
|
|
문제는, 이전 버전의 libc에서 `malloc_printerr` 함수가 호출되면 **`_IO_list_all`에 저장된 `_IO_FILE` 구조체 목록을 반복**하고 실제로 **그 구조체의** 명령어 포인터를 **실행**했습니다.\
|
|
이 공격은 **가짜 `_IO_FILE` 구조체**를 위조하여 **`_IO_list_all`에 기록**하고 `malloc_printerr`를 실행하게 합니다.\
|
|
그런 다음 **`_IO_FILE`** 구조체의 점프 테이블에 저장된 **주소를 실행**하게 됩니다.
|
|
|
|
### Attack
|
|
|
|
공격은 **정렬되지 않은 빈** 내에서 **상위 청크**를 얻는 것으로 시작됩니다. 이는 현재 상위 청크 크기보다 크지만 **`mmp_.mmap_threshold`**(기본값은 128K)보다 작은 크기로 `malloc`을 호출하여 달성됩니다. 상위 청크 크기가 수정될 때마다 **상위 청크 + 크기**가 페이지 정렬되고 **prev_inuse** 비트가 항상 설정되어 있는지 확인하는 것이 중요합니다.
|
|
|
|
정렬되지 않은 빈 내에서 상위 청크를 얻으려면, 상위 청크를 생성하기 위해 청크를 할당하고, 할당된 청크에서 오버플로우를 통해 상위 청크 크기를 변경하여 **상위 청크 + 크기**가 페이지 정렬되고 **prev_inuse** 비트가 설정되도록 합니다. 그런 다음 새로운 상위 청크 크기보다 큰 청크를 할당합니다. `free`는 정렬되지 않은 빈으로 상위 청크를 가져오기 위해 호출되지 않는다는 점에 유의하세요.
|
|
|
|
이제 이전 상위 청크가 정렬되지 않은 빈에 있습니다. 그 안의 데이터를 읽을 수 있다고 가정하면(오버플로우를 유발한 취약점으로 인해 가능할 수 있음), libc 주소를 누출하고 **\_IO_list_all**의 주소를 얻을 수 있습니다.
|
|
|
|
정렬되지 않은 빈 공격은 오버플로우를 악용하여 `topChunk->bk->fwd = _IO_list_all - 0x10`을 작성함으로써 수행됩니다. 새로운 청크가 할당되면 이전 상위 청크가 분할되고, 정렬되지 않은 빈에 대한 포인터가 **`_IO_list_all`**에 기록됩니다.
|
|
|
|
다음 단계는 이전 상위 청크의 크기를 **0x61**로 줄여 작은 빈에 맞추는 것입니다. 이는 두 가지 목적을 수행합니다:
|
|
|
|
1. **작은 빈 4에 삽입**: `malloc`이 정렬되지 않은 빈을 스캔할 때 이 청크를 보고 작은 크기 때문에 작은 빈 4에 삽입하려고 시도합니다. 이로 인해 청크가 **`_IO_list_all`**의 FD 포인터가 있는 작은 빈 4 목록의 머리에 위치하게 됩니다.
|
|
2. **Malloc 체크 트리거**: 이 청크 크기 조작은 `malloc`이 내부 검사를 수행하게 합니다. 잘못된 포워드 청크의 크기를 확인할 때, 이는 0이 되어 오류를 발생시키고 `malloc_printerr`를 호출합니다.
|
|
|
|
작은 빈의 조작은 청크의 포워드 포인터를 제어할 수 있게 해줍니다. **\_IO_list_all**과의 겹침은 가짜 **\_IO_FILE** 구조체를 위조하는 데 사용됩니다. 이 구조체는 `_IO_write_base` 및 `_IO_write_ptr`와 같은 주요 필드를 포함하도록 신중하게 제작되며, libc의 내부 검사를 통과하는 값으로 설정됩니다. 또한, 가짜 구조체 내에 점프 테이블이 생성되어 임의의 코드(예: `system` 함수)를 실행할 수 있는 주소에 명령어 포인터가 설정됩니다.
|
|
|
|
기술의 나머지 부분을 요약하면:
|
|
|
|
- **이전 상위 청크 축소**: 이전 상위 청크의 크기를 **0x61**로 조정하여 작은 빈에 맞춥니다.
|
|
- **가짜 `_IO_FILE` 구조체 설정**: 이전 상위 청크와 가짜 **\_IO_FILE** 구조체가 겹치도록 하고 필드를 적절히 설정하여 실행 흐름을 탈취합니다.
|
|
|
|
다음 단계는 정렬되지 않은 빈에 현재 있는 이전 상위 청크와 겹치는 가짜 **\_IO_FILE** 구조체를 위조하는 것입니다. 이 구조체의 첫 번째 바이트는 실행될 명령어(예: "/bin/sh")에 대한 포인터를 포함하도록 신중하게 제작됩니다.
|
|
|
|
가짜 **\_IO_FILE** 구조체의 주요 필드인 `_IO_write_base` 및 `_IO_write_ptr`는 libc의 내부 검사를 통과하는 값으로 설정됩니다. 또한, 가짜 구조체 내에 점프 테이블이 생성되어 임의의 코드를 실행할 수 있는 주소에 명령어 포인터가 설정됩니다. 일반적으로 이는 `system` 함수 또는 셸 명령을 실행할 수 있는 다른 함수의 주소가 됩니다.
|
|
|
|
공격은 `malloc` 호출이 조작된 **\_IO_FILE** 구조체를 통해 코드를 실행하게 할 때 절정에 달합니다. 이는 임의의 코드 실행을 효과적으로 허용하며, 일반적으로 셸이 생성되거나 다른 악성 페이로드가 실행되는 결과를 초래합니다.
|
|
|
|
**공격 요약:**
|
|
|
|
1. **상위 청크 설정**: 청크를 할당하고 상위 청크 크기를 수정합니다.
|
|
2. **상위 청크를 정렬되지 않은 빈으로 강제 이동**: 더 큰 청크를 할당합니다.
|
|
3. **libc 주소 누출**: 취약점을 사용하여 정렬되지 않은 빈에서 읽습니다.
|
|
4. **정렬되지 않은 빈 공격 수행**: 오버플로우를 사용하여 **\_IO_list_all**에 씁니다.
|
|
5. **이전 상위 청크 축소**: 작은 빈에 맞도록 크기를 조정합니다.
|
|
6. **가짜 \_IO_FILE 구조체 설정**: 제어 흐름을 탈취하기 위해 가짜 파일 구조체를 위조합니다.
|
|
7. **코드 실행 트리거**: 공격을 실행하고 임의의 코드를 실행하기 위해 청크를 할당합니다.
|
|
|
|
이 접근 방식은 힙 관리 메커니즘, libc 정보 누수 및 힙 오버플로우를 악용하여 `free`를 직접 호출하지 않고 코드 실행을 달성합니다. 가짜 **\_IO_FILE** 구조체를 신중하게 제작하고 올바른 위치에 배치함으로써, 공격은 표준 메모리 할당 작업 중에 제어 흐름을 탈취할 수 있습니다. 이는 임의의 코드 실행을 가능하게 하여, 잠재적으로 셸이나 다른 악성 활동을 초래할 수 있습니다.
|
|
|
|
## References
|
|
|
|
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/)
|
|
- [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|