TL; DR
Artifak Maven Central diterbitkan sebagai io.github.davidtimur:c2-lab menghantar sembilan keluaran, lapan daripadanya melaksanakan muatan akses jauh semasa penyusunan mana-mana projek hiliran yang meletakkan balang pada laluan pemproses anotasinya. Tiada kod aplikasi yang perlu mengimportnya. Tiada sumber yang perlu merujuknya. Tiada skrip pemasangan, tiada setara pasca pemasangan dan tiada sebarang jenis cangkuk kitaran hayat untuk diperiksa oleh perkakas.
Vektor pelaksanaan ialah fail 46-bait tunggal di dalam balang: pendaftaran penyedia perkhidmatan Java yang menamakan kelas yang melaksanakan javax.annotation.processing.ProcessorPengkompil Java akan menemui pendaftaran sedemikian secara automatik. Sebaik sahaja ditemui, javac mewujudkan dan menjalankan kelas sebagai bahagian biasa dalam pengkompilasi. Ini bermakna persekitaran masa jalan muatan ialah mesin binaan, pada masa ini mesin binaan sedang melakukan satu perkara yang wujud untuk dilakukan.
Merentasi sembilan keluaran, saluran arahan dan kawalan telah dibina semula sebanyak tiga kali: URL panggilan balik yang dibekalkan oleh operator, kemudian cangkerang terbalik melalui terowong TCP ngrok, kemudian saluran pengundian HTTP yang laluannya beralih dua kali lagi. Keluaran akhir memasang pengurus kepercayaan TLS tanpa operasi sebagai lalai JVM, menerima sebarang sijil sepanjang tempoh kompilasi.
Artifak itu mengandungi perkataan "C2 Lab Payload" dalam POMnya sendiri dan lesen MIT. Ia telah disiarkan di Maven Central sepanjang tempoh kami memerhatikannya dan telah dihapuskan, bersama-sama dengan keseluruhannya io.github.davidtimur kumpulan.
Anatomi: pengkompil sebagai enjin pelaksanaan
Kerangka kerja pemprosesan anotasi Java wujud supaya pustaka boleh menjana kod pada masa kompilasi — mekanisme di sebalik Lombok, Dagger dan senarai panjang alat ORM dan bersiri. Pemproses mengumumkan dirinya dengan fail teks biasa di dalam balang:
META-INF/perkhidmatan/pemproses.pemprosesan.annotasi.javax
Kandungan fail tersebut dalam setiap keluaran yang terjejas, secara verbatim dan lengkap:
io.github.davidtimur.c2lab.C2Processor
Fail ini adalah sama bait merentasi keluaran 1.0.1 hingga 1.0.8, md5 7d2a08a5c8869a47eea9fa62487dfbe4. Keluaran 1.0.0 tidak mengandunginya.
Bila bahasa jawa Apabila dijalankan, ia mengimbas laluan pemproses anotasi untuk entri perkhidmatan ini dan memuatkan apa yang ditemuinya. Tiada apa-apa dalam projek yang sedang dikompilasi perlu menyebut pemproses, memberi anotasi apa-apa atau mengkonfigurasi apa-apa. Kehadiran pada laluan sudah memadai. Ini adalah sifat yang memisahkan JavacDoor daripada corak rantaian bekalan yang kebanyakan perkakasan dibina:
| corak | Trigger | Kelihatan sebagai |
|---|---|---|
| cangkuk pemasangan npm | npm install | scripts.postinstall dalam manifes |
| Muatan masa import Python | import pertama modul | pernyataan peringkat modul dalam sumber |
| JavacDoor | javac pada mana-mana projek hiliran | nama fail pendaftaran perkhidmatan |
Cangkuk pemasangan ialah deklarasi dalam manifes dan manifes ialah perkara pertama yang dibaca oleh sesiapa sahaja. Muatan masa import sekurang-kurangnya berada dalam sumber yang boleh dibaca. Pendaftaran perkhidmatan bukanlah kedua-duanya: ia ialah nama fail ditambah satu baris yang menamakan kelas dan tingkah laku tersebut berada dalam bytecode yang dikompilasi satu direktori jauhnya.
Kelas muatan itu sendiri melakukan peninjauan hos dengan mengeluarkan shell. Kolam pemalar kelas yang dikompilasi mengandungi / Bin / sh, siapakah saya, uname -a, jentera pada laluan Unix dan tasklist pada laluan Windows, bersama-sama dengan AliranRalat pengalihan untuk menggabungkan output ralat proses anak ke dalam strim yang ditangkap. Dua templat JSON membawa hasil daripada hos — satu suar pendaftaran:
{"host":"%s","os":"%s","user":"%s","dir":"%s"}
penduduknya dari nama hos perintah dan nama.os, nama pengguna, dan pengguna.dir sifat sistem dan panggilan balik hasil:
{"version":"%s","host":"%s","time":"%s","output":"%s"}
Penanda kemajuan yang ditinggalkan dalam output pengkompil sendiri adalah luar biasa terang: [C2] pelaksanaan masa kompilasi selesai, [C2] panggilan balik dihantar → HTTP , [C2] cangkerang disambungkan ke .
Sembilan keluaran, tiga generasi C2
Siaran tersebut bukanlah sembilan salinan bagi satu muatan. Ia merupakan log lelaran dan membacanya mengikut susunan menunjukkan saluran sedang dibina semula sementara vektor penghantaran kekal tetap.
| Lepaskan | Melaksanakan secara automatik semasa kompilasi | Saluran |
|---|---|---|
1.0.0 | tiada (tiada fail perkhidmatan) | URL panggilan balik yang dibekalkan oleh pengendali sahaja |
1.0.1 | ya (vektor diperkenalkan) | URL panggilan balik yang dibekalkan oleh pengendali |
1.0.2 | yes | Cangkang terbalik, terowong TCP ngrok |
1.0.3 | yes | Saluran HTTP, /daftar /cmd /keluar |
1.0.4 | yes | Saluran HTTP, /daftar /cmd /keluar |
1.0.5 | yes | Saluran HTTP, /daftar /undi /keluar |
1.0.6 | yes | Saluran HTTP, /daftar /undi /keluar |
1.0.7 | yes | Saluran HTTP, /daftar /cmd |
1.0.8 | yes | Pengesahan saluran HTTP + TLS dilumpuhkan |
Tiga butiran dalam jadual itu perlu digariskan, kerana setiap satunya mengubah cara set artifak harus dibaca.
Vektor tiba pada 1.0.1, bukan 1.0.2. Keluaran 1.0.0 membawa logik peninjauan dan panggilan balik yang sama tetapi tidak mempunyai fail perkhidmatan dan tiada import pemprosesan anotasi; ia hanya berjalan jika sesuatu memanggilnya. Dari 1.0.1, fail perkhidmatan hadir dan kelas yang dikompilasi diimport javax.annotation.processing.SokonganSumberVersiSebarang penilaian yang membandingkan dua keluaran bertiket — 1.0.0 dan 1.0.2 — menyimpulkan dengan betul bahawa sesuatu telah berubah, tetapi salah mengenal pasti di mana.
Cangkerang terbalik wujud dalam tepat satu keluaran. Keluaran 1.0.2 mengandungi 0.tcp.ngrok[.]io, baris log [C2] cangkerang disambungkan ke 0.tcp.ngrok[.]io:19823, sepanduk interaktif cangkerang c2, dan penamat bingkai __TAMAT__Keluaran 1.0.3 dan seterusnya tidak mengandungi sebarang ciri tersebut dan sebaliknya sampai ke hos HTTPS. Permintaan penghapusan yang hanya menamakan keluaran bertiket akan memetik titik akhir TCP yang mati sambil meninggalkan saluran HTTP langsung, yang terdapat dalam enam keluaran kemudian, tanpa disebut.
Siaran akhir mengalih keluar pengesahan pengangkutan. Keluaran 1.0.8 menambah kelas yang melaksanakan javax.net.ssl.X509PengurusKepercayaan yang kaedah semakan sijilnya tidak melakukan apa-apa, pengesah nama hos yang sentiasa benar yang didaftarkan melalui tetapkanLalaiNamaHostPengesah, Dan percayaSemua rutin yang memasang kedua-duanya sebagai tetapan lalai JVM. Kesannya ialah untuk baki kompilasi itu, JVM menerima sebarang sijil daripada mana-mana hos — bukan sahaja untuk trafik muatan itu sendiri, tetapi untuk apa-apa sahaja yang dilakukan oleh binaan melalui TLS selepas itu.
Saluran HTTP, dalam kesemua enam keluaran yang menggunakannya, diterajui oleh satu hos: tableful-fervor-crazed.ngrok-free[.]devSetiap permintaan membawa pengepala amaran-langkau-pelayar-ngrok, yang menyekat halaman celahan yang disediakan oleh terowong ngrok percuma kepada pelayar. Set laluan beralih merentasi keluaran — /keluar hilang pada 1.0.7, dan /cmd berselang-seli dengan /poll — tetapi tuan rumah tidak pernah berubah.
Pengecualian diri memberitahu
Setiap POM dari 1.0.1 dan seterusnya menetapkan argumen pengkompil untuk binaan artifak itu sendiri:
-proc:tiada
Bendera itu melumpuhkan pemprosesan anotasi. Kesannya di sini adalah pracise: apabila projek yang mengandungi pemproses itu sendiri dikompilasi, pemproses tidak akan berjalan.
Bendera ini mempunyai kegunaan biasa sahaja. Projek yang menghantar pemproses anotasi selalunya perlu mengelak daripada menggunakan pemproses tersebut pada dirinya sendiri semasa bootstrap, dan dokumentasi alat binaan mengesyorkan perkara ini. Jika diabaikan sahaja, ia tidak membuktikan apa-apa.
Walau bagaimanapun, jika digabungkan dengan apa yang dilakukan oleh pemproses, ia menggambarkan asimetri tertentu: kod tersebut dilaksanakan pada mesin setiap orang yang mengkompil terhadap artifak, dan bukan pada mesin yang membina artifak. Bendera tersebut muncul dalam keluaran yang sama yang memperkenalkan fail perkhidmatan — 1.0.1 — dan dalam setiap keluaran selepasnya. Korelasi antara "keluaran tempat pelaksanaan masa kompilasi bermula" dan "keluaran tempat pelaksanaan masa kompilasi dimatikan secara setempat" ialah isyarat analitik tunggal yang paling berguna dalam set artifak, dan ia boleh dilihat dalam POM teks biasa tanpa menyahkompil apa-apa.
Kami perhatikan kesannya dan berhenti di situ. Tiada apa-apa dalam artifak yang menceritakan mengapa bendera itu dikibarkan.
Satu lagi metadata perlu disebut, kebanyakannya untuk melupuskannya. POM menamakan projek itu sebagai "Beban Makmal C2", menggambarkannya sebagai "artifak muatan makmal C2", dan melesenkannya di MIT. Pelabelan kendiri seperti ini kadangkala ditawarkan sebagai bukti bahawa sesuatu pakej adalah latihan penyelidikan.cise dan bukannya ancaman langsung, dan kadangkala bacaan itu betul — burung kenari yang diisytiharkan tanpa infrastruktur yang boleh dicapai adalah objek yang berbeza daripada yang ini. Ia tidak terpakai di sini. Implan berfungsi yang diterbitkan ke repositori awam, yang boleh dicapai oleh mana-mana pengguna, dengan infrastruktur keluar yang dibina semula tiga kali merentasi sembilan keluaran, ialah keupayaan langsung tanpa mengira apa yang dipanggil oleh metadatanya. Nama dalam POM tidak mengubah apa-apa tentang apa yang berlaku pada mesin yang mengkompil terhadapnya.
Petunjuk untuk mesin binaan
Jika hos binaan dikompilasi terhadap artifak ini, bukti tersebut berada dalam log binaan dan telemetri rangkaian dan bukannya dalam implan berterusan pada cakera — muatan berjalan di dalam proses pengkompil dan keluar bersamanya.
Dalam balang atau cache repositori tempatan
META-INF/services/javax.annotation.processing.Processormenamakanio.github.davidtimur.c2lab.C2Processor- Fail perkhidmatan md5
7d2a08a5c8869a47eea9fa62487dfbe4 - Kelas di bawah
io/github/davidtimur/c2lab/:C2Processor,C2Task,Task, dan dalam 1.0.8 kelas dalamanTask$1
Output dalam binaan
[C2] compile-time execution complete[C2] callback sent → HTTP[C2] callback failed:[C2] shell connected to- Sepanduk interaktif
c2-shell; penamat bingkai__END__
Telemetri dalam proses
javacsebagai ibu bapa kepada/bin/sh -c(Unix) atau penterjemah arahan Windows- Perintah kanak-kanak
whoami,uname -a,pwd(Unix) atautasklist(Windows) diindukkan oleh langkah kompilasi
Dalam telemetri rangkaian
- TCP Keluar ke
0.tcp.ngrok[.]io:19823(keluaran 1.0.2) - HTTPS ke
tableful-fervor-crazed.ngrok-free[.]dev, laluan/register,/cmd,/poll,/out(keluaran 1.0.3 hingga 1.0.8) - Permintaan pengepala
ngrok-skip-browser-warning: true - Minta padanan badan
{"host":...,"os":...,"user":...,"dir":...}or{"version":...,"host":...,"time":...,"output":...}
Dalam konfigurasi
- Pemboleh ubah persekitaran
CALLBACK,CALLBACK_URL; sifat sistemcallback.url
Metadata penerbit
- Kumpulan
io.github.davidtimur; alamat penerbitdavudboi999@gmail[.]com; kunci tandatanganE520C345EF94423D
Binaan yang menjalankan keluaran 1.0.8 memerlukan satu pemeriksaan tambahan. Oleh kerana keluaran tersebut memasang pengurus kepercayaan permisif sebagai lalai seluruh JVM, sebarang sambungan TLS yang dibuat kemudian dalam JVM yang sama — resolusi kebergantungan, muat naik artifak, langkah penggunaan — diteruskan tanpa pengesahan sijil. Trafik dari tetingkap tersebut tidak boleh dianggap disahkan.
Mengapa artifak yang dikompilasi memerlukan pengimbasan yang berbeza
JavacDoor ialah kes ujian yang berguna kerana ia menewaskan dua andaian biasa sekaligus, dan tiada kegagalan khusus untuk mana-mana perkakasan vendor.
Andaian pertama ialah kod berbahaya mengumumkan dirinya dalam manifes. Banyak perkakasan rantaian bekalan disusun mengikut kitaran hayat hooks, kerana untuk npm dan PyPI di situlah tindakan biasanya berada. JavacDoor tidak mempunyai cangkuk. Pencetusnya ialah fail pendaftaran perkhidmatan yang namanya ialah antara muka Java dan kandungannya ialah nama kelas. Untuk menangkapnya secara statik, anda perlu merawat META-INF/perkhidmatan/pemproses.pemprosesan.annotasi.javax sebagai titik permulaan pelaksanaan yang tersendiri, setanding dengan selepas pemasangan skrip — dan kemudian ikuti kelas yang dinamakan ke dalam bytecode. Ekosistem mempunyai mekanisme penemuan automatik mereka sendiri dalam bentuk ini, dan setiap satunya merupakan titik masuk sama ada tooling menyenaraikannya sebagai satu atau tidak.
Andaian kedua ialah rentetan berada dalam fail sumber. Untuk balang, titik akhir, arahan shell, templat JSON dan penanda log semuanya berada dalam himpunan malar .kelas fail. Alatan yang mengambil teks tidak menemui apa-apa — bukan kerana rentetan dikaburkan, tetapi kerana ia berada dalam bekas binari berstruktur yang tidak dihuraikan oleh imbasan teks. Setiap penunjuk rangkaian dalam siaran ini keluar daripada penghuraian kumpulan malar. Salah satunya ialah yang terbentuk sepenuhnya https:// URL berada dalam paparan biasa di dalam fail kelas; imbasan teks kandungan yang boleh dibaca dalam balang masih tidak dapat memaparkannya. Tiada pengekodan yang perlu diatasi di sini, hanya format kontena untuk dibaca.
Kedua-dua jurang mempunyai bentuk yang sama: format artifak dianggap sebagai beg fail dan bukannya sebagai struktur dengan semantik yang ditakrifkan. Pembetulannya tidak menarik — hurai bekas, senaraikan titik masuk penemuan automatik ekosistem itu sendiri dan ikutinya ke dalam kod yang dikompilasi. Khususnya untuk vektor masa binaan, semakan ketiga adalah murah dan mengejutkan diagnostik: bandingkan apa yang dilakukan oleh artifak kepada pengguna berbanding apa yang dikecualikannya. Artifak yang mendaftarkan pemproses masa kompilasi dan serentak melumpuhkan pemprosesan masa kompilasi untuk binaannya sendiri telah memberitahu anda sesuatu tentang dirinya dalam dua baris POM teks biasa.
Bagi pasukan yang menggunakan artifak Maven hari ini, tiga langkah praktikal berikut:
- Anggap laluan pemproses anotasi sebagai sempadan pelaksanaan. Kebergantungan yang sampai di sana menjalankan kod dalam binaan anda. Jika binaan tidak memerlukan pemprosesan anotasi, -proc:tiada adalah sama bergunanya secara defensif seperti yang nampaknya berlaku di sini; jika ia berlaku, pin set pemproses secara eksplisit dan bukannya mewarisinya daripada laluan kelas kompilasi.
- Subproses pengkompil log. Langkah kompilasi yang menghasilkan shell adalah anomali dalam kebanyakan projek dan mudah dimaklumkan.
- Jangan anggap metadata sebagai testimoni. "Makmal", "ujian", "muatan" dan "PoC" dalam nama atau perihalan pakej bukanlah had skop. Kebolehcapaian dan tingkah laku adalah had.
Artifak dan seluruh kumpulannya telah dikeluarkan dari Maven Central mengikuti laporan kami; kedua-dua laluan artifak dan laluan kumpulan kini mengembalikan 404, dan indeks Central tidak melaporkan koordinat yang sepadan. Itu menutup artifak ini. Ia tidak menutup vektor, yang merupakan ciri yang didokumenkan bagi pengkompil Java dan tersedia untuk sesiapa sahaja yang menerbitkan balang.
Rujukan
Catatan ini tidak memetik sumber luaran. Semua penemuan adalah analisis statik langsung terhadap sembilan balang yang diterbitkan, yang diambil dari Maven Central sebelum penyingkiran. Tiada kod daripada artifak dilaksanakan pada bila-bila masa.







