House of Orange
Reading time: 5 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Basic Information
Code
- https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c에서 예제를 찾으세요.
- 이 patch에서 취약점이 수정되었으므로 더 이상 작동하지 않습니다 (2.26 이전에서 작동).
- https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html에서 더 많은 주석이 있는 동일한 예제를 확인하세요.
Goal
malloc_printerr
함수 악용
Requirements
- 상위 청크 크기 덮어쓰기
- Libc 및 힙 누수
Background
이 예제에서 필요한 배경:
문제는, 이전 버전의 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로 줄여 작은 빈에 맞추는 것입니다. 이는 두 가지 목적을 수행합니다:
- 작은 빈 4에 삽입:
malloc
이 정렬되지 않은 빈을 스캔할 때 이 청크를 보고 작은 크기 때문에 작은 빈 4에 삽입하려고 시도합니다. 이로 인해 청크가 **_IO_list_all
**의 FD 포인터가 있는 작은 빈 4 목록의 머리에 위치하게 됩니다. - 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 구조체를 통해 코드를 실행하게 할 때 절정에 달합니다. 이는 임의의 코드 실행을 효과적으로 허용하며, 일반적으로 셸이 생성되거나 다른 악성 페이로드가 실행되는 결과를 초래합니다.
공격 요약:
- 상위 청크 설정: 청크를 할당하고 상위 청크 크기를 수정합니다.
- 상위 청크를 정렬되지 않은 빈으로 강제 이동: 더 큰 청크를 할당합니다.
- libc 주소 누출: 취약점을 사용하여 정렬되지 않은 빈에서 읽습니다.
- 정렬되지 않은 빈 공격 수행: 오버플로우를 사용하여 _IO_list_all에 씁니다.
- 이전 상위 청크 축소: 작은 빈에 맞도록 크기를 조정합니다.
- 가짜 _IO_FILE 구조체 설정: 제어 흐름을 탈취하기 위해 가짜 파일 구조체를 위조합니다.
- 코드 실행 트리거: 공격을 실행하고 임의의 코드를 실행하기 위해 청크를 할당합니다.
이 접근 방식은 힙 관리 메커니즘, libc 정보 누수 및 힙 오버플로우를 악용하여 free
를 직접 호출하지 않고 코드 실행을 달성합니다. 가짜 _IO_FILE 구조체를 신중하게 제작하고 올바른 위치에 배치함으로써, 공격은 표준 메모리 할당 작업 중에 제어 흐름을 탈취할 수 있습니다. 이는 임의의 코드 실행을 가능하게 하여, 잠재적으로 셸이나 다른 악성 활동을 초래할 수 있습니다.
References
- 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
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.