- Setelah menawarkan posisi software engineer di LinkedIn, pelaku mengirim repositori GitHub privat yang disamarkan sebagai tugas React/Web3 normal; saat dijalankan, malware JavaScript yang disembunyikan di
tailwind.config.jsaktif di komputer pengembang - File konfigurasi berukuran 30.987 byte itu menyembunyikan 27KB kode terobfuskasi di balik ribuan spasi, lalu mengambil payload tahap kedua yang dienkripsi dengan AES-256-CBC dari server jarak jauh, menyimpannya ke
%TEMP%\pack, kemudian menjalankannya dengannode pack - Hasil observasi sekitar 10 menit di VM terisolasi Windows 11 ARM menunjukkan payload tersebut mengaktifkan empat komponen: backdoor kendali jarak jauh, pencuri data browser dan dompet, pemindai file rekursif, serta pemantau clipboard
- Melalui Socket.IO, malware mengendalikan terminal, SSH, layar, keyboard, dan mouse, serta mengumpulkan database Chromium, penyimpanan ekstensi dompet, kunci SSH, source code, file konfigurasi, dan lainnya; pada port unggah file teramati 2.588 permintaan
- Repositori tugas dari orang tak dikenal harus diperlakukan sebagai kode tidak tepercaya dan diperiksa di VM atau container sekali pakai tanpa profil browser asli, kunci SSH, kredensial cloud, atau dompet; jika sudah terinfeksi, setelah memutus jaringan dan menjaga bukti, rahasia juga harus diganti
Repositori yang menyamar sebagai tugas rekrutmen Web3 biasa
- Pengguna LinkedIn Wayan Adrian menawarkan posisi software engineer di shrapnel.com dan mengirim repositori GitHub privat
tech-active-workplace-frontend-maindari akunyevhen-osebagai tugas - Platform kampanye NFT bernama BLAIEXS secara lahiriah tampak seperti proyek React/Web3 biasa
- Frontend React menyediakan brand, dashboard admin, pengelolaan kampanye, alur pembuatan NFT, dan lain-lain
- API Express menangani autentikasi, data dashboard, pemeriksaan KYB, pembuatan dan klaim NFT, unggah file, serta beberapa endpoint stub
- Skrip seed membuat akun demo superadmin, brand, dan konsumen, kampanye
Demo NFT Drop, serta NFTDemo Collectiblesebanyak 100 unit
- Ruang lingkup tugas sebenarnya hanyalah fitur sederhana penampil jaringan MetaMask
getChainId()asinkron disrc/utils/ethereum.jsdiimplementasikan agar memanggileth_chainIddan mengembalikan nilai heksadesimal yang telah di-parse ataunullgetNetworkLabel(chainId)di file yang sama diimplementasikan agar mencari nama jaringan yang mudah dibaca dari objekNETWORKSyang sudah adasrc/components/Wallet/ConnectWalletButton.jsdimodifikasi agar memanggil kedua fungsi tersebut setelah dompet terhubung
- Setelah implementasi selesai, server pengembangan dijalankan, tetapi lama tidak mulai; pengguna yang merasa ada kejanggalan lalu mencabut kabel internet
Kode eksekusi yang disembunyikan di tailwind.config.js
- Pada
ls -la,tailwind.config.jsberukuran 30.987 byte, tetapi editor hanya menampilkan 97 baris; ukuran yang sama juga terkonfirmasi lewatwc -c - Di sekitar baris ke-95, blob JavaScript besar yang sulit dibaca manusia disembunyikan setelah ribuan spasi
- Kode tersebut menggunakan metode obfuskasi JavaScript yang umum
- Menyimpan string penting dalam array besar
- Memutar array sampai checksum cocok
- Menyembunyikan akses string di balik fungsi decoder
- Mengganti nama yang jelas dengan indeks numerik dan pemanggilan wrapper
- Salah satu dari dua decoder memulihkan string dalam bentuk Base64, sedangkan yang lain menerapkan kunci per string dan stream cipher mirip RC4; array string juga diputar sebelum indeks decoder cocok
- Tanpa menjalankan malware, obfuskasi bisa dibuka dengan urutan berikut
- Mengekstrak array string
- Mereproduksi rotasi array hingga mencapai checksum yang diharapkan
- Mengimplementasikan ulang fungsi decoder
- Mengganti pemanggilan seperti
b(0x214),c(0x2f1, "key")dengan string aslinya - Menyederhanakan objek wrapper dan fungsi helper untuk menampilkan maksud eksekusinya
Cara kerja dropper tahap pertama
- Kode yang telah dibuka memuat
child_process,os,fs,path,crypto, lalu memasangaxiosdansocket.io-clientke direktori sementara - Handler
uncaughtExceptiondanunhandledRejectionpada level proses dikonfigurasi untuk mengabaikan error - Alur eksekusi payload jarak jauh adalah sebagai berikut
- UID-nya adalah
59e605dd78fb2aafccd1b622f06a00ca - Mengambil data dari
http://45.146.252.17/api/service/59e605dd78fb2aafccd1b622f06a00ca - Memasukkan UID dan string
saltkecrypto.scryptSyncuntuk menurunkan kunci 32 byte - Memisahkan respons dalam format
base64_iv:base64_ciphertextlalu mendekripsinya denganaes-256-cbc - Menulis plaintext ke file
packdi direktori sementara - Menjalankannya dengan
child_process.execSync("node pack", { windowsHide: true, cwd: os.tmpdir() })
- UID-nya adalah
- Ini adalah malware dropper yang mengunduh dan menjalankan malware lain alih-alih menjalankan fungsi sendiri
- Kode yang diunduh tidak memiliki verifikasi tanda tangan, allowlist hash, pinning asal, pembatasan path, atau guard pencegah eksekusi, sehingga endpoint jarak jauh dapat menjalankan kode dengan hak akun sistem operasi yang memuat konfigurasi Tailwind tersebut
Analisis dinamis yang dilakukan di VM terisolasi
- Untuk menghindari pemaparan sistem host, disiapkan Windows 11 ARM VM sekali pakai dengan UTM
- Memori
4096 MiB - Disk
64 GiB - Jaringan
shared/NAT - Folder bersama dinonaktifkan
- Memori
- Dipasang sejumlah alat agar perilaku malware dapat dikumpulkan dari beberapa sudut pandang
- Wireshark: mengumpulkan paket serta lalu lintas C2 dan eksfiltrasi
- Sysinternals Sysmon: telemetri event Windows yang persisten
- Procmon: mengumpulkan aktivitas proses, registry, dan filesystem saat berjalan
- Untuk memeriksa target pengumpulan malware, ditempatkan data umpan
- Sepasang kunci SSH
- Repositori GitHub privat
- Dompet kripto
- Data browser
- File lain yang kemungkinan dibidik pencuri informasi
- Di VM,
yarn startdijalankan lalu diamati selama sekitar 10 menit, setelah itu diperolehrun1-full.pcapng,run1-sysmon.evtx, danstage2-pack.bin
Alur infeksi yang teramati di jaringan
- Permintaan HTTP ke
45.146.252.17dibagi peran berdasarkan port- Port
80: mengambil payload tahap pertama, registrasi host, pengiriman log - Port
7641: backdoor command-and-control Socket.IO - Port
7646: 2.588 kali unggah file - Port
7649: 3 kali unggah data browser yang lebih besar tetapi lebih sedikit jumlahnya
- Port
- Permintaan pertama adalah
GET /api/service/59e605dd78fb2aafccd1b622f06a00ca, dan responsnya berformatbase64_iv:base64_ciphertextdenganContent-Length: 150897 tailwind.config.jsmendekripsi respons dengan AES-256-CBC, menulis plaintext ke%TEMP%\pack, lalu menjalankannya dengannode pack- Karakteristik payload tahap kedua yang diperoleh adalah sebagai berikut
- SHA-256:
68a64d8c015c06fd70bcb8c5878c1e430da827dd00b62f8e6ef69e76bb94de5b - Ukuran:
113136byte - Format: JavaScript ASCII satu baris
- SHA-256:
packyang sudah didekripsi juga kembali terobfuskasi, tetapi karena menggunakan teknik yang sama seperti tahap pertama, ia dapat dibuka dengan prosedur yang sama
Payload tahap 2 yang terdiri dari empat program
packbukan satu skrip tunggal, melainkan pohon proses kecil yang menjalankan empat program berikut- Menulis dan menjalankan backdoor command-and-control
scdatake direktori sementara - Menulis dan menjalankan pencuri data browser dan dompet
ldatake direktori sementara - Menjalankan pemindai file rekursif langsung di memori dengan
node -e - Menjalankan pemantau clipboard langsung di memori dengan
node -e
- Menulis dan menjalankan backdoor command-and-control
- Konfigurasi utamanya adalah UID
59e605dd78fb2aafccd1b622f06a00ca, kunci pengguna308, host45.146.252.17, port Socket.IO7641, port key7648, port unggah browser7649, dan port unggah file7646
scdata: backdoor kendali jarak jauh interaktif
scdataditulis sebagai file ke%TEMP%, lalu dijalankan dengannpm i axios socket.io-client ... && node scdata, dan tetap menjadi proses anak yang berjalan lama- Setelah dijalankan, ia mengatur dirinya agar tampak seperti proses normal
- Judul proses:
vhost.ctl - File penanda instans tunggal:
%TEMP%\\.npm\\vhost.ctl - Registrasi host:
http://45.146.252.17/api/service/… - Pengiriman log:
http://45.146.252.17/api/service/makelog - C2 Socket.IO:
http://45.146.252.17:7641
- Judul proses:
- Ia juga memasang paket tambahan yang diperlukan untuk fungsi kendali jarak jauh
socket.io-client,ssh2,node-pty: terminal dan fungsi mirip SSHsharp,screenshot-desktop,clipboardy,@nut-tree-fork/nut-js: screenshot, clipboard, gerakan/klik/scroll mouse, input keyboard
- Event Socket.IO secara langsung menunjukkan cakupan kendali jarak jauhnya
- Terminal:
start-terminal,terminal-input,terminal-resize,stop-terminal,command - Verifikasi host dan pengambilan tangkapan:
whour,capture - Kendali input:
mouseMove,mouseClick,mouseScroll,keyTap,keyCombo - Clipboard:
copyText,pasteText - SSH dan terminasi:
start_ssh,ssh_input,kill
- Terminal:
- Dalam PCAP, terkonfirmasi polling dan handshake WebSocket pada port
7641serta event server awalwhour, dan di Sysmon tertangkap secara berurutannode.exe scdata, PowerShell kueri informasi sistem, serta pemasangan dua kelompok paket npm - Melampaui sekadar pencurian informasi, ini juga memberi penyerang kemampuan shell dan kendali desktop
ldata: pencuri data browser dan dompet
ldataditulis ke%TEMP%dan dijalankan dengannpm i axios && node ldata, dengan judul prosesnpm-cache- Ia mengumpulkan profil browser dan penyimpanan ekstensi dompet lalu mengirimkannya ke
http://45.146.252.17:7649/upload, dan status LevelDB dicek di/cldbs - Browser target dikonfigurasi luas menurut sistem operasi
- Windows: Chrome, Edge, Brave, LT Browser
- macOS: Chrome, Brave, Opera, LT Browser, Edge dan keychain login lokal
- Linux: folder profil turunan Chromium yang sesuai
- Dari direktori
DefaultatauProfile*, ia mengunggah database Chromium berikutLogin DataLogin Data For AccountWeb Data
- Setelah itu ia menelusuri
Local Extension Settings/<extension-id>, dan ID ekstensi dompet yang di-hardcode mencakupnkbihfbeogaeaoehlefnkodbefgpgknnmilik MetaMask - Untuk delapan jalur ekstensi dompet pertama, direktori LevelDB disalin ke folder sementara dan file-file individual diunggah, lalu status selesai atau percobaan ulang ditentukan berdasarkan respons
cldbsdari server - Tiga unggahan yang terkonfirmasi pada port
7649adalah database berikutLogin_Data.sqlite: 51.200 byteLogin_Data_For_Account.sqlite: 51.200 byteWeb_Data.sqlite: 262.144 byte
- Data eksperimen tidak berisi kata sandi tersimpan atau baris kartu, tetapi memuat 6 nilai autofill dan metadata browser
- Browser berbasis Chrome mengenkripsi sebagian field secara lokal, sehingga database saja tidak selalu cukup untuk memulihkan rahasia dalam bentuk plaintext
- Namun bila digabungkan dengan rahasia OS, cookie, penyimpanan ekstensi, dan browser yang sudah terbuka, ini menjadi bagian dari pipeline pencurian kredensial
- Ia berhenti setelah mengunggah data browser dan LevelDB yang dibutuhkan atau ketika server menandainya selesai, tanpa menunggu perintah tambahan dari operator
Pemindai file rekursif dan pemantau clipboard
- Pemindai file rekursif dijalankan dengan
node -etanpa membuat file terpisah, dan mulai menelusuri dari direktori home pengguna- Di Windows, huruf drive didaftarkan dengan
Get-CimInstance Win32_LogicalDiskdan root tiap drive juga diperiksa - Pola file yang dikumpulkan mencakup
*.env*,*.md,*.pem,*.ini,*.secret,*.json,*.js,*.ts,*.csv,*.txt,*.doc,*.docx,*.pdf,*.xlsx,.zsh_history,.bash_history ~/.ssh,~/.aws,~/.azure,~/.config,~/.foundryotomatis diperlakukan sebagai folder penting- Ia juga mencari nama seperti
metamask,bitcoin,btc,solana,secret phrase,private key - Hasilnya dikirim ke
http://45.146.252.17:7646/upload
- Di Windows, huruf drive didaftarkan dengan
- Di lingkungan umpan,
id_ed25519,id_ed25519.pub,History.txt,seed.js,password.js,tokens.js,ConnectWalletButton.js,ExportWallet.js,RegisterWallet.js,tailwind.config.js,aptos-cli.jsondan lainnya benar-benar diunggah - Jika
ldatakhusus menangani penyimpanan browser dan dompet, maka pemindai file secara luas mengumpulkan kunci SSH, konfigurasi, source code, rahasia lokal, riwayat shell, dan file proyek - Pemantau clipboard juga dijalankan dengan
node -e, dengan judul prosesnpm-compiler.log- Setelah menunggu beberapa detik, ia berulang kali membaca clipboard
- Di macOS ia menggunakan
pbpaste, di Windows menggunakanpowershell -NoProfile -NonInteractive Get-Clipboard - Nilai yang berubah dikirim ke
http://45.146.252.17/api/service/makelog
- Bahkan tanpa menafsirkan format, ia bisa langsung menangkap kata sandi, frasa pemulihan, kunci privat, token API, kode sekali pakai, URL GitHub, alamat dompet, dan rahasia deployment yang disalin pengguna
Prinsip yang harus dijaga sebelum menjalankan tugas rekrutmen
- Repositori tugas yang dikirim orang asing harus diperlakukan sebagai kode eksekusi tak tepercaya sampai keamanannya terverifikasi
- Sebelum
yarn install,npm install,yarn build,yarn start, hal-hal berikut harus ditinjaupackage.json- Skrip lifecycle
- File konfigurasi
- Hook dependensi yang jelas
- Malware dalam kasus ini bersembunyi di
tailwind.config.js, yang mudah terlewat, dan file konfigurasi, dependensi, serta build tool semuanya bisa dieksekusi sebagai kode - Proyek wawancara harus dijalankan di VM atau container sekali pakai yang tidak memasang rahasia nyata
- Profil browser pribadi
- Password manager
- Kunci SSH
- Dompet kripto
- Token GitHub
- Kredensial cloud
- Sesi perbankan
- Akun email utama
- Untuk tugas yang memerlukan akun atau dompet, gunakan identitas uji baru yang tidak memiliki dana dan tidak dipakai ulang di layanan lain
- Untuk tugas Web3, gunakan hanya testnet, dan jangan hubungkan dompet nyata ke proyek tak dikenal meskipun terlihat tidak berbahaya
Indikator untuk memeriksa apakah sistem terinfeksi
- Di macOS·Linux, periksa terlebih dahulu item berikut
- proses yang sedang berjalan terkait
node,pack,scdata,ldata,npm-compiler,vhost.ctl - koneksi ke
45.146.252.17atau port7641,7646,7649 pack,scdata,ldata,vhost.ctldi bawah direktori sementara, Downloads, Desktop, Documents, Library- file penanda
*/.npm/vhost.ctl - string IP, UID,
/api/service/makelog,node scdata,node ldata,node packdi dalam proyek yang diunduh
- proses yang sedang berjalan terkait
- Di Windows, periksa item berikut
- di antara proses
node,npm,cmd,powershell, item yang baris perintahnya berisipack,scdata,ldata,node -e, alamat IP,Get-Clipboard - koneksi TCP terbuka ke
45.146.252.17atau port jarak jauh7641,7646,7649 pack,scdata,ldata,vhost.ctl,.npm\vhost.ctldi bawah%TEMP%- string C2 yang diketahui di dalam direktori tempat repositori wawancara dikloning
- di antara proses
- Jika ditemukan proses Node yang masih aktif, koneksi ke IP tersebut, atau salah satu artefak
pack·scdata·ldata, sistem harus dianggap sudah terekspos - Indikator ini adalah poin pemeriksaan awal yang spesifik untuk sampel yang dianalisis dan bukan prosedur forensik yang lengkap
Pembersihan sistem yang terinfeksi dan penggantian kredensial rahasia
- Pertama-tama, putuskan komputer dari jaringan, dan jangan terus menelusuri, melakukan debug, atau menyalin kredensial rahasia baru di lingkungan yang terinfeksi
- Jika bukti diperlukan, simpan dulu materi berikut sebelum menghapus apa pun
- daftar proses
- koneksi jaringan
- file mencurigakan
- riwayat browser
- repositori berbahaya
- Setelah itu, hentikan proses yang terkait dengan
node pack,node scdata,node ldata,node -e,npm-compiler,vhost.ctl, lalu hapuspack,scdata,ldata,.npm/vhost.ctldari direktori sementara - Jika ini adalah VM sekali pakai dan tidak perlu mempertahankan pekerjaan Node yang sah, Anda dapat memakai
pkill nodedi macOS·Linux atau penghentian paksa semua prosesnodedi Windows - Hapus repositori berbahaya dan
node_modules, tetapi jika analisis tambahan diperlukan, simpan salinan ZIP secara offline - Menghapus file saja tidak cukup; kredensial rahasia berikut harus diganti atau dicabut
- kunci SSH
- token GitHub·npm
- kunci cloud dan kunci API
- kredensial rahasia deployment
- kata sandi yang tersimpan di browser
- sesi login yang masih aktif
- Jika ada kemungkinan seed wallet atau private key sempat tersentuh sistem yang terinfeksi, buat wallet baru di perangkat yang bersih lalu pindahkan dananya
Serangan yang menyalahgunakan batas kepercayaan alat pengembang
- Produk antivirus tradisional tidak mendeteksi repositori ini, dan agen coding AI populer yang dipakai untuk mengerjakan tugas juga gagal mengidentifikasi malware yang disembunyikan di dalam proyek
- Tailwind mengevaluasi file konfigurasi JavaScript sebagai modul Node, sehingga saat alat pengembang·skrip build·integrasi editor·Tailwind CLI·bundler·pekerjaan CI memuat konfigurasi, IIFE di baris ke-95 akan dijalankan
- Konfigurasi Tailwind yang normal hanya sampai baris ke-94, dan setelah itu ditambahkan sekitar 27KB kode yang diobfuscate
- Payload yang diunduh dijalankan dengan hak akses sistem operasi yang sama dengan pengguna yang memuat konfigurasi
- dapat mengakses file lokal, profil browser, kredensial tersimpan, data ekstensi wallet, kunci SSH, variabel lingkungan, token paket, kredensial cloud, source code, clipboard
- jika dijalankan di CI, kredensial rahasia deployment, artefak build, kredensial registry, dan token akses produksi juga dapat terekspos
- Perbaikan yang diperlukan adalah menghapus sepenuhnya blob JavaScript yang diobfuscate dari
tailwind.config.js
Belum ada komentar.