บั๊กรีเซ็ตรหัสผ่าน GitLab ทำให้เซิร์ฟเวอร์กว่า 5,300 เครื่องเสี่ยง
(scmagazine.com)- ช่องโหว่ CVE-2023-7028 ของ GitLab ยังคงหลงเหลืออยู่ในเซิร์ฟเวอร์ 5,379 เครื่องทั่วโลก แม้ผ่านไปราว 2 สัปดาห์หลังเผยแพร่แพตช์ และอาจนำไปสู่การยึดบัญชีนักพัฒนาจากระยะไกล
- ปัญหาอยู่ใน โฟลว์รีเซ็ตรหัสผ่าน ของระบบล็อกอิน โดยผู้โจมตีสามารถทำให้ลิงก์รีเซ็ตถูกส่งไปยังที่อยู่อีเมลที่ยังไม่ได้ยืนยันของตนเองได้ โดยไม่ต้องให้เหยื่อมีปฏิสัมพันธ์ใด ๆ
- GitLab เปิดเผยช่องโหว่ที่มีคะแนน CVSS 10 เมื่อวันที่ 11 มกราคม 2024 และให้การอัปเดตความปลอดภัยสำหรับเวอร์ชัน 16.5.6, 16.6.4, 16.7.2 และเวอร์ชันแบ็กพอร์ต 16.1.6~16.4.5
- Shadowserver Foundation ตรวจพบอินสแตนซ์ที่มีช่องโหว่ 5,379 รายการเมื่อวันที่ 23 มกราคม โดยสหรัฐฯ มีมากที่สุด 964 รายการ และเยอรมนี 730 รายการ ก่อนลดลงเหลือ 4,652 รายการในวันที่ 24 มกราคม
- ผู้ดูแล GitLab Community Edition และ Enterprise Edition แบบ self-managed ควรตรวจสอบคำขอรีเซ็ตในล็อกจากรูปแบบ อาร์เรย์อีเมลหลายรายการ และเปิดใช้ 2FA เพื่อลดความเสี่ยงจากการยึดบัญชี
ความเสี่ยงของ CVE-2023-7028
- CVE-2023-7028 เป็นช่องโหว่ในระบบล็อกอินของ GitLab ซึ่งอาจนำไปสู่การยึดบัญชีจากระยะไกลบนเซิร์ฟเวอร์ GitLab ที่ยังไม่ได้แพตช์
- GitLab เปิดเผยและแพตช์ช่องโหว่นี้ครั้งแรกเมื่อวันที่ 11 มกราคม 2024
- คะแนน CVSS คือ 10 ซึ่งเป็นระดับความรุนแรงสูงสุด
- ผู้โจมตีสามารถใช้คำขอ HTTP ที่สร้างขึ้นเป็นพิเศษ เพื่อส่งอีเมลรีเซ็ตรหัสผ่านไปยังที่อยู่อีเมลที่ยังไม่ได้ยืนยันของตนเองได้ โดยไม่ต้องให้เหยื่อมีปฏิสัมพันธ์ใด ๆ
- นักวิจัยรายหนึ่งที่ทดสอบกับ GitLab Community Edition 16.6.1 ประเมินบน AttackerKB ว่า CVE-2023-7028 “มีประสิทธิภาพสูงและโจมตีได้ง่ายมาก”
เวอร์ชันที่ได้รับผลกระทบและแพตช์
- GitLab ให้ การอัปเดตความปลอดภัย สำหรับเวอร์ชันต่อไปนี้
- 16.5.6
- 16.6.4
- 16.7.2
- แพตช์ยังถูก แบ็กพอร์ต ไปยังเวอร์ชันต่อไปนี้ด้วย
- 16.1.6
- 16.2.9
- 16.3.7
- 16.4.5
ผลการตรวจพบของ Shadowserver
- Shadowserver Foundation ตรวจพบ อินสแตนซ์ GitLab ที่มีช่องโหว่ 5,379 รายการ ทั่วโลกเมื่อวันที่ 23 มกราคม หรือราว 2 สัปดาห์หลังเผยแพร่แพตช์
- แยกตามประเทศ สหรัฐฯ และเยอรมนีมีอินสแตนซ์ที่มีช่องโหว่มากที่สุด
- สหรัฐฯ: 964 รายการ
- เยอรมนี: 730 รายการ
- เมื่อวันที่ 24 มกราคม จำนวนอินสแตนซ์ที่มีช่องโหว่บนแดชบอร์ดของ Shadowserver ลดลงเหลือ 4,652 รายการ
- Shadowserver ยืนยันว่าการลดลงถือเป็นสัญญาณเชิงบวก แต่ยังต้องใช้เวลาเพิ่มเติมเพื่อพิจารณาว่าเป็นแนวโน้มจริงหรือเป็นความผันผวนชั่วคราวจากการสแกน
วิธีตรวจสอบตัวบ่งชี้การถูกเจาะระบบ
- ลูกค้า GitLab Community Edition และ GitLab Enterprise Edition แบบ self-managed ควรตรวจสอบ ร่องรอยการใช้ประโยชน์จาก CVE-2023-7028 ในล็อก
- ล็อกและเงื่อนไขที่ต้องตรวจสอบมีดังนี้
gitlab-rails/production_json.log: กรณีที่params.value.emailเป็นอาร์เรย์ JSON ที่มีที่อยู่อีเมลหลายรายการ ในคำขอ HTTP ที่เข้ามายังพาธ/users/passwordgitlabs-rails/audit_json.log: กรณีที่meta.caller.idเป็นPasswordsController#createและtarget_Detailsเป็นอาร์เรย์ JSON ที่มีที่อยู่อีเมลหลายรายการ
ผลกระทบต่อ GitLab.com, GitLab Dedicated และ 2FA
- GitLab ระบุว่ายังไม่พบกรณีที่มีการใช้บั๊กนี้โจมตีบนอินสแตนซ์ GitLab.com หรือ GitLab Dedicated
- แนะนำให้ลูกค้า เปิดใช้ 2FA
- 2FA สามารถป้องกันการยึดบัญชีผ่าน CVE-2023-7028 ได้ แต่บนอินสแตนซ์ที่ยังไม่ได้แพตช์ ผู้โจมตียังสามารถรีเซ็ตรหัสผ่านเพื่อทำให้ผู้ใช้ถูกล็อกออกจากบัญชีได้
1 ความคิดเห็น
ความเห็นจาก Hacker News
ผมมองว่าความสามารถในการ ผูกที่อยู่อีเมลเข้ากับบัญชี ในเว็บแอปที่อิงกับบัญชีนั้นน่ากลัวมาก
ไม่รู้ประวัติของบั๊กนี้ แต่เป็นจุดที่ผู้ทดสอบเจาะระบบมักจะลองก่อนทันที และเป็นช่องโหว่เก่าแก่ที่ย้อนกลับไปได้ถึงบั๊กในมาตรฐานการติดตั้ง Unix MTA ช่วงต้นยุค 2000 ที่หลอกให้ระบบส่งอีเมลรีเซ็ตรหัสผ่านไปหลายที่อยู่ได้
ดูเหมือนว่าใน GitLab เว็บเฟรมเวิร์กที่มีฟีเจอร์มากมายได้ทำให้พื้นผิวการโจมตีนี้กลับมาอีกครั้ง และถ้าผู้อ่าน HN ทั่วไปสนใจเรื่องนี้ ก็ควรไปตรวจสอบฟังก์ชันรีเซ็ตรหัสผ่าน โดยเฉพาะ ลอจิกการผูกอีเมล ให้ดี
ผมเข้าใจว่าทีมความปลอดภัยของ GitLab ค่อนข้างเก่ง แต่การที่ยังมีบั๊กแบบนี้หลุดออกมา ก็แสดงให้เห็นว่าการหลีกเลี่ยงบั๊กตระกูลนี้ยากแค่ไหน
ถ้าใช้ ภาษาแบบ static type ก็คงเกิดได้ยาก เว้นแต่ตั้งใจทำให้เป็นแบบนี้ และใน code review มันก็น่าจะเด่นชัดมากจนเพื่อนร่วมงานอาจสงสัยด้วยซ้ำว่ากำลังพยายามฝัง backdoor หรือเปล่า
ฟีเจอร์ การผูกอีเมลสำรอง เพิ่งถูกเพิ่มเข้ามาไม่นาน และไม่ใช่สิ่งที่มีมาตั้งแต่แรก จึงดูเหมือนว่าพวกเขาเลือกทางลัดโดยไม่ทดสอบการนำไปใช้ในทางที่ผิดของฟีเจอร์ใหม่ที่เกี่ยวกับความปลอดภัยของบัญชีอย่างเหมาะสม
นอกจากนี้ก็ดูเหมือนจะเคยมี CVE ระดับ CVSS 9.6 ที่ทำให้ฟังก์ชัน integration สามารถรันคำสั่งด้วยสิทธิ์ของผู้ใช้อื่นได้ด้วย
จากมุมคนนอก ดูเหมือนความเร็วในการปล่อยฟีเจอร์จะนำหน้าความเร็วที่สามารถทดสอบความปลอดภัยได้ และอาจเป็นเพราะทำรายได้ได้ยาก
ในมุมธุรกิจก็พอเข้าใจได้ แต่ถ้าแก่นของโซลูชัน Git แบบโฮสต์เองจริง ๆ คือการจัดการบัญชีผู้ใช้ ปัญหาความปลอดภัยแบบนี้ก็อาจทำลายตัวธุรกิจเองได้
ถ้าไม่ผูกกับอีเมล แล้วจะให้ผูกกับอะไร? ผมดูแลเว็บไซต์ที่มีฐานผู้ใช้ขนาดใหญ่มากว่า 20 ปี ตอนแรกใช้ชื่อผู้ใช้ แล้วมันหายนะมาก
ทุกคนรู้ชื่อผู้ใช้ของกันและกันอยู่แล้ว เลยทำให้การเดารหัสผ่านแบบ brute force หรือการพยายามรีเซ็ตทำได้ง่าย
ปัญหาไม่ใช่การใช้อีเมล แต่เป็นการทำให้ลอจิกล็อกอินและกู้รหัสผ่านซับซ้อนเกินจำเป็น ใช้ abstraction มากเกินไป ออกแบบเกินเหตุ และยัดโค้ดเข้าไปในส่วนที่อ่อนไหวด้านความปลอดภัยโดยตรวจสอบไม่ดีพอ
ควรไปดูประวัติด้านความปลอดภัยของ GitLab ด้วย มี exploit ระดับร้ายแรงออกมาหลายครั้งต่อปีจนต้องอัปเกรด GitLab deployment แบบฉุกเฉิน และในแง่ความปลอดภัย GitLab แย่ที่สุด ในบรรดาผลิตภัณฑ์ที่ผมเคยใช้
เรื่องนี้ยังไม่เคยเกิดกับผม แต่จากกรณีนี้ก็เห็นได้ว่ามันเป็นไปได้จริงอย่างน่าเสียดาย
ถ้าอยากดูว่าในโค้ดเบสของ Rails ส่วนไหนนำไปสู่ exploit นี้ commit ที่แก้ไขอยู่ตรงนี้
https://gitlab.com/gitlab-org/gitlab/-/commit/c571840ba2f0e9...
ตัวแก้น่าจะอยู่ตรงนี้: https://gitlab.com/gitlab-org/gitlab/-/commit/abe79e4ec43798...
เปลี่ยนจาก
recoverable.send_reset_password_instructions(to: email) if recoverable&.persisted?เป็นrecoverable.send_reset_password_instructions if recoverable&.persisted?# Concern that overrides the Devise methods/# to send reset password instructions to any verified user email/module RecoverableByAnyEmailนี่หมายความว่ามันเป็น ฟีเจอร์ เหรอ?แต่ถึงอย่างนั้นในเวอร์ชันที่แก้แล้วก็ยังใช้ชื่อ
RecoverableByAnyEmailอยู่ดี คนเราไม่อ่านโค้ดรอบ ๆ ส่วนที่ตัวเองแก้กันหรือไง?เราก็โดนการโจมตีนี้เหมือนกัน และยังเห็นว่ามันถูกใช้ร่วมกับ “ฟีเจอร์” ตัวที่สองที่ทำให้การเปิดเผยข้อมูลหนักขึ้นอีก
โดยพื้นฐานแล้ว การโจมตีนี้ต้องรู้จักอีเมลของผู้ใช้ที่ต้องการรีเซ็ตก่อน แต่ใน GitLab มีที่อยู่อีเมลที่ซ่อนอยู่ซึ่งผูกกับ user ID และ ID นี้เป็นตัวเลขเพิ่มขึ้นจาก 1
ID 1 หรือ 2 มักจะเป็นแอดมิน จึงเป็นเป้าหมายที่ดี และอีเมลจะมีรูปแบบอย่าง
1-user@mail.noreply..มันแย่มากและดูเหมือนเป็นการทำแบบอัตโนมัติ ที่นี่ 2FA ช่วยไว้
การรีเซ็ตรหัสผ่านผ่านอีเมล เป็นฝันร้ายด้านความปลอดภัย แม้จะทำได้ถูกต้องก็ตาม
ที่แย่กว่าคือบริการส่วนใหญ่ก็ปิดไม่ได้ และถ้าจะเลี่ยงก็มักมีแค่ Enterprise SSO
บางบริการให้ตั้งหมายเลขโทรศัพท์สำหรับ SMS token ได้ แต่ผมยังไม่เคยเห็นแบบที่บังคับทั้งอีเมลและ SMS token พร้อมกัน
ทำให้นึกถึงบั๊กที่ถ้าใส่อาร์เรย์ของรหัสผ่านลงในฟอร์มล็อกอิน ก็ brute force บัญชีได้
บังเอิญมันเป็นเว็บอินเทอร์เฟซห่วย ๆ ของอุปกรณ์ส่งสแปม ไม่รู้ว่าตั้งใจทำหรือเป็นโค้ดจากมือใหม่ PHP
ตอนนั้นมีผู้ใช้ที่ตั้งรหัสผ่านมีอักขระพิเศษซึ่งยังไม่ค่อยพบกันนัก แล้วเป็นคนไปเจอบั๊กนี้เข้า
.where(...)มันจะตีความค่าหลายค่าในอาร์เรย์เป็น เงื่อนไข ORเพราะงั้นถ้าโค้ดเป็นอะไรอย่าง
User.where(name: name, password: password)ก็พอจะเห็นได้เลยว่ามันอาจทำให้เกิดเรื่องแบบนี้ได้นี่เป็นเครื่องเตือนใจที่ดีว่าบริการภายในอย่าง GitLab ควรถูกวางไว้ หลัง VPN เพื่อให้มีแต่ผู้ใช้ที่เชื่อถือได้เท่านั้นที่เข้าถึงได้
VPN ก็มีไว้เพื่อสิ่งนี้โดยตรง
ผมทำงานที่บริษัทโทรคมนาคมของรัฐขนาดใหญ่ และทีมดูแลเครือข่ายเก่งมาก พวกเขาคอยกันไม่ให้ฝั่งดูแลเซิร์ฟเวอร์ล้ำเส้น
เราเปิด GitLab ไว้บางส่วนสำหรับโปรเจ็กต์ภายนอกบางงานและที่ปรึกษา แต่ก็ยังไม่ถึงขั้นให้เข้าจากอินเทอร์เน็ตได้อย่างอิสระ
ผู้ใช้ก็ถูกจัดการผ่าน AD อยู่แล้ว จึงไม่มีการเชื่อมต่อ SMTP สำหรับรีเซ็ตรหัสผ่านเลย
แต่ การบังคับใช้ 2FA ยังต้องเข้มขึ้นอีก ตอนนี้ยังปล่อยให้แต่ละโปรเจ็กต์กำหนดกฎ 2FA กันเองอยู่
พูดตามตรง ผมคงไม่เอาเซิร์ฟเวอร์ภายในตัวไหนไปไว้บนอินเทอร์เน็ตสาธารณะ
ให้เข้าผ่าน VPN เท่านั้นเพื่อมี แนวป้องกันชั้นที่สอง จะดีกว่า
จะทำ allowlist เฉพาะคำขอแบบนั้นก็ได้เหมือนกัน แต่ก็ค่อนข้างยุ่งยาก
ถ้าเป็นสภาพแวดล้อมที่ต้องการความปลอดภัยสูง ผมก็เห็นด้วยกับการใช้ยุทธวิธีที่ตั้งรับมากขึ้น แต่ผมก็คิดว่าซอฟต์แวร์ควรถูกออกแบบมาให้รับมือได้แม้อยู่บน เว็บสาธารณะ
การทำ GitLab update แบบอัตโนมัตินั้นง่ายมากจริง ๆ
เอาแค่วิธีเดียวก็พอ ถ้าใช้ GitLab กับ Docker+Compose มันเสถียรมาก และใช้เครื่องมืออย่าง Watchtower ให้อัปเดตทุกวันได้
ผมมีเซิร์ฟเวอร์ GitLab สองเครื่องที่รันแบบนี้มานานกว่า 7 ปีแล้วโดยไม่เคยมีปัญหาอะไร
มองไปรอบ ๆ แล้วเห็น GitLab เก่า ๆ เยอะเกินไป จนไม่รู้ว่าผู้ดูแลระบบกำลังทำอะไรกันอยู่
อยากให้เลิกแกล้งทำว่า Ruby/Rails เป็นตัวเลือกที่ดีสำหรับซอฟต์แวร์ที่ต้องปลอดภัยได้แล้ว
ผมเข้าใจว่า GitLab เป็นแบบนั้นไปแล้วก็ต้องรับสภาพ แต่ต่อจากนี้ช่วยเลิกทำเหมือนว่าภาษาและเฟรมเวิร์กที่เน้นความฉลาดแพรวพราวกับ hidden control flow ดีกว่าทางเลือกที่น่าเบื่อกว่าเสียที
ถ้าฟังดูเหมือนผมหงุดหงิดเกินไป นั่นก็เพราะผมต้องรับมือกับโค้ดเบส Ruby ที่ใช้งานจริงอยู่
มีหลายสถานการณ์มากที่ดูเหมือนกำลังรอให้ปัญหาคล้าย ๆ กันถูกนำไปใช้โจมตี เพียงเพราะมีใครบางคนคิดว่า abstraction 17 ชั้น จะทำให้โค้ดขยายต่อได้สุดยอด
ความเสียหายจากความผิดพลาดครั้งเดียวนี้อาจสูงกว่าคุณค่าทั้งหมดที่ได้จากความสามารถนั้นเสียอีก
เป็นอีกครั้งที่ย้ำเตือนว่าให้ใช้ SSO และ 2FA ตลอดเวลา