1 คะแนน โดย GN⁺ 2025-11-29 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ระบบนิเวศ 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 ที่ขโมยมาเพื่อทำให้ทุกแพ็กเกจของเหยื่อติดเชื้อ
    1. ดาวน์โหลดแพ็กเกจต้นฉบับ
    2. แทรก setup_bun.js เป็น preinstall script
    3. เพิ่มเพย์โหลด bun_environment.js
    4. เพิ่มหมายเลขเวอร์ชัน
    5. เผยแพร่แพ็กเกจที่ติดเชื้อกลับขึ้น 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 ความคิดเห็น

 
GN⁺ 2025-11-29
ความคิดเห็นจาก Hacker News
  • เมื่อประมาณเดือนที่แล้ว ผมต้องทำงานจุกจิกงานหนึ่งเลยไปหาแพ็กเกจ NPM
    พอรัน brew install npm ก็เจอ น้ำตกของ dependency ถาโถมเข้ามา เลยหยุดคิดเรื่องความเสี่ยงกับประโยชน์อยู่พักหนึ่ง ก่อนจะย้อนกลับด้วย brew uninstall npm ในที่สุด
    สุดท้ายแก้ปัญหาด้วย Unix utility pipeline แบบเก่าและ awk ซึ่งพอมาคิดดูตอนนี้ นั่นเป็นการตัดสินใจที่ดีที่สุดแล้ว

    • บทเรียนชัดเจนมาก — ไม่ควรใช้เทคโนโลยีเว็บกับ local scripting
      NPM เป็นเครื่องมือที่สร้างมาเพื่อแก้ปัญหาเรื่องความเข้ากันได้ของเบราว์เซอร์ จึงสร้างความซับซ้อนที่ไม่จำเป็นในสภาพแวดล้อมที่ไม่มีเบราว์เซอร์
    • นี่จึงเป็นเหตุผลว่าทำไมถึงต้องมี containerization หรือ virtualization
      ถ้ารันโค้ดจาก ecosystem ที่มี dependency หนาแน่นอย่าง Node หรือ Python บนระบบหลักโดยตรง ก็มีความเสี่ยงจะโดนโจมตีผ่าน supply chain สูง
      เพราะงั้นผมเลยไม่ติดตั้ง Python หรือ JS interpreter ลงบนระบบหลักไปเลย
    • เมื่อก่อนผมก็รัน npm เฉพาะใน Docker container เหมือนกัน แต่ก็มักโดนล้อในฟอรัม
      สุดท้ายเลยเลิกทำไป แต่ตอนนี้ดูเหมือนว่านั่นแหละที่ถูกต้อง
    • ผมก็มีประสบการณ์คล้ายกัน พอเห็นจำนวน dependency ที่ artillery จะดึงมาก็เลิกทันที
    • ที่น่าประหลาดคือ นักพัฒนามักพูดเสมอว่า “สามัญสำนึกคือความปลอดภัยที่ดีที่สุด” แต่กลับติดตั้งแพ็กเกจที่ไม่ผ่านการตรวจสอบจำนวนมากด้วยคำสั่งบรรทัดเดียว
  • มีคนพูดว่า “ถ้า GitHub ลบ repository อันตรายจำนวนมากพร้อมกัน ระบบหลายพันเครื่องก็อาจทำลายข้อมูลผู้ใช้พร้อมกันได้”
    มันเหมือนสถานการณ์จับตัวประกัน — เลยมีมุกว่า “ยิงตัวประกันซะ”

    • แต่ตัวประกัน (ผู้ใช้) ก็เป็นฝ่ายเดินเข้าไปอยู่ในความเสี่ยงเอง ดังนั้นสุดท้ายก็เป็นผลจากการเลือกของตัวเอง
  • ผมก็เป็น เหยื่อของการโจมตี npm ครั้งนี้เหมือนกัน
    ผมช็อกมากที่รู้ว่า GitHub CLI เก็บ OAuth token แบบ plain text ไว้ในไดเรกทอรี HOME
    ถ้าผู้โจมตีเข้าถึงได้ ก็แทบจะทำทุกอย่างในบัญชีผมได้เลย

    • ที่จริง GitHub CLI จะเก็บโทเค็นเป็น plain text เฉพาะตอนที่ไม่มี keyring เท่านั้น
      บน macOS จะเก็บอย่างปลอดภัยใน keychain ของระบบ — การสนทนาที่เกี่ยวข้อง
    • ใช่ แต่ไฟล์คุกกี้ของเบราว์เซอร์ก็มีปัญหาคล้ายกัน
      Chrome ใช้กลไกป้องกันของ OS แต่ Firefox ยังไม่ใช่
      สุดท้ายแล้ว การควบคุมการเข้าถึงแบบ sandbox-based ต่างหากที่เป็นทางแก้พื้นฐาน
    • โทเค็นทั้งหมดควรอยู่ใน keychain ที่ได้รับการปกป้อง
      แต่ยังไม่มีโซลูชันที่สม่ำเสมอข้ามแพลตฟอร์ม และแม้แต่บน MacOS เองก็ยังไม่มีวิธีที่สมบูรณ์แบบ
    • ผมก็เป็นเหยื่อเหมือนกัน ติดหลังจากติดตั้ง Backstage
      มีไดเรกทอรี ~/.dev-env โผล่ขึ้นมา แล้วโน้ตบุ๊กของผมก็กลายเป็น GitHub runner
      อาจเป็นไปได้ว่าระบบไฟล์ read-only ของ Bluefin Linux ช่วยลดความเสียหายลง
  • ทุกคนโทษแต่ npm แต่ GitHub ก็มีความรับผิดชอบ มากเหมือนกัน
    มันตรวจจับ repository อันตรายได้ไม่เร็วพอ และปัญหา repository มัลแวร์ ก็ร้ายแรงอยู่แล้ว

    • ถึงอย่างนั้น การที่มันถูกอัปโหลดขึ้น GitHub ก็ทำให้บางคนรู้ตัวได้เร็ว
      ถ้าถูกส่งออกไปยังเซิร์ฟเวอร์ภายนอกแบบเงียบ ๆ มันคงแย่กว่านี้มาก
    • Microsoft จะมากรองทุกอย่างให้หมดไม่ได้
      เราต้องมี เครื่องมือและแนวปฏิบัติในระดับชุมชน
    • เนื่องจาก GitHub เป็นของ Microsoft มันเลยพัวพันกับ repository แพ็กเกจ GoLang ด้วย
      ถ้ามีข้อกำกับเชิงพาณิชย์หรือข้อจำกัดต่อ build workflow ก็อาจลุกลามเป็นปัญหาใหญ่ได้
    • ปฏิเสธไม่ได้ว่าทั้งสองบริษัทมี ระดับความปลอดภัยธรรมดา ๆ
    • มัลแวร์นี้สร้าง repository ด้วยแพตเทิร์นเดียวกัน ดังนั้นแม้แต่กฎง่าย ๆ ก็น่าจะตรวจจับได้
  • ผมสงสัยว่าทำไม NPM ถึงเป็นเป้าโจมตีอยู่เรื่อย ๆ
    Python กับ Java ก็ได้รับความนิยมมาก แต่ช่วงหลังกลับเงียบ

    • NPM สามารถรันคำสั่งใดก็ได้ผ่าน post-install hook และ
      วัฒนธรรม dependency แบบช่วงเวอร์ชัน ก็ทำให้การติดเชื้อแพร่กระจายได้เร็ว
      ส่วน Java มักล็อกเป็นเวอร์ชันเฉพาะ จึงเกิดเรื่องแบบนี้ไม่บ่อย
    • Node มี standard library ขนาดเล็กและพึ่งพาชุมชนสูง
      เลยทำให้แพ็กเกจหนึ่งตัวดึง sub-dependency ตามมาเป็นสิบ ๆ ตัว
    • JS เป็นภาษาที่นิยมที่สุดบน GitHub จึงมี พื้นผิวการโจมตีที่กว้าง
      และมีนักพัฒนามือใหม่จำนวนมาก ทำให้ความปลอดภัยอ่อนแอกว่า
    • ชุมชน JS มีอาการ “ยึดติดกับเวอร์ชันล่าสุด” ค่อนข้างหนัก
      ecosystem ภาษาอื่นมักทดสอบก่อนอัปเดต แต่ JS มักอัปเกรดทันที
    • NPM มี ขอบเขตความปลอดภัยที่อ่อนแอ
      เพราะเปิดให้รันสคริปต์ได้อย่างอิสระตอนติดตั้ง ซึ่ง JVM หรือ Python ไม่เป็นแบบนั้น
  • ถ้าเพิ่มสิ่งนี้ลงใน .npmrc

    ignore-scripts=true
    

    ก็อาจลดช่องทางการโจมตีได้
    บทความที่เกี่ยวข้อง

    • ผมสงสัยว่ามีวิธีตรวจสอบล่วงหน้าก่อนติดตั้งไหมว่าแพ็กเกจไหนมี preinstall/postinstall hook
    • ถ้า “ignore scripts” ปลอดภัยกว่า แล้วทำไมมันถึงเป็นแค่ออปชัน
      และถ้าปิดใช้งานแล้วจะมีความเสี่ยงที่ dependency พัง หรือไม่ก็ยังน่าสงสัย
    • แต่สุดท้าย ถ้ารัน JS ในสภาพแวดล้อม Node ก็ ยังกันการเข้าถึง environment variable หรือไฟล์ไม่ได้ อยู่ดี
    • หรือจะใช้ pnpm ไปเลยก็ได้เหมือนกัน
  • สิ่งที่น่ากังวลที่สุดในการโจมตีครั้งนี้คือ การขโมยข้อมูลยืนยันตัวตน
    ถ้าคุณติดตั้งแพ็กเกจที่ติดเชื้อ environment variable หรือโทเค็นใน .npmrc อาจรั่วไหลไปแล้ว
    ต้อง หมุนโทเค็นและ API key ใหม่ ทันที
    การหมุนเป็นระยะไม่ใช่มาตรการตอบสนองหลังถูกเจาะ แต่เป็น มาตรการป้องกันล่วงหน้า

    • ถ้านักพัฒนา ใช้รหัสผ่านซ้ำ นี่ถือว่าเป็นปัญหาร้ายแรงมาก
      ไม่ควรเก็บข้อมูลยืนยันตัวตนไว้ใน environment variable หรือไฟล์ ควรใช้ security key หรือไฟล์เข้ารหัส
    • ถ้ายังไม่รู้ว่าติดเชื้อหรือไม่ ควรทำตามลำดับ ตรวจหาการติดเชื้อ → ทำความสะอาด → หมุนโทเค็น ก่อน
    • การโจมตีครั้งนี้ไม่ใช่แค่การติดเชื้อธรรมดา แต่เป็นการ จับทั้ง ecosystem เป็นตัวประกัน จึงอันตรายกว่า
      คล้ายกับการฝัง ธุรกรรมอันตรายใน distributed ledger
    • ความลับต้องเก็บไว้ใน secret locker เท่านั้น
      ปัญหาคือหลายบริการยังคงตั้งค่าเริ่มต้นให้เก็บแบบ plain text อยู่
    • และมัลแวร์ตัวนี้ยังพยายาม ทำลายข้อมูลเมื่อหยุดแพร่กระจาย อีกด้วย
  • การโจมตีแบบนี้เกิดซ้ำแล้วซ้ำอีก เลยสงสัยว่าทำไม ระบบตรวจจับที่ใช้ AI ถึงยังไม่ทำงาน
    Microsoft พูดถึง AI มากขนาดนั้น แต่ดูเหมือนจะไม่ได้นำมาใช้กับความปลอดภัยของ GitHub จริง ๆ

    • แต่คำว่า “AI ตรวจจับการโจมตีได้” ก็กลายเป็น วลีการตลาดด้านความปลอดภัยที่เชยแล้ว ไปมาก
      เหมือนสมัยที่ทุกความพยายามที่ไฟร์วอลล์บล็อกได้ถูกนับว่าเป็นการโจมตี จนความหมายเริ่มจางลง
    • บริษัทเราใช้ SonaType Lifecycle ซึ่งบอกว่าสามารถป้องกันการโจมตีแบบนี้ด้วย AI
      โดยภายในมี SonaType IQ Server รองรับอยู่
    • “AI” ในปัจจุบันเป็น โมเดลเชิงกำเนิด ที่เน้นการสร้างมากกว่าการประเมิน
      จริง ๆ แล้วโปรเจกต์ curl ก็เคยโดน สแปมรายงานช่องโหว่ความปลอดภัยที่สร้างโดย AI มาแล้ว
  • ผมสงสัยว่าทำไมเรายังต้องยอมให้มี postinstall script ต่อไป
    น่าจะดีกว่าไหมถ้าถามผู้ใช้ก่อนว่าจะยอมให้รันหรือไม่

    • แต่ผู้ใช้ส่วนใหญ่ก็คงกด “ใช่” อยู่ดี และ
      บนเซิร์ฟเวอร์ CI ก็ต้องมี การติดตั้งแบบไม่โต้ตอบ จึงมองว่าในทางปฏิบัติทำได้ยาก
  • บทความนี้มีมุมมองที่เฉียบคมมาก แต่ก็น่าเสียดายที่ตอนท้ายจบด้วย การโปรโมตฟีเจอร์ด้านความปลอดภัยของ GitLab

    • ถ้าเป็นผู้ใช้ GitLab ก็อาจมีประโยชน์
    • ถึงอย่างนั้น มันก็ ไม่ได้ลดทอนคุณค่าของข้อสังเกตในบทความ เอง