แพ็กเกจ npm ของ Red Hat Cloud Services ถูกโจมตีด้วยการวางมลพิษในห่วงโซ่อุปทาน

iconMetaEra
แชร์
Share IconShare IconShare IconShare IconShare IconShare IconCopy
AI summary iconสรุป

expand icon
มีการรายงานการรั่วไหลด้านความปลอดภัยในแพ็กเกจ npm หลายตัวภายใต้องค์กร Red Hat Cloud Services ตามข่าวบนโซ่จาก MetaEra ระบบของ MistEye พบเวอร์ชันที่เป็นอันตราย 96 เวอร์ชันใน 32 แพ็กเกจ โดยวิเคราะห์รายละเอียดอย่างลึกซึ้งในสามแพ็กเกจ โค้ดที่เป็นอันตรายในแพ็กเกจเช่น @redhat-cloud-services/frontend-components-config@6.11.3 จะทำงานระหว่างการติดตั้งผ่าน preinstall hook มัลแวร์ซึ่งเป็นรุ่นหนึ่งของ Shai-Hulud รวมถึงการขโมยข้อมูลประจำตัวและการใช้ประโยชน์จาก CI/CD ผู้โจมตีใช้การเลื่อน ROT/Caesar, AES-GCM และการเข้ารหัส B5 เพื่อซ่อนayload ซึ่งแพร่กระจายผ่าน npm และ workflow ของ GitHub

บริบท

เมื่อไม่นานมานี้ ระบบตรวจสอบความปลอดภัย MistEye ได้รับข้อมูลเกี่ยวกับการปรากฏตัวของเวอร์ชันผิดปกติในแพ็กเกจ npm หลายตัวภายใต้กลุ่ม Red Hat Cloud Services ครั้งนี้เกี่ยวข้องกับแพ็กเกจ npm 32 ตัวและเวอร์ชัน 96 เวอร์ชัน จากกลุ่มนี้ เราเลือกตัวอย่างท้องถิ่น 3 ตัวเพื่อวิเคราะห์แบบออฟไลน์อย่างละเอียด: ตัวอย่างเหล่านี้ไม่ใช่แพ็กเกจที่เลียนแบบชื่อหรือ typosquatting แต่เป็นเวอร์ชันที่แท้จริงภายใต้ scope @redhat-cloud-services; จากโค้ดต้นฉบับของตัวอย่างสามารถยืนยันได้ว่า tarball ของมันมีการฝัง loader ที่ถูกเข้ารหัสหลายชั้นซึ่งจะถูกกระตุ้นอัตโนมัติในขั้นตอนการติดตั้ง

หลังจากกู้คืนอย่างสมบูรณ์แล้ว สามารถยืนยันได้ว่าโหลดหลักของตัวอย่างทั้ง 3 ตัวมีความสามารถในการอ่านหน่วยความจำของ GitHub Actions Runner, การรวบรวมข้อมูลรับรองจากหลายคลาวด์และท้องถิ่น, การส่งข้อมูลผ่าน GitHub API และ dead-drop, การแทรกซึมใน GitHub workflow, การแพร่กระจายตัวเองผ่าน npm, การคงอยู่ถาวรผ่าน Claude Code / VS Code / systemd / LaunchAgent, การต่อต้าน Harden-Runner / StepSecurity, และการตรวจจับ EDR / ผลิตภัณฑ์ด้านความปลอดภัย จากขอบเขตของความสามารถ ผู้ที่อาจได้รับผลกระทบรวมถึงเครื่องของนักพัฒนา, CI/CD Runner, คอนเทนเนอร์การสร้าง, รีพอสิทอรี GitHub, GitHub Actions workflow, เส้นทางการเผยแพร่ npm และข้อมูลรับรองของสภาพแวดล้อมคลาวด์; ขอบเขตผลกระทบจริงจำเป็นต้องยืนยันเพิ่มเติมโดยใช้บันทึกการติดตั้ง, การตรวจสอบรีพอสิทอรี และข้อมูลการวัดจากระบบ

จากโครงสร้างโค้ด เส้นทางการแพร่กระจาย และการรวมกันของความสามารถ โปรแกรมโทรจันนี้จัดอยู่ในประเภทที่แปรเปลี่ยนมาจาก Shai-Hulud

MistEye ตอบกลับ

MistEye เป็นระบบข้อมูลภัยคุกคามและระบบติดตามความปลอดภัยแบบไดนามิกสำหรับ Web3 ที่ SlowMist พัฒนาขึ้นเอง โดยรวมความสามารถในการติดตามความปลอดภัยและการรวบรวมข้อมูลภัยคุกคาม เพื่อให้ผู้ใช้ได้รับการแจ้งเตือนความเสี่ยงแบบเรียลไทม์และการปกป้องสินทรัพย์

หลังจากจับกุมเหตุการณ์การปลอมแปลงซัพพลายเชนของแพ็กเกจ npm ของ Red Hat Cloud Services และตัวอย่างที่เป็นอันตรายที่เกี่ยวข้อง ระบบ MistEye ได้กระตุ้นการแจ้งเตือนระดับสูง และทำการวิเคราะห์ระบบเกี่ยวกับโครงสร้างที่ถูกเข้ารหัส กระบวนการถอดรหัสโหลด ความสามารถในการกู้คืน และ IOC

(https://enterprise.misteye.io/threat-intelligence/SM-2026-378450)

ภาพรวมของโซ่การโจมตี

ส่วนการวิเคราะห์ทางเทคนิคของบทความนี้อิงจากการวิเคราะห์แบบออฟไลน์และแบบคงที่เท่านั้น โดยทำการแกะแพ็ก ถอดรหัส และยืนยันการถอดรหัสความสับสนของตัวอย่าง npm tgz 3 ตัว

ตัวอย่างที่ได้รับการตรวจสอบในครั้งนี้มีดังนี้:

@redhat-cloud-services/frontend-components-config

เวอร์ชัน: 6.11.3

tgz SHA-256: 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060

@redhat-cloud-services/types

เวอร์ชัน: 3.6.1

tgz SHA-256: d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

@redhat-cloud-services/rule-components

เวอร์ชัน: 4.7.2

tgz SHA-256: aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f

จุดเข้าสู่การโจมตีของตัวอย่างทั้งสามนั้นเหมือนกันทั้งหมด: ในไฟล์ package.json มี scripts.preinstall = "node index.js" ทั้งหมด ซึ่งหมายความว่า เมื่อโฮสต์ของนักพัฒนาหรือสภาพแวดล้อม CI/CD ติดตั้งเวอร์ชันเหล่านี้ ไฟล์ index.js ที่รูทจะถูกดำเนินการอัตโนมัติในขั้นตอนการติดตั้ง โดยไม่จำเป็นต้องมีการนำเข้าหรือเรียกใช้โค้ดธุรกิจอย่างชัดเจนจากผู้ใช้

ตัวอย่างสามตัวมีรหัสความเสี่ยงหลักเดียวกัน แต่มีพารามิเตอร์ห่อภายนอกต่างกัน กล่าวคือ ตัวอย่างทั้งสามใช้ค่าการเลื่อน ROT/Caesar และคีย์/IV/แท็ก AES-GCM ที่แตกต่างกัน ซึ่งทำให้คุณลักษณะคงที่ที่อิงจาก hash ของห่อภายนอก คีย์คงที่ หรือค่าการเลื่อนคงที่ยากต่อการนำกลับมาใช้ใหม่ข้ามตัวอย่าง อย่างไรก็ตาม ตัวนำร่องสภาพแวดล้อมการรัน Bun และ hash ของรหัสความเสี่ยงหลักหลังถอดรหัสเหมือนกันทั้งหมด: หนึ่งคือโมดูลช่วยเริ่มต้นสำหรับเตรียมสภาพแวดล้อมการรัน Bun อีกอันคือรหัสความเสี่ยงหลักที่มีฟังก์ชันอันตรายจริง บทความนี้เรียกทั้งสองส่วนว่า "ตัวนำร่องสภาพแวดล้อมการรัน Bun (ชื่อตัวแปรในโค้ด _b)" และ "รหัสความเสี่ยงหลัก (ชื่อตัวแปรในโค้ด _p)"

สายการโจมตีที่กู้คืนได้คือ:

Technical Analysis

1. ช่องทางเข้า: การโจมตีด้วยการแย่งชิงสคริปต์ของ npm lifecycle

ตัวอย่างทั้งสามถูกกระตุ้นผ่านฮุกชีวิต cycle preinstall ใน package.json:

"scripts": {

"preinstall": "node index.js"

}

preinstall จะถูกดำเนินการอัตโนมัติในขั้นตอนการติดตั้งของ npm สำหรับคอมโพเนนต์เว็บฟรอนต์ทั่วไป คำจำกัดความประเภท หรือแพ็กเกจส่วนประกอบกฎ ไม่จำเป็นต้องรันไฟล์ JavaScript ขนาดใหญ่ที่รูทในขั้นตอนการติดตั้ง นี่คือสัญญาณผิดปกติที่ชัดเจนที่สุด

หลักฐานระดับตัวอย่างมีดังนี้:

@redhat-cloud-services/frontend-components-config@6.11.3

  • main: lib/index.js
  • ฟิลด์ files: ["/lib", "/bin"]
  • รูทไดเรกทอรี index.js SHA-256: 545a1838c66e1771f58d84a17b3e1841e5eeab91a73f4ccc59c9492450a6d9c0

@redhat-cloud-services/types@3.6.1

  • main: index.d.ts
  • ฟิลด์ files: ยังไม่ได้ตั้งค่า
  • รูทไดเรกทอรี index.js SHA-256: b86c5ae9e95bd841a595440faa3eb6317441e746f241ae8fd641ab59ed1d1966

@redhat-cloud-services/rule-components@4.7.2

  • main: index.js
  • ฟิลด์ files: ยังไม่ได้ตั้งค่า
  • รูทไดเรกทอรี index.js SHA-256: 1a30a9abe20bab121aaa75ed040565af14e6cdfb745609ee0e7b94a2d814fb9c

ในกรณีนี้ ฟิลด์ files ของ frontend-components-config@6.11.3 ประกาศเฉพาะ "/lib" และ "/bin" แต่ในรูทของ tarball มีไฟล์ index.js เพิ่มเติมที่ถูกเรียกใช้โดย preinstall ข้อผิดพลาดนี้ใช้ได้เฉพาะกับตัวอย่างนี้เท่านั้น; types@3.6.1 และ rule-components@4.7.2 ไม่ได้ตั้งค่าฟิลด์ files จึงไม่ควรสรุปข้อผิดพลาดนี้ให้ครอบคลุมตัวอย่างทั้งหมด

2. ชั้นที่หนึ่ง: อาเรย์ตัวเลข + การแทนที่ตัวอักษร ROT/Caesar

ไฟล์ index.js ที่รูทของตัวอย่างทั้งสามเป็นไฟล์ JavaScript บรรทัดเดียวขนาดใหญ่มาก มีโครงสร้างเหมือนกัน โดยมีตัวกรอบหลักเป็น try { eval(...) } catch (...)

ตัวแพ็กเกจแรกจะแปลงอาร์เรย์ตัวเลขขนาดใหญ่กลับเป็นสตริงผ่าน String.fromCharCode แล้วจึงเลื่อนตัวอักษรภาษาอังกฤษในสตริงด้วยการเลื่อน ROT/Caesar สุดท้ายจะส่งผลลัพธ์ที่ถอดรหัสให้ eval ดำเนินการ การจัดการข้อผิดพลาดจะแสดงเฉพาะคำว่า wrapper: เท่านั้น เพื่อลดการเปิดเผยข้อผิดพลาดที่ชัดเจนเมื่อการติดตั้งล้มเหลว

ค่าการเลื่อนชั้นนอกและ Stage 2 hash ของตัวอย่างสามตัวคือ:

frontend-components-config@6.11.3

ขนาดของ index.js: 4,294,798 ไบต์

ROT/Caesar shift: 10

ขั้นตอนที่ 2 SHA-256: b19c2fd48535c8c40aeb3e627ce92775f33ef9292611767bb1236c238e6f90cc

types@3.6.1

ขนาดของ index.js: 4,135,588 ไบต์

ROT/Caesar shift: 4

ขั้นตอนที่ 2 SHA-256: 9c0425aa6e6d7792ac38d24f3e7245f42fcaa553ddfeb6bd97677017f10c3b75

rule-components@4.7.2

ขนาดของ index.js: 4,294,336 ไบต์

ROT/Caesar shift: 11

ขั้นตอนที่ 2 SHA-256: d590bd375d95e4ac072b7ebc1fc4489bcaf5f20a939e92486267aa398bcf1e5d

3. ชั้นที่สอง: ถอดรหัส AES-128-GCM สำหรับ Bun bootloader และโหลดหลัก

รหัส Stage 2 ที่ถอดรหัสจาก ROT/Caesar ใช้ Node.js crypto.createDecipheriv เพื่อดีคริปต์ด้วย AES-128-GCM (Advanced Encryption Standard - Galois/Counter Mode) และตั้งแท็กการรับรองผ่าน setAuthTag เป้าหมายของการถอดรหัสคือสองส่วนประกอบถัดไป—ตัวเริ่มต้นสภาพแวดล้อม Bun และโหลดอันตรายหลัก

ในนั้น ตัวนำร่องสภาพแวดล้อม Bun มีหน้าที่ตรวจจับ ระบุ หรือเตรียมสภาพแวดล้อม Bun เพื่อให้รหัสถัดไปสามารถดำเนินการผ่าน Bun ได้; ส่วนโหลดที่เป็นอันตรายหลักคือส่วนหลักของโซ่การโจมตี ซึ่งรวมถึงความสามารถในการโจมตีหลักๆ เช่น การรวบรวมข้อมูลประจำตัว การแพร่กระจายผ่าน GitHub/npm การคงอยู่อย่างต่อเนื่อง การต่อต้านการป้องกัน และการถอดรหัสทรัพยากรที่ฝังอยู่

ตัวอย่างทั้งสามใช้คีย์ AES-128-GCM ตัวแปรเริ่มต้น และแท็กการรับรองที่แตกต่างกันในการเข้ารหัสส่วนประกอบทั้งสอง แต่ค่า SHA-256 ของตัวนำร่องสภาพแวดล้อม Bun หลังถอดรหัสทั้งสามตัวคือ ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6 และค่า SHA-256 ของภาระงานอันตรายหลักทั้งสามตัวคือ 0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35 ซึ่งแสดงให้เห็นว่าผู้โจมตีได้เปลี่ยนพารามิเตอร์การห่อชั้นนอกในแพ็กเกจ npm ที่แตกต่างกัน แต่ใช้ซ้ำชุดส่วนประกอบอันตรายหลักเดียวกัน

ถอดรหัสแล้ว Stage 2 จะเขียนโหลดที่เป็นอันตรายหลักไปยัง /tmp แล้วดำเนินการผ่าน Bun สุดท้ายจึงลบไฟล์ชั่วคราว ตรรกะที่แท้จริงที่ได้รับจากการกู้คืนตัวอย่างทั้งสามมีดังนี้:

ดังนั้น รูปแบบไฟล์ชั่วคราวที่สามารถตรวจสอบได้ในตัวอย่างทั้งสามคือ:

/tmp/p.js

ขนาดของตัวนำร่องสภาพแวดล้อม Bun คือ 898 ไบต์ แฮชของตัวอย่างทั้งสามตรงกันทั้งหมด:

ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6

ตัวนำร่องสภาพแวดล้อม Bun ประกอบด้วยตรรกะเช่น child_process.execSync, fs.existsSync, fs.mkdtempSync, fs.chmodSync, os.platform(), os.arch(), getBunPath() เพื่อระบุหรือเตรียมสภาพแวดล้อมการทำงานของ Bun กล่าวอีกนัยหนึ่ง ขั้นตอนที่ 2 ไม่ได้สมมติเพียงว่า Bun ติดตั้งแบบทั่วไปในระบบ; ในเส้นทางที่ไม่ใช่สภาพแวดล้อมการทำงานของ Bun มันจะโหลดตัวนำร่องสภาพแวดล้อม Bun ก่อน แล้วเรียก Bun ผ่าน getBunPath() เพื่อดำเนินการโหลดความเสี่ยงหลัก

4. ระดับที่สาม: ตารางสตริงของ obfuscator.io

ภาระงานที่ถอดรหัสได้ไม่ใช่ JavaScript แบบข้อความธรรมดาที่อ่านได้ทันที แต่ยังคงถูกทำให้สับสนด้วยรูปแบบของ obfuscator.io โดยใช้ตารางสตริง ซึ่งจะรวบรวมสตริงจำนวนมากไว้ในอาร์เรย์ และใช้การอ้างอิงแบบรันไทม์และตรรกะการหมุนเพื่อคืนค่ากลับ ทำให้นักวิเคราะห์ไม่สามารถค้นหา API, เส้นทาง และชื่อการตั้งค่าสำคัญถัดไปได้ หากยังไม่ได้คืนค่าตารางสตริงให้สมบูรณ์

5. ชั้นที่สี่: B5 การเข้ารหัสสตริงที่กำหนดเอง

หลังจากถอดรหัสตารางสตริงของ obfuscator.io แล้ว ยังคงมีการเข้ารหัสสตริงแบบกำหนดเองของ B5 อยู่ในโหลดที่เป็นอันตรายหลัก ได้ยืนยันพารามิเตอร์ดังต่อไปนี้:

  • KDF: PBKDF2 (Password-Based Key Derivation Function 2)
  • ฟังก์ชันแฮช: SHA-256
  • จำนวนการวนซ้ำ: 200000
  • ความยาวคีย์: 32 ไบต์
  • จำนวนรอบการถอดรหัส: 3
  • รหัสผ่าน: ba2c6ddb3672bdd6a611e6850b4f700b52aed3dab2f1b3d5f8c839d4a157a709
  • salt: 5b26508dc0f1075a7c0b4d8aa464487e

ผลหลังถอดรหัสคือ:

ในนั้น หลังจากถอดรหัส B5 จะสามารถมองเห็นสตริงข้อความชัดเจนหลายประเภท โปรดสังเกตว่า สตริงบางส่วนเดิมอยู่ในตารางสตริงของ obfuscator.io และจะสามารถค้นหาด้วย grep ได้โดยตรงเท่านั้น เมื่อเสร็จสิ้นขั้นตอนทั้งสองขั้นตอนคือ “การแทนที่ตารางสตริง + การถอดรหัส B5”

6. ชั้นฝังเพิ่มเติม: AES-256-GCM + gzip

โหลดอันตรายหลักยังรวมถึงทรัพยากรที่ฝังไว้ซึ่งถูกเข้ารหัสด้วย AES-256-GCM และบีบอัดด้วย gzip ตรรกะการกู้คืนใช้:

ทรัพยากรที่ถูกถอดรหัสแล้วจัดหมวดหมู่ตามฟังก์ชันเป็นสามประเภท:

การอ่านหน่วยความจำข้ามแพลตฟอร์ม:

ทรัพยากรประเภทนี้ใช้สำหรับอ่านหน่วยความจำของกระบวนการที่กำลังทำงานอยู่ คีย์หรือโทเค็นในไฟล์ทั่วไปยังสามารถค้นพบได้โดยการตรวจสอบไฟล์ แต่ CI/CD Runner หรือเครื่องมือพัฒนาจะเก็บค่าที่ละเอียดอ่อนบางอย่างไว้ชั่วคราวในหน่วยความจำขณะทำงาน ผู้โจมตีได้ฝังสคริปต์อ่านหน่วยความจำสำหรับแพลตฟอร์ม Linux, Windows และ macOS เพื่อพยายามดึง secret ที่ปรากฏชั่วคราวเหล่านี้จากหน่วยความจำของกระบวนการในระบบต่างๆ

การตั้งค่าแบบถาวร:

ทรัพยากรประเภทนี้ใช้เพื่อ “วางจุดกระตุ้นหลังประตู” กล่าวคือ แม้กระบวนการติดตั้ง npm เริ่มต้นจะเสร็จสิ้นแล้ว ผู้โจมตียังต้องการให้รหัสที่เป็นอันตรายทำงานอีกครั้งเมื่อผู้พัฒนาเปิดโครงการ khởi độngตัวแก้ไขรหัส เข้าสู่เซสชัน Claude Code หรือเมื่อระบบล็อกอินใหม่ ดังนั้นทรัพยากรเหล่านี้จึงมุ่งเป้าไปที่การตั้งค่าระดับโครงการและกลไกเริ่มต้นอัตโนมัติระดับผู้ใช้: การตั้งค่าระดับโครงการมีความซ่อนเร้นมากกว่า ขณะที่บริการระดับระบบเหมาะสำหรับการรันระยะยาว

C2 กับการแพร่กระจาย:

ทรัพยากรที่ฝังไว้เหล่านี้ใช้สำหรับการควบคุมเส้นทางถัดไปและการโอน secrets ของรีโพสิทอรี หลังจาก YZ ถอดรหัสแล้วจะเป็น GitHub commit search monitor ซึ่งจะค้นหาข้อความ commit ที่มีรูปแบบ firedalazer . เป็นระยะๆ ตรวจสอบลายเซ็นแล้วดาวน์โหลดและรันเนื้อหา Python จากระยะไกล ส่วน zZ หลังจากถอดรหัสแล้วจะเป็นเทมเพลต GitHub Actions workflow ชื่อ Run Copilot ซึ่งจะเขียน ${{ toJSON(secrets) }} ลงในไฟล์ format-results.txt และอัปโหลดเป็น artifact ตัวแรกให้บริการเส้นทางการรับ/รันงานถัดไป ส่วนตัวที่สองให้เทมเพลตในการโอน secrets ของรีโพสิทอรีผ่าน GitHub Actions artifact; การฉีด การรัน และการดาวน์โหลด artifact จะถูกดำเนินการโดยตรรกะ GitHub API ที่มาพร้อมกับโหลดหลัก

การวิเคราะห์ความสามารถของโหลดอันตรายหลัก

หลังจากดำเนินการถอดรหัสหลายชั้น ตัวอย่างสุดท้ายจะปล่อยและดำเนินการโหลดอันตรายหลัก การวิเคราะห์ทั้งหมดด้านล่างนี้เน้นที่โมดูลโหลดอันตรายหลัก โดยแยกออกเป็นห้าขั้นตอน: การรับข้อมูล การส่งออกข้อมูล การแพร่กระจาย การคงอยู่อย่างต่อเนื่อง และการต่อต้าน

การอ่านหน่วยความจำของ GitHub Actions Runner:

ตัวอย่างมีสคริปต์อ่านหน่วยความจำสำหรับแพลตฟอร์ม Linux, Windows และ macOS พร้อมความสามารถในการดัมพ์ข้ามแพลตฟอร์ม โดยการดำเนินการบน Linux ใช้การอ่าน /proc//maps และ /proc//mem ของกระบวนการเป้าหมายเพื่อดึงหน่วยความจำ:

ตรรกะการกระตุ้นอย่างแข็งขันของโหลดอันตรายหลักมุ่งเป้าไปที่ Linux runner ของ GitHub Actions: เมื่อ GITHUB_ACTIONS === "true" และ RUNNER_OS === "Linux" โค้ดจะค้นหากระบวนการ Runner.Worker และดัมพ์หน่วยความจำ จากนั้นดึง secrets ที่ถูกซ่อนในรูปแบบ "":{"value":"","isSecret":true} จากการดัมพ์ แม้ว่าเส้นทางการรวบรวมอย่างแข็งขันที่ยืนยันได้ในตัวอย่างทั้งสามจะมุ่งเน้นที่ Linux runner แต่สคริปต์สำหรับสามแพลตฟอร์มได้ถูกฝังไว้แล้ว

2. การรวบรวมข้อมูลรับรองของนักพัฒนาในสภาพแวดล้อมหลายคลาวด์:

โหลดไวรัสหลักประกอบด้วยโมดูลการรวบรวมข้อมูลรับรองอย่างเป็นระบบ ครอบคลุมผู้ให้บริการคลาวด์ สภาพแวดล้อม CI การตั้งค่าของนักพัฒนาในท้องถิ่น GitHub CLI ตัวจัดการรหัสผ่าน และไฟล์กระเป๋าเงิน

เป้าหมายการรวบรวมข้อมูลรับรองจากผู้ให้บริการคลาวด์คือ:

โมดูล AWS ยังรวมตรรกะที่เกี่ยวข้องกับ ECS/IMDS (Instance Metadata Service)/STS WebIdentity

การรวบรวมข้อมูลรับรองของนักพัฒนาในท้องถิ่นครอบคลุมเป้าหมายต่อไปนี้:

ลอจิกของตัวจัดการรหัสผ่านถูกดำเนินการในโค้ดแหล่งที่มาในรูปแบบของอาร์เรย์ runCommand(command, args) แทนการเชื่อมสตริง shell

โมดูลการรวบรวมข้อมูลประจำตัวเหล่านี้ครอบคลุมเป้าหมายหลากหลายตั้งแต่แพลตฟอร์มคลาวด์จนถึงอุปกรณ์ของนักพัฒนา; ข้อมูลที่ละเอียดอ่อนที่รวบรวมได้จะถูกส่งออกผ่านกลไกต่อไปนี้

3. GitHub API ถูกเปิดเผยและ dead-drop:

โหลดที่เป็นอันตรายหลักใช้ GitHub API เป็นช่องทางหลักในการส่งข้อมูลออก คำขอปลอมแปลง User-Agent เป็น python-requests/2.31.0 และหลังจากตรวจสอบ token ผ่าน x-oauth-scopes (ต้องมี repo, public_repo หรือ workflow) จะดำเนินการส่งข้อมูลออก: สร้าง repository (description ตั้งค่าคงที่เป็น Miasma: The Spreading Blight) และเขียนข้อมูลที่ขโมยมาซึ่งถูกเข้ารหัสแบบ base64 ผ่าน PUT /repos///contents/results/

นอกจากนี้ โหลดยังใช้กลไก dead-drop ที่อิงจากการค้นหา commit บน GitHub โดยการค้นหา marker "thebeautifulmarchoftime" (หรือ "thebeautifulsnadsoftime") เพื่อรับคำสั่ง C2:

let result = await X9("thebeautifulmarchoftime ", xZ);

ทรัพยากรฝังตัว YZ.bin เป็นตัวติดตาม GitHub commit แบบอิสระ ที่สแกนหาข้อความ commit รูปแบบ firedalazer . ทุกๆ 3600 วินาที หลังจากตรวจสอบลายเซ็นแล้ว จะดาวน์โหลดและรันเนื้อหา Python จากระยะไกล ซึ่งสร้างช่องทางการควบคุมต่อเนื่องที่แยกจากช่องทางหลัก

รหัสแหล่งที่มายังรวมถึงการตั้งค่าตัวส่ง HTTP POST ที่มีจุดหมายปลายทางเป็น api.anthropic.com และ v1/api ฟิลด์ noop ของการตั้งค่านี้ถูกตั้งค่าเป็น true ซึ่งหมายความว่าในกรณีที่ไม่มีการเปลี่ยนแปลงจากภายนอก ตัวส่งนี้จะไม่ส่งคำขอเครือข่ายจริง ดังนั้นการวิเคราะห์แบบคงที่สามารถยืนยันได้เฉพาะโครงสร้างโค้ดเท่านั้น ไม่สามารถพิสูจน์ได้ว่ามีพฤติกรรมการส่งข้อมูลไปยัง Anthropic API ที่ใช้งานอยู่

4. การติดเชื้อในรีโพสิทอรี GitHub และ Workflow:

โหลดที่เป็นอันตรายหลักสามารถดำเนินการวัตถุ git ของรีโพสิทอรีผ่าน GitHub REST / GraphQL API:

งานที่มีเจตนาไม่ดีที่สร้างขึ้นภายใต้ชื่อ release ขอสิทธิ์ id-token: write เพื่อแลกเปลี่ยนโทเค็นการเผยแพร่ npm ผ่านเส้นทาง OIDC (OpenID Connect) ตัวแปรสภาพแวดล้อมและอินเทอร์เฟซของเส้นทาง OIDC คือ ACTIONS_ID_TOKEN_REQUEST_TOKEN และ ACTIONS_ID_TOKEN_REQUEST_URL โดยตั้งค่า audience เป็น npm:registry.npmjs.org สามารถยืนยันได้ในระดับซอร์สโค้ดว่า payload มีความสามารถในการแทรกงาน workflow เข้าไปในรีโพสิทอรี GitHub และใช้ OIDC / npm trusted publishing เพื่อขอสิทธิ์การเผยแพร่

นอกจากวิธีการฉีด workflow ผ่าน git refs ที่กล่าวถึงข้างต้น โหลดยังฝังกลไกการขนส่ง secrets ที่ซ่อนเร้นยิ่งขึ้น: workflow GitHub Actions ที่ปลอมตัวเป็น Run Copilot จะเขียน ${{ toJSON(secrets) }} ลงในไฟล์ format-results.txt และอัปโหลด artifact แทนการเขียน secrets โดยตรงลงในเนื้อหาของรีโพสิทอรี วิธีนี้มุ่งเน้นการขนส่งข้อมูลผ่านผลลัพธ์ของการรัน workflow ซึ่งการตรวจสอบ diff ของโค้ดตามปกติอาจไม่สามารถมองเห็นเนื้อหา secrets ที่ส่งออกสุดท้ายได้

5. รันงาน流程 Copilot ผ่าน artifact ย้าย secrets:

ทรัพยากรที่ฝังไว้ zZ.bin เป็น workflow ของ GitHub Actions ที่ปลอมตัวเป็น Copilot ซึ่งเขียน ${{ toJSON(secrets) }} ลงในไฟล์ format-results.txt และอัปโหลดเป็น artifact

พฤติกรรม GitHub API ที่เกี่ยวข้องรวมถึง: สร้าง/อัปเดต branch ชั่วคราว → เขียน blob ของ workflow → รอการรัน workflow → ดาวน์โหลดไฟล์ zip ของ artifact → อ่านไฟล์ format-results.txt → ลบ workflow run และ branch ชั่วคราว คำสำคัญที่เกี่ยวข้องได้แก่ Run Copilot, VARIABLE_STORE, format-results, chore/add-codeql-static-analysis, .github/workflows/codeql.yml

6. npm การแพร่กระจายด้วยตัวเอง:

โหลดที่เป็นอันตรายหลักมีเส้นทางการเผยแพร่/แพร่กระจาย npm สองเส้นทางที่แยกจากกัน

เส้นทาง npm token: โหลดข้อมูลผ่าน GET /-/npm/v1/tokens เพื่อระบุ npm token ของผู้ใช้ปัจจุบัน กรอง token ที่มี bypass_2fa === true และมีสิทธิ์เขียนแพ็กเกจ ใช้ token เหล่านี้เพื่อเผยแพร่อัตโนมัติ bypass_2fa เป็นฟิลด์เมตาดาต้าของ token ไม่ใช่พารามิเตอร์ของ publish body

เส้นทาง GitHub Actions OIDC: อ่านตัวแปรสภาพแวดล้อม ACTIONS_ID_TOKEN_REQUEST_TOKEN และ ACTIONS_ID_TOKEN_REQUEST_URL ขอ OIDC token ที่มี audience เป็น npm:registry.npmjs.org แล้วแลกเปลี่ยนสิทธิ์การเผยแพร่ผ่านอินเทอร์เฟซ OIDC token exchange ของ npm

ขั้นตอนการปนเปื้อนไฟล์ tarball คือถอดแพ็กเกจ → เขียนไฟล์ index.js ที่มีอันตราย → แก้ไข package.json:

ที่นี่แบ่งออกเป็นสองประเภทของจุดเริ่มต้น: ตัวอย่างที่อัปโหลดท้องถิ่นสามชุดใช้ preinstall: "node index.js" — ในกรณีนี้ ไม่จำเป็นต้องติดตั้ง Bun ล่วงหน้าในการติดตั้งสภาพแวดล้อม เพราะการใช้ Node.js เป็นจุดเริ่มต้นจะซ่อนตัวได้ดีกว่า; ในขณะที่เมื่อแพร่กระจายเองเพื่อปนเปื้อนแพ็กเกจอื่นๆ จะเขียน preinstall: "bun run index.js" และเพิ่มการพึ่งพา bun — เนื่องจากตรรกะของโหลดที่เป็นอันตรายหลักพึ่งพา API ที่ให้โดยรันไทม์ของ Bun (เช่น Bun.gunzipSync และ Bun.file) ในสถานการณ์การแพร่กระจายเองจึงจำเป็นต้องรับประกันว่าสภาพแวดล้อมเป้าหมายมี Bun อยู่แล้ว

7. กลไกการบันทึกถาวร:

โหลดที่เป็นอันตรายหลักประกอบด้วยวิธีการยึดติดสี่แบบ ครอบคลุมไดเรกทอรีโปรเจกต์และการเริ่มต้นระบบ

Claude Code SessionStart hook: ฝังทรัพยากร S8.bin เพื่อเขียน SessionStart hook ลงใน .claude/settings.json โดยจะรัน node .claude/setup.mjs อัตโนมัติทุกครั้งที่เริ่มเซสชัน Claude Code โหลดที่เป็นอันตรายถูกเขียนลงใน .claude/setup.mjs และ .claude/index.js พร้อมกัน (เส้นทางถูกสร้างจาก ".claude/" + M0 โดยที่ M0 = "index.js")

งาน folderOpen ของ VS Code: ฝังทรัพยากร EZ.bin เพื่อเขียนงาน folderOpen ลงในไฟล์ .vscode/tasks.json และรันสคริปต์เดียวกันอัตโนมัติเมื่อเปิดโฟลเดอร์โปรเจกต์ที่ถูกโจมตี พร้อมเขียนไฟล์ .vscode/setup.mjs ด้วย

kitty-monitor (systemd / LaunchAgent): ฝังทรัพยากร RZ.bin เพื่อติดตั้งบริการแบบถาวร ไฟล์ถูกกระจายไปยัง /.local/share/kitty/cat.py, /.config/systemd/user/kitty-monitor.service (Linux) และ ~/Library/LaunchAgents/com.user.kitty-monitor.plist (macOS) โหลดที่เป็นอันตรายสร้างไดเรกทอรี /tmp/kitty- เขียน YZ.bin (GitHub commit monitor) ลงใน cat.py แล้วติดตั้งผ่าน RZ.bin

gh-token-monitor (systemd / LaunchAgent): ติดตั้งบริการตรวจสอบ GitHub token โดยฝังทรัพยากร jZ.bin ไฟล์ถูกจัดเก็บไว้ที่ /.local/bin/gh-token-monitor.sh, /.config/gh-token-monitor/ และเส้นทาง systemd / LaunchAgent ที่เกี่ยวข้อง ตัวตรวจสอบจะตรวจจับว่า GitHub token ตอบกลับด้วยรหัสสถานะ 40x หรือไม่ และวัดข้อมูลเมตาของแพ็กเกจ npm @cap-js/openapi@1.4.1 ว่าผิดปกติหรือไม่ เมื่อเกิดเหตุการณ์ จะเรียกใช้ handler:

นี่หมายความว่าเมื่อ monitor สังเกตเห็นว่า GitHub API ตอบกลับด้วยรหัสสถานะ 40x เช่น token ถูกเพิกถอน หมดอายุ หรือสถานะสิทธิ์ผิดปกติ สคริปต์ที่เป็นอันตรายจะดำเนินการ handler ที่ส่งเข้ามา ในตัวอย่างสามตัวอย่างจากบทความนี้ handler ที่ถูกกู้คืนคือ rm -rf ~/; rm -rf ~/Documents เมื่อจัดการสถานการณ์นี้ ห้ามเพิกถอน token โดยตรงบนโฮสต์ที่อาจยังคงรัน payload อยู่—ควรแยกโฮสต์ออกก่อน ลบรายการที่ยังคงอยู่และกระบวนการที่กำลังรันอยู่ แล้วจึงเปลี่ยนข้อมูลประจำตัวจากสภาพแวดล้อมที่สะอาด

8. Harden-Runner / StepSecurity ต่อสู้:

โหลดอันตรายหลักมีการฝังตรรกะในการตรวจจับและทำลาย StepSecurity Harden-Runner โดยข้ามการป้องกัน CI/CD ผ่านขั้นตอนต่อไปนี้:

  1. ตรวจสอบว่า Docker socket /var/run/docker.sock ใช้งานได้หรือไม่;
  2. แสดงคอนเทนเนอร์ Docker ที่ตรงกับคีย์เวิร์ด harden-runner หรือ stepsecurity ในชื่อหรือภาพ
  3. ยกเลิกคอนเทนเนอร์ที่ตรงกันผ่าน POST /containers//kill;
  4. สร้างคอนเทนเนอร์ Alpine แบบมีสิทธิ์พิเศษ โดยแก้ไขไฟล์ sudoers เป็น runner ALL=(ALL) NOPASSWD:ALL;
  5. เขียนการแก้ไขชื่อโดเมนที่เกี่ยวข้องกับ StepSecurity ลงใน /etc/hosts อย่างไม่ถูกต้อง;
  6. เขียนทับ /etc/resolv.conf ด้วย 8.8.8.8 และ 1.1.1.1

ตรรกะการต่อต้านนี้แสดงให้เห็นว่าตัวอย่างได้รับการปรับให้เหมาะกับสภาพแวดล้อม CI/CD ที่ได้รับการป้องกันโดย StepSecurity

9. EDR / การตรวจจับผลิตภัณฑ์ด้านความปลอดภัย การวิเคราะห์สภาพแวดล้อม และการหลีกเลี่ยง:

โหลดไวรัสหลักตรวจจับชื่อกระบวนการและเส้นทางการติดตั้งของผลิตภัณฑ์ EDR (Endpoint Detection and Response) / ความปลอดภัยหลายตัว:

โหลดยังรวมตรรกะการหลีกเลี่ยงภูมิภาค: ตรวจจับตัวแปรสภาพแวดล้อม LC_ALL, LC_MESSAGES, LANGUAGE, LANG หลังจากแปลงเป็นตัวพิมพ์เล็ก หากเริ่มต้นด้วย ru จะข้ามการดำเนินการ การระบุสภาพแวดล้อม CI รองรับ GitHub Actions, GitLab CI, Travis CI, CircleCI, Jenkins, AWS CodeBuild, Buildkite, AppVeyor, Bitbucket, Drone, TeamCity, Cirrus CI เป็นต้น ป้ายสถานะที่ใช้ในช่วงรันรวมถึง tmp.0987654321.lock, __IS_DAEMON (ป้ายกำกับกระบวนการเดโมนที่แยกตัวออก), SKIP_DOMAIN (ข้ามเส้นทาง sender ของโดเมน), /tmp/kitty-*, cat.py และ /var/tmp/.gh_update_state

Impact Analysis

จากความสามารถของซอร์สโค้ด ผลกระทบของตัวอย่างทั้งสามนี้ไม่ได้จำกัดอยู่เพียงการดำเนินการแบบครั้งเดียวในขั้นตอนการติดตั้งผ่าน npm ความเสี่ยงที่แท้จริงสามารถแบ่งออกเป็นสี่ระดับ:

ระดับโฮสต์ของนักพัฒนา ตัวอย่างจะรวบรวมตัวแปรสภาพแวดล้อม .npmrc .pypirc คีย์ SSH การตั้งค่า Docker .env โทเค็น GitHub CLI ข้อมูลผู้จัดการรหัสผ่าน และไฟล์กระเป๋าเงิน และรักษาความสามารถในการกระตุ้นในภายหลังผ่าน Claude Code VS Code systemd user service หรือ macOS LaunchAgent

ในระดับ CI/CD Runner ตัวอย่างจะตรวจจับ GitHub Actions Linux runner อ่านหน่วยความจำของกระบวนการ Runner.Worker และดึงข้อมูลลับที่ถูกซ่อนไว้; นอกจากนี้ยังมีตรรกะต่อต้าน StepSecurity Harden-Runner เพื่อพยายามทำลายหรือหลีกเลี่ยงส่วนประกอบป้องกัน CI/CD

ในระดับองค์กรและรีโพสิทอรีของ GitHub ตัวอย่างสามารถใช้ GitHub API เพื่อสร้างรีโพสิทอรี เขียนข้อมูลลงใน contents/results/ จัดการ git refs/blobs/trees/commits แทรก workflow ที่เป็นอันตราย และถ่ายโอน secrets ผ่านการรัน Copilot workflow + artifact

ในระดับการแพร่กระจายของระบบนิเวศ npm ตัวอย่างสามารถกรอง token npm ที่มีสิทธิ์เขียน package และ bypass_2fa === true หรือใช้เส้นทาง GitHub Actions OIDC / npm trusted publishing เพื่อแลกเปลี่ยนสิทธิ์การเผยแพร่ จากนั้นดาวน์โหลด tarball เป้าหมาย แทรก loader ที่เป็นอันตราย แก้ไข preinstall เพิ่มการพึ่งพา Bun ปรับเวอร์ชัน patch และเผยแพร่ เพื่อสร้างโซ่การแพร่กระจายภายใน npm

Summary

หลักฐานรหัสแหล่งที่มาจากตัวอย่างสามชุดแสดงว่าแพ็กเกจที่เป็นอันตรายครั้งนี้ไม่ใช่เพียงสคริปต์ขโมยข้อมูลในระหว่างการติดตั้ง แต่เป็นการรวมกันของ loader หลายขั้นตอนและ implant ที่สมบูรณ์: ชั้นนอกถูกสุ่มแบบเฉพาะของแต่ละแพ็กเกจ ขณะที่ตัวนำร่องสภาพแวดล้อม Bun และโหลดหลักที่เป็นอันตรายมีความสอดคล้องกัน; implant หลักครอบคลุมหลายขั้นตอน เช่น การเก็บข้อมูลการรับรองความถูกต้อง การดึง CI secret การแพร่กระจายผ่าน GitHub/npm การคงอยู่อย่างต่อเนื่อง และการต่อต้านการป้องกัน

การออกแบบช่องทางเข้าที่ซ่อนเร้นอย่างสูง ผู้โจมตีไม่ได้ฝังตรรกะที่เป็นอันตรายในโค้ดธุรกิจ แต่ติดตั้ง loader ที่ถูกเข้ารหัสไว้ในสคริปต์ชีวิตของ npm loader นี้มีหน้าที่หลักในการถอดรหัสและดำเนินการโหลดที่ฝังอยู่ ทำให้การตรวจสอบซอร์สโค้ดธุรกิจเพียงอย่างเดียวยากที่จะตรวจพบความสามารถที่แท้จริง

โซ่การถอดรหัสที่ซ้อนกันหลายชั้น ภาระงานที่เป็นอันตรายผ่านการเข้ารหัสแบบอาร์เรย์ตัวเลข + การแทนที่ตัวอักษร ROT, การเข้ารหัส AES-128-GCM, การทำให้สับสนโดย obfuscator.io, การเข้ารหัสสตริงเฉพาะตัวของ B5, และชั้นการฝังด้วย AES-256-GCM + gzip รวมทั้งหมดห้าชั้น คีย์หรือพารามิเตอร์ของแต่ละชั้นสามารถเปลี่ยนแปลงได้อย่างอิสระในแพ็กเกจต่างๆ ทำให้การตรวจจับแบบกลุ่มตามลักษณะคงที่ยากยิ่งขึ้น

ความสามารถในการโจมตีระดับองค์กรอย่างสมบูรณ์ implant นี้มีความสามารถในการอ่านหน่วยความจำของ GitHub Actions Runner, รวบรวมข้อมูลรับรองจากหลายคลาวด์และในท้องถิ่น, ส่งข้อมูลผ่าน GitHub API และ dead-drop, ติดเชื้อ repository และ workflow ของ GitHub, แพร่กระจายตัวเองผ่าน npm, การคงอยู่อย่างต่อเนื่อง และการต่อต้านการป้องกัน จากโครงสร้างโค้ดต้นฉบับ ดูเหมือนว่ามันมีเส้นทางโค้ดที่สามารถเริ่มต้นจากการติดตั้งจุดเดียวแล้วแพร่กระจายไปยัง repository, CI/CD และห่วงโซ่การเผยแพร่ npm ขอบเขตการแพร่กระจายที่แท้จริงยังต้องยืนยันร่วมกับบันทึกการติดตั้ง การตรวจสอบ repository และข้อมูลการวัดจากระบบ

จากหลักฐานรหัสต้นทางสามารถยืนยันได้ว่า: ตัวอย่างทั้งสามถูกกระตุ้นอัตโนมัติผ่าน preinstall และถอดรหัสเพื่อเรียกใช้ main implant เดียวกัน แต่ไม่สามารถพิสูจน์ได้จากตัวอย่าง tgz ทั้งสามนี้ว่าสิทธิ์เริ่มต้นในเหตุการณ์จริงได้มาอย่างไร

คำแนะนำในการจัดการ

  1. ตรวจสอบและลบเวอร์ชันที่เป็นอันตรายออกจากความพึ่งพาของโปรเจกต์ ไฟล์ล็อก แคชเรจิสทรีส่วนตัว และแคชการสร้าง
  2. ตรวจสอบว่าในบันทึกการติดตั้งมีคำสั่ง preinstall, node index.js, bun run, /tmp/p*.js, tmp.0987654321.lock หรือไม่
  3. อย่าเพิกถอนโทเค็นโดยตรงบนโฮสต์ที่ยังอาจรัน payload อยู่ แนะนำให้แยกโฮสต์ที่ถูกโจมตีออกก่อน ลบกระบวนการที่กำลังรันและรายการที่ยังคงอยู่อย่างถาวร จากนั้นจึงเปลี่ยนโทเค็นที่เกี่ยวข้องกับ GitHub, npm, ข้อมูลประจำตัวของคลาวด์, Kubernetes, Vault, SSH, Docker registry และตัวจัดการรหัสผ่านจากสภาพแวดล้อมที่สะอาด
  4. ตรวจสอบรีพอสิทอรี GitHub สำหรับ branch, commit, workflow, artifact และรีพอสิทอรีใหม่ล่าสุด โดยเน้นที่คีย์เวิร์ดเช่น Run Copilot, format-results, chore/add-codeql-static-analysis, .github/workflows/codeql.yml, OIDC_PACKAGES
  5. ตรวจสอบว่ามีการเพิ่มหรือแก้ไขไดเรกทอรีโปรเจกต์หรือไม่: .claude/settings.json, .claude/setup.mjs, .vscode/tasks.json, .vscode/setup.mjs
  6. ตรวจสอบการจัดเก็บถาวรระดับผู้ใช้: /.local/share/kitty/cat.py, /.config/systemd/user/kitty-monitor.service, ~/Library/LaunchAgents/com.user.kitty-monitor.plist, ไฟล์ที่เกี่ยวข้องกับ gh-token-monitor
  7. ตรวจสอบประวัติการเผยแพร่ npm เพื่อยืนยันว่ามีการเผยแพร่เวอร์ชันแพตช์ที่ไม่ได้รับอนุญาตหรือไม่; พร้อมทั้งตรวจสอบเมตาดาต้าของ npm token โดยเน้นที่ token ที่สามารถข้าม 2FA (Two-Factor Authentication) และมีสิทธิ์เขียนแพ็กเกจ
  8. ดำเนินการตรวจสอบความสมบูรณ์ของผลิตภัณฑ์ที่สร้างขึ้นในสภาพแวดล้อมที่ปนเปื้อน

IOC

ไฟล์ที่เป็นอันตราย

ชื่อไฟล์: redhat-cloud-services-frontend-components-config-6.11.3.tgz MD5: 633ad8849a59e2bfb7a0fe589e816a07 SHA1: 675294612f455fe6a9acb195f0cbe3687d8e2e34 SHA256: 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060

ชื่อไฟล์: redhat-cloud-services-types-3.6.1.tgz MD5: 9e6c5af01438b52c9a411686c1f1b8ff SHA1: 88d098c8d96e9ae17550e9798c3b62c420464b8c SHA256: d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

ชื่อไฟล์: redhat-cloud-services-rule-components-4.7.2.tgz MD5: f1ffdbf5e639899f26a6ebab2eec408d SHA1: f3c5c21274045ae02fef11e931de6dcf8462a067 SHA256: aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f

SHA256

ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6

0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35

การพึ่งพาอย่างไม่เหมาะสม

npm:@redhat-cloud-services/topological-inventory-client@3.0.10

npm:@redhat-cloud-services/topological-inventory-client@3.0.11

npm:@redhat-cloud-services/topological-inventory-client@3.0.13

npm:@redhat-cloud-services/compliance-client@4.0.3

npm:@redhat-cloud-services/compliance-client@4.0.4

npm:@redhat-cloud-services/compliance-client@4.0.6

npm:@redhat-cloud-services/rbac-client@9.0.3

npm:@redhat-cloud-services/rbac-client@9.0.4

npm:@redhat-cloud-services/rbac-client@9.0.6

npm:@redhat-cloud-services/insights-client@4.0.4

npm:@redhat-cloud-services/insights-client@4.0.5

npm:@redhat-cloud-services/insights-client@4.0.7

npm:@redhat-cloud-services/frontend-components@7.7.2

npm:@redhat-cloud-services/frontend-components@7.7.3

npm:@redhat-cloud-services/frontend-components@7.7.5

npm:@redhat-cloud-services/frontend-components-utilities@7.4.1

npm:@redhat-cloud-services/frontend-components-utilities@7.4.2

npm:@redhat-cloud-services/frontend-components-utilities@7.4.4

npm:@redhat-cloud-services/remediations-client@4.0.4

npm:@redhat-cloud-services/remediations-client@4.0.5

npm:@redhat-cloud-services/remediations-client@4.0.7

npm:@redhat-cloud-services/frontend-components-notifications@6.9.2

npm:@redhat-cloud-services/frontend-components-notifications@6.9.3

npm:@redhat-cloud-services/frontend-components-notifications@6.9.5

npm:@redhat-cloud-services/patch-client@4.0.4

npm:@redhat-cloud-services/patch-client@4.0.5

npm:@redhat-cloud-services/patch-client@4.0.7

npm:@redhat-cloud-services/host-inventory-client@5.0.3

npm:@redhat-cloud-services/host-inventory-client@5.0.4

npm:@redhat-cloud-services/host-inventory-client@5.0.6

npm:@redhat-cloud-services/rule-components@4.7.2

npm:@redhat-cloud-services/rule-components@4.7.3

npm:@redhat-cloud-services/rule-components@4.7.5

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.2

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.4

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.6

npm:@redhat-cloud-services/notifications-client@6.1.4

npm:@redhat-cloud-services/notifications-client@6.1.5

npm:@redhat-cloud-services/notifications-client@6.1.7

npm:@redhat-cloud-services/sources-client@3.0.10

npm:@redhat-cloud-services/sources-client@3.0.11

npm:@redhat-cloud-services/sources-client@3.0.13

npm:@redhat-cloud-services/integrations-client@6.0.4

npm:@redhat-cloud-services/integrations-client@6.0.5

npm:@redhat-cloud-services/integrations-client@6.0.7

npm:@redhat-cloud-services/frontend-components-config@6.11.3

npm:@redhat-cloud-services/frontend-components-config@6.11.4

npm:@redhat-cloud-services/frontend-components-config@6.11.6

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.2

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.3

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.5

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.1

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.2

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.4

npm:@redhat-cloud-services/frontend-components-remediations@4.9.2

npm:@redhat-cloud-services/frontend-components-remediations@4.9.3

npm:@redhat-cloud-services/frontend-components-remediations@4.9.5

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.1

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.2

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.4

npm:@redhat-cloud-services/javascript-clients-shared@2.0.8

npm:@redhat-cloud-services/javascript-clients-shared@2.0.9

npm:@redhat-cloud-services/javascript-clients-shared@2.0.11

npm:@redhat-cloud-services/quickstarts-client@4.0.11

npm:@redhat-cloud-services/quickstarts-client@4.0.12

npm:@redhat-cloud-services/quickstarts-client@4.0.14

npm:@redhat-cloud-services/config-manager-client@5.0.4

npm:@redhat-cloud-services/config-manager-client@5.0.5

npm:@redhat-cloud-services/config-manager-client@5.0.7

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.1

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.2

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.4

npm:@redhat-cloud-services/entitlements-client@4.0.11

npm:@redhat-cloud-services/entitlements-client@4.0.12

npm:@redhat-cloud-services/entitlements-client@4.0.14

npm:@redhat-cloud-services/tsc-transform-imports@1.2.2

npm:@redhat-cloud-services/tsc-transform-imports@1.2.4

npm:@redhat-cloud-services/tsc-transform-imports@1.2.6

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.1

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.2

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.4

npm:@redhat-cloud-services/frontend-components-testing@1.2.1

npm:@redhat-cloud-services/frontend-components-testing@1.2.2

npm:@redhat-cloud-services/frontend-components-testing@1.2.4

npm:@redhat-cloud-services/types@3.6.1

npm:@redhat-cloud-services/types@3.6.2

npm:@redhat-cloud-services/types@3.6.4

npm:@redhat-cloud-services/chrome@2.3.1

npm:@redhat-cloud-services/chrome@2.3.2

npm:@redhat-cloud-services/chrome@2.3.4

npm:@redhat-cloud-services/frontend-components-translations@4.4.1

npm:@redhat-cloud-services/frontend-components-translations@4.4.2

npm:@redhat-cloud-services/frontend-components-translations@4.4.4

npm:@redhat-cloud-services/vulnerabilities-client@2.1.8

npm:@redhat-cloud-services/vulnerabilities-client@2.1.9

npm:@redhat-cloud-services/vulnerabilities-client@2.1.11

แหล่งที่มา:แสดงต้นฉบับ
คำปฏิเสธความรับผิดชอบ: ข้อมูลในหน้านี้อาจได้รับจากบุคคลที่สาม และไม่จำเป็นต้องสะท้อนถึงมุมมองหรือความคิดเห็นของ KuCoin เนื้อหานี้จัดทำขึ้นเพื่อวัตถุประสงค์ในการให้ข้อมูลทั่วไปเท่านั้น โดยไม่มีการรับรองหรือการรับประกัน และจะไม่ถูกตีความว่าเป็นคำแนะนำทางการเงินหรือการลงทุน KuCoin จะไม่รับผิดชอบต่อความผิดพลาดหรือการละเว้นในเนื้อหา หรือผลลัพธ์ใดๆ ที่เกิดจากการใช้ข้อมูลนี้ การลงทุนในสินทรัพย์ดิจิทัลอาจมีความเสี่ยง โปรดประเมินความเสี่ยงของผลิตภัณฑ์และความเสี่ยงที่คุณยอมรับได้อย่างรอบคอบตามสถานการณ์ทางการเงินของคุณเอง โปรดดูข้อมูลเพิ่มเติมได้ที่ข้อกำหนดการใช้งานและเอกสารเปิดเผยข้อมูลความเสี่ยงของเรา