สรุปสั้น
ระบบนิเวศแพ็กเกจของภาษา Rust เผชิญเหตุโจมตีห่วงโซ่อุปทานที่ใหญ่ที่สุดครั้งหนึ่งเท่าที่เคยบันทึกไว้เมื่อวัดจากยอดดาวน์โหลด เมื่อ crate ที่ถูกใช้งานอย่างกว้างขวางอย่าง arrayref, append-only-vec และ internment ถูกดัดแปลงให้ส่งมัลแวร์ถึงเครื่องนักพัฒนาทันทีที่สั่งคอมไพล์โครงการ โดยที่นักพัฒนาไม่ต้องเรียกใช้ฟังก์ชันใด ๆ จากแพ็กเกจเหล่านั้นเลยแม้แต่ครั้งเดียว จุดเริ่มต้นคือแพ็กเกจหน้าใหม่ชื่อ proc-macro1 ซึ่งตั้งชื่อเลียนแบบ proc-macro2 หนึ่งใน crate ที่ทั้งวงการ Rust พึ่งพามากที่สุด แล้วคัดลอกคำอธิบายและเอกสารของตัวจริงมาใส่เพื่อให้ดูน่าเชื่อถือ จากนั้นภายในชั่วโมงเดียวกัน crate ทั้งสามตัวที่ดูแลโดยนักพัฒนาคนเดียวกันก็เพิ่ม proc-macro1 เข้าไปเป็น dependency พร้อมกัน เปลี่ยนเรื่องที่ควรจบแค่แพ็กเกจปลอมชื่อโดดเดี่ยวให้กลายเป็นเหตุห่วงโซ่อุปทานเต็มรูปแบบ
สิ่งที่ทำให้เหตุการณ์นี้ตรวจจับยากเป็นพิเศษคือซอร์สโค้ดที่มองเห็นได้ของ arrayref และ append-only-vec ไม่ถูกแก้ไขแม้แต่บรรทัดเดียว การไล่อ่านโค้ดด้วยตาจึงไม่มีทางสะดุด ของจริงถูกซ่อนไว้ในไฟล์ build.rs ของ proc-macro1 ซึ่งเป็นสคริปต์ที่ Cargo คอมไพล์และรันให้อัตโนมัติทุกครั้งที่ build เพย์โหลดปลายทางเป็นอินโฟสตีลเลอร์ที่มีเวอร์ชันแยกสำหรับ Linux, Windows และ macOS ทำหน้าที่กวาดรหัสผ่านที่บันทึกไว้ในเบราว์เซอร์ตระกูล Chromium อย่าง Chrome, Brave และ Edge พร้อมทั้งข้อมูลในที่เก็บของส่วนขยายเบราว์เซอร์ซึ่งเป็นที่อยู่ของกระเป๋าเงินคริปโท ทีม Rust Security Response เข้าจัดการหลังได้รับเบาะแสจากนักวิจัย ถอนเวอร์ชันที่ปนเปื้อนออกจาก crates.io ลบแพ็กเกจปลอมชื่อทั้งชุด และล็อกบัญชีผู้ดูแลที่ถูกยึด โดยระบุว่าเจ้าของบัญชีเป็นผู้เสียหายจากการถูกขโมยข้อมูลล็อกอิน ไม่ใช่ผู้ก่อเหตุเอง ทั้งหมดนี้เกิดขึ้นและถูกปิดฉากภายในกรอบเวลาราวสองชั่วโมงของวันที่ 20 สิงหาคม 2569
รายละเอียดข่าว
เว็บไซต์ Cyber Security News รายงานเมื่อวันที่ 20 สิงหาคม 2569 ว่านักวิจัยของบริษัท Aikido Security เป็นกลุ่มแรกที่สังเกตเห็นความผิดปกติของแพ็กเกจใหม่ชื่อ proc-macro1 ซึ่งแอบดาวน์โหลดและรันไฟล์จากเซิร์ฟเวอร์ระยะไกลระหว่างกระบวนการ build ชื่อแพ็กเกจถูกตั้งขึ้นเพื่อเลียนแบบ proc-macro2 อย่างจงใจ ซึ่งเป็น crate ระดับรากฐานที่โครงการ Rust จำนวนมหาศาลดึงเข้ามาโดยอ้อม และเนื้อหาหน้าแพ็กเกจก็คัดลอกคำอธิบายกับเอกสารของตัวจริงมาทั้งชุด
ภายในชั่วโมงเดียวกันนั้นเอง arrayref และ append-only-vec ซึ่งดูแลโดยนักพัฒนาคนเดียวกัน ได้เพิ่ม proc-macro1 เวอร์ชัน 1.0.107 เข้าเป็น dependency ผ่านการแทรกเพียงบรรทัดเดียวในไฟล์ manifest ของแต่ละ crate การเปลี่ยนแปลงระดับหนึ่งบรรทัดในไฟล์ตั้งค่านี้คือทั้งหมดที่ผู้โจมตีต้องทำ เพราะเมื่อ dependency ถูกดึงเข้ามาแล้ว Cargo จะจัดการรัน build script ของมันให้เองโดยอัตโนมัติ
ทีม Rust Security Response Team ยืนยันว่ามีสคริปต์ build ที่เป็นอันตรายจริง หลังได้รับเบาะแสจากนักวิจัยของบริษัท Nextron Systems GmbH แล้วดำเนินการลบ proc-macro1 พร้อมกับแพ็กเกจหน้าตาคล้ายกันอีกหลายตัว ได้แก่ proc-macro-en, aovine, arone, aronenao และ tinymember ทุกเวอร์ชัน จากนั้นจึงถอนเวอร์ชันที่ปนเปื้อนคือ arrayref 0.3.10, append-only-vec 0.1.9 และ internment 0.8.7 ออกจากทะเบียน
เกี่ยวกับตัวผู้ดูแลที่บัญชีถูกยึดนั้นมีข้อมูลไม่ตรงกันระหว่างสำนักข่าว รายงานฉบับแรกของ Cyber Security News ระบุชื่อนักพัฒนาคนหนึ่งที่เป็นผู้สร้างเครื่องมือค้นหาข้อความยอดนิยม แต่เว็บไซต์ The Hacker News ได้ตรวจสอบผ่าน API ของ crates.io เมื่อวันที่ 21 สิงหาคม 2569 แล้วพบว่าเจ้าของ arrayref ที่ปรากฏในทะเบียนมีเพียงรายเดียวคือผู้ใช้หมายเลข 2402 ชื่อนาย David Roundy ซึ่งลงทะเบียนไว้ตั้งแต่เดือนตุลาคม 2552 และรายการตัวบ่งชี้การถูกบุกรุกที่บริษัท StepSecurity เผยแพร่ก็ระบุชื่อบัญชี droundy ในฐานะเจ้าของที่ถูกต้องซึ่งคาดว่าถูกยึด ผู้อ่านจึงควรยึดข้อมูลจากทะเบียนเป็นหลัก ทีม Rust Security Response ระบุเพียงว่าไม่เชื่อว่าผู้เขียน arrayref มีเจตนาร้าย แต่เครื่องคอมพิวเตอร์หรือข้อมูลล็อกอินของเขาน่าจะถูกยึด และทีมกำลังพยายามติดต่ออยู่ ส่วนคำถามที่ว่าบัญชีถูกยึดด้วยวิธีใดนั้นยังไม่มีการเปิดเผย
ไทม์ไลน์และการตอบสนองของทีม Rust
ทีม Rust Security Response ระบุว่าได้รับรายงานว่า crate ชื่อ proc-macro1 เป็นอันตรายเมื่อเวลา 07:15 UTC ของวันที่ 20 สิงหาคม 2569 แล้วตรวจสอบยืนยันว่า crate ดังกล่าวมีสคริปต์ build ที่ดาวน์โหลดเพย์โหลดอันตรายจริง โดยให้เครดิตทีมวิจัยของบริษัท Nextron Systems GmbH ในฐานะผู้ค้นพบและรายงานเป็นรายแรก เวลาที่แต่ละเวอร์ชันปนเปื้อนอยู่บนทะเบียนถูกบันทึกไว้อย่างละเอียด ได้แก่ arrayref 0.3.10 เผยแพร่เวลา 07:15:00Z และถูกลบเวลา 08:41:40Z รวมอยู่บนทะเบียน 86 นาที, internment 0.8.7 เผยแพร่ 07:34:07Z ลบ 09:04:11Z รวม 90 นาที และ append-only-vec 0.1.9 เผยแพร่ 07:37:49Z ลบ 09:25:24Z รวม 107 นาที
จุดที่ควรบันทึกไว้เป็นบทเรียนคือกลไกการส่งมอบ ผู้โจมตีอาศัยบัญชีเจ้าของ ถอน (yank) เวอร์ชัน 0.3.5 ถึง 0.3.9 ของ arrayref ทั้งหมดในนาทีเดียวกับที่เผยแพร่เวอร์ชันปนเปื้อน ผลคือ 0.3.10 กลายเป็นเวอร์ชันเดียวที่ Cargo จะไม่ขึ้นคำเตือน และคำเตือนของ Cargo ที่แนะนำให้ผู้ใช้พิจารณาอัปเดตไปยังเวอร์ชันที่ไม่ถูกถอนนั่นเองที่กลายเป็นเหยื่อล่อ ผู้รายงานเหตุซึ่งใช้ชื่อผู้ใช้ GitHub ว่า jhobern อธิบายไว้ตรง ๆ ว่านั่นคือวิธีที่ตัวเองเจอเข้ากับมัน ในระหว่างการตอบสนอง ทีม Rust Security Response จึงยกเลิกการถอนเวอร์ชันเก่าที่ถูกถอนอย่างมีเจตนาร้ายเหล่านั้นกลับคืนมา
ประกาศ RUSTSEC-2026-0260 ระบุว่าไม่มีเวอร์ชันที่แก้ไขแล้ว ไม่มีการกำหนดหมายเลข CVE ให้ และประกาศของทั้งสาม crate บันทึกไว้ว่าไม่พบหลักฐานว่ามีเวอร์ชันอันตรายถูกนำไปใช้จริง โดยข้อความในประกาศระบุว่าเวอร์ชันที่ถูกยึดของ arrayref ถูกเผยแพร่เมื่อวันที่ 20 สิงหาคม 2569 และถูกลบไปราว 86 นาทีให้หลัง โดยไม่พบหลักฐานการใช้งานจริง ทั้งนี้ The Hacker News ระบุว่าได้ติดต่อทีม Rust Security Response เพื่อขอทราบว่าข้อสรุปเรื่อง “ไม่พบหลักฐานการใช้งาน” ตั้งอยู่บนฐานอะไร และขอตัวเลขยอดดาวน์โหลดของเวอร์ชันที่ถูกลบ แต่ยังไม่ได้รับคำตอบ ณ เวลาที่รายงาน
วิธีการโจมตี
หัวใจของการโจมตีอยู่ที่ไฟล์ build.rs ซึ่งเป็นกลไกปกติของ Rust ที่เปิดให้ crate รันโค้ดเตรียมการก่อนคอมไพล์ เช่น สร้างโค้ดอัตโนมัติหรือเชื่อมกับไลบรารีภาษา C สิ่งที่ผู้โจมตีทำคือใช้ช่องทางที่ถูกออกแบบมาให้รันโค้ดอยู่แล้วนี้เป็นจุดปล่อยมัลแวร์ ผลคือเครื่องของนักพัฒนาติดเชื้อตั้งแต่ขั้นตอน cargo build โดยไม่ต้องมีบรรทัดใดในแอปพลิเคชันเรียกใช้ฟังก์ชันจาก crate ที่ถูกยึดเลย และรายงานของ Nextron ระบุเพิ่มว่าคำสั่งที่ทริกเกอร์ได้ไม่ได้มีแค่ cargo build เท่านั้น แต่รวมถึง cargo check และ cargo test ด้วย ซึ่งเป็นคำสั่งที่นักพัฒนาและระบบ CI เรียกใช้บ่อยกว่าการ build เต็มรูปแบบเสียอีก ส่วนซอร์สโค้ดของไลบรารีใน proc-macro1 นั้นเป็นสำเนาจริงของ proc-macro2 การคอมไพล์จึงผ่านตามปกติทุกประการ
เมื่อสคริปต์ทำงาน มันจะประกอบที่อยู่ของเซิร์ฟเวอร์เพย์โหลดและเซิร์ฟเวอร์ควบคุมขึ้นใหม่จากชิ้นส่วนที่เข้ารหัสแบบ base64 ในเวลา build เพื่อเลี่ยงเครื่องมือสแกนที่ตรวจจับด้วยการค้นสตริงตรง ๆ จากนั้นจึงทำสิ่งที่เป็นจุดสังเกตสำคัญ คือ ติดตั้งตัวตรวจสอบใบรับรองของตัวเองที่ให้เมทอดตรวจสอบทั้งสามตัวคืนค่าว่าผ่านเสมอ ซึ่งเท่ากับปิดการตรวจสอบ TLS ทิ้งทั้งหมด แล้วเลือกเพย์โหลดหนึ่งในสี่ชุดตามระบบปฏิบัติการและสถาปัตยกรรมซีพียูของเครื่องเป้าหมาย
บนระบบตระกูลยูนิกซ์และ macOS มัลแวร์จะเขียนไฟล์ลงที่ /tmp/rust-setup ตั้งค่าให้เป็นไฟล์ที่รันได้ แล้วสั่งรันเป็นโปรเซสแยกตัวโดยส่งที่อยู่ของเซิร์ฟเวอร์ควบคุมเป็นอาร์กิวเมนต์ตัวแรก ส่วนบน Windows จะเขียนสคริปต์ PowerShell ลงในโฟลเดอร์ %TEMP% แล้วเรียกใช้แบบซ่อนหน้าต่างผ่านตัวเรียก VBScript ที่รันด้วย wscript.exe จากนั้นจึงปล่อยโปรเซสลูกทิ้งไป ซึ่งในซอร์สโค้ดมีคอมเมนต์กำกับไว้ว่าเป็นการหลุดออกจาก job object ของ Cargo เพื่อไม่ให้กระบวนการ build ต้องรอโปรเซสนั้น
การวิเคราะห์เพย์โหลดขั้นที่สองพบว่ามันติดต่อกลับเซิร์ฟเวอร์ควบคุมด้วยคำขอ HTTPS แบบ POST ไปยังเส้นทาง /49890878 และฝังตัวถาวรด้วยวิธีที่ต่างกันไปตามระบบปฏิบัติการ ได้แก่ Registry Run key บน Windows, LaunchAgent บน macOS และ systemd user service บน Linux โดยรองรับคำสั่งสี่ชุด ครอบคลุมการสั่งหยุดทำงาน การเปลี่ยนค่าเซิร์ฟเวอร์ควบคุม การติดตั้งกลไกฝังตัว และการดาวน์โหลดสคริปต์เพิ่มเติมมารัน บริษัท Wiz ระบุว่ามัลแวร์ขโมยข้อมูลล็อกอินจากเบราว์เซอร์ Chrome, Brave และ Edge ด้วยการสอบถามฐานข้อมูล SQLite ที่เก็บข้อมูลการล็อกอิน อย่างไรก็ตามการวิเคราะห์ของ Nextron ให้ภาพที่ละเอียดกว่านั้นและควรอ่านคู่กัน คือเพย์โหลดฝั่ง Windows ที่ถูกวิเคราะห์สอบถามเฉพาะคอลัมน์ origin_url และ username_value เท่านั้น ไม่ได้ดึงคอลัมน์ password_value โดยตรง แต่การวิเคราะห์ชุดนั้นครอบคลุมเฉพาะเพย์โหลดของ Windows ส่วนเพย์โหลดของ Linux และ macOS ทำได้เพียงคำนวณค่าแฮชไว้ ยังไม่ได้ถูกวิเคราะห์
| รายการ | รายละเอียดเชิงเทคนิค | ผลในทางปฏิบัติ |
|---|---|---|
| crate ที่ถูกยึด | arrayref (0.3.10), append-only-vec (0.1.9), internment (0.8.7) | ยอดดาวน์โหลดรวมระดับหลายร้อยล้านครั้ง |
| dependency ที่ถูกแทรก | proc-macro1 (1.0.107) | ปลอมชื่อเลียนแบบ proc-macro2 |
| จุดที่ทริกเกอร์ | Cargo รัน build.rs อัตโนมัติ | รันโค้ดตามอำเภอใจระหว่างคอมไพล์ |
| ประเภทเพย์โหลด | อินโฟสตีลเลอร์ข้ามแพลตฟอร์ม + เชลล์ระยะไกล | ดูดรหัสผ่านเบราว์เซอร์และกุญแจกระเป๋าคริปโท |
| การฝังตัวบน macOS | LaunchAgent ทำงานเบื้องหลัง | อยู่รอดหลังปิดโปรเซสและรีบูตเครื่อง |
| ช่วงเวลาของเหตุ | ราว 2 ชั่วโมง วันที่ 20 สิงหาคม 2569 | ถอน crate และล็อกบัญชีได้เร็ว |
เส้นทาง dependency ที่ทำให้โครงการทั่วไปดึงเวอร์ชันปนเปื้อนเข้ามา
ตัวเลขที่ The Hacker News ตรวจสอบผ่าน API ของ crates.io เมื่อวันที่ 21 สิงหาคม 2569 ระบุว่า arrayref มียอดดาวน์โหลดสะสมตลอดอายุ 245,385,500 ครั้ง และ 53,905,601 ครั้งในช่วง 90 วันที่สิ้นสุดวันที่ 20 สิงหาคม 2569 โดยมี crate อื่นบนทะเบียนถึง 403 ตัวที่ประกาศพึ่งพา arrayref โดยตรง
สิ่งที่อธิบายว่าทำไมโครงการที่ไม่เคยเรียก arrayref เองถึงยังเสี่ยง คือรูปแบบการประกาศเวอร์ชันแบบ caret range ตัวอย่างที่ตรวจสอบไว้เป็นสายโซ่คือ winit ต้องการ sctk-adwaita รุ่น ^0.10.1 ซึ่งต้องการ tiny-skia รุ่น ^0.11 ซึ่งต้องการ arrayref รุ่น ^0.3.6 ทุกข้อกำหนดในสายนี้เป็น caret range บนสาย 0.3.x และ caret range บนสาย 0.3.x ยอมรับเวอร์ชัน 0.3.10 ได้ทั้งหมด กล่าวคือโครงการที่ระบุแค่ไลบรารีระดับบนสุดตัวเดียวก็มีโอกาสถูกแก้ให้ดึงเวอร์ชันปนเปื้อนเข้ามาโดยอัตโนมัติในการ build ครั้งถัดไป
ปฏิกิริยาของโครงการปลายน้ำเกิดขึ้นเร็วมากในเช้าวันเดียวกัน โดยพบว่า blake3 ประกาศพึ่งพา arrayref มาจนถึงเวอร์ชัน 1.8.6 และตัดออกในเวอร์ชัน 1.8.7 ซึ่งเผยแพร่เวลา 09:09 UTC ของวันที่ 20 สิงหาคม 2569 ขณะที่ blake2b_simd และ blake2s_simd ก็ตัด dependency เดียวกันออกในเวอร์ชันที่เผยแพร่เวลา 09:25 และ 09:26 UTC ตามลำดับ
ความเชื่อมโยงกับแคมเปญของเกาหลีเหนือที่ยังไม่ถูกฟันธง
บริษัท Wiz ระบุว่าโครงสร้างพื้นฐานที่ใช้ในเหตุการณ์นี้ทับซ้อนอย่างมีนัยสำคัญกับการโจมตีห่วงโซ่อุปทานของเกาหลีเหนือในระยะหลัง โดยยกสองเหตุการณ์มาเทียบ คือการยึดแพ็กเกจ Mastra บน npm และการยึดแพ็กเกจ axios ในกรณีแรก บริษัท Microsoft ประเมินด้วยความเชื่อมั่นสูงว่าเป็นฝีมือของกลุ่ม Sapphire Sleet ซึ่งเคยรายงานไว้ในโพสต์ 06/147 ส่วนกรณี axios นั้น Google Threat Intelligence Group ระบุว่าเป็นฝีมือของผู้โจมตีที่ปัจจุบันติดตามในชื่อ MIDNIGHT NEPTUNE ซึ่งเดิมรู้จักในชื่อ UNC1069
ข้อที่ต้องเน้นให้ชัดคือ ยังไม่มีผู้ให้บริการรายใดระบุว่าเหตุการณ์บน crates.io ครั้งนี้เป็นฝีมือของกลุ่มที่มีชื่อเรียก สิ่งที่มีอยู่คือความทับซ้อนของโครงสร้างพื้นฐานตามการประเมินของ Wiz เท่านั้น ซึ่งเป็นหลักฐานเชิงบ่งชี้ ไม่ใช่การชี้ตัว กลุ่มที่ต้องสงสัยเหล่านี้มีประวัติเล่นงานทะเบียนแพ็กเกจมาต่อเนื่อง รวมถึงเหตุยึดแพ็กเกจ npm ยอดนิยมอย่าง debug และ chalk ที่เคยรายงานไว้ในโพสต์ 07/303
ช่องว่างเชิงนโยบาย — Cargo ยังไม่มีช่วงเวลาหน่วงก่อนใช้แพ็กเกจใหม่
รายงานของ GTIG และ Mandiant เมื่อวันที่ 30 กรกฎาคม 2569 ซึ่งวิเคราะห์เหตุ axios ได้เสนอมาตรการที่เรียกว่าช่วงเวลาหน่วง หรือ cooling window สำหรับทรัพยากรของบุคคลที่สามที่เพิ่งถูกเผยแพร่ใหม่ โดยชี้ว่าแม้เวอร์ชันอันตรายของ axios จะถูกลบออกจากทะเบียน npm ภายในสามชั่วโมง แต่ขอบเขตความเสียหายก็ยังประเมินว่ากว้าง เพราะแพ็กเกจนั้นมียอดดาวน์โหลดเกินร้อยล้านครั้งต่อสัปดาห์ หลักการของมาตรการนี้ตรงไปตรงมา คือหน่วงไม่ให้ระบบ build ดึง dependency ที่เพิ่งเผยแพร่ภายในเวลาที่กำหนดเข้ามาใช้ทันที
สิ่งที่เหตุการณ์นี้เปิดเผยคือ Cargo ยังไม่มีกลไกเทียบเท่าที่พร้อมใช้งาน คำขอรวมโค้ดที่จะทำให้การตั้งค่า global-min-publish-age มีสถานะเสถียร ซึ่งจะช่วยหน่วง dependency ที่อายุน้อยกว่าค่าที่กำหนดไว้ เพิ่งเข้าสู่ช่วงรับความเห็นรอบสุดท้ายเมื่อวันที่ 18 สิงหาคม 2569 หรือสองวันก่อนเกิดเหตุ และยังคงเปิดค้างไว้โดยไม่ถูกรวมเข้าโครงการจนถึงวันที่ 21 สิงหาคม 2569 ขณะที่ GitHub ได้เปิดใช้ค่าเริ่มต้นแบบหน่วงเวลาลักษณะเดียวกันให้ Dependabot ไปแล้วตั้งแต่เดือนกรกฎาคม 2569
ในแง่ของนโยบายทะเบียน เหตุการณ์นี้ยังต่างจากกรณีเมื่อเดือนกันยายน 2568 ที่มี crate อันตรายสองตัวปลอมตัวเป็นไลบรารีบันทึกล็อก เพราะครั้งนั้นโค้ดอันตรายทำงานเฉพาะตอนรันโปรแกรมเท่านั้น ซึ่งเป็นเส้นแบ่งที่ crates.io ชี้ไว้เองในเวลานั้น ต่างจากครั้งนี้ที่โค้ดทำงานตั้งแต่ขั้นคอมไพล์
ผลกระทบ
ผู้ที่เสี่ยงที่สุดคือทีมที่สั่ง build โครงการ Rust ในช่วงเวลาสองชั่วโมงดังกล่าว ทั้งบนเครื่องนักพัฒนาเองและในระบบ CI ซึ่งมักถือครองข้อมูลล็อกอินที่มีสิทธิ์สูงกว่าเครื่องส่วนตัวมาก เพราะการติดเชื้อเกิดที่ขั้นตอนคอมไพล์ ไม่ใช่ขั้นตอนรันแอปพลิเคชัน มาตรการที่พึ่งการตรวจสอบซอร์สโค้ดหรือการทดสอบพฤติกรรมของโปรแกรมที่คอมไพล์เสร็จแล้วจึงไม่ช่วยอะไรเลยในกรณีนี้
เหตุการณ์นี้ยังตอกย้ำจุดอ่อนเชิงโครงสร้างที่ระบบนิเวศแพ็กเกจแทบทุกภาษามีร่วมกัน นั่นคือสคริปต์ที่ทำงานตอน build สามารถรันโค้ดใด ๆ ด้วยสิทธิ์เต็มของผู้ใช้ ก่อนที่ตรรกะของแอปพลิเคชันจะเริ่มทำงานเสียอีก การตรวจสอบว่า dependency น่าเชื่อถือหรือไม่จึงมีน้ำหนักไม่แพ้การตรวจซอร์สโค้ด รูปแบบเดียวกันนี้เคยปรากฏมาแล้วในเหตุแพ็กเกจ npm, PyPI และ crates.io ที่ถูกฝังสตีลเลอร์ตามที่เคยรายงานไว้ในโพสต์ 05/059 รวมถึงกรณีแพ็กเกจของ Arch Linux AUR กว่า 400 รายการที่ถูกยึดในโพสต์ 06/086
ข้อจำกัดของหลักฐานที่ต้องระบุไว้คือประกาศ RUSTSEC ของทั้งสาม crate บันทึกว่าไม่พบหลักฐานว่ามีเวอร์ชันอันตรายถูกใช้จริง แต่ยังไม่มีคำอธิบายว่าข้อสรุปนั้นตั้งอยู่บนข้อมูลชุดใด และไม่มีการเปิดเผยยอดดาวน์โหลดของเวอร์ชันที่ถูกลบ ส่วนตัวเลขยอดดาวน์โหลดระดับ 245 ล้านครั้งที่ถูกอ้างถึงเป็นยอดสะสมตลอดอายุของแพ็กเกจ ไม่ใช่จำนวนการดาวน์โหลดที่เกิดขึ้นในช่วงที่เวอร์ชันปนเปื้อนอยู่บนทะเบียน ตัวเลขนี้จึงบอกขนาดของความนิยม ไม่ได้บอกขนาดของความเสียหาย
คำแนะนำ
ทีมที่คอมไพล์โครงการ Rust ในวันที่ 20 สิงหาคม 2569 ควรตั้งสมมติฐานว่าไปป์ไลน์ CI และแคช build บนเครื่องอาจถูกแตะต้องแล้ว ให้ค้นในโฟลเดอร์ ~/.cargo/registry/cache ว่ามีไฟล์ของ crate ที่ถูกลบค้างอยู่หรือไม่ และไล่ดูล็อกการ build ย้อนหลังเพื่อหาการเชื่อมต่อออกไปยังหมายเลขไอพีในรายการตัวบ่งชี้ด้านล่างระหว่างขั้นตอนคอมไพล์ พร้อมตรวจหาไฟล์และกลไกฝังตัวตามรายการเดียวกัน ทั้ง /tmp/rust-setup บนยูนิกซ์ ไฟล์ใน %TEMP% บน Windows คีย์ Run ในรีจิสทรี LaunchAgent บน macOS และ systemd user service บน Linux
ในเชิงการตั้งค่า ควรตรึงเวอร์ชันของ arrayref ไว้ที่ 0.3.9 หรือต่ำกว่า และตรวจว่า append-only-vec กับ internment ไม่ได้ค้างอยู่ที่เวอร์ชันที่ถูกถอน จากนั้นเปิดการยืนยันตัวตนสองชั้นสำหรับบัญชีที่ใช้เผยแพร่แพ็กเกจบน crates.io ทุกบัญชี เพราะต้นเหตุของเหตุการณ์นี้คือข้อมูลล็อกอินของผู้ดูแลที่ถูกขโมยไป ไม่ใช่ช่องโหว่ของตัวทะเบียนเอง และควรจำไว้ว่าคำเตือนของ Cargo ที่แนะนำให้เลี่ยงเวอร์ชันที่ถูกถอน ถูกใช้เป็นเหยื่อล่อในเหตุการณ์นี้ การเห็นคำเตือนนั้นจึงไม่ใช่เหตุผลเพียงพอที่จะรีบอัปเดตไปเวอร์ชันล่าสุดทันที
สำหรับองค์กรที่รันงาน build อัตโนมัติเป็นประจำ ควรพิจารณาแยกสภาพแวดล้อม build ออกจากเครือข่ายที่เข้าถึงข้อมูลสำคัญ จำกัดการเชื่อมต่อขาออกของเครื่อง build ให้เหลือเฉพาะปลายทางที่อนุญาต หมุนเวียนข้อมูลล็อกอินหรือโทเคนใด ๆ ที่เคยอยู่ในเครื่อง build ระหว่างช่วงเวลาที่มีความเสี่ยง และตั้งนโยบายหน่วงเวลาไม่ให้ระบบดึง dependency ที่เพิ่งเผยแพร่ใหม่ภายในไม่กี่ชั่วโมงเข้ามาใช้ทันที ซึ่งเป็นมาตรการเดียวที่จะทำให้หน้าต่างโจมตีสั้น ๆ ระดับหนึ่งถึงสองชั่วโมงแบบนี้ไม่มีผลกับองค์กร
Indicators of Compromise (IoCs)
ตัวบ่งชี้ด้านล่างรวบรวมจากรายงานของบริษัท StepSecurity โดยหมายเลขไอพีและโดเมนถูก defang ไว้ด้วยวงเล็บก้ามปูแล้ว ก่อนนำไปใช้ในเครื่องมือตรวจจับต้องแปลงกลับเป็นรูปแบบปกติก่อน
| ประเภท | ตัวบ่งชี้ | คำอธิบาย |
|---|---|---|
| เครือข่าย | 23.254.165[.]112:9089 | เซิร์ฟเวอร์ที่ใช้แจกจ่ายเพย์โหลด |
| เครือข่าย | 23.254.165[.]112:443 | เซิร์ฟเวอร์ควบคุม |
| เครือข่าย | hwsrv-798836.hostwindsdns[.]com | โดเมนที่เกี่ยวข้องกับโครงสร้างพื้นฐาน |
| ไฟล์ | /tmp/rust-setup | เพย์โหลดที่เขียนลงเครื่องบนยูนิกซ์และ macOS |
| ไฟล์ | %TEMP%\rust-setup.ps1 | สคริปต์ PowerShell บน Windows |
| ไฟล์ | %TEMP%\rust-setup-launch.vbs | ตัวเรียก VBScript ที่รันสคริปต์แบบซ่อนหน้าต่าง |
| ไฟล์ไบนารี | rust-crate_0.1.0, _0.2.0, _0.3.0, _0.4.0 | ชื่อไฟล์เพย์โหลดตามแพลตฟอร์มและสถาปัตยกรรม |
| บัญชี | dtolney (crates.io id 438608) | บัญชีที่สวมรอย |
| บัญชี | droundy | เจ้าของที่ถูกต้อง คาดว่าถูกยึดบัญชี |
| อีเมล | rchaitm@gmail.com | ข้อมูลผู้เขียนปลอมที่ฝังไว้ในเมตาดาตา |
แหล่งอ้างอิง
- RustSec — RUSTSEC-2026-0260
- Rust Blog — Supply chain attack on arrayref
- Wiz — Rust supply chain attack on arrayref: significant overlap with DPRK campaigns
- StepSecurity — arrayref Rust crate supply chain attack
- The Hacker News — Rust Supply Chain Attack Puts Build-Time Malware in Crates with 245 Million Downloads
- Cyber Security News — Popular Rust Packages With 244M Downloads Compromised to Run Malware
- Aikido Security — รายงานวิเคราะห์ crate ของ Rust ที่ถูกยึดและใช้ส่งโค้ดออกจากเครื่อง
