Container
Ein nativer BoxedApp-Wrapper bildet die äußere Verpackung des untersuchten Bestands.
PE-Merkmale, eingebettete Dateien und Wrapper-Artefakte bündeln.
Im Prüfbestand belegtMalware Analysis / Artefakt: BlueLoader bot payload · SHA-256 672320eb064f…
Die Untersuchung verbindet erstmals drei getrennte Schichten desselben Ökosystems: einen nativen BoxedApp-Container, ein DNGuard-geschütztes Management-Panel und einen zweistufigen .NET-Bot mit authentisiertem C2-Protokoll und Process Hollowing.
Kein erfolgreicher C2-Kontakt, keine dynamische Verhaltensmessung und keine Zuordnung zu einer Person oder Betreibergruppe.
BlueLoader war kein einzelner Fund, sondern eine Schichtarbeit: Wrapper, Schutzschicht, Loader und innerer Bot mussten getrennt werden. Erst danach ließ sich sagen, welche Funktion tatsächlich in welchem Artefakt steckt.
672320eb064f6d971e98c7cbfc5bfdd48541a992ccedac9b5550030953587c39Die erste Stufe entschlüsselt und dekomprimiert eine eingebettete Assembly. Sie ist Tarnschicht und Ladeweg, nicht der eigentliche Bot.
Zehn protobuf-Typen, AES-256-CBC und HMAC-SHA256 bilden das statisch rekonstruierte Protokoll. Das gemeinsame Geheimnis bleibt unveröffentlicht.
Persistenz, PowerShell, Download, Bereinigung und Process Hollowing ergeben zusammen den defensiv relevanten Ablauf.
Erklärendes Schema, keine Live-Telemetrie und kein Audit-Score. Die Einordnung und ihre Grenzen stehen im Artikel.
Der Analysepfad dieses Berichts. Jeder Knoten zeigt, was belegt ist, wo Detection ansetzen kann und wo die Aussage endet.
Ein nativer BoxedApp-Wrapper bildet die äußere Verpackung des untersuchten Bestands.
PE-Merkmale, eingebettete Dateien und Wrapper-Artefakte bündeln.
Im Prüfbestand belegtDie Panelassembly ist separat durch DNGuard geschützt; Verpackung und Schutz sind verschiedene Schichten.
Metadatenabweichungen und Laufzeitabhängigkeit markieren.
Im Prüfbestand belegtDer äußere .NET-Loader entschlüsselt und entpackt eine innere Assembly.
Ressourcenzugriff, Entschlüsselung und Assembly-Laden korrelieren.
Im Prüfbestand belegtBot und Panel teilen eine statisch rekonstruierte, authentisierte Nachrichtenstruktur.
Framing, Kryptomuster und wiederkehrende Verbindungen verbinden.
Im Prüfbestand belegtPersistenz, PowerShell und Prozessmanipulation ergeben erst als Kette ein belastbares Hostsignal.
Task-, Prozess-, Datei- und Netzwerkereignisse zeitlich verbinden.
Im Prüfbestand belegtAnalyseachsen aus dem Bericht – keine Live-Konfiguration und kein universeller Familienindikator.
Quelle, Validierung und Grenze gehören zu jeder Regel.
import "hash"
rule TW_BlueLoader_Exact_Samples_2026_10
{
meta:
description = "Exact BlueLoader artifacts from static review"
author = "TW Research"
date = "2026-10-17"
confidence = "high / exact hash only"
condition:
filesize < 5MB and (
hash.sha256(0, filesize) == "672320eb064f6d971e98c7cbfc5bfdd48541a992ccedac9b5550030953587c39" or
hash.sha256(0, filesize) == "c706546279ba2781d349bdf8512651e0ec1e82e3172a1a700dd991d1d562b77f" or
hash.sha256(0, filesize) == "46e5ca3417006841884c4cca9d76a6fd03772ec54f4692079df9af8319a1505c"
)
}title: BlueLoader-Like LocalAppData Installation Trace
id: 4262753e-797b-46d0-96df-a84521dbf3f2
status: experimental
description: Detects the reviewed directory and filename components together
author: TW Research
date: 2026-10-17
logsource:
category: file_event
product: windows
detection:
selection_path:
TargetFilename|contains: '\\RegisteredHandlers\\'
selection_name:
TargetFilename|endswith:
- '\\Current'
- '\\Current.exe'
condition: selection_path and selection_name
falsepositives:
- Legitimate software using the same generic components
level: medium
tags:
- attack.persistence
- attack.t1053.005alert tcp $HOME_NET any -> 82.102.27.163 [45050,45080] (
msg:"TW BlueLoader configured destination / review 2026-10-17";
flow:to_server;
classtype:trojan-activity;
sid:99001701; rev:1;
metadata:created_at 2026_10_17, confidence High, deployment Perimeter;
)let NetworkSignal = DeviceNetworkEvents
| where RemoteIP == "82.102.27.163"
| where RemotePort in (45050, 45080)
| project DeviceId, DeviceName, NetTime=Timestamp, RemoteIP, RemotePort;
let HostSignal = DeviceFileEvents
| where FolderPath contains @"\RegisteredHandlers\"
| where FileName in~ ("Current", "Current.exe")
| project DeviceId, HostTime=Timestamp, FolderPath, FileName;
NetworkSignal
| join kind=inner HostSignal on DeviceId
| where abs(datetime_diff('minute', NetTime, HostTime)) <= 15
| project NetTime, HostTime, DeviceName, RemoteIP, RemotePort, FolderPath, FileName
| order by NetTime descDie Analyse ergibt kein einzelnes „entpacktes Sample“, sondern eine belastbare Architektur aus getrennt untersuchten Komponenten.
01 · Panelcontainer. Produktspezifische BoxedApp-Symbole und die Ressourcenstruktur belegen die native Verpackung; Wrappercode und BlueLoader-Anwendungslogik wurden konsequent getrennt.
02 · Geschütztes Panel. Ein vorhandener isolierter Minidump ermöglichte die Offline-Rekonstruktion der geladenen BlueLoader.dll, zweier DNGuard-Laufzeitmodule und streng zugeordneter nativer JIT-Körper.
03 · Bot-Loader. Der separate 460-KB-.NET-Loader entschlüsselt eine eingebettete Stufe mit TripleDES-CBC, entfernt ein vier Byte breites Längenfeld, dekomprimiert GZip und lädt das Ergebnis ausschließlich aus dem Speicher.
04 · Technische Verbindung. Bot und Panel implementieren dieselben zehn protobuf-Nachrichtentypen mit übereinstimmenden Tags, Feldnummern und normalisierten Typen. Diese Protokollparität ist der stärkste technische Zusammenhang im Korpus.
05 · Wirkung. Der Bot kombiniert Scheduled-Task-Persistenz, verschlüsselte C2-Kommunikation, PowerShell, Download-and-Execute, Process Hollowing sowie Bereinigungs- und Selbstentfernungsroutinen.
Der Prüfbestand hat zwei getrennte Einstiege. Der Bot-Zweig beginnt mit einem 460 Kilobyte großen .NET-Loader und führt über TripleDES und GZip zur inneren Assembly. Der Panel-Zweig beginnt mit einem 98.218.496 Byte großen nativen PE64-Container, dessen BoxedApp-Wrapper statisch identifiziert wurde; die darin laufende Panelassembly ist zusätzlich mit DNGuard geschützt.
Der Bericht dokumentiert deshalb drei Beweisschichten: Containeridentifikation, begrenzte DNGuard-Rekonstruktion aus einem vorhandenen isolierten Speicherabbild und statische Bot-Deobfuskation. Erst der danach durchgeführte Protokollvergleich verbindet Bot und Panel technisch. Originalsamples und Geheimnisse bleiben außerhalb der Website.
b366867eb2a36257eb9e5b372f5cc8078b92e2a50388af90bd2fcd6a30628bcbDekompilierte Transportklasse der inneren Assembly
8d1200016033d40ea3aa4469533aa30c322a424f8d488655cb2b46019a161962Lesbare statische Rekonstruktion des Transportprofils
85a21ee7a1bfc216b18f97086079f950bbac9147c44f5c41b107fbf526561511Statisches Werkzeug für den Bot-/Panel-Schemavergleich
ae4cc6f3c530c3d5f90f3b358e979b11e7f45d94b1fa690d9ad172d515252ef3Dekompilierter TripleDES-Entschlüsselungspfad des äußeren Loaders
8497d74f9c84cfc15b3ef144f207f2532229abcaea4105d9a7d2a12458c04f6fDekompilierte Längenprüfung und GZip-Dekompression
808cd9d2e80e6250da691320c3f9e1db549a7823a4dad1aca0e45d198b536b59Aufrufkette von Entschlüsselung über Dekompression bis Assembly.Load
fd519190b4797d680a8564f2e339940a27e21cbc5035be06c9ee4f8c1433b965Statische Identifikation und Abgrenzung des BoxedApp-Wrappers
ffbe0ea270a76cbede69b586fc328d4b99b3a7f4d77db6515c8d04929a8b052cOffline-Rekonstruktion der DNGuard-geschützten Panelassembly aus dem Minidump
1698c4130405e9a55c6c6e97afd50501542041cd6ccd84faa3ddae5b54d33727Tokenweiser Vollständigkeits- und Grenznachweis der Panelrekonstruktion
Zscaler ThreatLabz beschrieb 2022 PureCrypter als mehrstufigen .NET-Loader mit Obfuskation, Kompression, Verschlüsselung, protobuf-basierter Konfiguration, Persistenz und Prozessinjektion. Diese Veröffentlichung liefert einen sinnvollen strukturellen Vergleich für den Loader-Teil unseres Korpus.
Der hier untersuchte Bestand geht jedoch in eine andere Richtung und erweitert den Blick erheblich: Zusätzlich zum Bot-Loader liegen ein eigenständiger nativer BoxedApp-Container, ein DNGuard-geschütztes Management-Panel, wiedergewonnene Panel-Metadaten, native JIT-Evidenz und ein feldgenauer Bot-/Panel-Protokollvergleich vor. Daraus folgt keine Gleichsetzung mit PureCrypter und keine Aussage über gemeinsame Entwickler. Der Vergleich betrifft Architekturmerkmale; die Familienzuordnung beruht ausschließlich auf dem eigenen Belegbestand.
Der 98-MB-Panelcontainer ist kein direkt dekompilierbares .NET-Programm: Das äußere AMD64-PE besitzt kein CLR-Verzeichnis. Die Zuordnung zu BoxedApp stützt sich stattdessen auf mehrere voneinander unabhängige Merkmale – zahlreiche BoxedAppSDK-Symbole, den PackerStubEntryPoint, eingebettete Hersteller-Buildpfade und die ungewöhnlich große Ressource 10/15/0.
01 · Wrapper von Nutzlast trennen. Wrapper-APIs und Hilfsdateien wurden nicht automatisch dem BlueLoader-Code zugerechnet. Vier gültige PE-Hilfsdateien erwiesen sich als bytegleich mit bekannten Wrapperkomponenten; die .NET-Hilfsdatei enthielt keinen Anwendungscode.
02 · Carving-Hypothesen testen. MZ/PE-, BSJB-, Archiv-, GZip-, zlib- und kurze periodische XOR-/Additionssuchen lieferten keine belastbare eingebettete Assembly. Das Fehlschlagen dieser begrenzten Heuristiken wurde als Negativbefund dokumentiert, nicht als Beweis für einen bestimmten Verschlüsselungsalgorithmus.
03 · Werkzeug passend auswählen. Ein öffentliches Unboxing-Werkzeug erwartete eine .bxpck-Sektion, die im Sample fehlt, und hätte die Eingabe überschrieben. Es wurde deshalb nicht auf das Original angewandt. Der BoxedApp-Befund identifiziert somit zuverlässig die Verpackung, behauptet aber keinen universellen statischen Unpackerfolg.
SHA-256 fd519190b4797d680a8564f2e339940a27e21cbc5035be06c9ee4f8c1433b965Zahlreiche `BoxedAppSDK_*`-Symbole, insbesondere `BoxedAppSDK_PackerStubEntryPoint`, und eingebettete BoxedApp-Buildpfade belegen einen BoxedApp-bezogenen Wrapper. Die eingebetteten Buildpfade sind Hersteller-/Buildinformationen, keine beobachteten Dateien auf diesem Rechner.
PE-Sektionen: `.text`, `.rdata`, `.data`, `.pdata`, `.Lmc`, `.rsrc`.
Die Ressource `10/15/0` umfasst 91.035.348 Bytes. Ihr Inhalt wurde nicht entpackt oder ausgeführt. Weitere Ressourcen enthalten Icon-, Versions- und Manifestdaten. Der geprüfte Standard-Signaturwert eines .NET-Single-File-Bundles wurde nicht gefunden.
Originalzeilen der Quelldatei. Erklärung wählen, um den Bereich zu markieren.
Die DNGuard-Schicht wurde nicht durch einen einzigen „Deobfuscate“-Schalter entfernt. Grundlage war ein bereits vorhandener vollständiger Minidump aus einer isolierten Windows-VM ohne aktive Netzwerkadapter. Alle folgenden Schritte lasen ausschließlich dieses Abbild; keine extrahierte PE-Datei und kein Einstiegspunkt wurde erneut ausgeführt.
01 · Geladene Module binden. BlueLoader.dll, DNRuntime.dll und DNGuard.Runtime.dll wurden über Speicheradressen, CLR-Modulzuordnung und SHA-256 getrennt inventarisiert. Beim geladenen Hauptmodul waren CLI- und Metadatenköpfe gelöscht; intakte Zweitkopien im selben Dump ermöglichten die Reparatur der Metadatenstreams.
02 · JIT-Körper streng zuordnen. Ein nativer Körper wurde nur übernommen, wenn Declaring Module, ClrMD-Signatur, gültiger MethodDef-Token, positiver JIT-Hot-Bereich und Eindeutigkeit zusammenpassten. So wurden Token-Kollisionen mit Framework- und DevExpress-Methoden ausgeschlossen.
03 · Rekonstruktion von Projektion trennen. Die Endinventur zählt 3.400 geschützte MethodDefs, 998 lokal abgegrenzte native Körper und 742 integrierte Analysekörper. Von diesen 742 sind 346 laufzeitabgeleitet und 396 ausdrücklich semantische Projektionen – keine Behauptung, das ursprüngliche CIL oder C# vollständig zurückgewonnen zu haben.
04 · Lücken quantifizieren. 498 abgegrenzte native Körper liegen außerhalb der Analyse-DLL. Nur zwei sind lokal und transitiv vollständig, beide ohne nutzbaren zusätzlichen Produktbefund. Die übrigen 496 benötigen weitere Zielattribution oder Callgraph-Abdeckung. Genau diese Grenze verhindert, Teilrekonstruktionen als vollständigen DNGuard-Unpack auszugeben.
SHA-256 ffbe0ea270a76cbede69b586fc328d4b99b3a7f4d77db6515c8d04929a8b052c`BlueLoader.dll` war als DNGuard-geschütztes, gemapptes Image bei
`0x32370000` geladen. Der gemappte CLI-Header war gelöscht; eine intakte
Zweitkopie lag bei `0x32370208`. Der ebenfalls gelöschte Metadatenkopf ließ
sich aus der intakten CLR-Kopie bei `0x14c78f3c` wiederherstellen. Danach
lesen `dnfile` und ILSpy alle fünf Metadatenstreams.
Originalzeilen der Quelldatei. Erklärung wählen, um den Bereich zu markieren.
Die Entschlüsselung wurde nicht erraten und der Loader nicht ausgeführt. Ausgangspunkt war die statische Aufrufkette in Qhtid.cs: Der mit „Decrypt“ markierte Schritt übergibt drei Bytefelder an ProcRunner.ExecuteConfigurableProc; dessen Ergebnis fließt unmittelbar in den mit „Decompress“ markierten Schritt und anschließend in Assembly.Load(byte[]).
01 · Primitive bestimmen. ProcRunner.cs instanziiert TripleDESCryptoServiceProvider. Die numerischen .NET-Enumwerte Mode = 1 und Padding = 2 entsprechen CBC und PKCS#7. Vor der Entschlüsselung werden außerdem 24 Byte für den Schlüssel und 8 Byte für den IV verlangt.
02 · Datenfluss verfolgen. Der eingebettete Bytepuffer wird in einen CryptoStream mit CreateDecryptor() geschrieben; erst FlushFinalBlock() materialisiert den entschlüsselten Puffer. Entscheidend war nicht ein einzelner String, sondern dass Eingabe, Schlüssel, IV und Ergebnis über denselben Callgraph verbunden sind.
03 · Containerformat bestätigen. OperationalTracker.cs liest die ersten vier Byte als Little-Endian-Int32, beginnt den MemoryStream bei Offset 4 und führt den Rest einem GZipStream zu. Die erwartete Ausgabelänge wird gegen das Präfix geprüft. Damit ist das vermeintliche Präfix funktional belegt, nicht nur anhand einer Magic-Byte-Suche vermutet.
04 · Zielstufe verifizieren. Der dekomprimierte Puffer wird ohne Dateischreibvorgang an Assembly.Load(byte[]) übergeben. Diese Senke bestätigt, dass die Ausgabe als verwaltete .NET-Assembly gedacht ist.
05 · Reproduzierbarkeit sichern. Jede Belegdatei ist im Manifest mit SHA-256 gebunden; Zeilenbereiche und Übergaben wurden getrennt gegengeprüft. Das Ergebnis ist eine statische Rekonstruktion. Es belegt die implementierte Entpackkette, aber keine erfolgreiche Ausführung auf einem Opfergerät.
SHA-256 8497d74f9c84cfc15b3ef144f207f2532229abcaea4105d9a7d2a12458c04f6f using (MemoryStream memoryStream = new MemoryStream(task, mean_visitor, task.Length - mean_visitor))
{
GZipStream gzipStream = new GZipStream(memoryStream, 0);
try
{
using (MemoryStream memoryStream2 = new MemoryStream((num2 <= 0) ? 0 : num2))
{
gzipStream.CopyTo(memoryStream2);
byte[] array = memoryStream2.ToArray();
if (array.Length != num2)
{
throw new InvalidDataException();
}
return array;
Originalzeilen der Quelldatei. Erklärung wählen, um den Bereich zu markieren.
Die Analyse arbeitet mit drei Evidenzklassen: unveränderten Quellartefakten, reproduzierbaren Analysewerkzeugen und explizit gekennzeichneten semantischen Projektionen. Die Karte bildet nicht nur Dateibeziehungen ab, sondern zeigt, an welcher Stelle eine Aussage von beobachteten Bytes zu einer analytischen Ableitung wechselt. Laufzeitbeleg, statischer Befund und Rekonstruktion bleiben dadurch voneinander unterscheidbar.
Umschaltbare Karte mit Hash-gebundenen Quellen und belegten Ableitungen.
Eine Dateireferenz belegt kein Laufzeitverhalten. Dokumentierte Aufbereitung ist keine erneute Ausführung.
Transportklasse, lesbare Projektion und Panelvergleich bilden getrennte Belegschichten.
Dekompilierte Transportlogik mit obfuskierten Bezeichnern.
Algorithmen, Größen und Layout wurden aus den dekompilierten Pfaden abgeleitet.
Lesbare Zusammenfassung der Kryptografie und Paketstruktur.
Algorithmen, Größen und Layout wurden aus den dekompilierten Pfaden abgeleitet.
Feldnummern und normalisierte Feldtypen stimmen für Tags 1 bis 10 überein.
Zehn strukturell passende protobuf-Nachrichtentypen.
Feldnummern und normalisierte Feldtypen stimmen für Tags 1 bis 10 überein.
Von dekompilierten Quellen über Schemaextraktion zur geheimnisfreien Projektion.
Statische C#-Ansichten von Bot und Panel.
Das Werkzeug verarbeitet gespeicherte C#-Dateien, nicht die Binärsamples.
Liest dekompilierte Quellen und normalisiert protobuf-Signaturen.
Das Werkzeug verarbeitet gespeicherte C#-Dateien, nicht die Binärsamples.
Namen werden von Feldnummern und normalisierten Typen getrennt.
Statisch belegte Projektion ohne Shared Secret.
Namen werden von Feldnummern und normalisierten Typen getrennt.
Projektion, Protokollbericht und Hashmanifest wurden statisch abgeglichen.
Befunde mit Grenzen und nicht anklickbaren IOCs.
Projektion, Protokollbericht und Hashmanifest wurden statisch abgeglichen.
Grenze: Die Karte dokumentiert Dateien und Ableitungen; sie ist keine Live-Telemetrie.
Die innere Bot-Assembly umfasst 1.923 Typen und 9.748 Methoden; 6.189 Methoden besitzen einen lesbaren IL-Körper. Der Bereinigungslauf ersetzte 990 verifizierte Stringresolver-Aufrufe und führte 9.514 Delegate-Proxys auf direkte Ziele zurück. Vier zunächst verdächtige Ausdrücke erwiesen sich nach vollständigem Expression-Scan als Aufrufe eines Zufallsnamengenerators – ein wichtiger Negativbefund, weil dort keine fehlenden Klartexte behauptet werden dürfen.
Die Protokollrekonstruktion wurde anschließend unabhängig vom Kontrollfluss durchgeführt. Das Analysewerkzeug extrahiert ProtoInclude-Beziehungen aus den dekompilierten Quellen, normalisiert die Signaturen und verwirft das Ergebnis, wenn die erwartete Tag-Menge 1 bis 10 nicht vollständig vorliegt.
SHA-256 85a21ee7a1bfc216b18f97086079f950bbac9147c44f5c41b107fbf526561511def read_sources(root: Path) -> list[tuple[Path, str]]:
return [(p, p.read_text(encoding="utf-8-sig", errors="replace")) for p in root.rglob("*.cs")]
def class_region(sources: list[tuple[Path, str]], class_name: str) -> tuple[Path, str]:
pattern = re.compile(r"\bclass\s+" + re.escape(class_name) + r"\b")
for path, text in sources:
match = pattern.search(text)
if not match:
continue
start = match.start()
next_namespace = text.find("\nnamespace ", match.end())
end = len(text) if next_namespace < 0 else next_namespace
return path, text[start:end]
raise KeyError(f"class not found: {class_name}")
def include_map(sources: list[tuple[Path, str]], base_class: str) -> tuple[Path, dict[int, str]]:
path, region = class_region(sources, base_class)
# Attributes are before the class declaration, so collect a bounded prefix.
text = path.read_text(encoding="utf-8-sig", errors="replace")
class_pos = re.search(r"\bclass\s+" + re.escape(base_class) + r"\b", text).start()
prefix = text[max(0, class_pos - 2500) : class_pos]
pairs = re.findall(r"\[ProtoInclude\((\d+),\s*typeof\(([^)]+)\)\)\]", prefix)
mapping = {int(tag): name.strip() for tag, name in pairs}
if set(mapping) != set(range(1, 11)):
raise ValueError(f"{base_class}: expected tags 1..10, found {sorted(mapping)}")
return path, mapping
Originalzeilen der Quelldatei. Erklärung wählen, um den Bereich zu markieren.
Die Obfuskation zerstört Semantik in Bezeichnern, nicht jedoch die beobachtbare Kryptografie. Im dekompilierten Transportpfad bleiben AES-Schlüsselgröße, CBC-Modus, PKCS#7-Padding, zufälliger IV und HMAC-Berechnung direkt sichtbar. Die Gegenüberstellung reduziert diesen Pfad auf prüfbare Protokolleigenschaften und kennzeichnet rekonstruierte Namen ausdrücklich als Analystenlabels. Das gemeinsame Geheimnis wird weder angezeigt noch in ableitbarer Form veröffentlicht.
Quellartefakt · Hash der vollständigen Datei, nicht des Ausschnitts
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider())
{
aesCryptoServiceProvider.KeySize = 256;
aesCryptoServiceProvider.BlockSize = 128;
aesCryptoServiceProvider.Mode = CipherMode.CBC;
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
aesCryptoServiceProvider.Key = this.U260suBvbl;
aesCryptoServiceProvider.GenerateIV();
for (;;)
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aesCryptoServiceProvider.CreateEncryptor(), CryptoStreamMode.Write))
{
memoryStream.Write(aesCryptoServiceProvider.IV, 0, aesCryptoServiceProvider.IV.Length);
cryptoStream.Write(\u0020, 0, \u0020.Length);
cryptoStream.FlushFinalBlock();
using (HMACSHA256 hmacsha = new HMACSHA256(this.BDg0C5xXGU))
{
byte[] array = hmacsha.ComputeHash(memoryStream.ToArray(), 32, memoryStream.ToArray().Length - 32);
memoryStream.Position = 0L;
memoryStream.Write(array, 0, array.Length);public static class TransportProfile
{
public const string Framing = "4-byte little-endian encrypted-payload length";
public const string Serialization = "protobuf-net base message with ProtoInclude tags 1..10";
public const string Encryption = "AES-256-CBC with PKCS#7 padding and a random 16-byte IV";
public const string Authentication = "HMAC-SHA256 over IV || ciphertext";
public const string WireLayout = "32-byte HMAC || 16-byte IV || ciphertext";
public const string KeyDerivation = "PBKDF2/Rfc2898DeriveBytes, 5,000 iterations";Textansicht · keine Ausführung · Original bleibt unverändert
AES-Schlüsselgröße, CBC-Modus, PKCS#7 und zufälliger IV sind direkt sichtbar.
Der Stream reserviert 32 Byte, schreibt den IV und setzt danach den HMAC an den Anfang.
Die Projektion dokumentiert Verhalten, stellt aber keine Laufzeitmessung dar.
Grenze: Das Shared Secret wird weder angezeigt noch in ableitbarer Form veröffentlicht.
Jede Nachricht wird als protobuf-Objekt serialisiert und anschließend mit AES-256-CBC sowie PKCS#7-Padding verschlüsselt. Ein zufälliger 16-Byte-IV steht vor dem Ciphertext; HMAC-SHA256 authentisiert IV und Ciphertext gemeinsam. Das resultierende Paket beginnt mit dem 32-Byte-HMAC, gefolgt von IV und Ciphertext. Ein vier Byte breites Little-Endian-Längenfeld rahmt die Übertragung auf dem TCP-Stream.
Diese Kombination liefert Vertraulichkeit und Integrität innerhalb des proprietären Protokolls. Sie verschleiert jedoch weder Zieladresse noch Verbindungsmetadaten und verhindert keine hostbasierte Erkennung. Die dargestellte Struktur ist ein defensives Protokollmodell, kein einsatzfähiger Client.
SHA-256 8d1200016033d40ea3aa4469533aa30c322a424f8d488655cb2b46019a161962public static class TransportProfile
{
public const string Framing = "4-byte little-endian encrypted-payload length";
public const string Serialization = "protobuf-net base message with ProtoInclude tags 1..10";
public const string Encryption = "AES-256-CBC with PKCS#7 padding and a random 16-byte IV";
public const string Authentication = "HMAC-SHA256 over IV || ciphertext";
public const string WireLayout = "32-byte HMAC || 16-byte IV || ciphertext";
public const string KeyDerivation = "PBKDF2/Rfc2898DeriveBytes, 5,000 iterations";
Originalzeilen der Quelldatei. Erklärung wählen, um den Bereich zu markieren.
Nach der Registrierung kann die zweite Stufe eine Installation unter Local Application Data anlegen und über einen geplanten Task persistieren. Das Tasking-Modell deckt Dateiübertragung, Ausführung von Datenträger oder Speicher, PowerShell, Statusbestätigung, Bereinigung und vollständige Deinstallation ab.
Der In-Memory-Pfad implementiert getrennte 32- und 64-Bit-Helfer für Process Hollowing: Zielprozess angehalten erzeugen, Abbildbereiche vorbereiten, Remote-Speicher reservieren und beschreiben, Thread-Kontext anpassen und den Hauptthread fortsetzen. Auf Windows-Builds ab 26100 kommt ein zusätzlicher Kompatibilitäts- oder Bypasszweig hinzu, der Funktionen innerhalb der ntdll des Zielprozesses verändert.
Für Verteidiger ist diese Sequenz belastbarer als jeder Einzelindikator: neuer Scheduled Task, RegisteredHandlers/Current, PowerShell, Remote-Memory-Write, Context-Set und ResumeThread auf demselben Host.
SHA-256 0c9a01896488877b5933af083ca80aefec385e50c58ef66c524fcf4de213f131 public static IReadOnlyList<BehaviorFinding> Findings { get; } = new[]
{
new BehaviorFinding("BL-001", "Two-stage loader", "Outer decrypts and decompresses a managed inner assembly.", "Exact/static", "T1027,T1140"),
new BehaviorFinding("BL-002", "Custom TCP C2", "protobuf messages are protected with AES-CBC and HMAC-SHA256 and framed with a little-endian length.", "Static", "T1095"),
new BehaviorFinding("BL-003", "Scheduled task persistence", "The install path creates and removes a configured scheduled task.", "Static", "T1053.005"),
new BehaviorFinding("BL-004", "Download and execute", "Tag 4 selects disk, PowerShell or in-memory handling.", "Static", "T1105,T1059.001"),
new BehaviorFinding("BL-005", "Process hollowing", "Separate 32-bit and 64-bit helpers replace a suspended process image.", "Static", "T1055.012"),
new BehaviorFinding("BL-006", "Aggressive cleanup", "The cleanup path can terminate processes and delete startup material.", "Static", "T1070.004"),
new BehaviorFinding("BL-007", "Host inventory", "Registration includes HWID, OS, user, AV, privilege, bitness, process and GPU data.", "Static", "T1082,T1518.001"),
new BehaviorFinding("BL-008", "Windows 26100 compatibility patch", "The hollowing path patches functions inside target-process ntdll on newer builds.", "Static", "T1055.012")
};
Originalzeilen der Quelldatei. Erklärung wählen, um den Bereich zu markieren.
Die Filter trennen Dateihashes, konfigurierte Serverwerte und lokale Artefakte. Ein konfiguriertes Ziel ist kein Beleg für erfolgreichen Kontakt oder aktuelle Kontrolle.
Fünf statisch belegte Indikatoren mit Fundkontext und Aussagegrenze.
672320eb064f6d971e98c7cbfc5bfdd48541a992ccedac9b5550030953587c3946e5ca3417006841884c4cca9d76a6fd03772ec54f4692079df9af8319a1505c82[.]102[.]27[.]163TCP 45080 / 45050LocalAppData / RegisteredHandlers / CurrentKeine Indikatoren in dieser Kategorie.
Die robuste Basisregel arbeitet ausschließlich mit den drei im Prüfbestand bestätigten SHA-256-Werten. Sie ist hochpräzise, erkennt aber keine neu kompilierten oder veränderten Varianten. Der Größenfilter begrenzt unnötige Hashberechnung; die Regel enthält weder Samplebytes noch Rekonstruktionslogik.
import "hash"
rule TW_BlueLoader_Exact_Samples_2026_10
{
meta:
description = "Exact BlueLoader artifacts from static review"
author = "TW Research"
date = "2026-10-17"
confidence = "high / exact hash only"
condition:
filesize < 5MB and (
hash.sha256(0, filesize) == "672320eb064f6d971e98c7cbfc5bfdd48541a992ccedac9b5550030953587c39" or
hash.sha256(0, filesize) == "c706546279ba2781d349bdf8512651e0ec1e82e3172a1a700dd991d1d562b77f" or
hash.sha256(0, filesize) == "46e5ca3417006841884c4cca9d76a6fd03772ec54f4692079df9af8319a1505c"
)
}
Zeilennummern gelten für diesen Ausschnitt. Erklärung wählen, um den Bereich zu markieren.
Die Sigma-Regel modelliert eine enge Dateisystemspur: die Kombination aus dem rekonstruierten Verzeichnisbestandteil RegisteredHandlers und dem Namensbestandteil Current. Sie setzt File-Event-Telemetrie voraus und ist als Hunting-Regel gedacht. Umgebungen sollten bekannte legitime Treffer zuerst als Filter ergänzen.
title: BlueLoader-Like LocalAppData Installation Trace
id: 4262753e-797b-46d0-96df-a84521dbf3f2
status: experimental
description: Detects the reviewed directory and filename components together
author: TW Research
date: 2026-10-17
logsource:
category: file_event
product: windows
detection:
selection_path:
TargetFilename|contains: '\\RegisteredHandlers\\'
selection_name:
TargetFilename|endswith:
- '\\Current'
- '\\Current.exe'
condition: selection_path and selection_name
falsepositives:
- Legitimate software using the same generic components
level: medium
tags:
- attack.persistence
- attack.t1053.005
Zeilennummern gelten für diesen Ausschnitt. Erklärung wählen, um den Bereich zu markieren.
Diese Netzwerkregel ist bewusst schmal und zeitgebunden. Sie alarmiert nur auf ausgehende TCP-Verbindungen zur im Sample konfigurierten Adresse über einen der beiden Ports. Vor Einsatz müssen Reputation, aktueller Besitz der Adresse und lokale Allowlist geprüft werden. Ein Treffer belegt Kontaktversuch, nicht erfolgreiche C2-Kommunikation.
alert tcp $HOME_NET any -> 82.102.27.163 [45050,45080] (
msg:"TW BlueLoader configured destination / review 2026-10-17";
flow:to_server;
classtype:trojan-activity;
sid:99001701; rev:1;
metadata:created_at 2026_10_17, confidence High, deployment Perimeter;
)
Zeilennummern gelten für diesen Ausschnitt. Erklärung wählen, um den Bereich zu markieren.
Die Hunting-Abfrage kombiniert den stärkeren Ansatz: Verbindungen zum konfigurierten Ziel müssen innerhalb von 15 Minuten mit der lokalen Pfadspur auf demselben Gerät zusammenfallen. Sie ist für Microsoft Defender XDR formuliert und muss an die tatsächlich verfügbaren Tabellen sowie Datenaufbewahrung angepasst werden.
let NetworkSignal = DeviceNetworkEvents
| where RemoteIP == "82.102.27.163"
| where RemotePort in (45050, 45080)
| project DeviceId, DeviceName, NetTime=Timestamp, RemoteIP, RemotePort;
let HostSignal = DeviceFileEvents
| where FolderPath contains @"\RegisteredHandlers\"
| where FileName in~ ("Current", "Current.exe")
| project DeviceId, HostTime=Timestamp, FolderPath, FileName;
NetworkSignal
| join kind=inner HostSignal on DeviceId
| where abs(datetime_diff('minute', NetTime, HostTime)) <= 15
| project NetTime, HostTime, DeviceName, RemoteIP, RemotePort, FolderPath, FileName
| order by NetTime desc
Zeilennummern gelten für diesen Ausschnitt. Erklärung wählen, um den Bereich zu markieren.
Der unabhängige Panel-Bestand enthält strukturelle Gegenstücke zu sämtlichen zehn protobuf-Nachrichtentypen des Bots. Der Vergleich erfolgte nicht anhand von Klassennamen, sondern über ProtoInclude-Tags, Feldnummern, normalisierte Feldtypen und die jeweiligen Verwendungsstellen. Abgedeckt sind Konfiguration, Registrierung, Taskzustellung, Bestätigung, Heartbeat, Bereinigung und Deinstallation.
Diese 10-von-10-Parität ist stärker als eine gemeinsame Zeichenkette oder ein ähnliches UI: Sie zeigt, dass beide Komponenten denselben Nachrichtenvertrag implementieren. Das Panel ergänzt außerdem Lizenz- und Updatepfade sowie einen lokalen Scanner für Reverse-Engineering-Werkzeuge. Belegt ist damit ein lokaler Anti-Analyse-Pfad; nicht belegt sind eine automatische serverseitige Sperre, Betreiberidentität oder bytegleiche Build-Provenienz.
Wir bewerten den Bot als BlueLoader-kompatibel mit hoher technischer Konfidenz. Grundlage sind zehn übereinstimmende Nachrichtenverträge, korrespondierende Kontrollflüsse und die funktionale Ergänzung zwischen Client und Panel. Diese Aussage ordnet Softwarekomponenten ein – keine Personen.
Nicht belastbar sind Rückschlüsse auf Entwickler, Käufer, Betreiber oder Infrastrukturinhaber. Ebenso wird der Konfigurationswert 12.09.2025 nur als eingebettetes Label behandelt; ohne unabhängige Zeitquelle ist er weder Build-Datum noch Kampagnenbeginn.
Der untersuchte Bestand zeigt ein vollständigeres BlueLoader-Ökosystem als eine reine Loaderanalyse: ein nativ verpacktes Management-Panel, eine DNGuard-geschützte .NET-Anwendung und einen getrennten zweistufigen Remote-Control-Bot. BoxedApp erschwert den direkten Zugriff auf das Panel, DNGuard verschiebt wesentliche Logik in laufzeitabhängige native Körper, und der Bot schützt sein proprietäres protobuf-Protokoll mit AES-CBC und HMAC.
Trotz dieser Schichten bleiben belastbare Erkennungspunkte bestehen. Die höchste Signalqualität entsteht aus korreliertem Host- und Netzwerkverhalten: Installation unter Local Application Data, geplanter Task, wiederkehrende TCP-Verbindungen zu einem konfigurierten Ziel, PowerShell sowie die charakteristische Process-Hollowing-Abfolge. Die beigefügten YARA-, Sigma-, Suricata- und KQL-Beispiele operationalisieren genau diese unterschiedlichen Evidenzebenen.
Der Evidence Anchor am Anfang nennt den tatsächlich verwendeten Binär-, Datei- oder Revisionsbezug. Diese Links liefern Einordnung und berichtete Beobachtungen; sie ersetzen keine lokale Sample-Analyse.
Zscaler ThreatLabz — Technical Analysis of PureCrypter (public structural comparison) ↗BlueLoader verbindet starke .NET-Obfuskation mit einem funktional vollständigen Bot. Die Schutzschichten verzögerten die Analyse, verbargen aber weder Transportprofil noch Host-Funktionen dauerhaft. Der unabhängige Abgleich aller zehn Nachrichtenmodelle ist der stärkste technische Link zum Panel.
Gespräch starten