XWorm ist keine neue Schadsoftware, tritt in diesem Fall jedoch mit einer ungewöhnlichen Phishing-Variante auf. Über WhatsApp Web werden speziell auf Tourismusbetriebe zugeschnittene Buchungsbestätigungen versendet, um die Empfänger zum Öffnen einer JavaScript-Datei zu verleiten.
Als Remote-Access-Trojaner (RAT) ermöglicht XWorm den Angreifern einen weitreichenden Zugriff auf infizierte Systeme. Dadurch können unter anderem Passwörter und Zahlungsdaten ausgespäht, Bildschirminhalte aufgezeichnet oder weitere Schadprogramme wie Ransomware installiert werden. Einen allgemeinen Überblick über die Fähigkeiten von XWorm bietet der Beitrag XWorm Malware Analysis von ANY.RUN.
Besonders gefährlich ist XWorm, weil die Schadsoftware als Malware-as-a-Service angeboten wird. Dadurch können auch technisch weniger versierte Angreifer den Trojaner gegen Bezahlung einsetzen. Die Täter können sich somit stärker auf die Auswahl ihrer Opfer und die Optimierung der Verbreitungsmethode konzentrieren – wie auch im vorliegenden Fall.
Attack Summary
Statt einer klassischen Phishing-E-Mail nutzen die Angreifer WhatsApp Web und passen ihre Köder gezielt an Unternehmen aus der Tourismusbranche in Lateinamerika an. In vielen Tourismusbetrieben wird WhatsApp Business als unkomplizierter Kommunikationskanal zwischen Mitarbeitenden und Gästen eingesetzt. Über die Webanwendung geöffnet, können Dokumente und Links jedoch ebenso gefährlich sein wie Anhänge einer Phishing-E-Mail.
Mit der Nachricht „Guten Tag, ich möchte die Reservierung bestätigen. Ich habe die Zahlung getätigt; die Quittung ist im Folgenden beigefügt“ werden die Opfer dazu verleitet, eine vermeintliche Zahlungs- oder Buchungsbestätigung zu öffnen. Der Köder ist dabei gezielt auf den Arbeitsalltag eines Hotels zugeschnitten. Eine möglicherweise übersehene Reservierung erzeugt unmittelbaren Handlungsdruck und erhöht damit die Wahrscheinlichkeit, dass die beigefügte Datei ohne weitere Prüfung geöffnet wird.
Bei der vermeintlichen Quittung handelt es sich aber nicht um ein gewöhnliches PDF-Dokument, sondern um eine JavaScript-Datei. Nach dem Öffnen wird zunächst ein sogenannter Erstloader ausgeführt. Dieser richtet weitere Komponenten auf dem System ein und lädt anschließend den eigentlichen XWorm-Trojaner nach. Die Schadsoftware legt ihre Dateien in einem unauffällig wirkenden, verschachtelten Ordner ab und richtet automatische Programmaufrufe ein, um auch nach einem Neustart des Systems aktiv zu bleiben. Ein sehr ähnlicher Ablauf wurde bereits im Februar 2026 in einem Beitrag von Moises Cerqueira untersucht.
Nach erfolgreicher Infektion stellt der Trojaner regelmäßig eine Verbindung zu einem Command-and-Control-Server, kurz C2-Server, der Angreifer her. Über diese Verbindung können Befehle empfangen und auf dem betroffenen Rechner ausgeführt werden. Auf diese Weise lassen sich weitere Schadprogramme installieren, Buchungsdaten und Gästekontakte auslesen, oder andere Systeme im Netzwerk angreifen.
Die folgenden Kapitel geben einen technischen Einblick in den JavaScript-basierten Erstloader, die nachgeladenen Hilfsprogramme sowie den Remote-Access-Trojaner selbst. Hierfür werden die sichergestellten Komponenten statisch analysiert, ganz ähnlich zu einem im September 2025 veröffentlichten Beitrag.
Analyse des JavaScript-Loaders
Datei: NU_Comprovante_47266772__82173625_72735278_Pdf.js
SHA-256: B8AFB6B8731DB787BAF5CF62EE6CA33D73D186CB8277C505940D35DDD3B60D33
MD5: B3B41B1A1DD2ED3E9047EFA4013D9AF1
Bei dieser Datei handelt es sich um den Erstloader, welcher über WhatsApp empfangen bzw verschickt wurde. Die JavaScript-Datei wurde mit Visual Studio Code statisch analysiert und schrittweise deobfuskiert. (Junk-Funktionen und Base64-Kodierung).
if-Bedingung in kapMb
Wenn das Skript aus Temp oder Downloads gestartet wird, kopiert es sich selbst in den Public-Ordner, startet die Kopie und beendet anschließend die ursprüngliche Instanz. Dadurch wird die Ausführung aus den typischen Downloadverzeichnissen in das öffentliche Benutzerverzeichnis verlagert.

Funktion wZtRoyXEvX()
Diese Funktion baut einen PowerShell-Befehl zusammen. Dabei werden die beiden obfuskierten Base64-Blöcke PoQct und HwdxE zusammengeführt, bereinigt und dekodiert.
Der dekodierte PowerShell-Code wird anschließend in folgender Datei abgelegt:
C:\Users\Public\fprnk.ps1.
Danach wird die Datei ausgeführt.

PowerShell-Code aus PoQct += HwdxE
Der dekodierte PowerShell-Code testet zunächst die Internetverbindung und prüft auf typische Analyse- oder Sandbox-Umgebungen. Dafür wird nach laufenden Prozessen gesucht, die häufig in der Malwareanalyse oder in Sandbox-Umgebungen vorkommen.
Wird eine Analyseumgebung erkannt, löst das Skript einen Neustart aus. Dieses Verhalten kann die dynamische Analyse unterbrechen und die Untersuchung der Malware erschweren.

Nachgelagerte Payload
In der Datei C:\Users\Public\lnzvp.txt wird eine URL abgelegt:
hxxps://andrefelipedon.../ArquivosDeTexto/03[.]txt.
Anschließend wird von dieser URL eine weitere Payload heruntergeladen und in der Datei C:\Users\Public\fcthg.txt gespeichert.
Reflection / Assembly-Loading
Im weiteren Code finden sich Bezeichner und Methodenaufrufe wie Load, Assembly und Invoke, die auf das dynamische Laden einer .NET-Assembly hindeuten.
Zusätzlich findet sich eine weitere URL: hxxps://andrefelipedona.../PeYes.
Die genaue Nutzung dieser konnte bisher nicht vollständig rekonstruiert werden.
PowerShell-Persistenz und Process Hollowing
Pfad: C:\Users[REDACTED]\AppData\LocalLow\Windows Sytem (x86)\Program Rules\Program Rules NVIDEO\Program Rules\Program Rules NVIDEO\
Das Verzeichnis enthält insgesamt 44 PowerShell-Skripte. Davon enthalten fünf Dateien Code zur C2-Kommunikation, zwölf Dateien legen Registry-Einträge an. Die übrigen Skripte dienen hauptsächlich dazu, über PowerShell eines der anderen Skripte aufzurufen.
Stellvertretend für die weiteren Skripte werden im Folgenden drei Dateien genauer betrachtet:
accwx.ps1– PowerShell-Aufrufjodjx.ps1– Anlegen eines Registry-Eintragslbtly.ps1– C2-Kommunikation und Payload-Ausführung
accwx.ps1
Startet über PowerShell das Skript jodjx.ps1.

jodjx.ps1
Legt über New-ItemProperty einen RunOnce-Eintrag an. Dadurch wird lbtly.ps1 bei der nächsten Anmeldung des Benutzers versteckt über PowerShell ausgeführt.

lbtly.ps1 Enthält zwei eingebettete Windows-Executables: dxxAS und litHM. Beide wurden Base64 codiert und als Byte-String in der Datei abgespeichert.

Die dezimalen Bytewerte 77 und 90 entsprechen den ASCII-Zeichen M und Z beziehungsweise der Bytefolge 0x4D 0x5A. Diese bildet die MZ-Signatur am Anfang einer PE-Datei. Die Komponente dxxAS wird direkt aus dem Byte-Array als .NET-Assembly geladen, ohne zuvor als ausführbare Datei auf die Festplatte geschrieben zu werden. Anschließend wird der Pfad zu installutil.exe an den Loader übergeben. Dieser startet die legitime Windows-Binärdatei als Zielprozess und injiziert die in litHM enthaltene Payload mittels Process Hollowing.
Zusammengefasst:
dxxAS= Loader bzw. InjectorlitHM= XWorm-Payloadinstallutil.exe= legitimer Hostprozess für Process Hollowing
Die beiden eingebetteten Komponenten wurden extrahiert, als separate Dateien gespeichert und anschließend mit dnSpyEx analysiert.
lbtly_dxxAS.bin
SHA-256: DA580B4DBE6FD9A90149121595797DD34A6266D0E1DAE92B5DBED7FAFE1E3C89
Aufbau:
Class3.Run()
-> Class2.wMAHY(installutil.exe, litHM_bytes, “”)
-> Class2.Execute(…)
Class3
Run()- Nimmt Parameter entgegen, startetCheck()und ruft anschließendClass2.wMAHYauf, wodurch der Schadprozess gestartet wird.Check()- Implementiert Sandbox-Evasion. Sucht alle drei Sekunden nach Analyse-Tools, löscht bei Bedarf den Ordner und erzwingt einen Neustart.D9AB4194(int)- Überprüft, ob der gestartete Prozess noch aktiv ist.5481E4A7()- Startetlbtly.ps1bei Bedarf neu.6433609D()- Watchdog-Funktion, die mehrere Varianten vonjodjx.ps1startet. Die Skripte werden nur gestartet, wenn die Prüfung keine Hinweise auf laufende Prozesse oder Komponenten von Avast, AVG oder QHActiveDefense ergibt.3BA1AC81(int)- Beendet den angegebenen Prozess.
Class2
Führt Process Hollowing mit installutil.exe durch.
Genauer Ablauf:
- Startet
installutil.exemit angehaltenem Hauptthread - Prüft die Payload auf MZ sowie auf 32-/64-Bit-Kompatibilität.
- Entfernt das Original-Image im Zielprozess über ZwUnmapViewOfSection.
- Reserviert Speicher im Zielprozess mit VirtualAllocEx.
- Schreibt die Payload in den Zielprozess mit WriteProcessMemory.
- Setzt den EntryPoint auf die Payload.
- Startet den Hauptthread wieder mit ResumeThread.
- Gibt die PID an Class3 zurück.
C2-Kommunikation
lbtly_litHM.bin
SHA-256: 4576C76F4B14CC339355789ED0BCE92975288E70C4580F3559ED218642C76A11
Ergebnisse von Detect It Easy (DiE): Malware: XWorm (3.0-5.0) und Packer: Generic [Assembly invoke]
Die Payload wurde anhand ihrer Konfiguration, ihrer C2-Kommandos und der Erkennung durch Detect It Easy der XWorm-Malwarefamilie zugeordnet.
Main()
Es werden Threads zur C2-Kommunikation genutzt. Die Konfigurationswerte sind mit AES im ECB-Modus verschlüsselt. Die Entschlüsselung ist in der Klasse AlgorithmAES implementiert. ClientSocket und Messages verarbeiten die C2-Kommunikation.
Entschlüsselung

Aus Settings.Mutex wird ein MD5-Hash berechnet und zweimal in das 32 Byte große Array array kopiert. Aufgrund der überlappenden Kopiervorgänge wird array[15] zweimal beschrieben, während array[31] unverändert den Wert 0x00 behält. Zu entschlüsselnde Werte aus Settings müssen zuerst noch Base64-dekodiert werden. Daraus ergeben sich folgende C2-Kommunikationsdaten:
Hostsporshe911[.]shop “ki2k5Ddc/7ybrdG0Es2Wdg==”Port1337 “BLA3RVoDqeO8BLMOLHB/8Q==”Key[REDACTED] “e[REDACTED]=”SPLXwormmm “+4k3B+7s0rFHbhtNugXN9g==”GroupSPAM01 “hSsToL6YAfXgCZyFcwViJg==”USBNMUSB.exe “Bstd7UGdFarWK+1gGl+LCw==”
VirusTotal ordnet die Hostnamen ebenfalls der untersuchten JavaScript-Datei zu.
ClientSocket.BeginConnect()
Liest die Host-Adresse aus Settings.Hosts aus und initiiert anschließend die Verbindung zum C2-Server.
Messages.Read(byte[] b)
Verarbeitet eingehende Befehle des C2-Servers. Die empfangenen Daten sind verschlüsselt und werden nach der Entschlüsselung anhand des Separators SPL (Xwormmm) in einzelne Bestandteile aufgeteilt. Anschließend folgt die Auswertung der Befehle über eine Kette von Fallunterscheidungen. Beispiele davon sind:
uninstall- DeinstallationUpdate- Neue PayloadFM- Mitgeschickte Payload im Speicher ausführenPCLogoff- Benutzer abmelden$Cap- Screenshot erstellen und senden
Weitere Dateien
Parallel zu lbtly.ps1 wurden vier weitere Skripte mit nahezu identischer Struktur identifiziert.
Die aus den jeweiligen Skripten extrahierten dxxAS.bin-Komponenten weisen jeweils denselben SHA-256-Hash auf und enthalten damit als Loader den identischen Inhalt.
Im Gegensatz dazu unterscheiden sich die extrahierten litHM.bin-Komponenten zwischen den einzelnen Skripten und weisen jeweils unterschiedliche Hashwerte auf. Eine nähere Untersuchung mit dnSpyEx zeigte insbesondere abweichende Mutexwerte. Die grundsätzliche Struktur sowie die implementierten Funktionen erscheinen jedoch weitgehend identisch.
Die folgende Tabelle gibt einen Überblick über die fünf untersuchten Dateien, die zugehörigen Programmnamen sowie die hinterlegten Domainadressen.
| Skript | Programmname | Domain (Port:1337) |
|---|---|---|
| gpcrr.ps1 | costarica.exe | porshe911[.]shop |
| kadxn.ps1 | costarica.exe | porshe911[.]shop |
| kphwh.ps1 | TESTEE.exe | porshe911[.]shop |
| lbtly.ps1 | SPAM01.exe | porshe911[.]shop |
| xmlad.ps1 | XClient9.exe | porshe911[.]shop / |
| 34.228.244.82 |
Indicators of Compromise
Dateien / Ordner
| NU_Comprovante_47266772__82173625_72735278_Pdf.js | JavaScript-basierter Erstloader |
| (SHA-256) B8AFB6B8731DB787BAF5CF62EE6CA33D73D186CB8277C505940D35DDD3B60D33 | |
| (MD5) B3B41B1A1DD2ED3E9047EFA4013D9AF1 | |
| hotel fazenda.txt | Textdatei mit kontaktierten Rufnummern |
| (SHA-256) CE394D023290A90763BB5CCFA53578527AECC8780292CD0A51E8CE60E7CFE9C1 | |
| (MD5) 7608F302A916AAAC5C633D6A2246C2F5 | |
| ss.txt | Textdatei mit versendeter Nachricht |
| (SHA-256) 2A39BC707184A735F84A9DD7F2A27ADCF7CC5783FEDC205143F4878A8EF28666 | |
| (MD5) B653BDCC36ACD1BAE130FB8C9E66C43F | |
| C:\Users[REDACTED]\AppData\LocalLow\Windows Sytem (x86)\Program Rules\Program Rules NVIDEO\Program Rules\Program Rules NVIDEO\ | Tarnverzeichnis der PowerShell-Komponenten |
| C:\Users\Public\vvksx.js | Kopierte Version des JavaScript-Erstloaders |
| C:\Users\Public\fprnk.ps1 | Dekodierter PowerShell-Code aus dem Erstloader |
| C:\Users\Public\lnzvp.txt | Datei zur Ablage einer nachgelagerten URL |
| C:\Users\Public\fcthg.txt | Datei zur Ablage nachgeladener Payload-Daten |
Registry-Werte
| HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce – Update Drivers NVIDEO_* | Persistenz über RunOnce |
| HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run – Update Drivers NVIDEO_* | Persistenz über Run |
C2- und Download-Infrastrukturen
| hxxps://andrefelipedonascime1775471117328.2082219.meusitehostgator[.]com.br/FVTwhWzaQj_06_04_Meus_ArquivosDeTexto/03[.]txt | Nachgelagerte Payload-/Konfigurationsquelle |
| hxxps://andrefelipedona…/PeYes | Weitere im Code referenzierte URL |
| andrefelipedonascime1775471117328.2082219.meusitehostgator[.]com[.]br | Nachgelagerte Download-/C2-Infrastruktur |
| porshe911[.]shop | C2-Domain | |
| porshe9111[.]shop | C2-Domain aus einer weiteren Payload-Variante | |
| 34.228.244.82 | Zusätzlich genannte C2-Adresse | |
| 1337 | C2-Kommunikationsport | |
| installutil.exe | Hostprozess für Process Hollowing |
