สรุปสั้น

แคมเปญโจมตีห่วงโซ่อุปทาน GhostAction กลับมาอีกครั้ง โดยใช้บัญชี GitHub ที่ถูกยึดของผู้ดูแลโอเพนซอร์สชื่อดัง 2 ราย คือนาย Takashi Kitao (kitao) ผู้สร้างเกมเอนจิน pyxel ที่มีกว่า 18,000 ดาว และนาย Henry Wu (henrywoo) ผู้สร้าง athenadriver ของ Uber ฝังเวิร์กโฟลว์ GitHub Actions ปลอมชื่อ “security audit” ลงใน 346 repo เมื่อ 8 ตุลาคม 2569 เวิร์กโฟลว์จะทำงานอัตโนมัติเมื่อมีการ push แล้วส่ง secret ของ CI/CD กุญแจคลาวด์ โทเคน API และ credential ที่ฝังอยู่ในซอร์สโค้ดไปยังเซิร์ฟเวอร์ของผู้โจมตีที่ 193.32.204[.]199

สิ่งที่ต่างจากรอบก่อนคือ เวิร์กโฟลว์รุ่นใหม่ไม่ได้ขโมยแค่ secret ที่ตั้งไว้ใน GitHub Actions แต่ไล่ค้น credential ในไฟล์ปัจจุบันและ ประวัติ git ทั้งหมด ด้วย กุญแจที่นักพัฒนาเคยลบออกจากไฟล์แต่ยังค้างอยู่ใน commit เก่าจึงถูกเก็บไปด้วย ขอบเขตจริงอาจใหญ่กว่าที่เห็นมาก บริษัท Socket ระบุว่า ณ 9 ตุลาคม พบบัญชี GitHub กว่า 500 บัญชีที่ commit เวิร์กโฟลว์นี้ไปยัง repo หลายหมื่นแห่งตั้งแต่ 7 ตุลาคม แต่ยังไม่พบแพ็กเกจอันตรายที่ถูกเผยแพร่บน PyPI หรือ crates.io จากรอบนี้

รายละเอียดข่าว

เว็บไซต์ Cyber Security News รายงานเมื่อวันที่ 9 ตุลาคม 2569 อ้างการสืบสวนของ Socket และ The Hacker News รายงานเพิ่มเติมเมื่อวันที่ 10 ตุลาคม 2569 อ้างข้อมูลของบริษัท StepSecurity ว่า “ผู้โจมตีใช้บัญชีของ Takashi Kitao ผู้สร้างเกมเอนจิน pyxel ที่มี 18,400 ดาว push เวิร์กโฟลว์อันตรายไปยัง 27 repo เริ่มเวลา 13:20 น. UTC อีก 8 ชั่วโมงต่อมา บัญชีของ Henry Wu ผู้สร้าง athenadriver ของ Uber ถูกใช้ push เวิร์กโฟลว์เดียวกันไปยัง 318 repo ภายใน 16 นาที ระหว่าง 21:10–21:26 น. UTC”

Socket นับได้ 318 repo ภายใต้ henrywoo ซึ่ง 279 รายการเป็น fork อีก 27 repo ภายใต้ kitao และ uber/athenadriver การ push ทำในช่วงเวลาสั้นมาก รวมถึง repo ที่ไม่มีการเปลี่ยนแปลงมาหลายปี บ่งชี้ว่าผู้โจมตีใช้ระบบค้นหา repo อัตโนมัติ ไม่ได้เลือกทีละโครงการ

GhostAction เปิดเผยครั้งแรกเมื่อกันยายน 2568 โดย GitGuardian พบว่ากระทบ 817 repo ของผู้ใช้ 327 ราย และขโมย secret อย่างน้อย 3,325 รายการ รวมถึงโทเคน PyPI, npm และ DockerHub ต้นสัปดาห์นี้ GitGuardian ยังรายงานระลอกระหว่าง 31 สิงหาคมถึง 30 กันยายน 2569 ที่ push เวิร์กโฟลว์ไปยัง 772 repo สาธารณะของผู้ใช้และองค์กร 373 ราย และเล็ง secret 2,577 รายการ ในกรณีหนึ่งเมื่อ 30 สิงหาคม 2569 ผู้โจมตีแก้ repo kuafuai/DevOpsGPT ให้ฝังตัวขุด XMRig ใน Docker image ของโครงการ

GhostAction campaign plants credential-stealing GitHub Actions workflows in hundreds of repositories

วิธีการโจมตี

StepSecurity สรุปห่วงโซ่การโจมตีเป็น 4 ขั้น

  1. ผู้โจมตีได้ credential GitHub ของผู้ดูแล ซึ่งน่าจะเป็น personal access token (PAT) ที่รั่วจาก log ของมัลแวร์ขโมยข้อมูลหรือชุดข้อมูลรหัสผ่านที่หลุด
  2. สแกนไฟล์เวิร์กโฟลว์เดิมของ repo เพื่อดูว่าอ้างถึง secret ชื่ออะไรบ้าง
  3. ฝังเวิร์กโฟลว์ที่ปลอมเป็น security audit ลงใน default branch ในนามของเจ้าของบัญชีเอง ผ่าน commit ชื่อ “Add security audit workflow” หรือ “Update security audit workflow”
  4. payload ดึงข้อมูลแล้วส่งด้วย curl ผ่าน HTTP ธรรมดาไปยัง IP ที่ฝังตายตัว

StepSecurity ระบุว่าเวิร์กโฟลว์ “ทำงานเมื่อมี workflow_dispatch และ push แบบไม่กรอง (ทุก branch ทุก tag) checkout ด้วย fetch-depth: 0 และรันขั้นตอน ‘Audit’ เดียวที่ทำ 4 อย่าง” ได้แก่ แนบ secret ที่มีชื่อซึ่งพบจากการสำรวจ สแกน working tree หา credential 13 รูปแบบ สแกนประวัติ git ทั้งหมดหารูปแบบเดียวกัน และจับคู่ AWS access key ID กับ secret access key ที่เข้าคู่กัน โดยเก็บบรรทัดรอบข้าง AWS key ID ไว้ด้วย

credential ที่เล็งได้แก่ AWS access key, secret key และ session token, โทเคน GitHub และ GitLab, Google API key, โทเคน Slack, credential ของ SendGrid และ API key ของ OpenAI, Anthropic และ OpenRouter รวมถึง secret ของ GitHub Actions ที่อ้างถึงในเวิร์กโฟลว์เดิม เช่น รหัสผ่าน PyPI, โทเคน crates.io และ PAT ของ GitHub

ตัวเลขจาก GitGuardian: ยึดบัญชีราว 1,900 บัญชี เล็งกว่า 30,000 repo และ GitHub เริ่มบล็อกเวิร์กโฟลว์

เว็บไซต์ The Hacker News รายงานเพิ่มเติมเมื่อวันที่ 15 ตุลาคม 2569 อ้างข้อมูลของบริษัท GitGuardian ว่าระลอกวันที่ 8-9 ตุลาคม 2569 ใหญ่กว่าที่รายงานไว้ข้างต้นมาก นาย Gaetan Ferry และนาย Guillaume Valadon นักวิจัยของ GitGuardian ระบุว่าผู้โจมตี ยึดบัญชี GitHub ของผู้ใช้ราว 1,900 ราย แล้วเล็ง repo มากกว่า 30,000 แห่งของผู้ใช้และองค์กรราว 3,000 ราย และพยายามดึง secret 3,174 รายการจาก CI ของ repo สาธารณะ

GitGuardian ระบุว่าระลอกใหม่ที่เริ่มตั้งแต่ 31 สิงหาคม 2569 “ดูเป็นการทดลองและทำด้วยมือมากกว่ารอบก่อน โดย payload ค่อย ๆ พัฒนาไปเรื่อย ๆ” รุ่นแรกเพิ่มการสแกนหา secret ในประวัติ git รุ่นที่สองเก็บบรรทัดรอบข้าง AWS key ID ราว 2 บรรทัดเพื่อจับคู่กับ secret access key และรุ่นที่สามซึ่งเป็นรุ่นสุดท้ายเพิ่มการดึงบริบทของ secret ระหว่างสแกนประวัติ git การปล่อย payload ทำเป็นขั้นตอน ครั้งแรกส่งไปยังเหยื่อเดิม 160 ราย จากนั้นอีก 20 นาทีต่อมาส่งไปยัง repo ใหม่ 28,000 แห่งระหว่างวันที่ 8-9 ตุลาคม

ข่าวดีคือ GitHub เริ่มป้องกันไม่ให้เวิร์กโฟลว์อันตรายนี้รันตั้งแต่วันที่ 9 ตุลาคม ระลอกถัดมาในวันที่ 10 และ 12 ตุลาคมที่ใช้ payload เดียวกันจึงดึง secret ไม่ได้ ส่วนข้อที่น่ากังวลคือเหยื่อบางส่วนในระลอกนี้เคยถูกเจาะมาแล้วในระลอกกันยายน 2568 และสิงหาคม 2569 ซึ่งบ่งชี้ว่าผู้โจมตีหวังพึ่ง secret ที่เหยื่อยังไม่ได้หมุนเปลี่ยนหลังเหตุครั้งก่อน

ผลกระทบ

ความเสียหายที่น่ากังวลที่สุดไม่ใช่ตัว repo แต่คือ credential สำหรับเผยแพร่แพ็กเกจ หากผู้โจมตีได้โทเคน PyPI, npm, Docker Hub หรือ crates.io ของโครงการที่คนนิยม ก็อาจปล่อยเวอร์ชันอันตรายจากโครงการที่ผู้ใช้เชื่อถือ แล้วลามไปถึงนักพัฒนาและระบบ production ปลายน้ำ แม้ยังไม่พบแพ็กเกจอันตรายจากรอบนี้ แต่ credential ที่ขโมยไปแล้วนำไปใช้ภายหลังได้

Socket เตือนว่า fork 279 รายการใน henrywoo ต่างมีไฟล์เวิร์กโฟลว์ติดไปด้วย หากเปิด Actions ไว้ การ push ครั้งต่อไปจะเรียกการขโมยอีก fork ปลายน้ำที่สร้างใหม่หรือ sync จาก upstream ก็รับเวิร์กโฟลว์ไปด้วย Socket ระบุว่า “fork แบบส่วนตัวและ mirror ปลายน้ำเสี่ยงที่สุด เพราะ repo ส่วนตัวคือที่ที่พบ credential ที่ commit ไว้จริง” และ “ทุกการรันส่ง identifier ของ repo กลับไปด้วยไม่ว่าจะพบ credential หรือไม่ ผู้โจมตีจึงได้แผนที่ของบริบทการรันที่เข้าถึงได้ แยกจากการขโมย credential” การลบเวิร์กโฟลว์ออกอย่างเดียวจึงไม่พอ

คำแนะนำ

  • ตรวจทุก branch ของ repo หา .github/workflows/security-audit.yml และ .github/workflows/github_actions_security.yml ตั้งแต่ 31 สิงหาคม 2569 หากพบให้ถือว่าถูกเจาะ
  • เพิกถอน session ของ GitHub, PAT, OAuth grant และ SSH key ของบัญชีที่ถูกใช้ และหมุน secret ทุกตัวที่เวิร์กโฟลว์อ้างถึง รวมถึง credential ที่เคยอยู่ในประวัติ git แม้ลบออกจากไฟล์แล้ว
  • ลบเวิร์กโฟลว์อันตรายออกจากทุก branch ตรวจ fork และ mirror ทั้งหมด ทั้งแบบสาธารณะและส่วนตัว
  • ตรวจประวัติการรัน GitHub Actions ประวัติการปล่อยแพ็กเกจ และค้นล็อกเครือข่ายหาการเชื่อมต่อไปยัง 193.32.204[.]199
  • สแกนประวัติ git ทั้งหมดด้วยเครื่องมือค้น secret เปิด secret scanning พร้อม push protection ตั้ง branch protection บังคับรีวิวการเปลี่ยนแปลงใน .github/workflows/ และจำกัดสิทธิ์ของ GITHUB_TOKEN ให้น้อยที่สุด
  • ใช้ PAT แบบ fine-grained ที่มีอายุสั้นและขอบเขตจำกัด และย้ายการเผยแพร่แพ็กเกจไปใช้ trusted publishing (OIDC) แทนโทเคนถาวร

Indicators of Compromise (IoCs)

ประเภทค่าคำอธิบาย
ไฟล์เวิร์กโฟลว์.github/workflows/security-audit.ymlไฟล์เวิร์กโฟลว์อันตราย
ไฟล์เวิร์กโฟลว์.github/workflows/github_actions_security.ymlไฟล์เวิร์กโฟลว์อันตรายแบบอื่น
ข้อความ commitAdd security audit workflowcommit ที่ฝังเวิร์กโฟลว์
ข้อความ commitUpdate security audit workflowcommit ที่ฝังเวิร์กโฟลว์
ข้อความ commitAdd Github Actions Security workflowcommit ที่ฝังเวิร์กโฟลว์แบบอื่น
marker ใน requestREPO=ตัวระบุ repo ใน body ของ request ขาออก
marker ใน requestAKIA_CTX_START / AKIA_CTX_ENDครอบบริบท AWS credential ที่เก็บได้
IP193.32.204[.]199ปลายทางรับ credential ที่ขโมย (HTTP)

แหล่งอ้างอิง