• หลังจากเสนอรับสมัครงานตำแหน่งวิศวกรซอฟต์แวร์บน LinkedIn ผู้โจมตีได้ส่ง GitHub repository แบบส่วนตัวที่ปลอมเป็นโจทย์ React/Web3 ปกติ และเมื่อรัน มัลแวร์ JavaScript ที่ซ่อนอยู่ใน tailwind.config.js จะทำงานบนคอมพิวเตอร์ของนักพัฒนา
  • ไฟล์ตั้งค่าขนาด 30,987 ไบต์ซ่อนโค้ด obfuscated ขนาด 27KB ไว้หลังช่องว่างหลายพันตัว จากนั้นรับ payload ระยะที่ 2 ที่เข้ารหัสด้วย AES-256-CBC จากเซิร์ฟเวอร์ระยะไกล บันทึกลงใน %TEMP%\pack แล้ว รันด้วย node pack
  • จากการสังเกตใน VM แยกสภาพแวดล้อม Windows 11 ARM เป็นเวลาประมาณ 10 นาที พบว่า payload เปิดใช้องค์ประกอบ 4 ส่วน ได้แก่ backdoor สำหรับควบคุมระยะไกล, ตัวขโมยข้อมูลเบราว์เซอร์·กระเป๋าเงิน, ตัวสแกนไฟล์แบบ recursive และตัวเฝ้าดู clipboard
  • ควบคุม terminal·SSH·หน้าจอ·คีย์บอร์ด·เมาส์ผ่าน Socket.IO และเก็บรวบรวมฐานข้อมูล Chromium, พื้นที่จัดเก็บของส่วนขยายกระเป๋าเงิน, คีย์ SSH, ซอร์สโค้ด, ไฟล์ตั้งค่า ฯลฯ โดยพบ คำขอ 2,588 รายการ ที่พอร์ตอัปโหลดไฟล์
  • repository โจทย์ที่ส่งมาจากคนแปลกหน้าควรถูกมองเป็นโค้ดที่ไม่น่าเชื่อถือ และควรตรวจสอบใน VM หรือคอนเทนเนอร์ใช้ครั้งเดียวที่ไม่มีโปรไฟล์เบราว์เซอร์จริง·คีย์ SSH·ข้อมูลรับรองคลาวด์·กระเป๋าเงิน หากติดมัลแวร์แล้ว ควรตัดเครือข่าย เก็บหลักฐาน และ เปลี่ยนข้อมูลลับทั้งหมดด้วย

repository ที่ปลอมเป็นโจทย์รับสมัครงาน Web3 ปกติ

  • ผู้ใช้ LinkedIn Wayan Adrian เสนอตำแหน่งวิศวกรซอฟต์แวร์ที่ shrapnel.com และส่ง GitHub repository ส่วนตัว tech-active-workplace-frontend-main ของบัญชี yevhen-o เป็นโจทย์
  • แพลตฟอร์มแคมเปญ NFT ชื่อ BLAIEXS ภายนอกดูเหมือนโปรเจกต์ React/Web3 ทั่วไป
    • ฟรอนต์เอนด์ React มีแบรนด์·แดชบอร์ดผู้ดูแลระบบ, การจัดการแคมเปญ, flow การสร้าง NFT ฯลฯ
    • Express API จัดการการยืนยันตัวตน, ข้อมูลแดชบอร์ด, การตรวจ KYB, การสร้าง·เคลม NFT, การอัปโหลดไฟล์ และ stub endpoint บางส่วน
    • seed script สร้างบัญชีเดโม superadmin·แบรนด์·ผู้บริโภค, แคมเปญ Demo NFT Drop และ NFT Demo Collectible จำนวน 100 ชิ้น
  • ขอบเขตงานจริงเป็นเพียง ฟีเจอร์แสดงเครือข่าย MetaMask แบบง่าย ๆ
    • นำ getChainId() แบบ async ไปใช้ใน src/utils/ethereum.js ให้เรียก eth_chainId แล้วคืนค่าเลขฐานสิบหกที่ parse แล้ว หรือ null
    • นำ getNetworkLabel(chainId) ไปใช้ในไฟล์เดียวกัน ให้หาอ่านชื่อเครือข่ายที่เข้าใจง่ายจากอ็อบเจ็กต์ NETWORKS เดิม
    • แก้ src/components/Wallet/ConnectWalletButton.js ให้เรียกสองฟังก์ชันดังกล่าวหลังเชื่อมต่อกระเป๋าเงิน
  • หลัง implement เสร็จและรัน development server แล้ว ระบบไม่เริ่มทำงานเป็นเวลานาน ผู้ใช้ที่สังเกตเห็นความผิดปกติจึงถอดสายอินเทอร์เน็ตออก

โค้ดรันที่ซ่อนอยู่ใน tailwind.config.js

  • จาก ls -la พบว่า tailwind.config.js มีขนาด 30,987 ไบต์ แต่ใน editor เห็นเพียง 97 บรรทัด และตรวจสอบด้วย wc -c ก็ได้ขนาดเดียวกัน
  • บริเวณบรรทัดที่ 95 มี blob JavaScript ขนาดใหญ่ที่อ่านยากสำหรับมนุษย์ซ่อนอยู่หลังช่องว่างหลายพันตัว
  • โค้ดใช้ วิธี obfuscation ของ JavaScript ทั่วไป
    1. เก็บสตริงสำคัญไว้ในอาร์เรย์ขนาดใหญ่
    2. หมุนอาร์เรย์จนกว่า checksum จะตรง
    3. ซ่อนการเข้าถึงสตริงไว้หลังฟังก์ชัน decoder
    4. แทนที่ชื่อที่ชัดเจนด้วย index ตัวเลขและการเรียก wrapper
  • decoder หนึ่งในสองตัวกู้คืนสตริงในรูปแบบ Base64 ส่วนอีกตัวใช้คีย์รายสตริงและ stream cipher คล้าย RC4 และหมุนอาร์เรย์สตริงก่อนที่ index ของ decoder จะตรง
  • สามารถคลาย obfuscation ได้ตามลำดับต่อไปนี้โดยไม่ต้องรันมัลแวร์
    1. ดึงอาร์เรย์สตริงออกมา
    2. ทำซ้ำการหมุนอาร์เรย์ให้ไปถึง checksum ที่คาดไว้
    3. implement ฟังก์ชัน decoder ใหม่
    4. แทนการเรียกอย่าง b(0x214), c(0x2f1, "key") ด้วยสตริงจริง
    5. ทำให้อ็อบเจ็กต์ wrapper และฟังก์ชัน helper ง่ายลงเพื่อเผยเจตนาการทำงาน

พฤติกรรมของ dropper ระยะที่ 1

  • โค้ดที่คลายแล้ว import child_process, os, fs, path, crypto และติดตั้ง axios กับ socket.io-client ในไดเรกทอรีชั่วคราว
  • handler ระดับโปรเซสของ uncaughtException และ unhandledRejection ถูกตั้งค่าให้เพิกเฉยต่อข้อผิดพลาด
  • flow การรัน payload ระยะไกล เป็นดังนี้
    • UID คือ 59e605dd78fb2aafccd1b622f06a00ca
    • ดึงข้อมูลจาก http://45.146.252.17/api/service/59e605dd78fb2aafccd1b622f06a00ca
    • ใส่ UID และสตริง salt ลงใน crypto.scryptSync เพื่อ derive คีย์ 32 ไบต์
    • แยก response เป็นรูปแบบ base64_iv:base64_ciphertext แล้วถอดรหัสด้วย aes-256-cbc
    • เขียน plaintext ลงไฟล์ pack ในไดเรกทอรีชั่วคราว
    • รันด้วย child_process.execSync("node pack", { windowsHide: true, cwd: os.tmpdir() })
  • เป็น malware dropper ที่ดาวน์โหลดและรันซอฟต์แวร์อันตรายตัวอื่น มากกว่าจะทำความสามารถของตัวเอง
  • โค้ดที่ดาวน์โหลดมาไม่มีการตรวจลายเซ็น, allowlist hash, การ pin แหล่งที่มา, การจำกัด path หรือ guard กันการรัน ทำให้ remote endpoint สามารถรันโค้ดด้วยสิทธิ์ของบัญชีระบบปฏิบัติการที่โหลดการตั้งค่า Tailwind ได้

การวิเคราะห์แบบ dynamic ใน VM แยกสภาพแวดล้อม

  • ตั้งค่า Windows 11 ARM VM แบบใช้ครั้งเดียวด้วย UTM เพื่อไม่ให้ระบบ host ถูกเปิดเผย
    • หน่วยความจำ 4096 MiB
    • ดิสก์ 64 GiB
    • เครือข่าย shared/NAT
    • ปิดใช้ shared folder
  • ติดตั้งเครื่องมือเพื่อเก็บพฤติกรรมของมัลแวร์จากหลายมุมมอง
    • Wireshark: เก็บแพ็กเก็ตและทราฟฟิก C2·การ exfiltration
    • Sysinternals Sysmon: telemetry เหตุการณ์ Windows ที่คงทน
    • Procmon: เก็บกิจกรรมของโปรเซส·registry·filesystem ระหว่างทำงาน
  • วาง ข้อมูลล่อ เพื่อยืนยันเป้าหมายที่มัลแวร์เก็บรวบรวม
    • คู่คีย์ SSH
    • GitHub repository ส่วนตัว
    • กระเป๋าเงินคริปโต
    • ข้อมูลเบราว์เซอร์
    • ไฟล์อื่น ๆ ที่ info stealer น่าจะเล็งเป้า
  • รัน yarn start ใน VM และ สังเกตประมาณ 10 นาที จากนั้นเก็บ run1-full.pcapng, run1-sysmon.evtx, stage2-pack.bin

flow การติดมัลแวร์ที่พบในเครือข่าย

  • คำขอ HTTP ไปยัง 45.146.252.17 แบ่งบทบาทตามพอร์ต
    • พอร์ต 80: ดึง payload ระยะที่ 1, ลงทะเบียน host, ส่ง log
    • พอร์ต 7641: backdoor สั่งการและควบคุมผ่าน Socket.IO
    • พอร์ต 7646: 2,588 รายการสำหรับอัปโหลดไฟล์
    • พอร์ต 7649: อัปโหลดข้อมูลเบราว์เซอร์ 3 รายการที่ใหญ่กว่าแต่จำนวนรายการน้อยกว่า
  • คำขอแรกคือ GET /api/service/59e605dd78fb2aafccd1b622f06a00ca และ response อยู่ในรูปแบบ base64_iv:base64_ciphertext พร้อม Content-Length: 150897
  • tailwind.config.js ถอดรหัส response ด้วย AES-256-CBC เขียน plaintext ลง %TEMP%\pack แล้วรันด้วย node pack
  • คุณลักษณะของ payload ระยะที่ 2 ที่เก็บมาได้มีดังนี้
    • SHA-256: 68a64d8c015c06fd70bcb8c5878c1e430da827dd00b62f8e6ef69e76bb94de5b
    • ขนาด: 113136 ไบต์
    • รูปแบบ: ASCII JavaScript บรรทัดเดียว
  • pack ที่ถอดรหัสแล้วก็ถูก obfuscate อีกครั้ง แต่ใช้เทคนิคเดียวกับขั้นแรก จึงคลายได้ด้วยขั้นตอนเดียวกัน

เพย์โหลดขั้นที่ 2 ที่ประกอบด้วยโปรแกรมสี่ตัว

  • pack ไม่ใช่สคริปต์เดี่ยว แต่เป็น process tree ขนาดเล็ก ที่รันโปรแกรมสี่ตัวต่อไปนี้
    1. เขียนและรันแบ็กดอร์ command-and-control scdata ในไดเรกทอรีชั่วคราว
    2. เขียนและรันตัวขโมยข้อมูลเบราว์เซอร์และวอลเล็ต ldata ในไดเรกทอรีชั่วคราว
    3. รันตัวสแกนไฟล์แบบ recursive โดยตรงในหน่วยความจำด้วย node -e
    4. รันตัวเฝ้าดูคลิปบอร์ดโดยตรงในหน่วยความจำด้วย node -e
  • ค่าตั้งค่าหลักคือ UID 59e605dd78fb2aafccd1b622f06a00ca, คีย์ผู้ใช้ 308, โฮสต์ 45.146.252.17, พอร์ต Socket.IO 7641, พอร์ตคีย์ 7648, พอร์ตอัปโหลดเบราว์เซอร์ 7649, และพอร์ตอัปโหลดไฟล์ 7646

scdata: แบ็กดอร์ควบคุมระยะไกลแบบโต้ตอบ

  • scdata ถูกเขียนเป็นไฟล์ใน %TEMP% แล้วรันด้วย npm i axios socket.io-client ... && node scdata และคงอยู่เป็นโปรเซสลูกที่ทำงานเป็นเวลานาน
  • หลังรันแล้ว จะตั้งค่าตัวเองให้ดูเหมือนโปรเซสปกติ
  • ยังติดตั้งแพ็กเกจเพิ่มเติมที่จำเป็นสำหรับความสามารถควบคุมระยะไกลด้วย
    • socket.io-client, ssh2, node-pty: เทอร์มินัลและความสามารถคล้าย SSH
    • sharp, screenshot-desktop, clipboardy, @nut-tree-fork/nut-js: สกรีนช็อต, คลิปบอร์ด, การขยับ·คลิก·เลื่อนเมาส์, การป้อนคีย์บอร์ด
  • อีเวนต์ Socket.IO แสดงขอบเขตการควบคุมระยะไกลโดยตรง
    • เทอร์มินัล: start-terminal, terminal-input, terminal-resize, stop-terminal, command
    • การตรวจสอบโฮสต์และการจับภาพ: whour, capture
    • การควบคุมอินพุต: mouseMove, mouseClick, mouseScroll, keyTap, keyCombo
    • คลิปบอร์ด: copyText, pasteText
    • SSH และการยุติ: start_ssh, ssh_input, kill
  • ใน PCAP พบการ polling และ WebSocket handshake ของพอร์ต 7641 รวมถึงอีเวนต์แรกจากเซิร์ฟเวอร์ whour และใน Sysmon พบ node.exe scdata, PowerShell ที่ query ข้อมูลระบบ, และการติดตั้งแพ็กเกจ npm สองกลุ่มตามลำดับ
  • นอกเหนือจากการขโมยข้อมูลอย่างง่าย ยังมอบความสามารถ ควบคุม shell และ desktop ให้ผู้โจมตีด้วย

ldata: ตัวขโมยข้อมูลเบราว์เซอร์และวอลเล็ต

  • ldata ถูกเขียนลงใน %TEMP% และรันด้วย npm i axios && node ldata โดยชื่อโปรเซสคือ npm-cache
  • รวบรวมโปรไฟล์เบราว์เซอร์และที่เก็บข้อมูลส่วนขยายวอลเล็ต ส่งไปยัง http://45.146.252.17:7649/upload และตรวจสอบสถานะ LevelDB ที่ /cldbs
  • เบราว์เซอร์เป้าหมายถูกตั้งค่าไว้อย่างกว้างขวางตามระบบปฏิบัติการ
    • Windows: Chrome, Edge, Brave, LT Browser
    • macOS: Chrome, Brave, Opera, LT Browser, Edge และ local login keychain
    • Linux: โฟลเดอร์โปรไฟล์ตระกูล Chromium ที่สอดคล้องกัน
  • อัปโหลด ฐานข้อมูล Chromium ต่อไปนี้จากไดเรกทอรี Default หรือ Profile*
    • Login Data
    • Login Data For Account
    • Web Data
  • จากนั้นสำรวจ Local Extension Settings/<extension-id> โดย ID ส่วนขยายวอลเล็ตที่ hardcode ไว้มีของ MetaMask คือ nkbihfbeogaeaoehlefnkodbefgpgknn รวมอยู่ด้วย
  • สำหรับเส้นทางส่วนขยายวอลเล็ต 8 รายการแรก จะคัดลอกไดเรกทอรี LevelDB ไปยังโฟลเดอร์ชั่วคราว แล้วอัปโหลดไฟล์แต่ละไฟล์ และตัดสินใจว่าเสร็จสิ้นหรือจะลองใหม่ตามการตอบกลับ cldbs ของเซิร์ฟเวอร์
  • การอัปโหลดสามรายการที่พบในพอร์ต 7649 คือฐานข้อมูลต่อไปนี้
    • Login_Data.sqlite: 51,200 ไบต์
    • Login_Data_For_Account.sqlite: 51,200 ไบต์
    • Web_Data.sqlite: 262,144 ไบต์
  • ข้อมูลทดลองไม่มีแถวรหัสผ่านหรือบัตรที่บันทึกไว้ แต่มี ค่า autocomplete 6 รายการ และ metadata ของเบราว์เซอร์
  • เบราว์เซอร์ตระกูล Chrome เข้ารหัสบางฟิลด์ไว้ในเครื่อง ดังนั้นฐานข้อมูลเพียงอย่างเดียวจึงไม่สามารถกู้คืนความลับแบบ plaintext ได้เสมอไป
    • อย่างไรก็ตาม เมื่อรวมกับความลับของระบบปฏิบัติการ·คุกกี้·ที่เก็บข้อมูลส่วนขยาย·เบราว์เซอร์ที่ปลดล็อกอยู่ ก็จะกลายเป็นส่วนหนึ่งของ pipeline การขโมยข้อมูลรับรอง
  • เมื่ออัปโหลดข้อมูลเบราว์เซอร์และ LevelDB ที่ต้องการ หรือเซิร์ฟเวอร์ทำเครื่องหมายว่าเสร็จสิ้นแล้ว ก็จะยุติการทำงาน โดยไม่รอคำสั่งเพิ่มเติมจาก operator

ตัวสแกนไฟล์แบบ recursive และตัวเฝ้าดูคลิปบอร์ด

  • ตัวสแกนไฟล์แบบ recursive ไม่สร้างไฟล์แยก แต่รันด้วย node -e และเริ่มสำรวจจาก home directory ของผู้ใช้
    • บน Windows จะ enumerate อักษรไดรฟ์ด้วย Get-CimInstance Win32_LogicalDisk และตรวจสอบ root ของแต่ละไดรฟ์ด้วย
    • รูปแบบไฟล์ที่รวบรวมมี *.env*, *.md, *.pem, *.ini, *.secret, *.json, *.js, *.ts, *.csv, *.txt, *.doc, *.docx, *.pdf, *.xlsx, .zsh_history, .bash_history
    • ~/.ssh, ~/.aws, ~/.azure, ~/.config, ~/.foundry จะถูกถือเป็นโฟลเดอร์ที่น่าสนใจโดยอัตโนมัติ
    • ยังค้นหาชื่ออย่าง metamask, bitcoin, btc, solana, secret phrase, private key ด้วย
    • ส่งผลลัพธ์ไปที่ http://45.146.252.17:7646/upload
  • ในสภาพแวดล้อมล่อ มีการอัปโหลด 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 ฯลฯ จริง
  • หาก ldata รับผิดชอบเบราว์เซอร์และที่เก็บข้อมูลวอลเล็ต ตัวสแกนไฟล์ก็จะรวบรวม คีย์ SSH·การตั้งค่า·ซอร์สโค้ด·ความลับในเครื่อง·ประวัติ shell·ไฟล์โปรเจกต์ อย่างกว้างขวาง
  • ตัวเฝ้าดูคลิปบอร์ด ก็รันด้วย node -e เช่นกัน โดยชื่อโปรเซสคือ npm-compiler.log
    • รอสักสองสามวินาทีแล้วอ่านคลิปบอร์ดซ้ำ ๆ
    • บน macOS ใช้ pbpaste และบน Windows ใช้ powershell -NoProfile -NonInteractive Get-Clipboard
    • ค่าที่เปลี่ยนแปลงจะถูกส่งไปยัง http://45.146.252.17/api/service/makelog
  • แม้ไม่ตีความรูปแบบ ก็สามารถจับรหัสผ่าน, recovery phrase, private key, API token, one-time code, GitHub URL, ที่อยู่วอลเล็ต, ความลับสำหรับ deployment ที่ผู้ใช้คัดลอกได้ตรง ๆ

หลักการที่ควรปฏิบัติก่อนรันโจทย์รับสมัครงาน

  • repository โจทย์ที่คนแปลกหน้าส่งมา ต้องถือเป็น โค้ดรันที่ไม่น่าเชื่อถือ จนกว่าจะตรวจสอบความปลอดภัยแล้ว
  • ก่อน yarn install, npm install, yarn build, yarn start ควรตรวจสอบรายการต่อไปนี้
    • package.json
    • lifecycle scripts
    • ไฟล์ตั้งค่า
    • dependency hooks ที่เห็นได้ชัด
  • มัลแวร์ในกรณีนี้ซ่อนอยู่ใน tailwind.config.js ซึ่งคนมักมองข้าม และไฟล์ตั้งค่า·dependency·build tools ทั้งหมดก็สามารถถูกรันเป็นโค้ดได้
  • โปรเจกต์สัมภาษณ์ควรรันใน VM หรือ container แบบใช้ครั้งเดียว ที่ไม่ได้ mount ความลับจริงไว้
    • โปรไฟล์เบราว์เซอร์ส่วนตัว
    • password manager
    • คีย์ SSH
    • วอลเล็ตคริปโต
    • GitHub token
    • ข้อมูลรับรอง cloud
    • เซสชันธนาคาร
    • บัญชีอีเมลหลัก
  • สำหรับโจทย์ที่ต้องใช้บัญชีหรือวอลเล็ต ควรใช้ตัวตนทดสอบใหม่ที่ไม่มีเงิน และไม่ได้นำไปใช้ซ้ำกับบริการอื่น
  • หากเป็นโจทย์ Web3 ให้ใช้เฉพาะ testnet และอย่าเชื่อมต่อวอลเล็ตจริงกับโปรเจกต์ที่ไม่รู้จัก แม้จะดูไม่มีอันตรายก็ตาม

ตัวบ่งชี้สำหรับตรวจสอบว่าติดเชื้อหรือไม่

  • บน macOS·Linux ให้ตรวจสอบรายการต่อไปนี้ก่อน
    • โปรเซสที่กำลังรันซึ่งเกี่ยวข้องกับ node, pack, scdata, ldata, npm-compiler, vhost.ctl
    • การเชื่อมต่อกับ 45.146.252.17 หรือพอร์ต 7641, 7646, 7649
    • pack, scdata, ldata, vhost.ctl ใต้ไดเรกทอรีชั่วคราว, Downloads, Desktop, Documents, Library
    • ไฟล์บ่งชี้ */.npm/vhost.ctl
    • สตริง IP, UID, /api/service/makelog, node scdata, node ldata, node pack ภายในโปรเจกต์ที่ดาวน์โหลดมา
  • บน Windows ให้ตรวจสอบรายการต่อไปนี้
    • ในบรรดาโปรเซส node, npm, cmd, powershell ให้ดูรายการที่มี pack, scdata, ldata, node -e, ที่อยู่ IP, Get-Clipboard อยู่ในบรรทัดคำสั่ง
    • การเชื่อมต่อ TCP ที่เปิดไปยัง 45.146.252.17 หรือพอร์ตระยะไกล 7641, 7646, 7649
    • pack, scdata, ldata, vhost.ctl, .npm\vhost.ctl ใต้ %TEMP%
    • สตริง C2 ที่รู้จักภายในไดเรกทอรีที่โคลนรีโพซิทอรีสำหรับสัมภาษณ์ไว้
  • หากพบอย่างใดอย่างหนึ่ง ไม่ว่าจะเป็นโปรเซส Node ที่ยังทำงานอยู่, การเชื่อมต่อไปยัง IP ดังกล่าว, หรือไฟล์ผลลัพธ์ pack·scdata·ldata ควร ถือว่าระบบถูกเปิดเผยแล้ว
  • ตัวบ่งชี้เหล่านี้เป็นรายการตรวจสอบเบื้องต้นที่เฉพาะกับตัวอย่างที่วิเคราะห์ ไม่ใช่ขั้นตอนฟอเรนสิกที่สมบูรณ์

การทำความสะอาดระบบที่ติดเชื้อและการเปลี่ยนความลับ

  • สิ่งแรกที่ต้องทำคือ ตัดคอมพิวเตอร์ออกจากเครือข่าย และไม่ควรสำรวจ ดีบัก หรือคัดลอกความลับใหม่ต่อไปในสภาพแวดล้อมที่ติดเชื้อ
  • หากต้องการหลักฐาน ให้เก็บรักษาข้อมูลต่อไปนี้ก่อนลบ
    • รายการโปรเซส
    • การเชื่อมต่อเครือข่าย
    • ไฟล์ที่น่าสงสัย
    • ประวัติเบราว์เซอร์
    • รีโพซิทอรีที่เป็นอันตราย
  • จากนั้นให้ยุติโปรเซสที่เกี่ยวข้องกับ node pack, node scdata, node ldata, node -e, npm-compiler, vhost.ctl และลบ pack, scdata, ldata, .npm/vhost.ctl ในไดเรกทอรีชั่วคราว
  • หากเป็น VM แบบใช้ครั้งเดียวและไม่จำเป็นต้องเก็บงาน Node ที่ปกติไว้ สามารถใช้ pkill node บน macOS·Linux หรือบังคับยุติโปรเซส node ทั้งหมดบน Windows ได้
  • ลบรีโพซิทอรีที่เป็นอันตรายและ node_modules แต่หากต้องวิเคราะห์เพิ่มเติม ให้เก็บสำเนา ZIP ไว้แบบออฟไลน์
  • การลบไฟล์อย่างเดียวไม่เพียงพอ และต้อง เปลี่ยน·เพิกถอนข้อมูลลับ ต่อไปนี้
    • คีย์ SSH
    • โทเคน GitHub·npm
    • คีย์คลาวด์และ API key
    • ความลับสำหรับดีพลอย
    • รหัสผ่านที่บันทึกไว้ในเบราว์เซอร์
    • เซสชันล็อกอินที่ยังใช้งานอยู่
  • หากมีความเป็นไปได้ที่ seed phrase ของวอลเล็ตหรือ private key เคยสัมผัสกับระบบที่ติดเชื้อ ให้สร้างวอลเล็ตใหม่บนอุปกรณ์ที่สะอาดและโอนเงินไปยังวอลเล็ตนั้น

การโจมตีที่ใช้ประโยชน์จากขอบเขตความเชื่อถือของเครื่องมือนักพัฒนา

  • ผลิตภัณฑ์แอนติไวรัสแบบดั้งเดิมตรวจไม่พบรีโพซิทอรีนี้ และ AI coding agent ยอดนิยมที่ใช้แก้โจทย์ก็ไม่สามารถระบุมัลแวร์ที่ซ่อนอยู่ในโปรเจกต์ได้
  • Tailwind ประเมินไฟล์ตั้งค่า JavaScript เป็นโมดูล Node ดังนั้นทันทีที่เครื่องมือนักพัฒนา·สคริปต์ build·การผสานกับ editor·Tailwind CLI·bundler·งาน CI โหลดการตั้งค่า IIFE ในบรรทัดที่ 95 จะถูกเรียกใช้
  • การตั้งค่า Tailwind ปกติอยู่ถึงบรรทัดที่ 94 และหลังจากนั้นมีการเพิ่ม โค้ด obfuscate ประมาณ 27KB เข้าไป
  • payload ที่ดาวน์โหลดมาจะทำงานด้วยสิทธิ์ของระบบปฏิบัติการเดียวกับผู้ใช้ที่โหลดการตั้งค่า
    • สามารถเข้าถึงไฟล์ local, โปรไฟล์เบราว์เซอร์, credentials ที่บันทึกไว้, ข้อมูลส่วนขยายวอลเล็ต, คีย์ SSH, environment variables, โทเคนแพ็กเกจ, credentials คลาวด์, ซอร์สโค้ด, คลิปบอร์ด
    • หากรันใน CI ความลับสำหรับดีพลอย, build artifacts, credentials ของ registry, production access token ก็อาจถูกเปิดเผยได้เช่นกัน
  • การแก้ไขที่จำเป็นคือการ ลบ JavaScript blob ที่ถูก obfuscate ออกทั้งหมด จาก tailwind.config.js

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น