1 คะแนน โดย GN⁺ 2025-08-25 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • ความสับสนระหว่าง ghcr.io กับ ghrc.io จากการพิมพ์ผิดเพียงเล็กน้อย ก่อให้เกิด ภัยคุกคามด้านความปลอดภัยร้ายแรง
  • ghrc.io ภายนอกดูเหมือนเซิร์ฟเวอร์ nginx ปกติ แต่ภายในตรวจพบว่า เลียนแบบ OCI API
  • เว็บไซต์นี้ใช้ www-authenticate header เพื่อชักจูงให้ไคลเอนต์คอนเทนเนอร์ส่ง ข้อมูลยืนยันตัวตนที่อ่อนไหว
  • หากเผลอกรอกข้อมูลยืนยันตัวตนด้วยคำสั่งอย่าง docker login หรือใช้งานรีจิสทรีผิดโดเมน อาจเกิด การรั่วไหลของข้อมูลรับรอง ได้
  • หากเคยล็อกอินกับเซิร์ฟเวอร์ผิด ควร เปลี่ยนรหัสผ่าน, เพิกถอน PAT และตรวจสอบกิจกรรมผิดปกติในบัญชี GitHub

ภาพรวม

กรณีนี้แสดงให้เห็นว่าความสับสนระหว่าง ghcr.io และ ghrc.io ที่เกิดขึ้นได้บ่อยจากการพิมพ์ผิดเพียงเล็กน้อย สามารถนำไปสู่ ปัญหาด้านความปลอดภัยที่อันตรายมาก ได้ โดยมีการตรวจพบ ความพยายามขโมยข้อมูลรับรอง บน ghrc.io ซึ่งเป็นโดเมนที่พิมพ์คล้ายกับ GitHub Container Registry (ghcr.io) ที่นักพัฒนาและทีมงานจำนวนมากใช้งาน

ghcr.io คืออะไร

  • ghcr.io คือ รีจิสทรีที่รองรับ OCI สำหรับ อิมเมจคอนเทนเนอร์และ OCI artifact
  • เป็นส่วนหนึ่งของ GitHub และถูกใช้งานเป็น รีจิสทรียอดนิยม ในโอเพนซอร์สจำนวนมาก

ghrc.io: สิ่งที่เห็นบนผิวหน้า

  • เมื่อเข้า ghrc.io จะเห็นเพียง หน้าเริ่มต้นของ nginx
  • การทำงานพื้นฐาน เช่น ข้อผิดพลาด 404 ทั่วไป เหมือนกับเซิร์ฟเวอร์ nginx ปกติ

พฤติกรรมอันตรายที่แท้จริง

  • ปัญหาหลักจะปรากฏเมื่อมี การเรียก OCI API ภายใต้พาธที่ขึ้นต้นด้วย /v2/
  • เมื่อเข้าถึงเส้นทางนี้ จะพบ พฤติกรรมที่คล้ายกับคอนเทนเนอร์รีจิสทรีทางการอย่างมาก ผ่านการตอบกลับ 401 และ www-authenticate header
  • มี header www-authenticate: Bearer realm="https://ghrc.io/token";
  • เนื่องจาก header นี้ ไคลเอนต์อย่าง Docker, containerd, podman, Kubernetes เป็นต้น จะพยายาม ส่งข้อมูลยืนยันตัวตนของผู้ใช้โดยอัตโนมัติ ไปยัง https://ghrc.io/token
  • ในการตั้งค่าปกติของ nginx จะไม่มี header นี้ จึงถือว่า ถูกตั้งค่าขึ้นโดยเจตนาอย่างชัดเจน
โฆษณา

ความเสี่ยง: สถานการณ์การขโมยข้อมูลรับรอง

  • รูปแบบนี้ถูกมองว่าเป็น การโจมตีขโมยข้อมูลรับรองแบบ typo-squatting
  • ความเสี่ยงจะเกิดขึ้นเฉพาะเมื่อไคลเอนต์ของผู้ใช้ ป้อนหรือบันทึกข้อมูลรับรองไว้กับ ghrc.io
  • ตัวอย่างสถานการณ์ที่ข้อมูลรับรองจริงอาจถูกเปิดเผย
    • รัน docker login ghrc.io
    • ใช้ docker/login-action ใน GitHub Action แล้วกำหนดรีจิสทรีเป็น ghrc.io
    • บันทึกข้อมูลรับรองรีจิสทรีสำหรับ ghrc.io ไว้ใน Kubernetes secret แล้วพยายามดึงอิมเมจ
  • หากเพียงแค่ลอง push/pull อิมเมจไปที่ ghrc.io โดยไม่ได้ล็อกอิน ข้อมูลยืนยันตัวตนจะไม่รั่วไหล (จะลองใช้ anonymous token ก่อนแล้วจบด้วยข้อผิดพลาด)

วิธีรับมือ

  • หากเคย เผลอล็อกอินเข้า ghrc.io ควรเปลี่ยนรหัสผ่านทันที และเพิกถอน PAT (personal access token) ที่ใช้
  • ต้องตรวจสอบ การล็อกอินผิดปกติหรือกิจกรรมอันตราย ในบัญชี GitHub อย่างละเอียด
  • ผู้โจมตีอาจใช้สิ่งนี้เพื่อ เพิ่มอิมเมจอันตราย ไปยังรีโพซิทอรีบน ghcr.io หรือเข้าถึงบัญชีได้

บทสรุป

  • ควรระวัง เว็บไซต์ฟิชชิง ที่ใช้โดเมนคล้ายกับ ghcr.io
  • จำเป็นต้องมีนโยบายที่เข้มงวดยิ่งขึ้นในการจัดการ ข้อมูลความปลอดภัย เช่น ข้อมูลรับรอง โทเค็น และรหัสผ่าน

2 ความคิดเห็น

 
ndrgrd 2025-08-25

แค่เปลี่ยนไปใช้เป็นโดเมนย่อยของ github.com ก็น่าจะดีกว่าไหมครับ

 
GN⁺ 2025-08-25
ความเห็นใน Hacker News
  • เน้นย้ำว่านี่เป็นปัญหาร้ายแรง เพราะ GitHub Container registry ยังรองรับเฉพาะ classic token เดิม ไม่รองรับ token แบบแยกสิทธิ์ละเอียด
    แนบลิงก์เอกสารและลิงก์ issue ที่เกี่ยวข้องไว้ด้วย
    เอกสารทางการ
    การสนทนาในชุมชน
    roadmap issue

    • เพราะปัญหานี้จึงอยู่ในสถานการณ์ที่ปิด classic PAT ทั้งหมดไม่ได้
      มาตรการเสริมที่ทำได้คือกำหนดอายุ session ให้สั้นลงและบังคับยืนยันตัวตนซ้ำผ่าน enterprise SSO แต่สำหรับ classic PAT เดียวที่จำเป็นจริง ๆ ก็เป็นตัวเลือกที่ยุ่งยาก

    • คงจะดีถ้ามีใครซื้อ typo domain ทั้งหมดด้วยเจตนาดีแล้วส่งต่อให้ Microsoft
      คิดว่า Microsoft ควรเปลี่ยนชื่อ registry
      ชื่อนี้ทำให้สับสนมากจนฉันเองก็เคยพิมพ์ผิดหลายครั้ง

  • ต้องอ่านประเด็นเรื่องโดเมนอยู่หลายรอบกว่าจะเข้าใจปัญหาได้ จึงนับว่าเป็น attack vector ที่น่าเชื่อมากทีเดียว

    • ไม่ใช่มีแค่ฉัน หลายคนก็เหมือนกัน
      พยายามหลายครั้งแล้วก็ล้มเหลว แถมถึงขั้นรีสตาร์ตคอมพิวเตอร์แล้วก็ยังเจอปัญหาเดิม
      มีกรณีอ้างอิงอย่าง คำตอบใน Stack Overflow และ การสนทนาใน Docker forum
  • ยก ผลการค้นหาโค้ดที่เกี่ยวกับ ghrc.io มาเป็นลิงก์ประกอบ

  • ไม่ทันสังเกตปัญหาจนกว่าบทความจะชี้ตรง ๆ ว่า c กับ r สลับกัน

    • การพิมพ์ผิดแบบนี้เป็นประเภทที่ฉันทำเกือบเกิน 10 ครั้งต่อวัน

    • ปัญหาตรงนี้คือชื่อโดเมนของ GitHub มันแย่มาก
      ชื่อ container registry นั้นแย่จริง ๆ

  • แชร์ ลิงก์การสนทนาใน Hacker News ก่อนหน้านี้

  • ตรวจสอบด้วย whois ได้ว่าโดเมนนี้จดทะเบียนกับ dynadot
    ดังนั้นการแจ้งไปที่ abuse@dynadot.com น่าจะมีประโยชน์

  • กล่าวถึงว่าโปรเจกต์โอเพนซอร์สจำนวนมากใช้โดเมนนี้อยู่ พร้อมแชร์ ผลการค้นหาโค้ด อีกครั้ง

    • ภายใน GitHub เองควรมีเครื่องมือที่สามารถเสนอและปล่อยการแก้ไขอัตโนมัติแบบจำนวนมากได้

    • กล่าวด้วยว่าผลการค้นหาโค้ดใน GitHub มีขนาดใหญ่พอสมควรจริง ๆ

  • แสดงความกังวลว่าถ้าพิมพ์ผิดในงาน CI อาจก่อปัญหาใหญ่ได้

  • แนะนำว่าควรหลีกเลี่ยงการใช้ TLD ที่มีคุณค่าด้านความปลอดภัยต่ำถ้าเป็นไปได้
    ความปลอดภัยควรมาก่อนความพยายามทำให้น่ารัก
    การถอดทะเบียนโดเมนอันตรายอาจไม่รวดเร็วเท่า .com จึงรู้สึกว่า .com ที่ Verisign ในสหรัฐฯ ดูน่าเชื่อถือกว่า
    การไปพึ่งพา British Indian Ocean Territory, โคลอมเบีย หรือแองกวิลลา นั้นไม่เหมาะสม

    • เสริมว่า .io TLD อยู่ภายใต้การดูแลของ Afilias ซึ่งเป็นบริษัทสหรัฐฯ
  • ถามว่าความเสี่ยงที่แท้จริงตรงนี้คือปัญหาการนำ token กลับมาใช้ซ้ำหรือไม่
    Bearer token ไม่ได้ส่งรหัสผ่านโดยตรง และอ้างถึงเอกสาร RFC กับ Mozilla พร้อมสงสัยว่าปัญหาจริง ๆ คือขั้นตอนการขอ token ใหม่เพื่อใช้ยืนยันตัวตน ไม่ใช่ตัว authentication token เองหรือเปล่า
    ถ้า OAuth ข้ามโดเมนไม่ reuse token สุดท้ายโดเมนปลอมก็น่าจะรับ token ไม่ได้อยู่แล้วไม่ใช่หรือ

    • ผู้เขียนบล็อกและผู้ดูแล OCI ตอบว่า
      ในคำขอเพื่อรับ Bearer token จะส่งรหัสผ่านหรือ PAT ใน basic auth header โดยเข้ารหัสแบบ base64 แต่โดยสาระแล้วก็คือส่งเป็นข้อความปกติ
      เมื่อฝั่งปลายทางรับคำขอ จะเกิด www-authenticate header แล้วจึงรับ authentication token มาเพื่อตรวจสอบสิทธิ์เข้าถึง registry จากนั้น token จะหมดอายุ
      ดังนั้นโครงสร้างของปัญหาไม่ใช่ว่าผู้โจมตีขโมย token ตัวจริง แต่เป็นการหลอกให้ส่ง credential เองเพื่อใช้ในการขอ Bearer token