• LinkedIn पर software engineer भर्ती का प्रस्ताव देने के बाद, एक private GitHub repository भेजी गई जो सामान्य React/Web3 assignment के रूप में छिपी हुई थी; चलाने पर tailwind.config.js में छिपा JavaScript malware developer के कंप्यूटर पर सक्रिय हो गया
  • 30,987-byte की configuration file ने हज़ारों spaces के बाद 27KB obfuscated code छिपाया था, remote server से AES-256-CBC से encrypted stage-2 payload लेकर उसे %TEMP%\pack में save किया और फिर node pack से execute किया
  • Windows 11 ARM isolated VM में करीब 10 मिनट तक observation करने पर पाया गया कि payload ने चार components चलाए: remote-control backdoor, browser और wallet stealer, recursive file scanner, और clipboard monitor
  • Socket.IO के ज़रिए terminal, SSH, screen, keyboard और mouse को control किया गया, और Chromium databases, wallet extension storage, SSH keys, source code, configuration files आदि collect किए गए; file upload port पर 2,588 requests observe हुईं
  • अनजान व्यक्ति द्वारा भेजे गए assignment repository को untrusted code मानकर ऐसे disposable VM या container में inspect करना चाहिए जिसमें real browser profile, SSH keys, cloud credentials या wallets न हों; अगर infection हो गया हो, तो network disconnect और evidence preservation के बाद secrets तक rotate करने चाहिए

सामान्य Web3 hiring assignment के रूप में छिपी repository

  • LinkedIn user Wayan Adrian ने shrapnel.com में software engineer role का प्रस्ताव दिया और assignment के रूप में yevhen-o account की private GitHub repository tech-active-workplace-frontend-main भेजी
  • BLAIEXS नाम का NFT campaign platform ऊपर से एक सामान्य React/Web3 project था
    • React frontend brand/admin dashboard, campaign management, NFT creation flow आदि प्रदान करता था
    • Express API authentication, dashboard data, KYB checks, NFT creation/claim, file upload और कुछ stub endpoints handle करता था
    • seed script superadmin, brand और consumer demo accounts, Demo NFT Drop campaign, और 100 items वाला Demo Collectible NFT बनाता था
  • असली assignment scope बस एक साधारण MetaMask network display feature था
    • src/utils/ethereum.js में async getChainId() को इस तरह implement करना था कि वह eth_chainId call करे और parsed hexadecimal value या null return करे
    • उसी file में getNetworkLabel(chainId) को existing NETWORKS object से पढ़ने योग्य network name खोजने के लिए implement करना था
    • src/components/Wallet/ConnectWalletButton.js को wallet connect होने के बाद दोनों functions call करने के लिए modify करना था
  • Implementation पूरी करके development server चलाया गया, लेकिन वह काफी देर तक start नहीं हुआ; गड़बड़ी भांपकर user ने internet cable unplug कर दी

tailwind.config.js में छिपा executable code

  • ls -la में tailwind.config.js 30,987 bytes का था, लेकिन editor में सिर्फ 97 lines दिखीं; wc -c से भी वही size confirm हुआ
  • line 95 के आसपास, हज़ारों spaces के बाद इंसान के लिए पढ़ना मुश्किल एक बड़ा JavaScript blob छिपा हुआ था
  • Code ने सामान्य JavaScript obfuscation techniques इस्तेमाल कीं
    1. अहम strings को एक बड़े array में store करना
    2. checksum match होने तक array को rotate करना
    3. string access को decoder function के पीछे छिपाना
    4. साफ names को numeric indexes और wrapper calls से replace करना
  • दो decoders में से एक Base64 format में strings recover करता था, जबकि दूसरा हर string के key और RC4-जैसे stream cipher को apply करता था; decoder indexes सही होने से पहले string array rotate किया जाता था
  • Malware execute किए बिना भी नीचे दिए क्रम में obfuscation हटाई जा सकी
    1. string array extract करना
    2. expected checksum तक पहुंचने के लिए array rotation reproduce करना
    3. decoder functions को reimplement करना
    4. b(0x214), c(0x2f1, "key") जैसी calls को असली strings से replace करना
    5. wrapper objects और helper functions को simplify करके execution intent सामने लाना

Stage-1 dropper का behavior

  • Deobfuscated code child_process, os, fs, path, crypto import करता है और temporary directory में axios और socket.io-client install करता है
  • Process-level uncaughtException और unhandledRejection handlers errors को ignore करने के लिए configured थे
  • Remote payload execution flow इस प्रकार था
    • UID 59e605dd78fb2aafccd1b622f06a00ca है
    • http://45.146.252.17/api/service/59e605dd78fb2aafccd1b622f06a00ca से data fetch करता है
    • UID और string salt को crypto.scryptSync में डालकर 32-byte key derive करता है
    • Response को base64_iv:base64_ciphertext format में split करता है और aes-256-cbc से decrypt करता है
    • Plaintext को temporary directory की pack file में लिखता है
    • child_process.execSync("node pack", { windowsHide: true, cwd: os.tmpdir() }) से execute करता है
  • यह खुद कोई feature perform करने के बजाय दूसरा malicious software download करके run करने वाला malware dropper है
  • Download किए गए code में signature verification, hash allowlist, origin pinning, path restrictions या execution-prevention guard नहीं थे, इसलिए remote endpoint Tailwind config load करने वाले OS account के privileges से code execute कर सकता है

Isolated VM में किया गया dynamic analysis

  • Host system को expose न करने के लिए UTM से disposable Windows 11 ARM VM configure किया गया
    • Memory 4096 MiB
    • Disk 64 GiB
    • shared/NAT networking
    • Shared folders disabled
  • Malware behavior को कई angles से collect करने के लिए tools install किए गए
    • Wireshark: packets और C2/exfiltration traffic collect करना
    • Sysinternals Sysmon: persistent Windows event telemetry
    • Procmon: running processes, registry और filesystem activity collect करना
  • Malware किन चीज़ों को collect करता है यह verify करने के लिए decoy data रखा गया
    • SSH key pair
    • Private GitHub repository
    • Cryptocurrency wallet
    • Browser data
    • Information stealer जिन अन्य files को target कर सकता है
  • VM में yarn start run किया गया, करीब 10 मिनट तक observe किया गया, फिर run1-full.pcapng, run1-sysmon.evtx, stage2-pack.bin हासिल किए गए

Network में दिखा infection flow

  • 45.146.252.17 पर जाने वाले HTTP requests में port के हिसाब से roles बंटे हुए थे
    • Port 80: stage-1 payload fetch, host registration, log transmission
    • Port 7641: Socket.IO command-and-control backdoor
    • Port 7646: file uploads 2,588 requests
    • Port 7649: बड़े लेकिन कम संख्या वाले browser data uploads के 3 requests
  • पहला request GET /api/service/59e605dd78fb2aafccd1b622f06a00ca था, और response Content-Length: 150897 वाला base64_iv:base64_ciphertext format था
  • tailwind.config.js response को AES-256-CBC से decrypt करता है, plaintext को %TEMP%\pack में लिखता है और फिर node pack से execute करता है
  • हासिल किए गए stage-2 payload की properties ये थीं
    • SHA-256: 68a64d8c015c06fd70bcb8c5878c1e430da827dd00b62f8e6ef69e76bb94de5b
    • Size: 113136 bytes
    • Format: single-line ASCII JavaScript
  • Decrypted pack भी फिर से obfuscated था, लेकिन first stage जैसी technique का इस्तेमाल कर उसी प्रक्रिया से deobfuscate किया जा सका

चार प्रोग्राम से बना चरण-2 payload

  • pack कोई एकल script नहीं था, बल्कि एक छोटा process tree था जो ये चार प्रोग्राम चलाता था
    1. scdata command-and-control backdoor को temporary directory में लिखकर execute करता था
    2. ldata browser और wallet stealer को temporary directory में लिखकर execute करता था
    3. recursive file scanner को node -e के जरिए सीधे memory में चलाता था
    4. clipboard monitor को node -e के जरिए सीधे memory में चलाता था
  • मुख्य configuration में UID 59e605dd78fb2aafccd1b622f06a00ca, user key 308, host 45.146.252.17, Socket.IO port 7641, key port 7648, browser upload port 7649, file upload port 7646 शामिल थे

scdata: interactive remote-control backdoor

  • scdata को %TEMP% में file के रूप में लिखा गया और npm i axios socket.io-client ... && node scdata से चलाया गया, और यह लंबे समय तक चलने वाले child process के रूप में बना रहा
  • चलने के बाद उसने खुद को सामान्य process जैसा दिखाने के लिए configure किया
  • remote-control functions के लिए जरूरी अतिरिक्त packages भी install किए
    • socket.io-client, ssh2, node-pty: terminal और SSH जैसी functionality
    • sharp, screenshot-desktop, clipboardy, @nut-tree-fork/nut-js: screenshot, clipboard, mouse movement/click/scroll, keyboard input
  • Socket.IO events remote-control scope को सीधे दिखाते हैं
    • terminal: start-terminal, terminal-input, terminal-resize, stop-terminal, command
    • host check और capture: whour, capture
    • input control: mouseMove, mouseClick, mouseScroll, keyTap, keyCombo
    • clipboard: copyText, pasteText
    • SSH और termination: start_ssh, ssh_input, kill
  • PCAP में port 7641 पर polling/WebSocket handshake और पहला server event whour confirm हुआ, और Sysmon में क्रम से node.exe scdata, system information query PowerShell, और npm package installation के दो groups पकड़े गए
  • यह सिर्फ जानकारी चुराने से आगे बढ़कर attacker को shell और desktop control functionality तक देता था

ldata: browser और wallet data stealer

  • ldata को %TEMP% में लिखा गया और npm i axios && node ldata से चलाया गया, और process title npm-cache था
  • यह browser profiles और wallet extension stores को collect करके http://45.146.252.17:7649/upload पर भेजता था, और LevelDB status को /cldbs पर check करता था
  • target browsers operating system के हिसाब से काफी व्यापक रूप से set थे
    • Windows: Chrome, Edge, Brave, LT Browser
    • macOS: Chrome, Brave, Opera, LT Browser, Edge और local login keychain
    • Linux: corresponding Chromium-based profile folders
  • Default या Profile* directories से ये Chromium databases upload किए गए
    • Login Data
    • Login Data For Account
    • Web Data
  • इसके बाद यह Local Extension Settings/<extension-id> को scan करता था, और hardcoded wallet extension IDs में MetaMask का nkbihfbeogaeaoehlefnkodbefgpgknn भी शामिल था
  • पहले 8 wallet extension paths के लिए LevelDB directory को temporary folder में copy करके individual files upload की जाती थीं, और server के cldbs response के आधार पर completion या retry तय किया जाता था
  • port 7649 पर confirm हुए तीन uploads ये databases थे
    • Login_Data.sqlite: 51,200 bytes
    • Login_Data_For_Account.sqlite: 51,200 bytes
    • Web_Data.sqlite: 262,144 bytes
  • test data में saved passwords या card rows नहीं थे, लेकिन 6 autocomplete values और browser metadata शामिल थे
  • Chrome-based browsers कुछ fields को locally encrypt करते हैं, इसलिए सिर्फ database से हमेशा plaintext secrets recover नहीं किए जा सकते
    • हालांकि OS secrets, cookies, extension storage और unlocked browser के साथ combine होने पर यह credential-theft pipeline का हिस्सा बन जाता है
  • जरूरी browser data और LevelDB upload करने के बाद, या server द्वारा complete mark किए जाने पर यह exit हो जाता था, और operator के अलग command का इंतजार नहीं करता था

recursive file scanner और clipboard monitor

  • recursive file scanner अलग file बनाए बिना node -e से run होता था और user home directory से scan शुरू करता था
    • Windows पर यह Get-CimInstance Win32_LogicalDisk से drive letters enumerate करता और हर drive root को भी check करता था
    • collected file patterns में *.env*, *.md, *.pem, *.ini, *.secret, *.json, *.js, *.ts, *.csv, *.txt, *.doc, *.docx, *.pdf, *.xlsx, .zsh_history, .bash_history शामिल थे
    • ~/.ssh, ~/.aws, ~/.azure, ~/.config, ~/.foundry को अपने-आप interested folders माना जाता था
    • metamask, bitcoin, btc, solana, secret phrase, private key जैसे नाम भी खोजे जाते थे
    • results http://45.146.252.17:7646/upload पर भेजे जाते थे
  • decoy environment में id_ed25519, id_ed25519.pub, History.txt, seed.js, password.js, tokens.js, ConnectWalletButton.js, ExportWallet.js, RegisterWallet.js, tailwind.config.js, aptos-cli.json आदि वास्तव में upload हुए
  • जहां ldata browser और wallet storage का जिम्मा लेता था, वहीं file scanner SSH keys, configuration, source code, local secrets, shell history और project files को व्यापक रूप से collect करता था
  • clipboard monitor भी node -e से run होता था और process title npm-compiler.log था
    • कुछ seconds इंतजार करने के बाद यह बार-बार clipboard पढ़ता था
    • macOS पर pbpaste, Windows पर powershell -NoProfile -NonInteractive Get-Clipboard इस्तेमाल करता था
    • बदली हुई values http://45.146.252.17/api/service/makelog पर भेजी जाती थीं
  • format interpret किए बिना भी यह user द्वारा copy किए गए passwords, recovery phrases, private keys, API tokens, one-time codes, GitHub URLs, wallet addresses और deployment secrets को जस का तस पकड़ सकता था

recruitment assignment चलाने से पहले पालन करने वाले सिद्धांत

  • किसी अजनबी द्वारा भेजे गए assignment repository को safety verify होने तक untrusted executable code मानना चाहिए
  • yarn install, npm install, yarn build, yarn start से पहले नीचे की चीजें review करनी चाहिए
    • package.json
    • lifecycle scripts
    • configuration files
    • obvious dependency hooks
  • इस case में malware tailwind.config.js में छिपा था, जिसे लोग अक्सर नजरअंदाज कर देते हैं, और configuration files, dependencies और build tools भी सभी code के रूप में execute हो सकते हैं
  • interview project को ऐसे throwaway VM या container में run करना चाहिए जिसमें असली secrets mounted न हों
    • personal browser profile
    • password manager
    • SSH keys
    • cryptocurrency wallet
    • GitHub token
    • cloud credentials
    • banking session
    • primary email account
  • जिन assignments में account या wallet चाहिए, उनके लिए ऐसा नया test identity इस्तेमाल करना चाहिए जिसमें funds न हों और जिसे दूसरी services में reuse न किया गया हो
  • Web3 assignment हो तो सिर्फ testnet का इस्तेमाल करें, और भले ही project harmless लगे, अपने real wallet को किसी unknown project से connect न करें

संक्रमण का पता लगाने के संकेतक

  • macOS·Linux पर पहले ये चीज़ें जांचें
    • node, pack, scdata, ldata, npm-compiler, vhost.ctl से जुड़े चल रहे processes
    • 45.146.252.17 या ports 7641, 7646, 7649 से connections
    • temporary directory, Downloads, Desktop, Documents, Library के तहत pack, scdata, ldata, vhost.ctl
    • */.npm/vhost.ctl marker file
    • डाउनलोड किए गए project में IP, UID, /api/service/makelog, node scdata, node ldata, node pack strings
  • Windows पर ये चीज़ें जांचें
    • node, npm, cmd, powershell processes में वे entries जिनकी command line में pack, scdata, ldata, node -e, IP address, Get-Clipboard हों
    • 45.146.252.17 या remote ports 7641, 7646, 7649 पर खुले TCP connections
    • %TEMP% के तहत pack, scdata, ldata, vhost.ctl, .npm\vhost.ctl
    • interview repository clone की गई directory के अंदर ज्ञात C2 strings
  • अगर live Node process, उस IP से connection, या pack·scdata·ldata artifacts में से कुछ भी मिले, तो सिस्टम को exposed माना जाना चाहिए
  • ये indicators विश्लेषित sample के लिए खास शुरुआती जांच बिंदु हैं, पूरी forensic प्रक्रिया नहीं

संक्रमित सिस्टम की सफाई और secrets बदलना

  • सबसे पहले कंप्यूटर को network से अलग करें, और संक्रमित environment में आगे explore या debug न करें, न ही नए secrets copy करें
  • अगर evidence की जरूरत हो, तो delete करने से पहले ये data सुरक्षित रखें
    • process list
    • network connections
    • संदिग्ध files
    • browser history
    • malicious repository
  • इसके बाद node pack, node scdata, node ldata, node -e, npm-compiler, vhost.ctl से जुड़े processes बंद करें और temporary directory से pack, scdata, ldata, .npm/vhost.ctl हटाएं
  • अगर यह disposable VM है और वैध Node काम को सुरक्षित रखने की जरूरत नहीं है, तो macOS·Linux पर pkill node या Windows पर सभी node processes को force terminate किया जा सकता है
  • malicious repository और node_modules delete करें, लेकिन अगर आगे analysis चाहिए तो ZIP copy offline सुरक्षित रखें
  • सिर्फ files delete करना काफी नहीं है; नीचे दी गई secret जानकारी को rotate या revoke करना होगा
    • SSH keys
    • GitHub·npm tokens
    • cloud keys और API keys
    • deployment secrets
    • browser में saved passwords
    • active login sessions
  • अगर wallet seed या private key के संक्रमित सिस्टम के संपर्क में आने की संभावना है, तो किसी clean device पर नया wallet बनाकर funds transfer करें

development tools की trust boundary का दुरुपयोग करने वाला हमला

  • traditional antivirus products ने इस repository को detect नहीं किया, और assignment हल करने में इस्तेमाल किए गए लोकप्रिय AI coding agents भी project में छिपे malware की पहचान नहीं कर पाए
  • Tailwind JavaScript config file को Node module की तरह evaluate करता है, इसलिए जैसे ही development tools, build scripts, editor integrations, Tailwind CLI, bundlers या CI jobs config load करते हैं, line 95 का IIFE execute हो जाता है
  • वैध Tailwind config line 94 तक था, और उसके बाद लगभग 27KB का obfuscated code जोड़ा गया था
  • downloaded payload उसी operating system privileges के साथ चलता है जो config load करने वाले user के पास होते हैं
    • यह local files, browser profiles, saved credentials, wallet extension data, SSH keys, environment variables, package tokens, cloud credentials, source code और clipboard तक पहुंच सकता है
    • अगर CI में run हो, तो deployment secrets, build artifacts, registry credentials और production access tokens भी expose हो सकते हैं
  • जरूरी fix है tailwind.config.js से obfuscated JavaScript blob को पूरी तरह हटाना

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.