Neosigurane ispravke relokacija u učitačima resursa

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Zašto su relokacije resursa važne

Mnogi zastareli game engine-i (Granny 3D, Gamebryo, itd.) učitavaju kompleksne resurse na sledeći način:

  1. Parsiranjem zaglavlja i tabele sekcija.
  2. Alokacijom jednog heap buffer po sekciji.
  3. Pravljenjem SectionArray koji čuva base pointer svake sekcije.
  4. Primenom relocation tabela tako da se pokazivači ugrađeni u podatke sekcije patchuju na odgovarajuću ciljnu sekciju + offset.

Kada relocation handler slepo veruje attacker-controlled metadata, svaka relokacija postaje potencijalni arbitrary read/write primitive. U Anno 1404: Venice, granny2.dll sadrži sledeći helper:

`GrannyGRNFixUp_0` (trimmed) ```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 nikada nije proveravan po opsegu, a SectionOffset nikada nije validiran u odnosu na veličinu trenutne sekcije. Crafting relocation entries sa negativnim offsetima ili prevelikim indeksima omogućava vam da izađete izvan sekcije kojom upravljate i pregazite allocator metadata kao što je sam section pointer array.

Faza 1 – Pisanje unazad u loader metadata

Cilj je navesti relocation table za section 0 da prepiše unose SectionContentArray (koji preslikava SectionArray i nalazi se odmah pre prvog section buffera). Pošto Granny’s custom allocator preprenda 0x1F bajtova, a NT heap dodaje svoj 0x10-bajtni header plus poravnanje, napadač može unapred izračunati rastojanje između početka prve sekcije (destination) i section-pointer array.

U testiranom buildu, prisiljavanje loader-a da alocira a GrannyFile strukturu koja je tačno 0x4000 bytes uzrokuje da se section-pointer arrays smeste odmah pre prvog section buffera. Rešavanje

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

daje n = 2720 sekcija. Relokacioni unos sa SectionOffset = -0x3FF0 ( 0x4000 - 0x20 - 0x20 + 0x30 ) sada se rešava na SectionContentArray[1] iako odredišna sekcija misli da menja interne pokazivače.

Faza 2 – Deterministički raspored heapa na Windows 10

Windows 10 NT Heap usmerava alokacije ≤ RtlpLargestLfhBlock (0x4000) u randomizovani LFH, a veće u deterministički backend allocator. Održavanjem GrannyFile metadata malo iznad tog praga (koristeći trik sa 2720 sekcija) i predučitavanjem nekoliko malicioznih .gr2 assets, možete napraviti:

  • Alokacija #1 (metadata + section pointer arrays) se nađe u backend chunk-u >0x4000.
  • Alokacija #2 (section 0 contents) se nađe odmah nakon alokacije #1.
  • Alokacija #3 (section 1 contents) se nađe odmah posle alokacije #2, dajući vam predvidljiv cilj za naredne relokacije.

Process Monitor je potvrdio da se assets streamuju na zahtev, tako da je ponovnim zahtevom za crafted units/buildings dovoljno da se “prime” raspored heapa bez diranja izvršnog imidža.

Faza 3 – Pretvaranje primitiva u RCE

  1. Korumpirajte SectionContentArray[1]. Relokaciona tabela sekcije 0 je prepisuje koristeći offset -0x3FF0. Usmerite ga na bilo koji zapisivi region koji kontrolišete (npr. podatke kasnije sekcije).
  2. Reciklirajte korumpirani pokazivač. Relokaciona tabela sekcije 1 sada tretira SectionNumber = 1 kao bilo koji pokazivač koji ste ubacili. Handler zapisuje SectionArray[1] + Offset na destination + SectionOffset, dajući vam proizvoljno 4-bajtno pisanje za svaki relokacioni unos.
  3. Napadnite pouzdane dispatchere. U Anno 1404 meta je bio granny2.dll allocator callbacks (no ASLR, DEP disabled). Prepisivanje funkcijskog pokazivača koji granny2.dll koristi za naredni Malloc/Free poziv odmah preusmerava izvršenje na kod pod kontrolom napadača učitan iz trojanizovanog asseta.

Pošto i granny2.dll i injektovani .gr2 bufferi leže na stabilnim adresama kada su ASLR/DEP isključeni, napad se svodi na izgradnju malog ROP chain-a ili raw shellcode-a i usmeravanje callback-a na njega.

Praktična kontrolna lista

  • Tražite asset loadere koji održavaju SectionArray / relocation tables.
  • Uporedite relocation handlere zbog nedostatka provera granica na indeksima/offsetima.
  • Izmerite allocator header-e koje dodaju i wrapper alokatora igre i osnovni OS heap da precizno izračunate povratne offsete.
  • Primenite determinističko pozicioniranje tako što ćete:
    • naduvavati metadata (mnogo praznih sekcija) dok veličina alokacije ne pređe > RtlpLargestLfhBlock;
    • ponovnim učitavanjem malicioznog asseta da popunite praznine u backendu.
  • Koristite dvofaznu relokacionu tabelu (prvo da preusmerite SectionArray, drugo da sprejate zapise) i prepišite funkcijske pokazivače koji će se aktivirati tokom normalnog renderovanja (allocator callbacks, virtual tables, animation dispatchers, itd.).

Kada steknete proizvoljno pisanje fajla (npr. putem path traversal-a u multiplayer save transferu), repakovanje RDA arhiva sa crafted .gr2 daje čist vektor isporuke koji se automatski dekompresuje od strane udaljenih klijenata.

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks