Небезпечні виправлення релокацій у завантажувачах ассетів
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Чому релокації ассетів важливі
Багато застарілих ігрових движків (Granny 3D, Gamebryo тощо) завантажують складні ассети шляхом:
- Розбору заголовка і таблиці секцій.
- Виділення одного heap-буфера на секцію.
- Побудови
SectionArray, який зберігає базовий вказівник кожної секції. - Застосування таблиць релокацій, щоб вказівники, вбудовані у дані секцій, були виправлені на правильну цільову секцію + зсув.
Коли обробник релокацій сліпо довіряє метаданим, контрольованим атакувальником, кожна релокація стає потенційним примітивом довільного читання/запису. У Anno 1404: Venice, granny2.dll містить наступну допоміжну функцію:
`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 ніколи не перевіряється в межах діапазону, а SectionOffset ніколи не валідується щодо поточного розміру секції. Створення записів релокації з від’ємними зсувами або занадто великими індексами дозволяє вийти за межі секції, якою ви керуєте, і перезаписати метадані аллокатора, такі як масив вказівників секцій.
Етап 1 – Запис у зворотному напрямку в метадані завантажувача
Мета — змусити таблицю релокацій section 0 перезаписати записи SectionContentArray (яка віддзеркалює SectionArray і зберігається безпосередньо перед першим буфером секції). Оскільки власний аллокатор Granny додає попередньо 0x1F байтів, а NT heap додає власний заголовок розміром 0x10 байтів плюс вирівнювання, атакуючий може препорахувати відстань між початком першої секції (destination) і масивом вказівників секцій.
У протестованій збірці примусове виділення завантажувачем структури GrannyFile точно розміром 0x4000 bytes змушує масиви вказівників секцій опинитися безпосередньо перед першим буфером секції. Розв’язання
0x20 (header) + 0x20 (section descriptors)
+ n * 1 (section types) + n * 1 (flags)
+ n * 4 (pointer table) = 0x4000
дає n = 2720 секцій. Запис релокації з SectionOffset = -0x3FF0 ( 0x4000 - 0x20 - 0x20 + 0x30 ) тепер резольвиться в SectionContentArray[1], хоча призначена секція думає, що вона патчує внутрішні покажчики.
Stage 2 – Детермінований макет heap у Windows 10
Windows 10 NT Heap маршрутизує алокації ≤ RtlpLargestLfhBlock (0x4000) у рандомізований LFH, а більші — до детермінованого backend allocator. Тримаючи метадані GrannyFile трохи вище цього порогу (використовуючи трюк з 2720 секціями) і попередньо завантаживши кілька зловмисних .gr2 asset-ів, ви можете зробити так, щоб:
- Allocation #1 (metadata + section pointer arrays) опинилася в чанку бекенду >0x4000.
- Allocation #2 (section 0 contents) виявилася відразу після allocation #1.
- Allocation #3 (section 1 contents) опинилася відразу після allocation #2, даючи передбачувану ціль для наступних релокацій.
Process Monitor підтвердив, що assets стрімляться за потребою, тому повторні запити crafted units/buildings достатні, щоб «підготувати» макет heap без звернення до executable image.
Stage 3 – Перетворення примітиву в RCE
- Corrupt
SectionContentArray[1]. Таблиця релокацій секції 0 перезаписує її, використовуючи зсув-0x3FF0. Вкажіть її на будь-яку записувану область, якою ви керуєте (наприклад, дані пізніших секцій). - Recycle the corrupted pointer. Таблиця релокацій секції 1 тепер трактує
SectionNumber = 1як будь-який інжектований вами покажчик. Обробник записуєSectionArray[1] + Offsetуdestination + SectionOffset, даючи вам довільний 4-байтовий запис для кожного запису релокації. - Hit reliable dispatchers. В Anno 1404 ціллю вибору були allocator callbacks з
granny2.dll(немає ASLR, DEP відключено). Перезапис функціонального покажчика, якийgranny2.dllвикористовує для наступного викликуMalloc/Free, негайно відхиляє виконання на код під контролем атакуючого, завантажений із троянізованого asset-а.
Оскільки і granny2.dll, і інжектовані буфери .gr2 перебувають за стабільними адресами, коли ASLR/DEP вимкнені, атака зводиться до побудови невеликого ROP chain або сирого shellcode і вказування callback-а на нього.
Практичний чекліст
- Шукайте asset loaders, які підтримують
SectionArray/ relocation tables. - Diff relocation handlers на предмет відсутніх перевірок меж для індексів/зрушень.
- Виміряйте заголовки аллокатора, додані як обгорткою аллокатора гри, так і самим OS heap, щоб точно обчислити зворотні зсуви.
- Примусьте детерміноване розміщення, шляхом:
- надування метаданих (багато порожніх секцій) до тих пір, поки розмір алокації не перевищить
RtlpLargestLfhBlock; - повторного завантаження зловмисного asset-а, щоб заповнити дірки бекенду.
- надування метаданих (багато порожніх секцій) до тих пір, поки розмір алокації не перевищить
- Використовуйте двоступеневу таблицю релокацій (спочатку для перенаправлення
SectionArray, потім для розпилення записів) і перезапишіть функціональні покажчики, які спрацюють під час нормального рендерингу (allocator callbacks, virtual tables, animation dispatchers тощо).
Після того як ви отримаєте arbitrary file write (наприклад, через path traversal у передачі збережень для multiplayer), перепакування RDA архівів із crafted .gr2 дає чистий вектор доставки, який автоматично декомпресується віддаленими клієнтами.
References
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


