# Titan Quest: Anniversary Edition heap overflow in .lvl/.pfx file parsing exploited via malicious custom maps (no CVE)

> Synacktiv researcher Thomas Dubier disclosed heap overflows in Engine.dll of Titan Quest: Anniversary Edition v2.10.21415 (GOG), reachable by loading a crafted .lvl level file or .pfx particle-effect file. A working code-execution chain was demonstrated on Windows 11, with shared community maps and assets as the delivery vector. No CVE, in-the-wild exploitation, or patch is reported.

- **Published:** 2026-11-12T06:31:49Z
- **Last reviewed:** 2026-11-12T06:31:49Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-5832
- **Card image:** https://intel.threadlinqs.com/og/threat/TL-2026-5832.png
- **ID:** TL-2026-5832
- **Severity:** MEDIUM
- **Category:** VULNERABILITY
- **Status:** TRACKING
- **Detections:** 9 (1 shown free below) · **IOCs:** 16

## Description

Synacktiv's 'Exploiting Titan Quest' (published 2026-07-29) analyses the map and asset parsers of Titan Quest: Anniversary Edition (THQ Nordic's 2016 re-release of the original Iron Lore/THQ game), tested on the GOG build v2.10.21415 under Windows 11 Professional build 10.0.26200. The game is a 32-bit process, and some of its bundled DLLs do not opt in to ASLR. The author notes that 49 methods in Engine.dll take a 16-byte GAME::BinaryReader structure, making binary game-file parsing a large attack surface. The GOG install bundles developer tools (Editor.exe for .wrl worlds, MapCompiler.exe to compile .map files, PSEditor.exe for .pfx particle effects) and the custom-maps folder sits under Documents\My Games\Titan Quest - Immortal Throne\custommaps on the test system.

Vulnerability 1 is in GAME::ImpassableData::Load, which parses chunk type 03h (CHUNK_TYPE_IMPASSABLE_DATA) of a .lvl level file. The destination buffer size is computed as width * height, which can overflow 32 bits, and the 'count' of bytes subsequently copied from the file is never checked against that allocation, producing a heap buffer overflow (CWE-190 integer overflow leading to CWE-122/CWE-787 heap/out-of-bounds write). Vulnerability 2 is a set of heap overflows in GAME::EmitterData::InternalBinaryRead, which parses .pfx files and copies several arrays of uncontrolled size into a fixed-size structure; the author judged these less exploitable because the allocation size itself is not attacker-controlled.

The research describes a multi-stage exploitation path built around the game's Segment Heap behaviour (allocations over 0x4000 bytes) and NT heap header XOR encoding. GAME::Water::Load (.lvl chunk 09h, CHUNK_TYPE_WATER) accepts variable-length WaterType strings, letting the researcher groom the heap into a predictable layout so the vulnerable impassable-data buffer lands adjacent to a Level object; a follow-on water chunk then causes an object teardown path (GAME::Level::NewWater / GAME::Water::~Water) to dereference attacker-influenced memory, yielding a hijacked indirect call. The write-up separately describes a documented technique for working around 32-bit ASLR in this process by filling address space with large repeated string allocations (WaterLayer objects) to make certain addresses predictable, and references a found code sequence reachable through this layout that can pivot execution. From there the article describes marking heap memory executable and ultimately running attacker-supplied code in the game process. Synacktiv states this chain was demonstrated end-to-end on a Windows 11 VM (build 10.0.26200) with a linked demonstration video, but does not publish a complete, directly reusable PoC.

The delivery vector is user-supplied content: custom maps and asset archives (.map, .lvl, .pfx, .arc, extractable with the ArcExplorer tool) are manually placed in the custommaps folder and shared informally within the modding community (e.g. via forums such as TitanQuestFans). Exploitation requires a victim to install and load an attacker-supplied map or asset bundle; code then runs with that user's privileges. The article states no CVE, CVSS score, in-the-wild exploitation, or attribution. The researcher began the vulnerability search 2026-03-23, contacted the publisher 2026-04-15, followed up 2026-05-02, and the article does not describe any vendor response or patch status as of publication (2026-07-29). Severity is analyst-assigned given the lack of a CVSS score in the source.

## MITRE ATT&CK

- T1587.004 Develop Capabilities: Exploits
- T1588.005 Obtain Capabilities: Exploits
- T1195 Supply Chain Compromise
- T1195.002 Supply Chain Compromise: Compromise Software Supply Chain
- T1203 Exploitation for Client Execution
- T1204 User Execution
- T1204.002 User Execution: Malicious File
- T1518 Software Discovery

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**Titan Quest Malicious Map/Asset Staged in custommaps Folder (Exploitation)** (`TL-2026-5832-SPL-001`)

Behaviour-first detection of the delivery step for the Titan Quest Engine.dll heap overflows disclosed by Synacktiv (no CVE). Fires when a .lvl, .pfx, .map, .wrl or .arc file lands in the Documents\My Games\Titan Quest - Immortal Throne\custommaps folder from a process that is not the game or its official editors (browser, archiver, script host). A crafted .lvl (chunk 03h, GAME::ImpassableData::Load width*height overflow) or .pfx (GAME::EmitterData::InternalBinaryRead) is parsed when the map is loaded (T1204.002, T1195.002).

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1204.002, T1204, T1195.002, T1195
- **Data sources:** sysmon
- **Severity:** medium
- **Confidence:** medium

### Splunk SPL

```spl
index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=11 TargetFilename="*\\Titan Quest*\\custommaps\\*" earliest=-24h
| where match(lower(TargetFilename), "\.(lvl|pfx|map|wrl|arc)$")
| where NOT match(lower(Image), "(^|[^a-z0-9_])(tq|titanquest|editor|mapcompiler|pseditor)\.exe$")
| stats count AS file_events dc(TargetFilename) AS distinct_files values(TargetFilename) AS staged_files min(_time) AS first_seen max(_time) AS last_seen BY Computer, User, Image
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| table Computer User Image distinct_files staged_files first_seen last_seen file_events
```

### Microsoft KQL

```kql
let GameFileExt = @"\.(lvl|pfx|map|wrl|arc)$";
let Staging = DeviceFileEvents
    | where Timestamp > ago(24h)
    | where ActionType in ("FileCreated", "FileModified", "FileRenamed")
    | where FolderPath has "custommaps" and FolderPath has "Titan Quest"
    | where tolower(FileName) matches regex GameFileExt
    | where InitiatingProcessFileName !in~ ("TQ.exe", "TitanQuest.exe", "Editor.exe", "MapCompiler.exe", "PSEditor.exe")
    | project Timestamp, DeviceName, Account = InitiatingProcessAccountName, Signal = "map_asset_staged_by_non_game_process", FileName, Detail = FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine;
let Tooling = DeviceProcessEvents
    | where Timestamp > ago(24h)
    | where (FileName in~ ("MapCompiler.exe", "PSEditor.exe", "Editor.exe") and FolderPath has "Titan Quest") or FileName =~ "ArcExplorer.exe"
    | project Timestamp, DeviceName, Account = AccountName, Signal = "exploit_crafting_tooling_executed", FileName, Detail = ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine;
union Staging, Tooling
| order by Timestamp desc
```

### Sigma

```yaml
title: Titan Quest Custom Map or Asset File Staged by Non-Game Process
id: 5b0c3f1e-7a42-4d1b-9c58-2e6a91d4b001
status: experimental
description: Detects lvl, pfx, map, wrl or arc files written into the Titan Quest custommaps folder by a process other than the game or its official editors. Crafted level and particle files can trigger heap overflows in Engine.dll when loaded. No CVE is assigned.
references:
    - https://www.synacktiv.com/en/publications/exploiting-titan-quest.html
author: Threadlinqs Team
date: 2026-11-12
tags:
    - attack.initial-access
    - attack.t1195.002
    - attack.execution
    - attack.t1204.002
    - attack.t1204
logsource:
    category: file_event
    product: windows
detection:
    selection_path:
        TargetFilename|contains: '\custommaps\'
    selection_ext:
        TargetFilename|endswith:
            - '.lvl'
            - '.pfx'
            - '.map'
            - '.wrl'
            - '.arc'
    filter_game:
        Image|endswith:
            - '\TQ.exe'
            - '\TitanQuest.exe'
            - '\Editor.exe'
            - '\MapCompiler.exe'
            - '\PSEditor.exe'
    condition: selection_path and selection_ext and not filter_game
falsepositives:
    - Players manually copying community maps with explorer.exe or an archive tool
    - Mod managers or sync tools restoring custommaps content
level: medium

```

**Known false positives:**

- Players copying community maps with explorer.exe or an archive extractor
- Mod managers restoring custommaps content
- Legitimate map authors saving from tools not on the allow-list

**Tuning notes:** Requires Sysmon EventCode 11 (FileCreate) coverage for the custommaps path. Exclude explorer.exe and approved mod-manager images on gaming-focused hosts, or keep them to catch manual map drops. Raise priority when the staging process is a browser, mail client or script host. Adjust the Titan Quest path pattern if the game is installed outside the default GOG layout.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- Titan Quest Malicious Map/Asset Staging and Crafting Tooling (Exploitation) [KQL] (locked: unlock with TL Creds)
- Titan Quest Game Process Spawning Shell or Discovery Children (Post-Exploitation) [KQL] (locked: unlock with TL Creds)
- Titan Quest Game Process Outbound Public Connections (C2 Hunt) [KQL] (locked: unlock with TL Creds)
- Titan Quest Malicious Map/Asset Staged in custommaps Folder (Exploitation) [Sigma] (locked: unlock with TL Creds)
- Titan Quest Game Process Spawning Shell or Discovery Children (Post-Exploitation) [Sigma] (locked: unlock with TL Creds)
- Titan Quest Game Process Outbound Public Connections (C2 Hunt) [Sigma] (locked: unlock with TL Creds)
- Titan Quest Game Process Spawning Shell or Discovery Children (Post-Exploitation) (locked: unlock with TL Creds)
- Titan Quest Game Process Outbound Public Connections (C2 Hunt) (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sources

- [Exploiting Titan Quest (Synacktiv, Thomas Dubier)](https://www.synacktiv.com/en/publications/exploiting-titan-quest.html)
- [Titan Quest modding guide (TitanQuestFans)](https://titanquestfans.net/index.php?topic=914.0)
- [Windows 10 NT Heap Exploitation (English version)](https://fr.slideshare.net/slideshow/windows-10-nt-heap-exploitation-english-version/154467191)
- [System Informer](https://systeminformer.sourceforge.io/)
- [UPX - the Ultimate Packer for eXecutables](https://upx.github.io/)
- [Titan Quest Anniversary Edition (GOG)](https://www.gog.com/en/game/titan_quest_anniversary_edition)
- [Titan Quest Anniversary Edition full changelog (GOG forum)](https://www.gog.com/forum/titan_quest_anniversary_edition/full_changelog)
- [Synacktiv publications index](https://www.synacktiv.com/en/publications)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-5832
