26.02.2026

Gratisspiele mit ungeahnten Kosten

Gratisspiele mit ungeahnten Kosten Malware Analyse

Von Karsten Hahn und John Dador

In diesem Artikel schauen wir uns an, wie diese Piraten-Gaming-Plattform Spaß und „kostenlose“ Unterhaltung in eine Gelegenheit für Cyberkriminelle verwandelt – und warum ein einziger Download eines raubkopierten Spiels Sie mehr kosten kann als nur ein paar Stunden Spielzeit.

Diese Blogserie besteht aus zwei Teilen. Dieser Artikel ist Teil eins und behandelt die Erstinfektion sowie HijackLoader im Detail. Der zweite Teil beschreibt die ACRStealer-Payload.

Initiale Infektion

Im November 2025 stießen wir auf einen Reddit-Beitrag (Abbildung 1) über bösartige Aktivitäten. Der Reddit-Nutzer gab an, von einem unbekannten Infostealer kompromittiert worden zu sein, nachdem er ein Spiel heruntergeladen hatte. Die zunächst gemeldete Datei gab sich als Python-basiertes Setup aus, aber bei unserer Untersuchung stellte sich heraus, dass die heruntergeladene Datei inzwischen durch eine andere ersetzt worden war. Das war für uns ein Hinweis darauf, dass die URL weiterhin aktiv ist und nach wie vor Infektionen verursacht.

Wir baten den betroffenen Nutzer um die Download-URL. Das führte uns zu PiviGames, einer Gaming-Seite.

 

PiviGames-Weiterleitung als Malvertising

Die Analyse der Website zeigt, dass sie Cloudflares Challenge- und Telemetrie-Skripte einsetzt, um seriös zu wirken. Bei genauerer Betrachtung lädt sie jedoch gleich zu Beginn des Codes eine JavaScript-Datei namens pgedshop.js. Diese JavaScript-Datei ist dafür verantwortlich, Nutzer auf bösartige Seiten weiterzuleiten. Das Skript enthält zwei fest definierte URLs und nutzt Browser-Cookies, um das Weiterleitungsverhalten der Seite zu steuern. Beim ersten Besuch eines Nutzers leitet das Skript auf hxxps://adbuho[.]shop/HIx0J weiter, was wie ein Werbenetzwerk aussieht. Danach markiert es die verwendeten Cookies so, dass weitere Besuche zu hxxps://pulseadnetwork[.]com/jump/next.php?r=2558259 weitergeleitet werden – ebenfalls ein harmloses Werbenetzwerk (ohne Hosting einer schädlichen Datei).

Die URL hxxps://adbuho[.]shop/HIx0J leitet auf eine Domain weiter, die aus zufälligen Zeichen besteht, gefolgt von einer Top-Level-Domain „.pro/“ und einem zusätzlichen zufälligen Pfad. Diese Weiterleitungskette führt schließlich zu einem MediaFire-Download-Link.

Der MediaFire-Link hostet ein ZIP-Archiv mit dem Namen „Full Version Setup 6419 Open.zip“. Auffällig ist, dass das Passwort direkt im Dateinamen eingebettet ist („6419“).

Nach dem Entpacken der ZIP-Datei sind mehrere Ressourcendateien vorhanden sowie eine einzelne ausführbare Datei mit dem Namen Setup.exe[2].

HijackLoader

Die Setup.exe[2] ist ein sauberer Game-Launcher, führt jedoch über DLL-Sideloading bösartigen Code aus, wenn das Spiel Conduit.Broker.dll[3] lädt.

Conduit.Broker.dll[3] gehört zur HijackLoader-Familie. Bedeutende Analysen und Beschreibungen dieser Loader-Familie wurden bereits von Nikolaos Pantazopoulos in [zscaler23] und [zscaler25] sowie von Ryan Weil in [trellix25] veröffentlicht. Angesichts der Komplexität der Malware glauben wir, dass unsere Analyse einige bislang nicht dokumentierte Details ergänzt. Außerdem stellen wir für HijackLoader ein Tooling auf Github bereit.

Stufe 1: ConduitBroker.dll

Die DLL exportiert 50 Funktionen und besteht größtenteils aus sauberem Code. Allerdings ist die Funktion BrokerManagerClient_AddPathMapping mit bösartigem Code gepatcht und reicht in andere Import-Funktionen hinein, etwa BrokerManagerClient_MapPath. Wer diesen Patch eingefügt hat, hat offenbar nicht geprüft, ob die Größe überhaupt in diese Funktion passt. Das führt auch zu seltsamem Verhalten in IDA Pro, da einige dieser Funktionen mitten in gepatchten Instruktionen beginnen (siehe Abbildung 4) und IDA darauf besteht, Funktionsdefinitionen aus den Exports beizubehalten.

Conduit.Broker.dll verwendet Inline-API-Resolving, d. h. es gibt keine dedizierte Funktion, die die Malware nutzt, um APIs dynamisch aufzulösen. Stattdessen ist der vollständige Code zum Durchlaufen des PEB („PEB walking“) jedes Mal inline eingebettet, wenn ein Funktionsaufruf erfolgen soll. Inline-API-Resolving haben wir in den letzten zwei Jahren in verschiedenen Samples gesehen, zum Beispiel in RisePro – dort allerdings mit einem anderen Hash-Algorithmus.

Der API-Hashing-Algorithmus ähnelt djb2; statt den Seed mit 5381 und den Multiplikator mit 33 zu initialisieren, verwendet die Malware jedoch 0x8798338 als Seed und 2 als Multiplikator. Der genaue Hash-Algorithmus lautet wie folgt (Python-3-Implementierung):

 

def calc_hash(apiname): 
    hash = 0x8798338 
    for c in apiname: 
        hash = (ord(c) + 2 * hash)  & 0xFFFFFFFF 
    return hash & 0xFFFFFFFF 

 

Die Malware entschlüsselt Teile der Datei Groumcumgag.ic[4], die sich im selben Ordner wie die DLL befindet. Der Header des verschlüsselten Daten-Blobs beginnt bei Offset 0x4A19: Das erste DWORD ist die Größe der verschlüsselten Daten (0x2080), und das zweite DWORD ist ein XOR-Key, in diesem Fall 0x1CAB3515. Direkt danach folgt der XOR-verschlüsselte Datenbereich selbst (siehe Abbildung 5).

Wir haben ein Entschlüsselungsskript für Groumcumgag.ic erstellt, das Sie hier herunterladen können. Der entschlüsselte Blob enthält Shellcode für die nächste Stufe sowie den Namen einer DLL, in diesem Fall „evr.dll“ (Enhanced Video Renderer).

Conduit.Broker.dll lädt anschließend die nächste Stufe mittels Module Stomping: Zuerst lädt sie die legitime System32-Bibliothek „evr.dll“ und injiziert den entschlüsselten Shellcode in den BaseOfCode von „evr.dll“. Danach ruft sie eine Funktion des Shellcodes auf und übergibt dabei eine Struktur als Argument, die unter anderem den Dateinamen „Zootkumbak.uhp“ enthält. Bei dieser Datei handelt es sich um die Konfiguration der Malware.

Stage 2: evr.dll-Shellcode und Module Table

Der Shellcode in evr.dll hat hauptsächlich die Aufgabe, die Hauptkonfiguration aus der Datei Zootkumbak.uhp[5]zusammenzusetzen und zu entschlüsseln.

Zunächst löst er jedoch Imports auf und prüft, ob bestimmte Prozesse vorhanden sind, indem er Hashes für die Prozessnamen berechnet. Findet er einen der anvisierten Prozesse, verzögert er die Ausführung um fünf Sekunden.

Die Hash-Berechnungsfunktion für Imports und Prozessnamen basiert auf einem konstanten Multiplikator aus der vorherigen Stufe; wir erwarten daher, dass sich dieser Wert bei anderen HijackLoader-Varianten ändern kann.

Als Nächstes verarbeitet der Shellcode der zweiten Stufe die Datei Zootkumbak.uhp[5]. Die verschlüsselten Daten der Konfiguration sind in 90 Fragmente aufgeteilt, die über die Datei verteilt sind.

Um herauszufinden, wo sich die einzelnen Fragmente befinden, führt HijackLoader eine Pattern-Suche durch. Dafür verwendet er das Suchmuster ‘?????@IDAT’, das HijackLoader als ein Wildcard-behaftetes 4-Byte-Feld interpretiert, auf das direkt der String ‘IDAT’ folgt. Der Wildcard-Wert entspricht der Größe des aktuellen Chunks. In unserem Sample gibt es insgesamt 90 Chunks.

Nach dem ersten ‘IDAT’-Pattern beginnt der Header unserer verschlüsselten Konfiguration. Der vollständige Header inklusive Suchpattern sieht so aus:

chunk_size | ‘IDAT’ | magic | xor_key | compressed_size | uncompressed_size

Jeder dieser Werte ist vier Bytes lang. Der XOR-Key entschlüsselt alle Chunks der Konfiguration. compressed_size ist die Gesamtgröße aller Chunks vor der Dekompression, uncompressed_size entsprechend die Gesamtgröße nach der Dekompression. Nach diesem Header beginnen die verschlüsselten Daten des ersten Chunks.

Bei allen weiteren ‘IDAT’-Chunks beginnen die verschlüsselten Daten direkt nach dem ‘IDAT’-Pattern.

Um die Konfigurationsdatei Zootkumbak.uhp zu deobfuskieren, entschlüsseln wir jeden Chunk mit dem XOR-Key aus dem Header, hängen die Chunks in der Reihenfolge aneinander, in der sie gefunden wurden, und dekomprimieren sie anschließend mit LZNT1.

Die Konfiguration enthält unter anderem die verschlüsselte Payload, verschiedene Einstellungen sowie eine Module Table mit Namen und Offsets zu weiterer Konfigurations-Daten.

Wir haben einen Konfigurations-Extractor erstellt, der Zootkumbak.uhp deobfuskiert, daraus Einstellungen extrahiert, die Payload dump’t und alle Einträge der Module Table ausgibt.

 

Wir verwenden hier den Begriff „Module Table“, um konsistent mit der Terminologie früherer Artikel zu bleiben ([zscaler23, zscaler25, trellix25]). Der Inhalt ist jedoch nicht strikt auf Module beschränkt. Die Tabelle kann tatsächlich jegliche Art von Daten enthalten. In einigen Fällen – konkret MUTEXCOPYLISTSM und CUSTOMINJECTPATH– sind die Einträge string-basierte Einstellungen oder Listen von Strings. In anderen Fällen sind es Konfigurationswerte, Shellcode oder vollständige PE-Images.

Das vorliegende Sample enthält die folgenden Module-Table-Einträge (für String-Einträge sind die Werte angegeben). Beschreibungen zu diesen Einträgen finden sich in [zscaler23, zscaler25]:

 

ModuleValue
AVDATAbenutzerdefinierte strukturierte Daten mit CRC-Hashes von AV-Prozessnamen und Flags; kann mit avdata_decoder.py decodiert werden.
ESALShellcode, unterstützt bei Injection
ESAL64Shellcode, unterstützt bei Injection
ESLDRShellcode, unterstützt bei Injection
ESLDR64Shellcode, unterstützt bei Injection
ESWRShellcode, unterstützt bei Injection
ESWR64Shellcode, unterstützt bei Injection
FIXEDPE-Datei, hier zip.exe signiert von „VMWare Inc“, dient als Host für Process Doppelgänging
LauncherLdr64PE-Datei zum Laden der Payload
modCreateProcessShellcode, hilft bei Prozess-Erstellung
modCreateProcess64Shellcode, hilft bei Prozess-Erstellung
modTaskShellcode, für Persistenz
modTask64Shellcode, für Persistenz
modUACShellcode, UAC-Bypass
modUAC64Shellcode, UAC-Bypass
modWDShellcode, Defender-Evasion
modWD64Shellcode, Defender-Evasion
modWriteFileShellcode
modWriteFile64Shellcode
rshellShellcode, lädt die Payload via Module Stomping
rshell64Shellcode, lädt die Payload via Module Stomping
tiShellcode, Hauptmodul, 32-bit
ti64Shellcode, Hauptmodul, 64-bit
tinycallProxyShellcode, führt API-Calls aus
tinycallProxy64Shellcode, führt API-Calls aus
tinystubPE file stub
tinystub64PE file stub
tinyutilitymodule.dllPE-Datei
tinyutilitymodule64.dllPE-Datei
SMString „mpr.dll“, Name der sauberen Ziel-DLL für Module Stomping
COPYLIST

String-Luiste mit den folgenden Dateinamen:

  • Conduit.Broker.dll 

  • D_C.exe 

  • Groumcumgag.ic 

  • TE.Common.dll 

  • TE.Host.dll 

  • TE.Loaders.dll 

  • TE.WinRT.dll 

  • Wex.Common.dll 

  • Wex.Communication.dll 

  • Wex.Logger.dll 

  • Zootkumbak.uhp 

  • !D_C.exe 

  • ~TE.Loaders.dll 

MUTEX String „RXRCJOIAVDWOEK“, als Mutex-Name genutzt
CUSTOMINJECTPE-Datei (MicrosoftEdgeUpdate), wird als Injection-Host verwendet
CUSTOMINJECTPATH String „%TEMP%\d0eccdb9\MicrosoftEdgeUpdate.exe“, Zielpfad zum Ablegen von CUSTOMINJECT
X64LShellcode

 

Der Shellcode der zweiten Stufe lädt das Hauptmodul aus der Module Table – in diesem Fall den Shellcode ti64. Die Konfigurationsdatei enthält außerdem den Ziel-DLL-Pfad für die nächste Stufe in ihrem Haupt-Header (nicht in der Module Table): %windir%\SysWOW64\rasapi32.dll.

Wie in der vorherigen Stufe „stompt“ HijackLoader auch hier das Modul: Er lädt die Ziel-DLL rasapi32.dll, injiziert den Shellcode der nächsten Stufe in den BaseOfCode des Targets und führt ihn aus.

Der evr.dll-Shellcode übergibt die deobfuskierte Konfigurations-Daten sowie die Module Table als Argumente an die dritte Stufe.

Stufe 3: ti64 module in rasapi32.dll

Der Code dieses Shellcodes ist umfangreich, weil er alle möglichen Einstellungen der Konfiguration und die Module-Table-Einträge abarbeitet, die HijackLoader verwenden kann. Da er den größten Teil des interessanten Codes dieser Loader-Familie enthält, wird er häufig als Hauptmodul von HijackLoader bezeichnet.

Der ti64-Shellcode beginnt damit, Import-Funktionen über API-Hashing aufzulösen. Dieses Mal nutzt er CRC32 als Hash-Algorithmus.

Danach holt er sich den SM-Eintrag aus der Module Table (hier: „mpr.dll“) und speichert ihn als Ziel-DLL für Module Stomping.

Anschließend prüft das Sample NTDLL auf Inline-Hooks und entfernt sie, falls welche gefunden werden.

Falls der Module-Table-Eintrag ANTIVM vorhanden ist, führt er verschiedene Anti-VM-Checks aus. Im vorliegenden Sample gibt es diesen Eintrag jedoch nicht.

Wenn ein bestimmtes Flag in der Konfiguration gesetzt ist, kopiert HijackLoader alle Dateien, die im Module-Table-Eintrag COPYLIST aufgeführt sind, in ein Unterverzeichnis unter %ALLUSERSPROFILE% und startet sich dort neu. Die Konfiguration definiert dieses Unterverzeichnis bei Offset 0x13; in unserem Sample ist das „d0eccdb9“.

Der ti64-Shellcode lädt außerdem die verschlüsselte Payload aus der Konfiguration. Dazu ermittelt er drei Werte: relativer Daten-OffsetKey-Größe und Größe der verschlüsselten Daten.

  • Bei Offset 0xeec (ausgehend von der Module Table) steht der relative Offset zu den verschlüsselten Daten. Dieser Offset ist relativ zum Feld module count bei 0xee4, d. h. der tatsächliche Offset lautet: module table offset + 0xee4 + relative offset
  • Bei Offset module table + 0xca4 steht die Key-Größe in DWORDs.
  • Bei Offset module table + 0xca8 steht die Größe der verschlüsselten Daten.

Die verschlüsselten Daten beginnen mit dem XOR-Key, der die Payload in den verbleibenden Daten entschlüsselt. Unser Tool entschlüsselt und dumpt die Payload als Datei namens PAYLOAD in denselben Ordner wie die Module-Table-Einträge.

Zusammengefasst ist der ti64-Shellcode ein Orchestrator für die meisten Module in der Module Table und verantwortlich für folgende HijackLoader-Funktionen:

  • Erkennung von AV-Produkten und anpassbares Verhalten basierend auf AVDATA-Flags, Prozess-CRC-Hashes und erkannten Produkten

  • Persistenz-Module
  • Anti-VM-Module
  • UAC-Bypass-Module
  • Auswahl einer von sechs Payload-Injection- bzw. Lade-Techniken
  • Anpassbare Injection-Host-Dateien über FIXED und CUSTOMINJECT
  • Interprozess-Kommunikation
  • Erkennung und Entfernung von NTDLL-Hooks
  • Prozess-Injection in ti64 und nach Stufe 3

Process Injection in ti64 und über Stufe 3

HijackLoader implementiert mehrere Methoden, um die Payload in ti64 zu laden und zu injizieren. Verschiedene injection_flag-Bitmasks sowie das Vorhandensein eines Relocation Directory bestimmen, welche Injection-Funktion ausgewählt wird. Es ist nicht möglich, die Bedeutung all dieser Flags anhand dieses Samples allein vollständig zu bestimmen, da einige lediglich aus der Konfiguration gelesen werden.

Außerdem gibt es viel duplizierten Code, und die Teile von ti64, die die passende Injection-Funktion auswählen, sind zwischen dem riesigen Entry-Point und verschiedenen Entscheidungsbäumen in Unterfunktionen verteilt. Das macht es insgesamt schwierig, die exakten Bedingungen zu bestimmen, unter denen HijackLoader welche Injection-Funktion wählt.

Insgesamt fanden wir mindestens sechs unterschiedliche Methoden zum Laden bzw. Injizieren der Payload (ohne minimale Unterschiede ansonsten duplizierter Funktionen mitzuzählen):

  • Zwei Varianten von Process Hollowing
  • Zwei Varianten eines Hybrids aus Process Doppelgänging und Mapped Section Injection
  • Mapped Section Injection
  • Payload ausführen über das ESWR-Modul
  • Payload ausführen über Process Doppelgänging und ESWR-Modul
  • Payload ausführen über das LauncherLdr/LauncherLdr64-Modul

Wir beschreiben nachfolgend zwei repräsentative Techniken (1 und 2).

Beim Process Hollowing kopiert HijackLoader das in CUSTOMINJECT gespeicherte PE-Image an den in CUSTOMINJECTPATHangegebenen Pfad. In diesem Sample lautet der Pfad %TEMP%\d0eccdb9\MicrosoftEdgeUpdate.exe, und die CUSTOMINJECT-Executable ist tatsächlich eine legitime 32-Bit-MicrosoftEdgeUpdate.exe.

Anschließend lädt und startet das ti64-Modul das modCreateProcess64-Modul, um einen suspendierten MicrosoftEdgeUpdate.exe-Prozess zu erstellen. Es injiziert den 32-Bit-Shellcode des rshell-Moduls in die 32-Bit-MicrosoftEdgeUpdate.exe und führt ihn aus. Das injizierte rshell nutzt dann Heaven’s Gate mit einem call-add-retf-Trampolin, um in 64-Bit-Code zu wechseln, und verwendet Module Stomping, um die Payload zu laden.

Der ti64-Shellcode beim Process-Doppelgänging-Hybrid schreibt das saubere PE aus dem Module-Table-Eintrag FIXED auf die Festplatte und nennt es „com_web_filter_v4_0“ (dieser Name ist Teil der Konfiguration außerhalb der Module Table).

In unserem Sample ist FIXED ein sauberes zip.exe, signiert von „VMWare Inc“. Das Modul ti64 nutzt diese saubere Datei als Host für Process Doppelgänging, indem es eine neue .dat-Section zur Datei hinzufügt und das rshell-Modul über transaktionales Schreiben und Rollback-Operationen in diese Section schreibt.

Anschließend führt es Mapped Section Injection aus, um die .dat-Section in den Remote-Prozess von MicrosoftEdgeUpdate.exe zu laden. Dieser Prozess führt wiederum rshell aus, um die Payload über Module Stomping zu laden.

HijackLoaders Interprozess-Kommunikation

HijackLoader verwendet zwei Wege für Interprozess-Kommunikation.

Erstens speichert er verschlüsselte Daten – darunter die Module Table und Injection-Informationen – in temporären Dateien.

Zweitens speichert er Daten in Umgebungsvariablen, einschließlich der Dateinamen der oben genannten temporären Dateien. Die Variablennamen dieser Umgebungsvariablen sind kodiert. Der Generator für die Variablennamen erhält einen Hash, der repräsentiert, wofür die Variable steht. Zuerst erzeugt HijackLoader einen systemspezifischen Seed, indem er den CRC32-Hash des Ergebnisses von GetComputerNameW berechnet. Dann XORt er den Seed mit dem Hash-Wert. Anschließend übergibt er den Wert an srand(). Nachfolgende Aufrufe von rand() erzeugen einen Großbuchstaben-String variabler Länge.

Die Bedeutung einiger dieser Hashes ist in der Tabelle unten aufgeführt und kann für Logging der Interprozess-Kommunikation genutzt werden.

Die Bedeutung einiger dieser Hashes ist in der Tabelle unten aufgeführt und kann für Logging der Interprozess-Kommunikation genutzt werden.

Initial hashMeaning
0xe1abd1c2temporary file name, contains injection information
0xf1e5a323command line string
0xaabbccddinjection flags 1
0xaaeecedbinjection flags 2
0xccbbccddinjection size
0xbbaaccddinjection address
0xaebecedeinjection meta data
0xdabecedeimage base of inject PE
0xa5b5c41a"cmd.exe /start" command line string

 

Lovecraftsche Malware: eine Geduldsprobe

Diese HijackLoader-Analyse ist keineswegs vollständig; wir haben uns auf die Details konzentriert, die für das vorliegende Sample am wichtigsten sind.

In früheren Artikeln über HijackLoader gab es mehrere kleine, aber bemerkenswerte Hinweise auf die Codequalität – und nachdem wir uns selbst durch diesen Code gearbeitet haben, verstehen wir, warum.

Das ti64-Modul ist ein großes Stück Spaghetti-Software in Form von purem Shellcode. Im Decompiler dauert es mehrere Sekunden, durch die lokalen Variablen-Deklarationen der Entry-Point-Funktion zu scrollen – obwohl der Code nicht obfuskiert ist, abgesehen vom Hash-Resolving von APIs, Modulen und Prozessnamen. Das Umbenennen einer einzigen Variablen im Decompiler friert die Anwendung für drei Sekunden ein. Die mehreren Strukturen, die wir erstellt haben, um den Code verständlicher zu machen, haben Größen von 0x100 bis 0x500 Bytes. Diese Strukturen werden in anderen Modulen des Codes wiederverwendet.

Verglichen mit anderen tiefgehenden Analysearbeiten, die wir zuvor durchgeführt haben, ist das keine Erfahrung, die wir sehr bald wiederholen möchten.

Unser nächster Artikel wird die Payload dieses HijackLoader-Samples im Detail beschreiben – ACRStealer.

Sample hashes

[1] FuII Verslon Setup 6419 σρєи Download.zip (sic!), archive with all files 
418a1a6b08456c06f2f4cc9ad49ee7c63e642cce1fa7984ad70fc214602b3b1 

[2] Setup.exe, loads Conduit.Broker.dll  
5d11218f67cfe78347280b0e1a06ade63c890ac78f970f57b0200ff5be8aa77c 

[3] Conduit.Broker.dll, sideloaded DLL with malicious patch 
772fde719a53147 6740db34df6bdb530f4e96acfd9a92e30ec0476fe65f588f5  

[4] Groumcumgag.ic, encrypted stage 2 shellcode 
fed719608185e516c70a1e801b5c568406ef6e1c292e381ba32825c6add93995 

[5] Zootkumbak.uhp, encrypted configuration 
af2ade19542dde58b424618b928e715ebf61dffb6d8ca9d4b299e532dfa3b763 

[6] ACRStealer, payload
59202cb766c3034c308728c2e5770a0d074faa110ea981aa88f570eb402540d2


Wichtige IT-Security-News per E-Mail

  • Aktuelle IT-Gefahren
  • Schutz-Tipps für Privatkunden
  • 15 % Willkommensgutschein