Unsafe Relocation Fixups in Asset Loaders

Tip

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

HackTricks 지원하기

왜 asset relocations가 중요한가

많은 레거시 게임 엔진(Granny 3D, Gamebryo 등)은 복잡한 assets를 다음과 같이 로드한다:

  1. 헤더와 섹션 테이블을 파싱한다.
  2. 섹션마다 힙 버퍼를 하나 할당한다.
  3. 모든 섹션의 base pointer를 저장하는 SectionArray를 구축한다.
  4. 섹션 데이터 내부에 포함된 포인터들이 올바른 대상 섹션 + 오프셋으로 패치되도록 relocation tables를 적용한다.

relocation 핸들러가 공격자가 제어하는 메타데이터를 맹신하면, 모든 relocation은 잠재적인 임의 읽기/쓰기 프리미티브가 된다. Anno 1404: Venice에서, granny2.dll은 다음 헬퍼를 제공한다:

`GrannyGRNFixUp_0` (생략됨) ```c int *__cdecl GrannyGRNFixUp_0(DWORD RelocationCount, Relocation *PointerFixupArray, int *SectionArray, char *destination) { while (RelocationCount--) { int target_base = SectionArray[PointerFixupArray->SectionNumber]; // unchecked index int *patch_site = (int *)(destination + PointerFixupArray->SectionOffset); // unchecked offset *patch_site = target_base ; if (target_base) *patch_site = target_base + PointerFixupArray->Offset; ++PointerFixupArray; } return SectionArray; } ```

SectionNumber은 범위 검사되지 않으며 SectionOffset은 현재 섹션 크기에 대해 검증되지 않습니다. 음수 오프셋이나 과도한 인덱스를 가진 relocation entries를 조작하면 제어하는 섹션 밖으로 벗어나 섹션 포인터 배열 자체와 같은 allocator metadata를 짓밟을 수 있습니다.

Stage 1 – 로더 메타데이터로 역방향 쓰기

목표는 section 0의 relocation table이 SectionContentArray의 엔트리들을 덮어쓰게 만드는 것입니다(SectionContentArraySectionArray를 미러링하며 첫 번째 섹션 버퍼 바로 앞에 저장됩니다). Granny’s custom allocator가 앞에 0x1F 바이트를 추가하고 NT heap이 자체 0x10-바이트 헤더와 정렬을 더하기 때문에, 공격자는 첫 번째 섹션의 시작(destination)과 섹션-포인터 배열 사이의 거리를 미리 계산할 수 있습니다.

테스트된 빌드에서는 로더가 정확히 0x4000 bytesGrannyFile 구조를 할당하도록 강제하면 섹션-포인터 배열이 첫 번째 섹션 버퍼 바로 앞에 위치하게 됩니다. Solving

0x20 (header) + 0x20 (section descriptors)
+ n * 1 (section types) + n * 1 (flags)
+ n * 4 (pointer table) = 0x4000

gives n = 2720 sections. A relocation entry with SectionOffset = -0x3FF0 ( 0x4000 - 0x20 - 0x20 + 0x30 ) now resolves to SectionContentArray[1] even though the destination section thinks it is patching internal pointers.

Stage 2 – Windows 10에서 결정론적 힙 레이아웃

Windows 10 NT Heap는 ≤ RtlpLargestLfhBlock (0x4000) 인 할당을 랜덤화된 LFH로, 그보다 큰 할당을 결정론적 백엔드 할당자로 보낸다. GrannyFile 메타데이터를 그 임계값보다 약간 크게 유지(2720 섹션 트릭 사용)하고 악성 .gr2 에셋을 여러 개 미리 로드하면 다음을 만들 수 있다:

  • Allocation #1 (metadata + section pointer arrays)가 >0x4000 백엔드 청크에 배치된다.
  • Allocation #2 (section 0 contents)가 Allocation #1 바로 다음에 배치된다.
  • Allocation #3 (section 1 contents)가 Allocation #2 바로 뒤에 배치되어 이후 재배치(relocations)에 대해 예측 가능한 타깃을 제공한다.

Process Monitor는 에셋이 온디맨드로 스트리밍된다는 것을 확인했다. 따라서 조작된 유닛/건물을 반복적으로 요청하면 실행 파일 이미지를 건드리지 않고도 힙 레이아웃을 “프라임“하는 데 충분하다.

Stage 3 – 프리미티브를 RCE로 전환

  1. Corrupt SectionContentArray[1]. Section 0의 재배치 테이블이 -0x3FF0 오프셋을 사용해 이를 덮어쓴다. 이를 제어 가능한 쓰기 가능한 영역(예: 이후 섹션 데이터)을 가리키게 하라.
  2. Recycle the corrupted pointer. 이제 Section 1의 재배치 테이블은 SectionNumber = 1을 당신이 주입한 임의의 포인터로 취급한다. 핸들러는 SectionArray[1] + Offsetdestination + SectionOffset에 쓰므로 각 재배치 엔트리마다 임의의 4바이트 쓰기가 가능해진다.
  3. Hit reliable dispatchers. Anno 1404에서는 대상 선택으로 granny2.dll의 allocator 콜백이 사용되었다(ASLR 없음, DEP 비활성). 다음 Malloc/Free 호출에 granny2.dll이 사용하는 함수 포인터를 덮어쓰면 트로이화된 에셋에서 로드된 공격자 제어 코드로 즉시 실행이 전환된다.

ASLR/DEP가 비활성화된 상태에서는 granny2.dll과 주입된 .gr2 버퍼가 안정적인 주소에 존재하므로, 공격은 작은 ROP 체인이나 원시 쉘코드를 구성하고 콜백을 그쪽으로 가리키게 하는 것으로 귀결된다.

실전 체크리스트

  • SectionArray / 재배치 테이블을 유지하는 에셋 로더를 찾아라.
  • 인덱스/오프셋에 대한 경계 검사가 누락된 재배치 핸들러를 diff하여 찾아라.
  • 게임의 allocator 래퍼와 기저 OS 힙이 추가하는 allocator 헤더를 측정해 역방향 오프셋을 정확히 계산하라.
  • 결정론적 배치를 강제하려면:
    • 메타데이터를 늘려(여러 빈 섹션) 할당 크기가 RtlpLargestLfhBlock보다 커지게 한다;
    • 악성 에셋을 반복 로드해 백엔드의 빈틈을 채운다.
  • 2단계 재배치 테이블을 사용하라(먼저 SectionArray를 재타깃팅하고, 두번째는 쓰기 스프레이) 그리고 정상 렌더링 중에 실행될 함수 포인터들(allocator 콜백, 가상 테이블, 애니메이션 디스패처 등)을 덮어써라.

임의의 파일 쓰기 권한을 얻으면(예: 멀티플레이어 세이브 전송의 경로 탐색을 통해) 조작된 .gr2로 RDA 아카이브를 재패키징하는 것은 원격 클라이언트가 자동으로 압축 해제하는 깔끔한 전달 벡터를 제공한다.

참고자료

Tip

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

HackTricks 지원하기