- ระบบนิเวศ npm กำลังเผชิญการแพร่กระจายของ มัลแวร์แบบทำลายล้างสายพันธุ์ใหม่ และทีมความปลอดภัยของ GitLab เป็นผู้ตรวจพบ
- มัลแวร์นี้เป็นรูปแบบวิวัฒนาการของ Shai-Hulud และมี โครงสร้างการแพร่กระจายแบบหนอน ที่สามารถแพ็กเกจอื่นของนักพัฒนาที่ติดเชื้อให้ติดเชื้อตามโดยอัตโนมัติ
- หลัง ขโมยข้อมูลรับรอง จาก GitHub, AWS, GCP, Azure และอื่นๆ แล้ว จะ ส่งข้อมูลออก ไปยัง GitHub repository ที่ผู้โจมตีควบคุม
- มีการฝัง “dead man’s switch” ที่จะลบข้อมูลผู้ใช้ทันที หากการเข้าถึง GitHub และ npm ถูกบล็อกพร้อมกัน
- GitLab ยืนยันว่าระบบของตนไม่ได้ติดเชื้อ และนำเสนอแนวทางการตรวจจับและรับมือผ่าน Dependency Scanning และ GitLab Duo Chat
ภาพรวมของการโจมตี
- ทีม Vulnerability Research ของ GitLab ตรวจพบการโจมตีซัพพลายเชนขนาดใหญ่ในระบบนิเวศ npm
- ระบบมอนิเตอร์ภายในพบแพ็กเกจที่ติดเชื้อหลายรายการ
- ยืนยันได้ว่ามัลแวร์เป็นสายพันธุ์หนึ่งของ Shai-Hulud
- มัลแวร์แพร่กระจายแบบ หนอน ทำให้แพ็กเกจอื่นของนักพัฒนาที่ติดเชื้อถูกติดเชื้อตามโดยอัตโนมัติ
- GitLab ยืนยันว่าไม่ได้ใช้แพ็กเกจอันตรายเหล่านี้ในระบบของตน และได้แบ่งปันข้อมูลกับชุมชนความปลอดภัย
โครงสร้างภายในของการโจมตี
- แพ็กเกจ npm อันตรายที่ระบบมอนิเตอร์ภายในตรวจพบ มีความสามารถดังนี้
- เก็บรวบรวมข้อมูลรับรอง ของ GitHub, npm, AWS, GCP และ Azure
- ส่งข้อมูลที่ขโมยมาไปยัง GitHub repository ที่ผู้โจมตีควบคุม
- ทำให้แพ็กเกจอื่นของเหยื่อติดเชื้อโดยอัตโนมัติ
- รันเพย์โหลดแบบทำลายล้างเมื่อการเข้าถึงโครงสร้างพื้นฐานถูกบล็อก
- มีการยืนยันแพ็กเกจที่ติดเชื้อหลายรายการแล้ว และการสืบสวนยังดำเนินต่อไป
การวิเคราะห์ทางเทคนิค: วิธีดำเนินการของการโจมตี
เวกเตอร์การติดเชื้อเริ่มต้น
- มัลแวร์แทรกซึมเข้าสู่ระบบผ่านกระบวนการโหลดหลายขั้นตอน
- มีการเพิ่มสคริปต์
setup_bun.js เข้าไปใน package.json ของแพ็กเกจที่ติดเชื้อ
- ภายนอกดูเหมือนเป็นสคริปต์สำหรับติดตั้ง Bun JavaScript runtime
- แต่จริงๆ แล้วจะรัน
bun_environment.js (เพย์โหลดที่ถูกทำให้อ่านยาก ขนาด 10MB)
- โครงสร้างนี้ใช้ไฟล์โหลดเดอร์ขนาดเล็กคู่กับเพย์โหลดขนาดใหญ่ที่ถูก obfuscate เพื่อหลบเลี่ยงการตรวจจับ
การเก็บข้อมูลรับรอง
- ทันทีที่เริ่มทำงาน มันจะรวบรวม โทเค็นและข้อมูลลับ จากหลายแหล่ง
- GitHub token (
ghp_, gho_)
- ข้อมูลรับรอง AWS, GCP, Azure
- npm token (จาก
.npmrc และ environment variables)
- ใช้เครื่องมือ Trufflehog สแกนทั้งโฮมไดเรกทอรีเพื่อค้นหา API key, รหัสผ่าน, ประวัติ Git และอื่นๆ
เครือข่ายการส่งข้อมูลออก
- ใช้ GitHub token ที่ขโมยมาเพื่อสร้าง public repository พร้อมคำอธิบาย “Sha1-Hulud: The Second Coming.”
- repository ดังกล่าวทำหน้าที่เป็น กล่องรับส่งข้อมูลที่ถูกขโมย
- มีการติดตั้ง GitHub Actions runner เพื่อคงความต่อเนื่องของการเข้าถึง
- หากสิทธิ์ไม่เพียงพอ จะค้นหา repository อื่นที่มีมาร์กเกอร์เดียวกันเพื่อ นำโทเค็นจากระบบอื่นกลับมาใช้ซ้ำ
- ทำให้เกิด เครือข่ายแชร์โทเค็นแบบกระจายศูนย์
การแพร่กระจายในซัพพลายเชน
- ใช้ npm token ที่ขโมยมาเพื่อทำให้ทุกแพ็กเกจของเหยื่อติดเชื้อ
- ดาวน์โหลดแพ็กเกจต้นฉบับ
- แทรก
setup_bun.js เป็น preinstall script
- เพิ่มเพย์โหลด
bun_environment.js
- เพิ่มหมายเลขเวอร์ชัน
- เผยแพร่แพ็กเกจที่ติดเชื้อกลับขึ้น npm
Dead man’s switch
- มัลแวร์จะมอนิเตอร์การเข้าถึง GitHub (สำหรับส่งข้อมูลออก) และ npm (สำหรับแพร่กระจาย) อย่างต่อเนื่อง
- หากทั้งสองช่องทางถูกบล็อกพร้อมกัน จะ เริ่มทำลายข้อมูลทันที
- Windows: ลบไฟล์ผู้ใช้และเขียนทับเซกเตอร์ดิสก์
- Unix ตระกูลต่างๆ: ใช้คำสั่ง
shred เขียนทับไฟล์ก่อนลบ
- หากมีการลบ GitHub repository เป็นชุดหรือเพิกถอน npm token จำนวนมาก ก็มี ความเสี่ยงที่ระบบที่ติดเชื้อจะลบข้อมูลพร้อมกัน
ตัวบ่งชี้การถูกบุกรุก (IoC)
- ตัวชี้วัดสำคัญสำหรับการตรวจจับ
- ไฟล์:
bun_environment.js (สคริปต์ post-install อันตราย)
- ไดเรกทอรี:
.truffler-cache/, .truffler-cache/extract/
- โปรเซส:
del /F /Q /S "%USERPROFILE%*", shred -uvz -n 1, cipher /W:%USERPROFILE%
- คำสั่ง:
curl -fsSL https://bun.sh/install | bash, powershell -c "irm bun.sh/install.ps1|iex"
การตรวจจับและการสนับสนุนการตอบสนองจาก GitLab
- ผู้ใช้ GitLab Ultimate สามารถตรวจสอบการเปิดรับความเสี่ยงได้ทันทีผ่านฟีเจอร์ความปลอดภัยในตัว
- เมื่อเปิดใช้ Dependency Scanning ระบบจะตรวจจับแพ็กเกจที่ติดเชื้อใน
package-lock.json หรือ yarn.lock โดยอัตโนมัติ
- หาก merge request มีแพ็กเกจที่ติดเชื้อรวมอยู่ ระบบจะแสดง คำเตือน
- สามารถเชื่อมกับ GitLab Duo Chat เพื่อให้ตรวจจับแบบถามตอบได้อย่างรวดเร็ว
- ตัวอย่าง: “มี dependency ที่ได้รับผลกระทบจากแคมเปญ Shai-Hulud v2 หรือไม่?”
- Security Analyst Agent จะดึงข้อมูลช่องโหว่ของโปรเจกต์มาตรวจสอบและตอบได้ทันที
- สำหรับทีมที่ดูแลหลาย repository แนะนำให้ใช้ทั้ง การตรวจจับอัตโนมัติบนพื้นฐาน CI/CD และ การตอบสนองอย่างรวดเร็วแบบ agent-based ควบคู่กัน
แนวโน้มในระยะต่อไป
- การโจมตีครั้งนี้ถูกมองว่าเป็น รูปแบบใหม่ของการโจมตีซัพพลายเชนที่ใช้การทำลายข้อมูลของเหยื่อเพื่อปกป้องโครงสร้างพื้นฐานของผู้โจมตี
- GitLab กำลังร่วมมือกับชุมชนเพื่อพัฒนา กลยุทธ์การกู้คืนที่ปลอดภัย และติดตามสายพันธุ์ใหม่อย่างต่อเนื่องด้วยระบบตรวจจับอัตโนมัติ
- เป้าหมายคือป้องกัน ความเสียหายระลอกสองจาก dead man’s switch ผ่านการแชร์ข้อมูลตั้งแต่ระยะเริ่มต้น
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เมื่อประมาณเดือนที่แล้ว ผมต้องทำงานจุกจิกงานหนึ่งเลยไปหาแพ็กเกจ NPM
พอรัน
brew install npmก็เจอ น้ำตกของ dependency ถาโถมเข้ามา เลยหยุดคิดเรื่องความเสี่ยงกับประโยชน์อยู่พักหนึ่ง ก่อนจะย้อนกลับด้วยbrew uninstall npmในที่สุดสุดท้ายแก้ปัญหาด้วย Unix utility pipeline แบบเก่าและ awk ซึ่งพอมาคิดดูตอนนี้ นั่นเป็นการตัดสินใจที่ดีที่สุดแล้ว
NPM เป็นเครื่องมือที่สร้างมาเพื่อแก้ปัญหาเรื่องความเข้ากันได้ของเบราว์เซอร์ จึงสร้างความซับซ้อนที่ไม่จำเป็นในสภาพแวดล้อมที่ไม่มีเบราว์เซอร์
ถ้ารันโค้ดจาก ecosystem ที่มี dependency หนาแน่นอย่าง Node หรือ Python บนระบบหลักโดยตรง ก็มีความเสี่ยงจะโดนโจมตีผ่าน supply chain สูง
เพราะงั้นผมเลยไม่ติดตั้ง Python หรือ JS interpreter ลงบนระบบหลักไปเลย
สุดท้ายเลยเลิกทำไป แต่ตอนนี้ดูเหมือนว่านั่นแหละที่ถูกต้อง
มีคนพูดว่า “ถ้า GitHub ลบ repository อันตรายจำนวนมากพร้อมกัน ระบบหลายพันเครื่องก็อาจทำลายข้อมูลผู้ใช้พร้อมกันได้”
มันเหมือนสถานการณ์จับตัวประกัน — เลยมีมุกว่า “ยิงตัวประกันซะ”
ผมก็เป็น เหยื่อของการโจมตี npm ครั้งนี้เหมือนกัน
ผมช็อกมากที่รู้ว่า GitHub CLI เก็บ OAuth token แบบ plain text ไว้ในไดเรกทอรี HOME
ถ้าผู้โจมตีเข้าถึงได้ ก็แทบจะทำทุกอย่างในบัญชีผมได้เลย
บน macOS จะเก็บอย่างปลอดภัยใน keychain ของระบบ — การสนทนาที่เกี่ยวข้อง
Chrome ใช้กลไกป้องกันของ OS แต่ Firefox ยังไม่ใช่
สุดท้ายแล้ว การควบคุมการเข้าถึงแบบ sandbox-based ต่างหากที่เป็นทางแก้พื้นฐาน
แต่ยังไม่มีโซลูชันที่สม่ำเสมอข้ามแพลตฟอร์ม และแม้แต่บน MacOS เองก็ยังไม่มีวิธีที่สมบูรณ์แบบ
มีไดเรกทอรี
~/.dev-envโผล่ขึ้นมา แล้วโน้ตบุ๊กของผมก็กลายเป็น GitHub runnerอาจเป็นไปได้ว่าระบบไฟล์ read-only ของ Bluefin Linux ช่วยลดความเสียหายลง
ทุกคนโทษแต่ npm แต่ GitHub ก็มีความรับผิดชอบ มากเหมือนกัน
มันตรวจจับ repository อันตรายได้ไม่เร็วพอ และปัญหา repository มัลแวร์ ก็ร้ายแรงอยู่แล้ว
ถ้าถูกส่งออกไปยังเซิร์ฟเวอร์ภายนอกแบบเงียบ ๆ มันคงแย่กว่านี้มาก
เราต้องมี เครื่องมือและแนวปฏิบัติในระดับชุมชน
ถ้ามีข้อกำกับเชิงพาณิชย์หรือข้อจำกัดต่อ build workflow ก็อาจลุกลามเป็นปัญหาใหญ่ได้
ผมสงสัยว่าทำไม NPM ถึงเป็นเป้าโจมตีอยู่เรื่อย ๆ
Python กับ Java ก็ได้รับความนิยมมาก แต่ช่วงหลังกลับเงียบ
วัฒนธรรม dependency แบบช่วงเวอร์ชัน ก็ทำให้การติดเชื้อแพร่กระจายได้เร็ว
ส่วน Java มักล็อกเป็นเวอร์ชันเฉพาะ จึงเกิดเรื่องแบบนี้ไม่บ่อย
เลยทำให้แพ็กเกจหนึ่งตัวดึง sub-dependency ตามมาเป็นสิบ ๆ ตัว
และมีนักพัฒนามือใหม่จำนวนมาก ทำให้ความปลอดภัยอ่อนแอกว่า
ecosystem ภาษาอื่นมักทดสอบก่อนอัปเดต แต่ JS มักอัปเกรดทันที
เพราะเปิดให้รันสคริปต์ได้อย่างอิสระตอนติดตั้ง ซึ่ง JVM หรือ Python ไม่เป็นแบบนั้น
ถ้าเพิ่มสิ่งนี้ลงใน
.npmrcก็อาจลดช่องทางการโจมตีได้
บทความที่เกี่ยวข้อง
และถ้าปิดใช้งานแล้วจะมีความเสี่ยงที่ dependency พัง หรือไม่ก็ยังน่าสงสัย
สิ่งที่น่ากังวลที่สุดในการโจมตีครั้งนี้คือ การขโมยข้อมูลยืนยันตัวตน
ถ้าคุณติดตั้งแพ็กเกจที่ติดเชื้อ environment variable หรือโทเค็นใน
.npmrcอาจรั่วไหลไปแล้วต้อง หมุนโทเค็นและ API key ใหม่ ทันที
การหมุนเป็นระยะไม่ใช่มาตรการตอบสนองหลังถูกเจาะ แต่เป็น มาตรการป้องกันล่วงหน้า
ไม่ควรเก็บข้อมูลยืนยันตัวตนไว้ใน environment variable หรือไฟล์ ควรใช้ security key หรือไฟล์เข้ารหัส
คล้ายกับการฝัง ธุรกรรมอันตรายใน distributed ledger
ปัญหาคือหลายบริการยังคงตั้งค่าเริ่มต้นให้เก็บแบบ plain text อยู่
การโจมตีแบบนี้เกิดซ้ำแล้วซ้ำอีก เลยสงสัยว่าทำไม ระบบตรวจจับที่ใช้ AI ถึงยังไม่ทำงาน
Microsoft พูดถึง AI มากขนาดนั้น แต่ดูเหมือนจะไม่ได้นำมาใช้กับความปลอดภัยของ GitHub จริง ๆ
เหมือนสมัยที่ทุกความพยายามที่ไฟร์วอลล์บล็อกได้ถูกนับว่าเป็นการโจมตี จนความหมายเริ่มจางลง
โดยภายในมี SonaType IQ Server รองรับอยู่
จริง ๆ แล้วโปรเจกต์ curl ก็เคยโดน สแปมรายงานช่องโหว่ความปลอดภัยที่สร้างโดย AI มาแล้ว
ผมสงสัยว่าทำไมเรายังต้องยอมให้มี postinstall script ต่อไป
น่าจะดีกว่าไหมถ้าถามผู้ใช้ก่อนว่าจะยอมให้รันหรือไม่
บนเซิร์ฟเวอร์ CI ก็ต้องมี การติดตั้งแบบไม่โต้ตอบ จึงมองว่าในทางปฏิบัติทำได้ยาก
บทความนี้มีมุมมองที่เฉียบคมมาก แต่ก็น่าเสียดายที่ตอนท้ายจบด้วย การโปรโมตฟีเจอร์ด้านความปลอดภัยของ GitLab