สรุปสั้น
นักวิจัยด้านความปลอดภัยพบแพ็กเกจ npm อันตรายชื่อ indexed-btree ที่ซ่อนพฤติกรรมอันตรายไว้ภายในโค้ดของแอปพลิเคชันตอนรันไทม์ แทนที่จะพึ่ง lifecycle script อย่าง preinstall หรือ postinstall แบบที่พบทั่วไป ความเปลี่ยนแปลงนี้บ่งชี้ว่าผู้โจมตีกำลังปรับกลยุทธ์เพื่อตอบโต้มาตรการความปลอดภัยล่าสุด โดยเฉพาะการที่ npm เวอร์ชัน 12 เพิ่งเพิ่มการป้องกันไม่ให้รัน lifecycle script โดยอัตโนมัติ ซึ่งเป็นหนึ่งในช่องทางที่มัลแวร์ถูกรันผ่านแพ็กเกจบ่อยที่สุด
indexed-btree ปลอมตัวเป็นไลบรารี sorted-btree ที่ถูกต้องตามกฎหมาย ซึ่งเป็นยูทิลิตี B-tree/indexing ทั่วไป แพ็กเกจถูกอัปโหลดขึ้น registry ครั้งแรกเมื่อวันที่ 18 มิถุนายน 2569 โดยผู้ใช้ npm ชื่อ charlessadler25 และมียอดดาวน์โหลดถึงหลักล้านครั้งในเวลาอันสั้น ที่แย่ไปกว่านั้นคือแคมเปญนี้อาจสร้างกำไรผิดกฎหมายให้ผู้โจมตีไปแล้วราว 230,933.57 ยูโรในรูปสกุลเงินคริปโต (คิดเป็น 109 ETH) ปัจจุบันทั้งแพ็กเกจและรีโพ GitHub ที่เกี่ยวข้องถูกลบออกจาก npm แล้ว
รายละเอียดข่าว
เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 22 กันยายน 2569 ว่า บริษัท Checkmarx บริษัทด้านความปลอดภัยของห่วงโซ่อุปทานซอฟต์แวร์ ได้เปิดเผยแพ็กเกจ npm อันตราย indexed-btree ที่ต่างจากการโจมตีซัพพลายเชนทั่วไปตรงที่ไม่พึ่ง preinstall หรือ postinstall เลย แต่รันทั้งหมดจากโค้ดของแอปพลิเคชันตอนรันไทม์
Checkmarx อธิบายว่าโดยปกติ lifecycle script ถูกใช้อย่างถูกต้องเพื่อคอมไพล์โค้ดที่จำเป็น seed ข้อมูล หรือตั้งค่าคอนฟิกสำคัญ แต่ผู้โจมตีมักฉวยใช้มันรันโค้ดอันตรายโดยอัตโนมัติระหว่างติดตั้งแพ็กเกจโดยที่ผู้ใช้ไม่ยินยอม เมื่อ npm เวอร์ชัน 12 เพิ่มการป้องกันไม่ให้รัน lifecycle script อัตโนมัติ ผู้โจมตีจึงเลี่ยงไปฝังโค้ดอันตรายไว้ในตัวไลบรารีโดยตรงแทน
นาย Ensar Seker ซึ่งเป็น CISO ของบริษัท SOCRadar ระบุว่า สิ่งที่ทำให้แคมเปญนี้สำคัญเป็นพิเศษคือการที่ผู้โจมตีปรับตัวแทบจะทันทีต่อการป้องกันซัพพลายเชนที่แข็งแรงขึ้น การที่ npm ปรับปรุงความปลอดภัยช่วงติดตั้งด้วยการจำกัด lifecycle script เป็นการพัฒนาที่สำคัญ แต่แคมเปญนี้แสดงให้เห็นว่าผู้โจมตีสามารถย้ายการรันโค้ดอันตรายไปไว้ในฟังก์ชันรันไทม์ที่ดูปกติได้ บทเรียนในภาพกว้างคือมาตรการความปลอดภัยเปลี่ยนพฤติกรรมของผู้โจมตี แต่ไม่ได้กำจัดภัยคุกคามที่รากเหง้า ผู้ป้องกันจึงต้องมีการควบคุมแบบหลายชั้นที่ตรวจจับพฤติกรรมอันตรายได้ทั้งก่อนติดตั้ง ระหว่างรัน และหลังใช้งาน

วิธีการโจมตี
ในกรณีนี้ loader ของมัลแวร์ถูกซ่อนไว้ภายใน method ชื่อ BTree.prototype.set() ซึ่งเมื่อถูกเรียกใช้จะไปกระตุ้นไฟล์ sharedLoad.min.js ที่เป็น payload JavaScript ฝังสเตจแรกของมัลแวร์ในรูปแบบ obfuscate ไว้ มัลแวร์ถูกออกแบบมาให้ทำ fingerprint เครื่องเหยื่อ ส่งข้อมูลกลับ (beacon) ไปยังช่อง Slack และบอต Telegram ที่ฝังไว้แบบ hard-coded จากนั้นใช้เทคนิค EtherHiding ดึง blob เข้ารหัสสเตจถัดไปจาก smart contract ที่วางไว้บน Sepolia testnet แล้วนำมารวมกันเป็น payload สเตจสอง ก่อนจะปิดท้ายด้วยการลบ artifact อันตรายและถอด trigger ออกจากโค้ดแพ็กเกจเพื่อกลบร่องรอย
Checkmarx ระบุว่า indexed-btree เป็นเพียงหนึ่งในหลายแพ็กเกจ npm ที่ผูกกับปฏิบัติการเดียวกัน ซึ่งทั้งหมดถูกลบออกจาก npm ไปแล้ว ได้แก่ ordered-kv-index, btree-leaderboard, priority-slot-queue, btree-range-store, btree-core, btree-time-index, btree-lru-cache, neighbor-key-map, sliding-score-window และ mutex-forge
PolinRider กลับมาโผล่บน Packagist
การเปิดเผยครั้งนี้เกิดขึ้นในช่วงเวลาเดียวกับที่บริษัท Socket ระบุว่าได้ลบโค้ดอันตรายในเวอร์ชัน dev-main ของแพ็กเกจ visanduma/nova-two-factor บน Packagist ซึ่งมียอดดาวน์โหลดสะสมกว่า 700,000 ครั้ง โดยเป็นส่วนหนึ่งของแคมเปญที่โยงกับเกาหลีเหนือชื่อ PolinRider ลักษณะเด่นของ PolinRider คือการยึดบัญชีนักพัฒนาเพื่อ inject เนื้อหาอันตรายเข้าสู่รีโพซอร์สโค้ด และใช้การกระทำปกติของนักพัฒนา เช่น การโคลนรีโพหรือเปิดโปรเจกต์ใน IDE เป็นตัวกระตุ้นห่วงโซ่การติดเชื้อ
พฤติกรรมนี้มักมาพร้อมการเขียนประวัติ Git ใหม่ ซ่อน payload ไว้ในไฟล์คอนฟิกหรือไฟล์ฟอนต์ ตั้ง task auto-run อันตรายใน VS Code และพึ่งเทคนิคที่ทนต่อการ takedown อย่าง EtherHiding และตัวสืบทอดที่เน้นการซ่อนตัวชื่อ NullReceiver เพื่อส่ง payload เป็นสเตจผ่านบล็อกเชน นาย Karlo Zanki นักวิจัยของ Socket ระบุว่ารีโพขององค์กร Visanduma บน GitHub ถูกยึดมาตั้งแต่กลางเดือนมิถุนายน 2569 ผ่านบัญชีนักพัฒนา LaHiRu จุดที่เปลี่ยนไปในรอบล่าสุดคือการ inject โค้ด JavaScript ที่ obfuscate หนักเข้าไปใน index.php โดยตรง แล้วรันผ่านฟังก์ชัน shell_exec() ของ PHP สะท้อนว่าผู้โจมตีปรับวิธีการรันตามโปรเจกต์ที่ยึดได้แทนการใช้เส้นทางส่งมอบตายตัว
ผลกระทบ
แคมเปญ indexed-btree แสดงให้เห็นชัดว่าผู้โจมตีปรับตัวได้แทบจะทันทีเมื่อการป้องกันซัพพลายเชนแข็งแรงขึ้น การที่ npm v12 บล็อก lifecycle script ช่วยลดความเสี่ยงช่วงติดตั้งได้จริง แต่ผู้โจมตีก็เพียงย้ายการรันโค้ดอันตรายไปไว้ในฟังก์ชันรันไทม์ที่ดูปกติแทน ประกอบกับยอดดาวน์โหลดหลักล้านครั้งและกำไรคริปโตหลักแสนยูโร ยิ่งตอกย้ำว่าการพึ่งการสแกนเฉพาะตอนติดตั้งเพียงอย่างเดียวไม่เพียงพออีกต่อไป
เมื่อรวมกับการกลับมาของ PolinRider ที่ใช้การยึดบัญชีนักพัฒนาและรีโพเป็นฐาน จะเห็นว่าห่วงโซ่อุปทานซอฟต์แวร์กำลังถูกโจมตีจากหลายทิศทางพร้อมกัน ทั้งแพ็กเกจปลอมที่หลอกให้ติดตั้ง และการเจาะรีโพต้นทางเพื่อแพร่เชื้อผ่านเวิร์กโฟลว์การพัฒนาปกติ องค์กรที่ดึง dependency จากภายนอกจึงมีพื้นผิวการโจมตีที่กว้างกว่าที่คิด
คำแนะนำ
นักพัฒนาไม่ควรพึ่งเพียงการสแกนตอนติดตั้งและการบล็อก lifecycle script เท่านั้น แต่ควรเพิ่มการวิเคราะห์พฤติกรรมตอนรัน (runtime behavior analysis) เพื่อจับโค้ดอันตรายที่ย้ายไปซ่อนในฟังก์ชันปกติ ควรวางการควบคุมแบบหลายชั้นที่ตรวจจับได้ทั้งก่อนติดตั้ง ระหว่างรัน และหลังนำไปใช้งาน
นอกจากนี้ควรตรวจสอบและตรึงเวอร์ชันของ dependency (pin/lockfile) พร้อมทบทวนแพ็กเกจก่อนอัปเดต เฝ้าระวังการเชื่อมต่อออกที่ผิดปกติไปยังบริการอย่าง Slack, Telegram หรือโหนดบล็อกเชนสาธารณะ ซึ่งอาจเป็นสัญญาณของการ beacon หรือเทคนิค EtherHiding สำหรับความเสี่ยงแบบ PolinRider ควรบังคับใช้การยืนยันตัวตนที่แข็งแรงกับบัญชีนักพัฒนา ตรวจสอบการเปลี่ยนแปลงประวัติ Git ที่ผิดปกติ และระวัง task auto-run ที่ถูกตั้งไว้ในโปรเจกต์หรือ IDE
