SI-CERT TZ016 / BeaverTail & InvisibleFerret
quality 7/10 · good
0 net
Tags
SI-CERT TZ016 / BeaverTail & InvisibleFerret - SI CERT Skoči na vsebino Uvod Obravnavali smo zanimiv primer napada, pri katerem se napadalci lažno predstavljajo kot iskalci zaposlitve ali pa želijo kakšno drugo sodelovanje z neko organizacijo. Prvi kontakt praviloma vzpostavijo preko omrežja LinkedIn, nato pa poskušajo zavesti žrtev v zagon zlonamerne kode. Njihov cilj so predvsem podjetja in posamezniki, ki se ukvarjajo z Web3 tehnologijo (pametne pogodbe, kriptovalute, tehnologija veriženja blokov…). Tekom komunikacije napadalec pošlje povezavo do nekega predstavitvenega projekta, ki na prvi pogled zgleda povsem običajen in neškodljiv, vendar pa ob zagonu izvrši tudi zlonamerno kodo, ki ukrade podatke in vzpostavi stranska vrata do okuženega sistema. Sama zlonamerna koda je razdeljena na dva glavna dela, ki sta znana po imenih BeaverTail in InvisibleFerret . Razlikujeta se po namenu in programskem jeziku, v katerem sta modula spisana: BeaverTail – Node.js, InvisibleFerret – Python. Ta tehnični zapis se ne ukvarja z atribucijo napadalcev, raziskave in poročila nekaterih drugih varnostnih strokovnjakov pa povezujejo tovrstno prakso in zlonamerno kodo z aktivnostmi državno sponzoriranih hekerjev iz Severne Koreje. Analiza projekta Analiza deljenega projekta je pokazala, da gre za Node.js Package Manager (NPM) paket. Projekt vsebuje tudi navodila za gradnjo in zagon programa, katera izvedejo tudi zlonamerno kodo. Konfiguracijska datoteka package.json vsebuje podatke o NPM paketu in definira tudi glavno (main) datoteko, v kateri se začne izvajanje Node.js kode. Datoteka server.js sama ne vsebuje zlonamerne kode, vendar pa s funkcijo require naloži dodatne module. Večina teh modulov je standardnih in legitimnih, modul app je pa lokalen in se nahaja v datoteki app.js . Datoteka app.js tudi direktno ne vsebuje zlonamerne kode, naloži pa dodatne lokalne module. Večina teh modulov vsebuje le odvečno kodo, ki ni preveč zanimiva, v modulu userRoutes se pa skriva začetek zlonamerne kode. userRoutes.js Datoteka userRoutes.js na koncu vsebuje prikrito kodo. Vsa prikrita koda je v eni sami vrstici in ima pred njo veliko presledkov. Na ta način se skrije v tekstovnih urejevalnikih brez možnosti preloma besed (word wrap). Koda pa je bila verjetno zamaskirana oz. obfuskirana z uporabo odprto-kodnega obfuskatorja javascript-obfuscator . S pomočjo orodja synchrony in nekaj ročnega dela smo pridobili bolj berljivo oz. deobfuskirano obliko kode. Analiza kode je pokazala, da najprej poskusi poslati nekaj osnovnih informacij o sistemu na t.i. C2 strežnik, ki je pod nadzorom napadalcev, zatem pa z njega prenese in izvrši nadaljnji tovor. Ta postopek skripta izvrši 3x, in sicer ob zagonu in nato še dvakrat z zamikom 10 minut, nato pa zaključi izvajanje. V zgornjem izseku kode vidimo funkcijo, ki pošlje podatke na C2 strežnik. To naredi s HTTP POST zahtevo na sledeč naslov: hxxp://23[.]106.253.221:1244/keys Opomba: vsi C2 strežniki iz tega zapisa v času objave niso bili več dosegljivi Med podatki, ki jih pošlje v zahtevi, so timestamp, type/fingerprint, host ID (hostname), data type, in data. Prenos in zagon tovora Drugi del skripte je namenjen prenosu in izvršitvi tovora. Vidimo, da funkcija poskusi kreirati novo mapo z imenom .vscode v domači mapi trenutnega uporabnika (Windows – %USERPROFILE% , Linux/Darwin – $HOME , ~/ ) in nato vanjo prenese datoteki test.js ( hxxp://23[.]106.253.221:1244/j/ZU1RINz7 ) in package.json ( hxxp://23[.]106.253.221:1244/p ). Zatem v isti mapi požene ukaz npm install , ki prenese potrebne knjižnice (dependencies), nato pa še node test.js , ki izvrši prenešen tovor. Preprečevanje izvedbe Skripta vsebuje tudi zanimiv način preprečevanja izvedbe deobfuskirane kode, ki lahko oteži izvajanje dinamične analize: Notranja funkcija v spremenljivki H pridobi niz, ki vsebuje kodo zunanje funkcije (rezultat funkcije F ), in nad njim požene regex (((.+)+)+)+$ . V primerih, kjer niz vsebuje novo vrstico, čas izvajanja tega regularnega izraza eksponentno narašča glede na število znakov v vrstici. Tovrstno izvajanje ima tudi ime catastrophic backtrace ali runaway regular expression . To pomeni, da se bo za deobfuskirano kodo, ki vsebuje presledke, ta izraz predolgo izvajal in vrnil neko napako. Ker pa je obfuskirana koda v eni sami vrstici, se izraz hitro zaključi in nato se lahko izvede še nadaljnja zlonamerna koda. Glavni Node.js modul – BeaverTail Če se vrnemo malo nazaj in se osredotočimo na prenešen tovor, ugotovimo, da gre tudi tu za NPM paket. Konfiguracijska datoteka ( package.json ) je zelo preprosta in vsebuje le nekaj knjižnic, ki se prenesejo z npm install ukazom. Nadaljnja koda se pa nahaja v datoteki test.js . Tako kot prejšnji del je tudi ta koda obfuskirana in vsebuje enak način preprečevanja izvedbe z uporabo regularnih izrazov. Kodo smo deobfuskirali na podoben način kot v prejšnjem delu in dodatno smiselno preimenovali funkcije ter nekatere spremenljivke. Pridobljena koda je malo bolj kompleksna in vsebuje dva dela, s katerima najprej ukrade podatke in nato prenese ter izvede kodo nadaljnje stopnje. Kraja podatkov Zgoraj je vidna glavna funkcija, ki pridobi in pošlje podatke iz različnih spletnih brskalnikov. Najprej poskusi pridobiti podatke iz razširitev/dodatkov brskalnikov, na Linux in Darwin sistemih pa nato še druge podatke, shranjenih v brskalnikih (gesla, seje, zgodovina, itd.). Pridobljene podatke pošlje nadzornemu strežniku preko HTTP POST zahtev na naslov: hxxp://23[.]106.253.221:1244/uploads Spodaj je naveden seznam razširitev iz katerih program krade podatke: ID razširitve Ime Vir nkbihfbeogaeaoehlefnkodbefgpgknn Metamask Chrome store ejbalbakoplchlghecdalmeeeajnimhm Metamask Microsoft store ibnejdfjmmkpcnlpebklmnkoeoihofec TronLink Chrome store fhbohimaelbohpjbbldcngcnapndodjp BNB Chain Wallet Chrome store hnfanknocfeofbddgcijnmhnfnkdnaad Coinbase Wallet Chrome store bfnaelmomeimhlpmgjnjophhpkkoljpa Phantom Chrome store aeachknmefphepccionboohckonoeemg Coin98 Wallet Chrome store egjidjbpglichdcondbcbdnbeeppgdph Trust Wallet Chrome store hifafgmccdpekplomjjkcfgodnhcellj Crypto.com | Wallet Extension Chrome store aholpfdialjgjfhomihkjbmgjidlcdno Exodus Web3 Wallet Chrome store mcohilncbfahbmgdjkbpemcciiolgcge OKX Wallet Chrome store pdliaogehgdbhbnmkklieghmmjkpigpa Bybit Wallet Chrome store bhghoamapcdpbohphigoooaddinpkbai Authenticator Chrome store Prenos in izvršitev naslednje stopnje Drugi del kode na Windows sistemih najprej namesti Python 3.11 okolje. To naredi tako, da z orodjem curl prenese ZIP arhiv iz naslova hxxp://23[.]106.253.221:1244/pdown , ki vsebuje celotno Python okolje za Windows OS in ga shrani pod imenom p2.zip v mapi z začasnimi datotekami. Ta arhiv nato z orodjem tar razširi v domačo mapo uporabnika. Zanimivost pri tem je uporaba orodji curl in tar (bsdtar – omogoča razširitev ZIP datotek), ki sta bolj značilni za operacijske sisteme podobne Unixu, vendar sta orodji vsebovani tudi v Windows OS-ih novejših od verzije 1803 (build 17063). Za ostale operacijske sisteme program predvideva, da je Python okolje že nameščeno. Zatem program s HTTP GET zahtevo pridobi kodo iz naslova: hxxp://23[.]106.253.221:1244/client/ZU1RINz7 Odgovor shrani v datoteko .npl v domači mapi uporabnika in jo nato izvrši s Python interpretorjem. Zatem se zlonamerna koda nadaljuje v različnih Python skriptah. Node.js koda v tej sekciji je znana po imenu BeaverTail in se jo lahko prepozna po formatu URL-jev, s katerimi komunicira, imenu prenešenih datotek ( .npl ) in po sami funkciji prenosa Python okolja in zagonu tovora. Python – InvisibleFerret Koda v datoteki .npl je šifrirana po zelo preprostem postopku. Spremenljivka qt vsebuje ključ (prvih 8 znakov ) in zašifrirane podatke (preostali znaki). Podatke najprej dekodira (base64) in dešifrira (XOR), nato pa dobljeno kodo izvrši s pomočjo funkcije exec . Poleg enostavnega šifriranja koda ne vsebuje drugih metod obfuskacije, kar močno olajša analizo. Namen kode je prenos in izvršitev dveh dodatnih Python skript oz. modulov: Ime modula URL Mesto prenosa Payload hxxp://23[.]106.253.221:1244/payload/ZU1RINz7 $HOME/.n2/pay Browser hxxp://23[.]106.253.221:1244/brow/ZU1RINz7 $HOME/.n2/bow Program na Darwin sistemih izvrši samo prvi modul (Payload) in zatem, s klicem funkcije sys.exit , zaključi izvajanje. Začetek programa vsebuje tudi zanimiv način, s katerim dinamično namesti vse potrebne knjižnice (dependencies). Payload modul Podobno kot prejšnji del je tudi tu koda prekrita, vendar po nekoliko drugačnem postopku. V tem primeru je koda stisnjena (zlib), kodirana (base64) in na koncu je rezultat kodiranja še obrnjen. Razširjena koda je nato izvedena s funkcijo exec . Vendar po le eni iteraciji tega postopka še ne dobimo povrnjene kode, saj je v tem primeru koda večkrat stisnjena. Pridobljena koda po prvi iteraciji: Za popolno povrnitev kode smo spisali preprosto Python skripto: Po 50 iteracijah dobimo dokončno razširjeno kodo. Tudi ta ne vsebuje kakšnih drugih metod obfuskacije. Njen glavni namen je izvajanje prejetih ukazov iz C2 strežnika. Zgornji izsek kode vsebuje razred Client , ki izvede povezavo na C2 strežnik in začne komunikacijo, ki poteka preko TCP protokola. V tem primeru je naslov C2 strežnika sledeč: 173[.]211.106.101:1244 Po povezavi na C2 strežnik začne program izvajati prejete ukaze. Struktura paketa, ki vsebuje ukaz, je zelo preprosta: 4 bajti – big endian … Velikost podatkov Podatki Sam ukaz (podatki) je v JSON formatu in je sestavljen iz ID ukaza (število) in argumentov. Razred, ki bere in izvrši ukaze, je Shell : Tabela možnih ukazov: ID ukaza Ime funkcije Opis 1 ssh_obj Izvrši ukaz v ukazni lupini in vrne izhod. 2 ssh_cmd Izvrši posebne ukaze. V tem primeru je implementiran samo en ukaz, ki zapre celotno povezavo. 3 ssh_clip Vrne zabeležene vnose (keylogger). Keylogger je aktiven samo na Windows OS. 4 ssh_run Prenese in izvrši »Browser« modul (opisan v nadaljevanju). 5 ssh_upload Omogoča iskanje datotek po sistemu in odlaganje datotek na nek FTP strežnik (podatki FTP strežnika so podani v argumentih ukaza). 6 ssh_kill Ubije procese brsklanikov Chrome in Brave 7 ssh_any Prenese in izvrši dodatno skripto, ki namesti in konfigurira program za oddaljen dostop AnyDesk 8 ssh_env Pridobi datoteke iz zunanjih diskov in map za dokumente ter prenose in jih odloži na FTP strežnik 9 ssh_zcp Ukrade podatke brskalnikov, razširitev, upravljalcev gesel, kripto denarnic in nekaterih drugih aplikacij ter jih shrani v zašifriran arhiv. Arhiv nato odloži na FTP strežnik ali pa jih pošlje v Telegram kanal (preko API-ja) Ukaz ssh_zcp krade podatke iz aplikacij Chrome, Chromium, Opera, Brave, Edge, Vivaldi, 1Password, Exodus, Atomic, Electrum, WinAuth, Proxifier v4, Dashlane, ter iz razširitev iz spodnjega seznama: ID razširitve Ime aeachknmefphepccionboohckonoeemg Coin98 aholpfdialjgjfhomihkjbmgjidlcdno Exodus bfnaelmomeimhlpmgjnjophhpkkoljpa Phantom ejbalbakoplchlghecdalmeeeajnimhm MetaMask ejjladinnckdgjemekebdpeokbikhfci PetraAptos egjidjbpglichdcondbcbdnbeeppgdph Trust fhbohimaelbohpjbbldcngcnapndodjp Binance gjdfdfnbillbflbkmldbclkihgajchbg Termux hifafgmccdpekplomjjkcfgodnhcellj Crypto hnfanknocfeofbddgcijnmhnfnkdnaad CoinBase ibnejdfjmmkpcnlpebklmnkoeoihofec TronLink lgmpcpglpngdoalbgeoldeajfclnhafa Safepal mcohilncbfahbmgdjkbpemcciiolgcge OKX nkbihfbeogaeaoehlefnkodbefgpgknn MetaMask nphplpgoakhhjchkkhmiggakijnkhfnd Ton pdliaogehgdbhbnmkklieghmmjkpigpa ByBit phkbamefinggmakgklpkljjmgibohnba Pontem kkpllkodjeloidieedojogacfhpaihoh Enkrypt agoakfejjabomempkjlepdflaleeobhb Core jiidiaalihmmhddjgbnbgdfflelocpak Bitget kgdijkcfiglijhaglibaidbipiejjfdp Cirus kkpehldckknjffeakihjajcjccmcjflh HBAR idnnbdplmphpflfnlkomgpfbpcgelopg Xverse fccgmnglbhajioalokbcidhcaikhlcpm Zapit fijngjgcjhjmmpcmkeiomlglpeiijkld Talisman enabgbdfcbaehmbigakijjabdpdnimlg Manta onhogfjeacnfoofkfgppdlbmlmnplgbn Sub amkmjjmmflddogmhpjloimipbofnfjih Wombat glmhbknppefdmpemdmjnjlinpbclokhn Orange hmeobnfnfcmdkdcmlblgagmfpfboieaf XDEFI acmacodkjbdgmoleebolmdjonilkdbch Rabby fcfcfllfndlomdhbehjjcoimbgofdncg LeapCosmos anokgmphncpekkhclmingpimjmcooifb Compass epapihdplajcdnnkdeiahlgigofloibg Sender efbglgofoippbgcjepnhiblaibcnclgk Martian ldinpeekobnhjjdofggfgjlcehhmanlj Leather lccbohhgfkdikahanoclbdmaolidjdfl Wigwam abkahkcbhngaebpcgfmhkoioedceoigp Casper bhhhlbepdkbapadjdnnojkbgioiodbic Solflare klghhnkeealcohjjanjjdaeeggmfmlpl Zerion lnnnmfcpbkafcpgdilckhmhbkkbpkmid Koala ibljocddagjghmlpgihahamcghfggcjc Virgo ppbibelpcjmhbdihakflkdcoccbgbkpo UniSat afbcbjpbpfadlkmhmclhkeeodmamcflc Math ebfidpplhabeedpnhjnobghokpiioolj Fewcha fopmedgnkfpebgllppeddmmochcookhc Suku gjagmgiddbbciopjhllkdnddhcglnemk Hashpack jnlgamecbpmbajjfhmmmlhejkemejdma Braavos pgiaagfkgcbnmiiolekcfmljdagdhlcm Stargazer khpkpbbcccdmmclmpigdgddabeilkdpd Suiet kilnpioakcdndlodeeceffgjdpojajlo Aurox bopcbmipnjdcdfflfgjdgdjejmgpoaab Block kmhcihpebfmpgmihbkipmjlmmioameka Eternl aflkmfhebedbjioipglgcbcmnbpgliof Backpack ajkifnllfhikkjbjopkhmjoieikeihjb Moso pfccjkejcgoppjnllalolplgogenfojk Tomo jaooiolkmfcmloonphpiiogkfckgciom Twetch kmphdnilpmdejikjdnlbcnmnabepfgkh OsmWallet hbbgbephgojikajhfbomhlmmollphcad Rise nbdhibgjnjpnkajaghbffjbkcgljfgdi Ramper fldfpgipfncgndfolcbkdeeknbbbnhcc MyTon jnmbobjmhlngoefaiojfljckilhhlhcj OneKey fcckkdbjnoikooededlapcalpionmalo MOBOX gadbifgblmedliakbceidegloehmffic Paragon ebaeifdbcjklcmoigppnpkcghndhpbbm SenSui opfgelmcmbiajamepnmloijbpoleiama Rainbow jfflgdhkeohhkelibbefdcgjijppkdeb OrdPay kfecffoibanimcnjeajlcnbablfeafho Libonomy opcgpfmipidbgpenhmajoajpbobppdil Sui penjlddjkjgpnkllboccdgccekpkcbin OpenMask kbdcddcmgoplfockflacnnefaehaiocb Shell abogmiocnneedmmepnohnhlijcjpcifd Blade omaabbefbmiijedngplfjmnooppbclkk Tonkeeper cnncmdhjacpkmjmkcafchppbnpnhdmon HAVAH eokbbaidfgdndnljmffldfgjklpjkdoi Fluent fnjhmkhhmkbjkkabndcnnogagogbneec Ronin dmkamcknogkgcdfhhbddcghachkejeap Keplr dlcobpjiigpikoobohmabehhmhfoodbb ArgentX aiifbnbfobpmeekipheeijimdpnlpgpp Station eajafomhmkipbjmfmhebemolkcicgfmd Taho mkpegjkblkkefacfnmkajcjmabijhclg MagicEden ffbceckpkpbcmgiaehlloocglmijnpmp Initia lpfcbjknijpeeillifnkikgncikgfhdo Nami fpkhgmpbidmiogeglndfbkegfdlnajnf Cosmostation kppfdiipphfccemcignhifpjkapfbihd Frontier fdjamakpfbbddfjaooikfcpapjohcfmg Dashalane hdokiejnpimakedhajhdlcegeplioahd LastPass bhghoamapcdpbohphigoooaddinpkbai GoogleAuth Browser modul Tudi ta modul je kodiran in stisnjen po enakem postopku kot prejšnji. Njegov namen je kraja gesel in kreditnih kartic shranjenih v spletnih brskalnikih. Gre za bolj specializirano različico ssh _zcp ukaza iz prejšnjega modula in kradljivca v BeaverTail kodi. Razlika je v tem, da ostala dva kradljivca preneseta celotne mape s shranjenimi podatki spletnih brskalnikov, ta se pa osredotoči samo na shranjena gesla in kreditne kartice. Zgornja funkcija pridobi podatke kreditnih kartic, shranjenih v nekem brskalniku. Najprej iz SQLite baze webdata.db pridobi zašifrirane podatke in jih zatem še dešifrira. Pridobitev ključa in dešifriranje se razlikuje glede na operacijski sistem, saj se tudi sama implementacija v brskalnikih nekoliko razlikuje. V Windows OS-u program za dešifriranje podatkov uporabi funkcijo dec_win_pwd , na ostalih OS-ih pa dec_unx_pwd . Na Windows OS-u je ključ dodatno zašifriran in shranjen v JSON datoteki Local State , za dešifriranje tega ključa se uporablja Windows API funkcija CyptUnprotectData , ki s posebnim ključem trenutnega uporabnika dešifrira podatke. Ostali operacijski sistemi pa imajo ključ shranjen v t.i. keychain/keyring sistemskih shrambah. V zgornjem izseku kode vidimo, da podatke krade samo iz spletnih brskalnikov Chrome, Opera, Brave, Yandex in Edge (baziranih na Chromium), kar je najverjetneje posledica višje specializiranosti. Pridobljene podatke pošlje z metodo save, kjer se tudi vidi, da uporabi HTTP POST zahtevo na fiksni naslov hxxp://23[.]106.253.221:1244/keys . Povzetek V tem delu smo pogledali delovanje dveh zlonamernih Python skript, ki sta prenešeni in izvedeni preko t.i. loaderja ali dropperja ( .npl ) z imenom InvisibleFerret. Podobno kot za BeaverTail lahko tudi tega prepoznamo po obliki URL-jev s katerimi komunicira, imenih modulov (pay, bow, adc) ali pa imenu skripte .npl . Seznam indikatorjev zlorabe (IoC) Ime SHA256 userRoutes.js 4f632429fedb39fa2addaeff3ba900679ebff99e45353d523776831e2558df80 test.js 354e7014103783c2096b9f29e4eed11f79d19b13bda112b6fed4ffbf3ad438b9 p2.zip 6a104f07ab6c5711b6bc8bf6ff956ab8cd597a388002a966e980c5ec9678b5b0 .npl f46b47e859f321b6676289f3637538b60e1d7d97ee8d79b8ba9d12248858a75a pay 95e3cbaac2749928598928c3b8ca80358c136e01bc429d2c2da77cc788566e1e bow 6b331ab212a839ad1b1b673ca74a3c50c6dae383c19661e0ae71853f615aa891 adc 335ad22f143ff050bb405cd48d0011a9eb9f4c7501b18781a42d3956718827c8 URL hxxps://github[.]com/0xcestlaview/addingtoken hxxp://23[.]106.253.221:1244/j/ZU1RINz7 hxxp://23[.]106.253.221:1244/p hxxp://23[.]106.253.221:1244/keys hxxp://23[.]106.253.221:1244/pdown hxxp://23[.]106.253.221:1244/uploads hxxp://23[.]106.253.221:1244/client/ZU1RINz7 hxxp://23[.]106.253.221:1244/payload/ZU1RINz7 hxxp://23[.]106.253.221:1244/brow/ZU1RINz7 hxxp://23[.]106.253.221:1244/adc/ZU1RINz7 hxxp://23[.]106.253.221:1244/any IP Vrata 173[.]211.106.101 1244 Preberite tudi Novice / 30. 3. 2026 Spletni seminar Kršitev varnosti osebnih podatkov – zaznava, ukrepi in poročanje Kraja baz osebnih podatkov je ena najresnejših posledic vdora v informacijski sitem. Organizacije se z njimi srečujejo vse pogosteje, zato je ključno, da znamo takšne in podobne dogodke pravilno prepoznati, … Več Novice / 29. 3. 2026 Serija spletnih seminarjev Na SI-CERT-u izvajamo brezplačne spletne seminarje, s katerimi naslavljamo konkretne kibernetske incidente in grožnje, ki vidimo, da predstavljajo izziv slovenskim podjetjem in posameznikom. Na voljo so posnetki vseh spletnih seminarjev, … Več Novice / 29. 1. 2026 Kibernetska varnost 2025 v številkah V 2025 kar 35 % porast obravnavanih zadev na letni ravni, kar se ujema z rastjo škode, ki jo za spletne goljufije beleži Slovenska policija. Več Prijavite se na SI-CERT novičnik Odziv Na elektronski naslov vam bomo poslali zadnje varnostno opozorilo in druge novice iz področja kibernetske varnosti. Vnesite e-pošto za prijavo na novičnik Odziv. Prebral sem in se strinjam z obdelavo mojega elektronskega naslova . Prijava