„JavacDoor“, „Maven“ kenkėjiška programa, kuri veikia kompiliavimo metu

„JavacDoor“: „Maven“ artefaktas, kuris veikė kompiliavimo, o ne diegimo metu

Lt; DR

„Maven Central“ artefaktas, publikuotas kaip io.github.davidtimur:c2-lab išleido devynis leidimus, iš kurių aštuoniose buvo vykdomas nuotolinės prieigos naudingasis failas kompiliuojant bet kurį tolesnį projektą, kuris įtraukė JAR failą į anotacijų procesoriaus kelią. Jokiam programos kodui nereikėjo jo importuoti. Jokia šaltinio eilutė nereikėjo į jį nurodyti. Nebuvo jokio diegimo scenarijaus, jokio atitikmens po diegimo ir jokio gyvavimo ciklo kabliuko, kurį įrankiai galėtų patikrinti.

Vykdymo vektorius yra vienas 46 baitų failas JAR faile: „Java“ paslaugų teikėjo registracija, kuri įvardija klasę, įgyvendinančią javax.annotation.processing.Processor„Java“ kompiliatorius tokias registracijas aptinka automatiškai. Suradęs jas, javac sukuria klasės egzempliorių ir ją paleidžia kaip įprastą kompiliavimo dalį. Tai reiškia, kad naudingosios apkrovos vykdymo aplinka yra kompiliavimo mašina tuo metu, kai kompiliavimo mašina atlieka vienintelį dalyką, kuriam ji egzistuoja.

Devyniuose leidimuose komandų ir valdymo kanalas buvo tris kartus perkurtas: operatoriaus pateiktas atgalinio iškvietimo URL, tada atvirkštinis apvalkalas per „ngrok TCP“ tunelį, o tada HTTP apklausos kanalas, kurio keliai pasikeitė dar du kartus. Paskutinėje laidoje kaip numatytoji JVM įdiegtas TLS patikimumo tvarkyklė be operacijų. priimant bet kokį sertifikatą kompiliavimo laikotarpiu.

Artefaktas turėjo savo POM ir MIT licenciją su užrašu „C2 Lab Payload“. Jis buvo aktyvus „Maven Central“ visą stebėjimo laikotarpį. nuo to laiko buvo pašalintas kartu su visu io.github.davidtimur grupė.

Anatomija: kompiliatorius kaip vykdymo variklis

„Java“ anotacijų apdorojimo sistema egzistuoja, kad bibliotekos galėtų generuoti kodą kompiliavimo metu – tai mechanizmas, kuriuo paremtos „Lombok“, „Dagger“ ir daugybė ORM bei serializavimo įrankių. Procesorius save pristato paprasto teksto failu JAR faile:

META-INF/services/javax.annotation.processing.Processor

To failo turinys kiekviename susijusiame leidime, pažodžiui ir pilnai:

io.github.davidtimur.c2lab.C2Procesorius

Failas yra baitų skaičiumi identiškas visuose leidimuose nuo 1.0.1 iki 1.0.8, md5 7d2a08a5c8869a47eea9fa62487dfbe4. 1.0.0 versijoje jo nėra.

Kada javiečių Paleidus programą, ji nuskaito anotacijų-procesoriaus kelią, ieškodama šių paslaugų įrašų, ir įkelia tai, ką randa. Kompiliuojamame projekte nereikia paminėti procesoriaus, nieko anotuoti ar konfigūruoti. Pakanka, kad jis būtų kelyje. Ši savybė skiria „JavacDoor“ nuo tiekimo grandinės modelių, kuriais remiantis kuriami dauguma įrankių:

RaštaiSukeltiMatomas kaip
npm diegimo kabliukasnpm installscripts.postinstall manifeste
Python importavimo laiko naudingoji apkrovapirmasis modulio importavimasmodulio lygio teiginys šaltinyje
JavacDoorjavac bet kuriame tolesniame projektepaslaugos registracijos failo pavadinimas

Diegimo kabliukas yra deklaracija manifeste, o manifestas yra pirmas dalykas, kurį kas nors perskaito. Importavimo laiko naudingoji apkrova bent jau yra skaitomame šaltinio faile. Paslaugos registracija nėra nei viena, nei kita: tai failo pavadinimas ir viena eilutė, pavadinanti klasę, o elgesys yra kompiliuotame baitiniame kode, esančiame už katalogo.

Pati naudingosios apkrovos klasė atlieka pagrindinio kompiuterio žvalgybą, naudodama išorinius modulius. Sukompiliuotų klasių pastovūs telkiniai sudaro / Bin / sh, Whoami, uname-a, pwd Unix kelyje ir Tasklist „Windows“ kelyje kartu su peradresavimo klaidos srautas sujungti antrinio proceso klaidos išvestį su užfiksuotu srautu. Du JSON šablonai perkelia rezultatus iš pagrindinio kompiuterio – registracijos švyturėlio:

{"host":"%s","os":"%s","user":"%s","dir":"%s"}

apgyvendinta iš hostname komandą ir os.name, user.nameir user.dir sistemos ypatybės ir rezultato iškvietimas:

{"version":"%s","host":"%s","time":"%s","output":"%s"}

Kompiliatoriaus išvestyje palikti progreso žymekliai yra neįprastai atviri: [C2] vykdymas kompiliavimo metu baigtas, [C2] atgalinis iškvietimas išsiųstas → HTTP , [C2] apvalkalas prijungtas prie .

Devyni leidimai, trys C2 kartos

Leidimai nėra devynios vienos naudingosios apkrovos kopijos. Tai iteracijos žurnalas, ir juos skaitant eilės tvarka matyti, kad kanalas yra atstatomas, o pristatymo vektorius lieka nepakitęs.

AtleiskiteAutomatiškai vykdomas kompiliavimo metuKanalas
1.0.0ne (nėra aptarnavimo bylos)Tik operatoriaus pateiktas atgalinio iškvietimo URL
1.0.1taip (įvestas vektorius)Operatoriaus pateiktas atgalinio iškvietimo URL
1.0.2taipAtvirkštinis apvalkalas, ngrok TCP tunelis
1.0.3taipHTTP kanalas, /register /cmd /out
1.0.4taipHTTP kanalas, /register /cmd /out
1.0.5taipHTTP kanalas, /register /poll /out
1.0.6taipHTTP kanalas, /register /poll /out
1.0.7taipHTTP kanalas, /register /cmd
1.0.8taipHTTP kanalas + TLS patvirtinimas išjungtas

Verta atkreipti dėmesį į tris lentelės detales, nes kiekviena iš jų keičia artefaktų rinkinio skaitymo būdą.

Vektorius pasiekia 1.0.1, o ne 1.0.2. 1.0.0 versijoje naudojama ta pati žvalgybos ir grįžtamojo ryšio logika, tačiau nėra aptarnavimo failo ir anotacijų apdorojimo importavimo; ji veikia tik tada, kai kas nors ją iškviečia. Nuo 1.0.1 versijos aptarnavimo failas yra ir sukompiliuotos klasės importuojamos. javax.annotation.processing.SupportedSourceVersionBet koks vertinimas, lyginantis du leidimus su bilietais – 1.0.0 ir 1.0.2 – teisingai daro išvadą, kad kažkas pasikeitė, bet neteisingai nurodoma, kur.

Atvirkštinis apvalkalas egzistuoja lygiai viename leidime. 1.0.2 versijoje yra 0.tcp.ngrok[.]io, žurnalo eilutė [C2] apvalkalas prijungtas prie 0.tcp.ngrok[.]io:19823, interaktyvi reklaminė juosta c2-apvalkalasir kadro nutraukimo elementą __END__1.0.3 ir vėlesnėse versijose šių elementų nėra ir jos pasiekia HTTPS serverį. Pašalinimo užklausa, kurioje būtų įvardyti tik registruoti leidimai, būtų nurodžiusi neveikiantį TCP galinį tašką, o aktyvus HTTP kanalas, esantis šešiuose vėlesniuose leidimuose, būtų nepaminėtas.

Galutinėje versijoje transportavimo patvirtinimas pašalinamas. 1.0.8 versijoje pridėta klasė, įgyvendinanti javax.net.ssl.X509TrustManager kurio sertifikatų tikrinimo metodai nieko nedaro, visada teisingas pagrindinio kompiuterio pavadinimo tikrintuvas, užregistruotas per setDefaultHostnameVerifier, Ir pasitikėtiVisais rutina, kuri įdiegia abu kaip numatytuosius JVM nustatymus. Dėl to likusioje kompiliavimo dalyje JVM priima bet kokį sertifikatą iš bet kurio kompiuterio – ne tik paties naudingojo srauto, bet ir visko, ką vėliau kompiliavimas atlieka per TLS.

Visose šešiose HTTP kanalo versijose, kuriose jis naudojamas, priekyje yra vienas mazgas: pilnas-užsidegimas-išprotėjęs.ngrok-free[.]devKiekviena užklausa turi antraštę „ngrok-skip-browser-warning“, kuris slopina tarpinį puslapį, kurį naršyklėms teikia nemokami „ngrok“ tuneliai. Kelių rinkiniai keičiasi skirtingose ​​versijose — /išeiti dingsta ties 1.0.7 ir /cmd kaitaliojasi su /apklausa – bet šeimininkas niekada nesikeičia.

Savęs išskyrimo pasakojimas

Kiekvienas POM nuo 1.0.1 versijos nustato kompiliatoriaus argumentą paties artefakto kompiliavimui:

-proc:none

Ši vėliavėlė išjungia anotacijų apdorojimą. Jos poveikis čia yra išankstinis.cise: kai projektas, kuriame yra procesorius, yra kompiliuojamas, procesorius neveikia.

Ši vėliavėlė turi visiškai įprastą paskirtį. Projektas, kuris pateikia anotacijų procesorių, dažnai turi vengti taikyti tą procesorių sau pačiam paleidimo metu, ir kūrimo įrankio dokumentacija būtent tai ir rekomenduoja. Vien tai nieko neįrodo.

Tačiau kartu su procesoriaus veiksmais tai apibūdina specifinę asimetriją: kodas vykdomas visų, kurie kompiliuoja pagal artefaktą, kompiuteriuose, o ne kompiuteryje, kuris kuria artefaktą. Ši vėliavėlė rodoma toje pačioje laidoje, kurioje pristatomas aptarnavimo failas – 1.0.1 – ir kiekvienoje vėlesnėje laidoje. Koreliacija tarp „leidimo, kuriame prasideda vykdymas kompiliavimo metu“ ir „leidimo, kuriame vykdymas kompiliavimo metu yra išjungtas lokaliai“ yra pats naudingiausias analitinis signalas artefaktų rinkinyje ir yra matomas paprasto teksto POM faile nieko nedekompiliuojant.

Pastebime efektą ir ties tuo sustojame. Artefaktuose nėra nieko, kas pasakytų, kodėl vėliava buvo iškelta.

Verta paminėti dar vieną metaduomenų elementą, daugiausia siekiant jį sunaikinti. POM projektą pavadina „C2 laboratorijos naudingąja apkrova“ (angl. „C2 Lab Payload“), apibūdina jį kaip „C2 laboratorijos naudingosios apkrovos artefaktą“ (angl. „C2 lab payload“) ir licencijuoja jį MIT. Toks savęs žymėjimas kartais siūlomas kaip įrodymas, kad paketas yra tyrimo užduotis.cise, o ne reali grėsmė, ir kartais šis aiškinimas teisingas – deklaruota „kanarėlė“ be pasiekiamos infrastruktūros yra skirtingas objektas. Čia tai netaikoma. Funkcinis implantas, paskelbtas viešojoje saugykloje, pasiekiamas bet kuriam vartotojui, su išorine infrastruktūra, kuri buvo tris kartus perkurta devyniuose leidimuose, yra reali galimybė, nepriklausomai nuo to, kaip ją vadina metaduomenys. Pavadinimas POM nieko nekeičia apie tai, kas vyksta kompiuteryje, kuris ją kompiliuoja.

Statybinių mašinų indikatoriai

Jei kompiliavimo serveris kompiliavosi pagal šį artefaktą, įrodymai saugomi kompiliavimo žurnaluose ir tinklo telemetrijoje, o ne nuolatiniame diske esančiame įraše – naudingoji apkrova veikia kompiliavimo proceso viduje ir baigiama kartu su juo.

Jar arba vietinės saugyklos talpykloje

  • META-INF/services/javax.annotation.processing.Processor pavadinimų io.github.davidtimur.c2lab.C2Processor
  • Paslaugų failas md5 7d2a08a5c8869a47eea9fa62487dfbe4
  • Klasės pagal io/github/davidtimur/c2lab/: C2Processor, C2Task, Task, o 1.0.8 versijoje vidinė klasė Task$1

Sukurta išvestis

  • [C2] compile-time execution complete
  • [C2] callback sent → HTTP
  • [C2] callback failed:
  • [C2] shell connected to
  • Interaktyvus reklaminis skydelis c2-shellkadro nutraukimo elementas __END__

Proceso telemetrija

  • javac kaip tėvas /bin/sh -c (Unix) arba Windows komandų interpretatorius
  • Vaikų komandos whoami, uname -a, pwd (Unix) arba tasklist (Windows) su kompiliavimo etapu

Tinklo telemetrijoje

  • Išeinantis TCP į 0.tcp.ngrok[.]io:19823 (1.0.2 versija)
  • HTTPS į tableful-fervor-crazed.ngrok-free[.]dev, keliai /register, /cmd, /poll, /out (1.0.3–1.0.8 versijos)
  • Užklausos antraštė ngrok-skip-browser-warning: true
  • Užklausos atitikmenų skyriai {"host":...,"os":...,"user":...,"dir":...} or {"version":...,"host":...,"time":...,"output":...}

Konfigūracijoje

  • Aplinkos įvairovė CALLBACK, CALLBACK_URLsistemos savybė; callback.url

Leidėjo metaduomenys

  • Ką reiškia keliauti su grupe? io.github.davidtimurleidėjo adresas; davudboi999@gmail[.]compasirašymo raktas; E520C345EF94423D

Versijai, kurioje buvo paleista 1.0.8 versija, reikalingas vienas papildomas patikrinimas. Kadangi šioje versijoje pagal numatytuosius nustatymus visoje JVM įdiegiama leidžiama patikros tvarkyklė, bet koks vėliau tame pačiame JVM užmegztas TLS ryšys – priklausomybių sprendimas, artefaktų įkėlimas, diegimo etapas – buvo tęsiamas be sertifikato patvirtinimo. Srauto iš to lango nereikėtų laikyti autentifikuotu.

Kodėl kompiliuotiems artefaktams reikia skirtingo nuskaitymo

„JavacDoor“ yra naudingas testo atvejis, nes jis paneigia dvi įprastas prielaidas vienu metu ir nė vienas iš šių gedimų nėra būdingas tik vieno tiekėjo įrankiams.

Pirmoji prielaida yra ta, kad pavojingas kodas save paskelbia manifeste. Daug tiekimo grandinės įrankių yra organizuoti pagal gyvavimo ciklą hooks, nes npm ir PyPI atveju veiksmas paprastai atliekamas ten. „JavacDoor“ neturi kabliuko. Jo trigeris yra paslaugos registracijos failas, kurio pavadinimas yra „Java“ sąsaja, o turinys – klasės pavadinimas. Norint tai statiškai aptikti, reikia apdoroti META-INF/services/javax.annotation.processing.Processor kaip savarankiškas vykdymo įėjimo taškas, lygiavertis a po įdiegimo scenarijų – ir tada sekti įvardytąją klasę baitiniame kode. Ekosistemos turi savo automatinio aptikimo mechanizmus, tokius kaip ši forma, ir kiekvienas iš jų yra įėjimo taškas, nepriklausomai nuo to, ar įrankiai jį išvardija kaip vieną.

Antra prielaida yra ta, kad eilutės yra šaltinio failuose. JAR failo galiniai taškai, apvalkalo komandos, JSON šablonai ir žurnalų žymekliai yra nuolatiniuose telkiniuose .klasė failai. Įrankiai, kurie naudoja „greps“ tekstą, nieko neranda – ne todėl, kad eilutės yra užmaskuotos, bet todėl, kad jos yra struktūrizuotame dvejetainiame konteineryje, kurio teksto nuskaitymas neanalizuoja. Kiekvienas šiame įraše esantis tinklo indikatorius gautas analizuojant „constant-pool“. Vienas iš jų yra visiškai suformuotas https:// URL, esantis aiškiai matomoje vietoje klasės faile; nuskenavus skaitomą JAR failo turinį, jo vis tiek nerasta. Čia nėra jokio kodavimo, kurį reikėtų panaikinti, tik konteinerio formatas, kurį reikia perskaityti.

Abi spragos yra tokios pačios formos: artefakto formatas buvo traktuojamas kaip failų krepšys, o ne kaip struktūra su apibrėžta semantika. Pataisa nėra patraukli – išanalizuokite konteinerį, išvardykite pačios ekosistemos automatinio aptikimo įėjimo taškus ir vadovaukitės jais kompiliuojamame kode. Konkrečiai, kalbant apie kompiliavimo laiko vektorius, trečias patikrinimas yra pigus ir stebėtinai diagnostinis: palyginkite, ką artefaktas daro vartotojams, su tuo, nuo ko jis pats atleidžiamas. Artefaktas, kuris registruoja kompiliavimo laiko procesorių ir tuo pačiu metu išjungia kompiliavimo laiko apdorojimą savo kompiliavimui, papasakojo apie save kažką dviejose paprasto teksto POM eilutėse.

Komandoms, kurios šiandien naudoja „Maven“ artefaktus, yra trys praktinės priemonės:

  • Anotacijų ir procesoriaus kelią traktuokite kaip vykdymo ribą. Priklausomybės, kurios ten patenka, paleidžia kodą jūsų kompiliacijoje. Jei kompiliacijai nereikia apdoroti anotacijų, -proc:none yra taip pat naudingas gynybiškai, kaip, matyt, buvo lokaliai; kur jis tai daro, procesoriaus rinkinys yra aiškiai priskirtas, o ne paveldėtas iš kompiliavimo klasės kelio.
  • Žurnalų kompiliatoriaus subprocesai. Kompiliavimo žingsnis, kuris sukuria apvalkalą, daugumoje projektų yra anomalinis ir lengvai įspėjamas.
  • Nelaikykite metaduomenų parodymais. „Lab“, „test“, „payload“ ir „PoC“ paketo pavadinime ar aprašyme nėra apimties apribojimai. Pasiekiamumas ir elgsena yra.

Artefaktas ir visa jo grupė buvo pašalinti iš Specialistė Po mūsų ataskaitos „Central“; ir artefakto kelias, ir grupės kelias dabar grąžina 404, o „Central“ indeksas nepraneša apie atitinkamas koordinates. Tai uždaro šį artefaktą. Tai neuždaro vektoriaus, kuris yra dokumentuota „Java“ kompiliatoriaus funkcija ir prieinama visiems, publikuojantiems JAR failą.

Nuorodos

Šiame įraše nenurodyti jokie išoriniai šaltiniai. Visi radiniai yra tiesioginė devynių publikuotų stiklainių, paimtų iš „Maven Central“ prieš juos pašalinant, statinė analizė. Jokiu būdu nebuvo vykdomas joks kodas iš artefaktų.

sca-tools-software-composition-analyses-tools
Prioritetizuoti, pašalinti ir apsaugoti savo programinės įrangos rizikas
Gaukite nemokamą paskyrą.
Nebūtina kreditinės kortelės.

Apsaugokite savo programinės įrangos kūrimą ir tiekimą

su „Xygeni“ produktų rinkiniu