สรุปสั้น
นักวิจัยพบกลุ่มแพ็กเกจประสงค์ร้ายเกือบ 800 รายการถูกอัปโหลดขึ้นคลัง npm ในแคมเปญใหม่ที่ออกแบบมาให้ส่งมัลแวร์ทำงานได้ครบทั้งบน Windows, macOS และ Linux โดยนาย Paul McCarty นักวิจัยจาก OpenSourceMalware ระบุว่าชื่อแพ็กเกจทั้งหมดถูกสุ่มขึ้นในลักษณะ AI slop squatting คือเลียนชื่อที่ผู้ช่วยเขียนโค้ดมักมโนขึ้นมาเองเวลาแนะนำไลบรารี ทำให้นักพัฒนาที่ลอกคำแนะนำของ AI ไปติดตั้งตรง ๆ มีโอกาสหยิบของปลอมโดยไม่รู้ตัว จุดที่ต่างจากการโจมตีซัพพลายเชนบน npm ที่ผ่านมาคือชุดนี้ไม่พึ่ง lifecycle hook อย่าง preinstall หรือ postinstall ซึ่งเป็นกลไกที่เครื่องมือสแกนจับตามาตลอด แต่กลับใส่ไฟล์ README ที่เขียนสอนให้ผู้ใช้เรียกโมดูลด้วยฟังก์ชัน require() เอง เท่ากับผลักภาระการรันโค้ดอันตรายไปให้เหยื่อทำเองในขั้นตอนที่ดูปกติที่สุดของการเขียนโปรแกรม
เมื่อโค้ดถูกเรียกใช้ ระบบจะรันดาวน์โหลดเดอร์ชื่อ WEL1DROPPER ซึ่งตรวจสอบระบบปฏิบัติการและสถาปัตยกรรมซีพียูของเครื่องก่อน แล้วจึงไปดึง payload ที่เข้ากันได้จากโฮสต์ Cloudflare Workers สามแห่ง หากการดาวน์โหลดผ่าน HTTPS ล้มเหลว มัลแวร์จะสลับไปใช้โดเมนเฉพาะแพลตฟอร์มและดึงขั้นถัดไปผ่านเรกคอร์ด DNS TXT ของโดเมน wel1[.]ru แทน ซึ่งเป็นช่องทางที่องค์กรจำนวนมากไม่ได้เฝ้าระวัง บริษัท Sonatype ที่ติดตามแคมเปญเดียวกันในชื่อ Flooding Dropper นับแพ็กเกจได้ราว 850 รายการ และพบว่าตัวอย่างบน Windows แพตช์กลไก ETW และ AMSI เพื่อรบกวนการตรวจจับ ส่วนตัวอย่างบน Linux เป็นไฟล์ ELF ที่บีบอัดด้วย UPX และปิดท้ายด้วยการติดตั้งเฟรมเวิร์กสั่งการ Sliver ขณะที่การพบโดเมนของธนาคารและผู้ให้บริการชำระเงินรัสเซียในเพย์โหลดฝั่ง macOS ชี้ว่าเป้าหมายอาจเป็นสถาบันการเงินในรัสเซีย
รายละเอียดข่าว
เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 8 สิงหาคม พ.ศ. 2569 ว่า มีการค้นพบคลัสเตอร์แพ็กเกจประสงค์ร้ายเกือบ 800 รายการบนคลัง npm ซึ่งเป็นส่วนหนึ่งของแคมเปญใหม่ที่มุ่งปล่อยมัลแวร์ข้ามแพลตฟอร์ม โดยนาย Paul McCarty จาก OpenSourceMalware อธิบายว่า “แพ็กเกจเหล่านี้ดูเหมือนใช้ชื่อแบบ AI slop squatted หรือชื่อ typo-squatting ที่สุ่มขึ้นมา แต่ทุกตัวส่งเพย์โหลด RAT และตัวขโมยข้อมูลที่มีความสามารถสูง”
เทคนิคการล่อเหยื่อของแคมเปญนี้อาศัยพฤติกรรมของนักพัฒนายุคผู้ช่วย AI โดยตรง แทนที่จะซ่อนโค้ดไว้ในสคริปต์ที่รันอัตโนมัติตอนติดตั้ง ผู้โจมตีเขียน README ให้ดูเหมือนเอกสารประกอบไลบรารีทั่วไปและสั่งให้ผู้ใช้โหลดโมดูลด้วย require() ซึ่งเป็นฟังก์ชันมาตรฐานของ Node.js สำหรับนำเข้าโมดูล ไฟล์ท้องถิ่น และแพ็กเกจของบุคคลที่สาม การออกแบบเช่นนี้ทำให้เครื่องมือที่คอยจับ hook ตอนติดตั้งไม่เห็นความผิดปกติ เพราะการติดตั้งแพ็กเกจเปล่า ๆ ไม่ก่อให้เกิดพฤติกรรมอันตรายใด ๆ จนกว่านักพัฒนาจะเรียกใช้จริง
แคมเปญนี้ยังถูกสงสัยว่าเป็นวิวัฒนาการของแคมเปญ dependency confusion ที่ใช้รหัสเรียกว่า Moika ซึ่งพบเมื่อเดือนเมษายนที่ผ่านมา และมีการอัปโหลดแพ็กเกจกว่า 250 รายการขึ้น npm เพื่อขโมยข้อมูลสภาพแวดล้อมของเครื่องแล้วส่งเพย์โหลดขั้นที่สองตามระบบปฏิบัติการ รูปแบบการทำงานที่คล้ายกันแต่ขยายสเกลขึ้นเกือบสี่เท่าบ่งชี้ว่าผู้ก่อเหตุยังพัฒนาเครื่องมือชุดเดิมต่อเนื่อง
ในช่วงเวลาไล่เลี่ยกัน หน่วยวิจัย Unit 42 ของบริษัท Palo Alto Networks เผยแพร่รายงานหลายฉบับเกี่ยวกับแคมเปญที่เล่นงานทั้ง npm และคลัง Python Package Index (PyPI) ชุดแรกเป็นแพ็กเกจ npm สิบรายการที่ดาวน์โหลดตัวขโมยคริปโตเคอร์เรนซีและโทรจันเข้าถึงระยะไกลจากเซิร์ฟเวอร์ภายนอก โดย Unit 42 ระบุว่า “หลังติดตั้ง แพ็กเกจจะ export ฟังก์ชันชื่อ getPlugin ที่ประกอบ URL สำหรับดาวน์โหลดเพย์โหลดขึ้นมาในรูปโค้ด JavaScript แบบ IIFE ที่ถูกทำให้อ่านยาก ฝังอยู่ในอ็อบเจ็กต์ JSON”
ชุดที่สองเป็นแพ็กเกจประสงค์ร้ายกระจายทั้งบน npm และ PyPI ซึ่ง Unit 42 ประเมินว่ามาจากผู้ก่อเหตุหลายรายที่ไม่เกี่ยวข้องกัน ความสามารถที่พบครอบคลุมตั้งแต่การขโมย credential ของคลาวด์ การปล่อยดรอปเปอร์ที่ใช้เทคนิค EtherHiding ซ่อนที่อยู่เซิร์ฟเวอร์สั่งการไว้บนบล็อกเชน การขโมยกุญแจกระเป๋าคริปโต Solana แล้วส่งออกผ่าน Telegram การดูดความลับจากไฟล์ .env การหลอกด้วย CAPTCHA ปลอมเพื่อให้เหยื่อรันคำสั่งเอง ไปจนถึงการขโมยโทเคน Discord และ credential ของ GitHub Actions ในสายพานพัฒนา CI/CD
รายงานอีกฉบับของ Unit 42 ชี้ว่าผู้ก่อเหตุยังใช้ส่วนขยาย Google Chrome ที่โฆษณาตัวเองเป็นโปรแกรมจำลองเกม ตัวจัดการรหัสผ่าน เครื่องมือเพิ่มประสิทธิภาพ ตัวตรวจ CSS และตัวแปลงมาร์กดาวน์ เพื่อเปลี่ยนเบราว์เซอร์ของผู้ใช้ให้กลายเป็นพร็อกซีสำหรับเก็บข้อมูลเว็บ โดยส่วนขยายเหล่านี้ฝัง SDK แบ่งปันแบนด์วิดท์เชิงพาณิชย์ตัวเดียวกัน เชื่อมเบราว์เซอร์เข้ากับเครือข่ายพร็อกซีที่พักอาศัยของบุคคลที่สาม รับคำสั่งเก็บข้อมูลผ่านการเชื่อมต่อ WebSocket ที่เปิดค้างไว้ แล้วแอบฉีด iframe ที่มองไม่เห็นเข้าไปในแท็บที่เปิดอยู่ แปลงเนื้อหาหน้าเว็บเป็นมาร์กดาวน์เบื้องหลัง และส่งกลับไปยังแบ็กเอนด์บนคลาวด์ อย่างไรก็ตาม Unit 42 ตั้งข้อสังเกตว่าส่วนขยายบางตัวเปิดเผยพฤติกรรมนี้ไว้แล้วในคำอธิบายบน Chrome Web Store และในนโยบายความเป็นส่วนตัวบนเว็บไซต์ของตัวเอง
วิธีการโจมตี
หัวใจของแคมเปญคือดาวน์โหลดเดอร์ WEL1DROPPER ซึ่งเมื่อถูกเรียกใช้จะระบุระบบปฏิบัติการและสถาปัตยกรรมของโปรเซสเซอร์ก่อน แล้วดึงเพย์โหลดที่เข้ากันได้จากหนึ่งในสามโฮสต์บน Cloudflare Workers ถ้าการดาวน์โหลดผ่าน HTTPS ถูกบล็อกหรือล้มเหลว มัลแวร์จะเปลี่ยนไปใช้โดเมนย่อยเฉพาะแพลตฟอร์มใต้ wel1[.]ru และรับข้อมูลผ่านเรกคอร์ด DNS TXT แทน วิธีนี้ทำงานได้แม้ในเครือข่ายที่กรองเว็บอย่างเข้มงวด เพราะทราฟฟิก DNS มักถูกอนุญาตให้ผ่านโดยไม่ตรวจ
กลไกลำเลียงผ่าน DNS ถูกอธิบายไว้ละเอียด McCarty ระบุว่า “แพ็กเกจจะขอเรกคอร์ด TXT จาก c.<โดเมน> ก่อน แล้วตีความค่าที่ได้เป็นจำนวนชิ้นของเพย์โหลด โดยรับค่าระหว่าง 1 ถึง 2,000 จากนั้นจึงทยอยขอเรกคอร์ด TXT ที่มีหมายเลขกำกับ นำสตริงที่ได้มาต่อกันแล้วถอดรหัส Base64 กลับเป็นบัฟเฟอร์ไบนารี” เมื่อได้ไฟล์ครบ เพย์โหลดจะถูกเขียนลงโฟลเดอร์ชั่วคราวและสั่งรันด้วย /bin/sh บน Linux และ macOS หรือ cmd.exe บน Windows
บน Windows Sonatype พบว่าขั้นสุดท้ายถูกเรียกเป็นโปรเซสแยกที่ไม่ผูกกับตัวเรียก มัลแวร์จะแพตช์ Event Tracing for Windows (ETW) และ Antimalware Scan Interface (AMSI) เพื่อรบกวนการเฝ้าระวัง ตรวจหาแซนด์บ็อกซ์และสภาพแวดล้อมเสมือน สร้างความคงทนผ่าน Registry Run key ควบคู่กับ scheduled task แล้วดาวน์โหลดเพย์โหลดที่เข้ารหัสไว้ที่พาธ /pkg/update_win.exe มารัน สายการติดเชื้อบน macOS ทำงานคล้ายกัน คือไล่ตรวจดีบักเกอร์และร่องรอยเครื่องมือวิเคราะห์ก่อน แล้วจึงดึงเพย์โหลด /pkg/beacon_mac.bin จากเซิร์ฟเวอร์ระยะไกล ถ้าล้มเหลวก็สลับไปใช้ช่องทาง DNS TXT ตั้งความคงทนด้วย LaunchAgent และเปิดไฟล์ประมวลผลเป็นโปรเซสแยก
ส่วนตัวอย่างบน Linux เป็นไฟล์ ELF ที่บีบอัดด้วย UPX ตั้งค่าให้ดาวน์โหลดเพย์โหลดเสริมจาก URL ของ Cloudflare Worker และท้ายที่สุดนำไปสู่การติดตั้ง Sliver ซึ่งเป็นเฟรมเวิร์กสั่งการและควบคุมแบบโอเพนซอร์สที่ผู้โจมตีนิยมใช้แทน Cobalt Strike นอกจากนี้ในแพ็กเกจยังพบไฟล์ชื่อ lib/telemetry.js ที่เขียนเลียนแบบ SDK เก็บสถิติการใช้งานให้ดูสมจริง แต่แฝงตรรกะดาวน์โหลดชุดเดียวกันไว้ด้วย OpenSourceMalware ระบุว่า “จุดเริ่มต้นของแพ็กเกจไม่ได้ import ไฟล์นี้ และไฟล์นี้ก็ไม่มีโครงสร้างพื้นฐานฝังตายเพิ่มเติม การเขียนโค้ดเทเลเมทรียาวเกินจำเป็นดูเหมือนตั้งใจสร้างสัญญาณรบกวน เพื่อให้พฤติกรรมอันตรายดูเหมือนฟังก์ชันวัดประสิทธิภาพหรือเก็บสถิติตามปกติเวลาถูกตรวจอย่างผ่าน ๆ”
ผลกระทบ
ผู้รับผลกระทบโดยตรงคือนักพัฒนาและเครื่องที่ใช้เขียนโค้ด ซึ่งมักถือ credential ของคลาวด์ โทเคนของคลังโค้ด และกุญแจสำหรับสายพาน CI/CD ไว้พร้อมกัน การยึดเครื่องนักพัฒนาได้หนึ่งเครื่องจึงเปิดทางไปยังระบบหลังบ้านขององค์กรได้ทั้งชุด และเมื่อขั้นสุดท้ายเป็น Sliver ผู้โจมตีก็ได้ช่องทางควบคุมแบบโต้ตอบเต็มรูปแบบ ไม่ใช่แค่การขโมยข้อมูลครั้งเดียวจบ ขนาดของแคมเปญที่เกือบ 800 ถึง 850 แพ็กเกจยังสะท้อนว่าการอัปโหลดของปลอมขึ้นคลังสาธารณะยังมีต้นทุนต่ำมากเมื่อเทียบกับผลตอบแทน
จุดที่ต้องระวังในการตีความคือรายงานทั้งสองฉบับไม่ได้เปิดเผยยอดดาวน์โหลดรวม จำนวนองค์กรที่ติดจริง หรือระบุว่าแพ็กเกจทั้งหมดถูกถอดออกจาก npm แล้วหรือยัง ตัวเลขที่ต่างกันระหว่างเกือบ 800 กับราว 850 รายการก็มาจากเกณฑ์การนับของสองบริษัทที่ไม่ตรงกัน ส่วนข้อสันนิษฐานว่าแคมเปญเล็งสถาบันการเงินรัสเซียนั้นมาจากการพบสตริงโดเมน tcsbank[.]ru และ cloudpayments[.]ru ในเพย์โหลดฝั่ง macOS เท่านั้น ยังไม่ใช่การยืนยันเหยื่อรายใดรายหนึ่ง และยังไม่มีการระบุตัวผู้อยู่เบื้องหลัง
คำแนะนำ
ทีมพัฒนาควรตั้งกฎว่าชื่อแพ็กเกจที่ได้จากผู้ช่วย AI ต้องถูกตรวจสอบกับคลังจริงก่อนติดตั้งเสมอ โดยดูวันที่เผยแพร่ จำนวนเวอร์ชัน คลังซอร์สโค้ดต้นทาง และผู้ดูแลแพ็กเกจ เพราะแคมเปญนี้อาศัยการที่นักพัฒนาเชื่อชื่อที่ AI แนะนำโดยไม่ตรวจ ถัดมาควรเลิกถือว่า “ติดตั้งแล้วยังไม่รัน = ปลอดภัย” เนื่องจากแพ็กเกจชุดนี้ย้ายจุดจุดชนวนไปอยู่ที่ require() ซึ่งเกิดตอนเขียนโค้ดปกติ การล็อกเวอร์ชันด้วย lockfile และให้ทุกการดึงแพ็กเกจผ่านพร็อกซีคลังภายในที่มีการสแกน จะช่วยลดโอกาสที่ชื่อสุ่มหลุดเข้ามาในโครงการ
ฝั่งเฝ้าระวังเครือข่ายควรเพิ่มการตรวจจับการสอบถาม DNS TXT ที่มีปริมาณผิดปกติหรือมีรูปแบบหมายเลขต่อเนื่อง ซึ่งเป็นลายเซ็นของการลำเลียงไฟล์ผ่าน DNS และเฝ้าดูทราฟฟิกออกไปยังโดเมนย่อยของ workers.dev ที่ไม่เคยใช้งานมาก่อน บนเครื่องปลายทางควรตรวจ Registry Run key และ scheduled task ที่ถูกสร้างใหม่บน Windows ตรวจ LaunchAgent บน macOS และเปิดการแจ้งเตือนเมื่อมีการแก้ไขหรือปิดการทำงานของ ETW และ AMSI สุดท้ายควรทบทวนส่วนขยายเบราว์เซอร์ที่ติดตั้งในองค์กร และถอนตัวที่ฝัง SDK แบ่งปันแบนด์วิดท์ออก เพราะแม้บางตัวจะเปิดเผยพฤติกรรมไว้ในนโยบายความเป็นส่วนตัว แต่การเปลี่ยนเบราว์เซอร์พนักงานเป็นโหนดพร็อกซีก็ยังเป็นความเสี่ยงต่อข้อมูลภายใน
Indicators of Compromise (IoCs)
ตัวบ่งชี้ทั้งหมด defang แล้ว ห้ามคัดลอกไปเปิดใช้งานตรง ๆ
| ตัวบ่งชี้ | ประเภท | คำอธิบาย |
|---|---|---|
| oob-worker.cf103-070.workers[.]dev | โดเมน | โฮสต์ Cloudflare Workers สำหรับดึงเพย์โหลด |
| oob-worker.cf102-baf.workers[.]dev | โดเมน | โฮสต์ Cloudflare Workers สำหรับดึงเพย์โหลด |
| oob-worker.cf99-9b3.workers[.]dev | โดเมน | โฮสต์ Cloudflare Workers และแหล่งเพย์โหลดเสริมของตัวอย่าง Linux |
| wel1[.]ru | โดเมน | โดเมนสำรองสำหรับลำเลียงเพย์โหลดผ่านเรกคอร์ด DNS TXT |
| sdk.dl.wel1[.]ru | โดเมน | เพย์โหลดสำหรับ Linux x64 |
| ext.dl.wel1[.]ru | โดเมน | เพย์โหลดสำหรับ Linux ARM64 |
| pkg.dl.wel1[.]ru | โดเมน | เพย์โหลดสำหรับ macOS |
| net.dl.wel1[.]ru | โดเมน | เพย์โหลดสำหรับ Windows |
| /pkg/update_win.exe | พาธไฟล์ | เพย์โหลดเข้ารหัสขั้นสุดท้ายบน Windows |
| /pkg/beacon_mac.bin | พาธไฟล์ | เพย์โหลดขั้นสุดท้ายบน macOS |
| lib/telemetry.js | ไฟล์ในแพ็กเกจ | ไฟล์ลวงที่เลียนแบบ SDK เทเลเมทรี แฝงตรรกะดาวน์โหลดเดอร์ |
| tcsbank[.]ru | โดเมน | ปรากฏในเพย์โหลด macOS ใช้ประเมินเป้าหมาย ไม่ใช่โครงสร้างของผู้โจมตี |
| cloudpayments[.]ru | โดเมน | ปรากฏในเพย์โหลด macOS ใช้ประเมินเป้าหมาย ไม่ใช่โครงสร้างของผู้โจมตี |
แหล่งอ้างอิง
- Nearly 800 Malicious npm Packages Deliver Cross-Platform RAT and Infostealer — The Hacker News
- Russian AI Slopsquatting npm Campaign — OpenSourceMalware
- Flooding Dropper Hits npm With 850 Malicious Packages — Sonatype
- Obfuscated JavaScript Crypto Stealer — Unit 42 Timely Threat Intel
- Browser as Proxy Extensions — Unit 42 Timely Threat Intel
