สงสัยว่า ghrc.io เป็นเว็บไซต์อันตราย
(bmitch.net)- ความสับสนระหว่าง 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-authenticateheader - มี 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 ความคิดเห็น
แค่เปลี่ยนไปใช้เป็นโดเมนย่อยของ github.com ก็น่าจะดีกว่าไหมครับ
ความเห็นใน 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, โคลอมเบีย หรือแองกวิลลา นั้นไม่เหมาะสม
ถามว่าความเสี่ยงที่แท้จริงตรงนี้คือปัญหาการนำ token กลับมาใช้ซ้ำหรือไม่
Bearer token ไม่ได้ส่งรหัสผ่านโดยตรง และอ้างถึงเอกสาร RFC กับ Mozilla พร้อมสงสัยว่าปัญหาจริง ๆ คือขั้นตอนการขอ token ใหม่เพื่อใช้ยืนยันตัวตน ไม่ใช่ตัว authentication token เองหรือเปล่า
ถ้า OAuth ข้ามโดเมนไม่ reuse token สุดท้ายโดเมนปลอมก็น่าจะรับ token ไม่ได้อยู่แล้วไม่ใช่หรือ
ในคำขอเพื่อรับ Bearer token จะส่งรหัสผ่านหรือ PAT ใน basic auth header โดยเข้ารหัสแบบ base64 แต่โดยสาระแล้วก็คือส่งเป็นข้อความปกติ
เมื่อฝั่งปลายทางรับคำขอ จะเกิด
www-authenticateheader แล้วจึงรับ authentication token มาเพื่อตรวจสอบสิทธิ์เข้าถึง registry จากนั้น token จะหมดอายุดังนั้นโครงสร้างของปัญหาไม่ใช่ว่าผู้โจมตีขโมย token ตัวจริง แต่เป็นการหลอกให้ส่ง credential เองเพื่อใช้ในการขอ Bearer token