Keamanan

Library npm mathmain Simpan Implant Terenkripsi: Bedah Malware Supply Chain 2026

Library npm mathmain Simpan Implant Terenkripsi: Bedah Malware Supply Chain 2026

Salah satu library matematika di npm ternyata menyimpan remote access implant yang dienkripsi dan didesain tidak aktif sampai korbannya menjalankan satu persamaan tertentu. Kasus ini dibedah publik oleh tim SafeDep lewat postingan 18 September 2026, dan polanya jauh lebih licik daripada malware npm pada umumnya. Tidak ada install hook, tidak ada kode mencurigakan yang langsung jalan, dan source code di GitHub-nya bersih. Kodenya baru "bangun" ketika fungsi solver dipakai menghitung matriks dengan nilai yang sangat spesifik.

Artikel ini mengurai cara kerja loader tersebut, kenapa mekanisme enkripsinya bikin deteksi biasa jadi tidak berguna, dan langkah konkret yang bisa diambil developer Indonesia yang dependensi npm-nya mungkin ikut kepasang.

mathmain: Kembaran mathjs yang Menyimpan Sesuatu

Paket bermasalahnya bernama mathmain. Secara tampilan, ini praktis kembaran mathjs, library matematika JavaScript yang sangat populer, dengan nama berbeda dan kode yang diobfuscasi. Analisis SafeDep dimulai pada 17 September 2026, dan yang membuat mereka curiga bukan manifest-nya, bukan juga install script, melainkan satu extra call yang nyelip di dalam fungsi lusolve(), solver untuk sistem persamaan linear.

Di build CommonJS-nya, setelah hasil kalkulasi selesai, ada pemanggilan tambahan ke removeSolveValidation() yang mengirim data matriks segitiga bawah. Hasil pemanggilannya disimpan ke variabel yang tidak pernah dipakai lagi. Sepintas terlihat seperti kode validasi sisa build. Ternyata fungsi itu adalah pintu masuk ke rantai dekripsi.

Dari situ alurnya bergerak ke fungsi isGraph() di file lib/cjs/utils/is.js. Fungsi ini mengkonversi inputnya menjadi string JSON, lalu memakai string itu sebagai password untuk membongkar sebuah blob base64 yang tertanam di file yang sama. Blob itu pertama-tama didekripsi menjadi nama file, lalu file hasil dekripsi ditulis ke disk dan dimuat dengan require(). Kode yang lolos dari proses itu berjalan dengan izin penuh setara proses Node.js.

Enkripsi yang Kuncinya adalah Data Matematika

Bagian paling aneh dari kasus ini: password-nya bukan string statis yang bisa dicari dengan grep. Loader ini memakai skema yang cukup serius: turunan key dengan scrypt sepanjang 256 bit, lalu dekripsi AES-256-GCM. Layout blob-nya tetap, 16 byte salt, 12 byte initialization vector, 16 byte authentication tag, sisanya ciphertext, semuanya dibungkus base64.

Password yang dipakai adalah hasil JSON.stringify() dari matriks L (faktor segitiga bawah dari dekomposisi LU). Artinya, kodenya hanya terbuka kalau ada program yang memanggil solver dengan matriks yang menghasilkan string persis sama. Salah satu angka saja, cek autentikasi AES-GCM gagal, tidak ada file yang ditulis, dan tidak ada perilaku mencurigakan yang muncul.

Pemicunya akhirnya teridentifikasi: inputnya adalah matriks Pascal 3x3, yaitu [[1,1,1],[1,2,3],[1,3,6]]. Ketika matriks itu didekomposisi secara LU, faktor L-nya menjadi [[1,0,0],[1,1,0],[1,0.5,1]], dan bentuk JSON dari matriks itulah password-nya. SafeDep menyebut JFrog lebih dulu melaporkan input pemicu ini, lalu mereka mereproduksinya terhadap file mathmain. Hasilnya konsisten: password yang sama membuka seluruh keluarga paket ini.

Tiga File Besar Berisi Ciphertext, Bukan JavaScript

Di direktori utils paket tersebut, tim SafeDep menemukan tiga file yang isinya bukan kode JavaScript normal, melainkan data base64 berukuran besar:

  • graph.js sekitar 20.918 byte ciphertext
  • fraction.js sekitar 9.084 byte
  • bignumber/type.js sekitar 1.179.416 byte

Dua file terakhir tidak dirujuk oleh loader yang terlihat. Keduanya baru dipanggil setelah stage pertama, graph.js, berhasil didekripsi dan dieksekusi. Dari hasil analisis statik terhadap kode yang sudah terbuka, file-file itu membentuk implant akses jarak jauh: stage pertama mengumpulkan data host, membuat pasangan kunci X25519 lewat modul crypto Node, dan punya jalur eksekusi perintah shell lewat child_process. Kanal perintahnya tidak memakai server C2 konvensional, tapi menumpang pada layanan chat publik dan jaringan blockchain, kombinasi yang makin sering dipakai malware modern supaya traffic-nya sulit diblokir.

Sumbernya Bukan di GitHub, Melainkan di Proses Publish

Detail yang bikin kasus ini penting untuk dipahami: dua paket saudaranya, mathsbase dan math-universe, menautkan repository GitHub publik. Keduanya dibaca tim SafeDep, dan di commit yang dituju, kode loader itu tidak ada. Solver di sumber GitHub mengakhiri fungsinya dengan rapi tanpa extra call. Loader itu baru ditambahkan pada saat build dipublikasikan ke registry.

Ini menegaskan satu kelas risiko yang sering terlewat: audit terhadap repository saja tidak cukup, karena artefak npm yang terpasang di mesin developer tidak wajib identik dengan sumbernya. Loader yang sama ditemukan di lima versi lintas tiga paket itu. Untuk mathmain sendiri, versi default yang diserve registry pada 17 September (1.5.3) justru bersih, sementara versi 1.0.1 yang membawa implant. Jadi cek satu baris ke versi terbaru saja, malware-nya lolos.

Angka Download yang Tidak Bisa Dipercaya

SafeDep memeriksa statistik unduhan registry pada 19 September untuk tiga paket tersebut, mencakup rentang 12 sampai 18 September 2026 di semua versi. Angkanya fantastis: mathmain 605.157 unduhan, mathsbase 1.923.059, dan math-universe 569.730.

Tapi tim itu sendiri langsung memberi peringatan: angka-jangan dibaca sebagai jumlah instalasi nyata. npm pada periode yang sama melaporkan nol unduhan untuk seluruh registry pada 17 September, yang membuat hitungan sebelumnya tidak bisa dijadikan acuan. Paket-paket ini juga tidak punya dependents publik, dan traffic di jaringan konten jsDelivr nyaris nol. Sampai postingan diterbitkan, tidak bisa ditentukan apa yang menghasilkan volume sebesar itu, dan berapa banyak (kalau ada) sistem yang benar-benar menjalankan kode terenkripsinya.

Terus, kenapa angka download tidak jujur? Untuk paket yang belum diadopsi siapa pun, lonjakan tidak wajar adalah sinyal itu sendiri: manipulasi metrik adalah cara klasik menaikkan skor popularitas palsu supaya paket terlihat sah oleh manusia maupun oleh mesin rekomendasi otomatis.

Percaya atau Tidak, Pencarian Password-nya Bukan Hal Sepele

Aspek lain yang layak dicatat: tim SafeDep butuh upaya besar untuk membongkar kunci ini. Percobaan pertama menguji 16.922 kandidat password terhadap file nama terenkripsi, termasuk matriks dengan elemen diagonal nol yang sempat terlewat. Percobaan kedua menguji 533 kandidat terhadap lima blob terenkripsi yang berbeda, memakai password umum dan matriks dari test suite solver. Semua gagal, tidak ada yang lolos cek autentikasi.

Kuncinya ternyata bukan nilai generik, melainkan satu matriks spesifik (Pascal 3x3 tadi). Skenario pemicu seperti ini juga menjelaskan kenapa payload-nya bisa berbulan-bulan tidak terdeteksi: implant hanya aktif di jalur kode yang jarang dieksekusi. SafeDep menyatakan mencari program publik yang memanggil solver dengan pemicu itu lewat penelusuran kode GitHub, lockfile, dan layanan dependensi, dan tidak menemukan satu pun.

Yang Bisa Dilakukan Developer: Checklist Praktis

Pola serangan mathmain menargetkan titik buta tooling keamanan mainstream. Beberapa pembersihan yang realistis untuk dilakukan, diurutkan dari yang paling murah:

  • Kunci versi secara eksplisit. Jangan mengandalkan "versi terbaru sudah aman". Kasus ini membuktikan versi lama yang masih bisa di-resolve justru membawa payload, sementara versi default bersih.
  • Perlakukan paket mirror/typosquat sebagai red flag. mathmain adalah salinan dengan nama berbeda. Sebelum menambah dependensi, cocokkan nama dengan paket asli, cek repository, riwayat publikasi, dan jumlah dependents terbalik.
  • Audit lockfile, bukan hanya manifest. yang menentukan isi yang terpasang di CI dan di laptop adalah lockfile. Diff package-lock secara rutin, karena loader bisa masuk lewat versi yang jarang dipakai tapi masih bisa ter-resolve.
  • Jangan bersandar pada install script sebagai satu-satunya sinyal. Paket ini tidak punya install hook, dan kodenya aktif lewat jalur require biasa. Rekomendasi umum "pakai --ignore-scripts" tetap layak sebagai pertahanan berlapis, tapi kasus ini menunjukkan itu bukan obat mujarab.
  • Monitoring egress di environment produksi. Koneksi keluar ke protokol blockchain atau API layanan chat yang tidak dikenal adalah anomali yang bisa ditangkap dari sisi jaringan, bahkan tanpa memahami isi kodenya.

Timeline Kasusnya, Singkat dan Padat

Biar mudah dirujuk, kronologinya kurang lebih begini. Pada 17 September 2026, SafeDep memulai analisis terhadap mathmain setelah paket itu masuk antrean pemindaian sebagai kandidat tiruan mathjs. Di hari yang sama, registry masih menyerve versi 1.5.3 sebagai release default yang bersih, sementara 1.0.1 menyimpan loader. JFrog lebih dulu mempublikasikan temuan soal input pemicu password, lalu SafeDep mereproduksinya terhadap file asli dan memastikan satu kunci yang sama membuka seluruh keluarga paket. Pada 18 September 2026, laporan lengkapnya terbit publik beserta indikator compromise. Sehari kemudian, 19 September, tim memeriksa statistik unduhan dan menemukan pola volume yang tidak masuk akal seperti diuraikan di atas. Rantai kejadian ini juga menjelaskan kenapa dua saudaranya, mathsbase dan math-universe, ikut masuk daftar amatan: file loader yang identik ditemukan melintasi lima versi di tiga paket.

Satu catatan tambahan dari laporan: artefak terenkripsi di tiap salinan tidak selalu identik. Payload mathmain dan math-universe terbukti sama persis byte per byte, sementara versi 1.0.2 memakai data terenkripsi berbeda dengan password yang sama. Artinya yang tersebar bukan satu artefak jadi, melainkan satu kerangka yang dibangun ulang per rilis, ciri khas operasi yang aktif dipelihara, bukan iseng sekali tempel.

Kenapa Pola "Kunci = Data" Jadi Tren yang Mengganggu

Membaca laporan SafeDep sampai selesai, pelajaran terbesarnya bukan satu paket bernama mathmain. Pelajarannya adalah pergeseran teknik: payload dienkripsi di in transit dengan kunci turunan yang berasal dari input program korban sendiri, sehingga di permukaan paket terlihat inert untuk hampir semua penggunaan. Static analysis biasa tidak melihat perilaku apa pun, dan dynamic analysis tidak memicu apa pun kalau test-nya tidak menjalankan jalur solver dengan input yang tepat.

Kombinasi pemicu deterministik plus jalur C2 yang menumpang infrastruktur publik seperti layanan chat dan blockchain membuat kategori malware ini bergerak di area abu-abu monitoring: traffic-nya mirip aplikasi legit. Untuk developer yang bergantung pada library pihak ketiga, satu-satunya perlindungan yang realistis adalah mengecilkan permukaan dependensi itu sendiri: lebih sedikit paket, semua terkunci versinya, dan sumbernya diverifikasi.

Sebagai rujukan lanjutan, laporan lengkap SafeDep tersedia publik di situs mereka dengan analisis payload, daftar indikator compromise, dan hash file asli yang bisa dipakai untuk mengecek sistem. Untuk yang ingin membaca contoh lain dari kelas risiko yang sama, artikel ZCode dan upload riwayat Git tanpa izin dan checklist hardening VPS pertama di Toolkuy membahas sisi lain supply chain dan keamanan server.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar akan muncul setelah moderasi.