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 지원하기

Basic Information

Code

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로 줄여 작은 빈에 맞추는 것입니다. 이는 두 가지 목적을 수행합니다:

  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

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기