GnuTLS แก้ไขข้อผิดพลาดการจัดการหน่วยความจำผิดพลาด – อัปเดตทันที!

โหนดต้นทาง: 1603833

ห้องสมุดเข้ารหัสที่รู้จักกันดีที่สุดในโลกโอเพ่นซอร์สนั้นเกือบจะแน่นอน OpenSSL.

ประการแรก มันเป็นหนึ่งในโปรแกรมที่ใช้กันอย่างแพร่หลายมากที่สุด จนถึงจุดที่นักพัฒนาส่วนใหญ่บนแพลตฟอร์มส่วนใหญ่เคยได้ยินเกี่ยวกับมัน แม้ว่าจะไม่ได้ใช้งานโดยตรงก็ตาม

ประการที่สอง มันอาจจะเป็นที่แพร่หลายมากที่สุด น่าเสียดายเพราะแมลงที่น่ารังเกียจที่เรียกว่า Heartbleed ที่ถูกค้นพบเมื่อแปดกว่าปีที่แล้ว

แม้จะได้รับการแก้ไขโดยทันที (และถึงแม้จะมีวิธีแก้ปัญหาที่เชื่อถือได้สำหรับนักพัฒนาที่ไม่สามารถหรือไม่สามารถอัปเดตเวอร์ชัน OpenSSL ที่มีช่องโหว่ได้อย่างรวดเร็ว) Heartbleed ยังคงเป็นบั๊ก "โชว์เคส" อย่างน้อยก็เพราะเป็นหนึ่งในบั๊กแรกๆ กลายเป็นยานพาหนะประชาสัมพันธ์เชิงรุกโดยผู้ค้นพบ

ด้วยชื่อที่น่าประทับใจ โลโก้ทั้งหมด และเว็บไซต์เฉพาะ Heartbleed จึงกลายเป็นการรักษาความปลอดภัยทางไซเบอร์ระดับโลกอย่างรวดเร็ว ซุปเปอร์สตอรี่และไม่ว่าจะดีขึ้นหรือแย่ลงก็เชื่อมโยงอย่างแยกไม่ออกกับการกล่าวถึงชื่อ OpenSSLราวกับว่าจุดบกพร่องยังคงมีอยู่แม้จะถูกตัดออกจากโค้ดแล้วก็ตาม

ชีวิตที่เหนือกว่า OpenSSL

แต่มีไลบรารีเข้ารหัสโอเพนซอร์ซอื่น ๆ อีกหลายแห่งที่ใช้กันอย่างแพร่หลายเช่นเดียวกับหรือแทนที่ OpenSSL โดยเฉพาะอย่างยิ่งของ Mozilla เอ็นเอส (ย่อจาก บริการรักษาความปลอดภัยเครือข่าย) และ . ของโปรเจ็กต์ GNU gnuTLS ห้องสมุด.

เมื่อมันเกิดขึ้น GnuTLS เพิ่งแก้ไขจุดบกพร่องที่เรียกว่า CVE-2022-2509, รายงานใน . ของโครงการ ที่ปรึกษาด้านความปลอดภัย กนุตส์-SA-2022-07-07.

แพตช์นี้แก้ไขข้อผิดพลาดการจัดการหน่วยความจำที่ไม่ถูกต้องซึ่งเรียกว่า a ฟรีสองเท่า.

อธิบายฟรีสองเท่า

พูดง่ายๆ ก็คือ ช่องโหว่ double-free ถูกสร้างขึ้นเมื่อโปรแกรมเมอร์ขอให้ระบบปฏิบัติการจัดสรรบล็อกของหน่วยความจำเพื่อใช้ชั่วคราว...

…และส่งคืนให้ลบออกจากรายการบล็อกที่ยืมมาเพื่อให้ส่วนอื่นๆ ของโปรแกรมใช้งานได้...

…จากนั้นก็ขอให้ระบบว่างบล็อกหน่วยความจำเดิมซ้ำอีกครั้งโดยไม่ได้ตั้งใจ

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

การจัดการเบา ๆ กับ double-free ที่ตรวจพบในเชิงรุกเป็นปัญหาที่ยุ่งยาก ฟังก์ชัน C ที่ส่งกลับหน่วยความจำนั้นสร้างต้นแบบเป็น void free(void *ptr); เพื่อให้คุณส่งที่อยู่ของบล็อกที่คุณต้องการทำให้ว่าง แต่ไม่ได้รับรหัสส่งคืน (ฟังก์ชัน AC กับ a void ค่าที่ส่งคืนคือสิ่งที่ภาษาโปรแกรมอื่นเรียกว่าa procedure: มันทำบางอย่างให้คุณ แต่ไม่มีวิธีรายงานผลลัพธ์) ดังนั้นแม้แต่โค้ด C ที่เขียนอย่างระมัดระวังก็ไม่มีวิธีมาตรฐานในการตรวจหาว่ามีบางอย่างผิดปกติ free()ดังนั้นจึงไม่มีทางจัดการกับข้อผิดพลาดด้วยการพยายามปิดอย่างสง่างาม การยุติโปรแกรมที่กระทำผิดเพียงฝ่ายเดียวเป็นวิธีแก้ปัญหาที่ปลอดภัยเพียงระบบเดียวสำหรับระบบ

แต่ถ้าหน่วยความจำที่จัดสรรไม่รู้ตัว (อาจเป็นเพราะว่าบล็อกเดียวกันนั้นได้ถูกส่งต่อไปยังส่วนอื่นของโปรแกรมเดียวกัน ดังนั้นมันจึงกลับมาอยู่ในรายการ "ยืมออก" ในรูปแบบเดียวกับที่เคยเป็นมา) แล้วสิ่งเลวร้ายมักจะเกิดขึ้น

โดยเฉพาะอย่างยิ่ง ตัวจัดการหน่วยความจำอาจ "ยึด" บล็อกแบบ double-freed โดยไม่ตั้งใจและโดยไม่คาดคิดจากโค้ดที่ตอนนี้ใช้งานอย่างถูกต้อง และกำหนดใหม่ให้กับส่วนอื่นของโปรแกรม อาจเป็นโค้ดอันตรายที่ผู้โจมตีได้กำหนดเวลาไว้อย่างรอบคอบเพื่อใช้ประโยชน์ ของการจัดการที่ผิดพลาด

ดังนั้น คุณอาจลงเอยด้วยสองส่วนของโปรแกรมเดียวกันที่จัดการหน่วยความจำชุดเดียวกัน

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

ในเวลาเดียวกัน อีกส่วนหนึ่งของโปรแกรมรู้ว่ามันสามารถยุ่งกับข้อมูลได้ (หรืออาจถูกหลอกให้เข้าไปยุ่งกับมัน) เพื่อที่จะสะดุดส่วนแรกอย่างจงใจ

ทำผิดก็ทำในสิ่งที่ถูก

ที่น่าแปลกคือ มีจุดบกพร่อง CVE-2022-2509 ในรหัสการตรวจสอบใบรับรองใน GnuTLS

(ในกรณีที่คุณสงสัยว่าจะประชดคือซอฟต์แวร์นั้นโดยทั่วไปไม่ปลอดภัยเพราะไม่ต้องคอยตรวจสอบการเชื่อมต่อ TLS ที่น่าเชื่อถือนั้นไม่มีภูมิคุ้มกันต่อจุดบกพร่องด้านความปลอดภัยเฉพาะนี้)

ตัวอย่างเช่น เมื่อคุณเยี่ยมชมเว็บไซต์ (หรือเซิร์ฟเวอร์ประเภทอื่น) ที่มีการรักษาความปลอดภัยด้วย TLS ปลายทางอื่นมักจะส่งใบรับรองเว็บที่ยืนยันว่าเซิร์ฟเวอร์เป็นเจ้าของและดำเนินการโดยองค์กรที่คุณคาดหวังจริงๆ

แน่นอน เนื่องจากทุกคนสามารถสร้างใบรับรองในชื่อใดก็ได้ที่พวกเขาต้องการ ใบรับรองดิบโดยตัวมันเองไม่ได้บอกคุณมาก ดังนั้นเจ้าของใบรับรองมักจะได้รับการเซ็นชื่อแบบดิจิทัลโดยบริษัทที่เบราว์เซอร์ของคุณเชื่อถืออยู่แล้ว

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

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

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

ในกรณีดังกล่าว GnuTLS จะตรวจสอบใบรับรองที่ให้มาอย่างถูกต้องและปลอดภัย ก่อนที่จะเพิ่มพื้นที่ว่างในบล็อกหน่วยความจำที่ใช้จัดเก็บ

แต่ถ้าปลายอีกด้านหนึ่งไม่ได้จัดเตรียมชุดใบรับรองที่สร้างไว้ล่วงหน้า ดังนั้นจึงปล่อยให้ GnuTLS สร้างและตรวจสอบสายโซ่ด้วยตัวเอง รหัส GnuTLS จะทำให้หน่วยความจำที่ใช้เก็บใบรับรองที่ให้มาโดยไม่ตั้งใจก่อนที่จะเริ่มสาย ขั้นตอนการตรวจสอบ…

…จากนั้นเพิ่มพื้นที่ว่างอีกครั้งหลังจากการตรวจสอบเสร็จสิ้น

สิ่งนี้ทำให้เกิดอุบัติเหตุซ้ำสองครั้ง ซึ่งอาจนำไปสู่ความเสียหายของหน่วยความจำ ตามด้วยโปรแกรมหยุดทำงาน

สกัดกั้นความผิดพลาดเพื่อฝังมัลแวร์

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

ในกรณีนี้ การขัดข้องจะทำให้เกิดข้อผิดพลาดของระบบ และแม้ว่าบั๊กประเภทนี้อาจถูกนำไปใช้ในทางที่ผิดสำหรับสิ่งที่เรียกว่า Denial of Service การโจมตี (DoS) ซึ่งเป้าหมายทั้งหมดเป็นเพียงเพื่อขัดขวางโปรแกรมที่ถูกโจมตี จะไม่นำไปสู่ การดำเนินการโค้ดจากระยะไกล (RCE) โดยที่โค้ดซอฟต์แวร์ที่ไม่น่าเชื่อถือและไม่พึงประสงค์จะถูกเรียกใช้แทน

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

อย่างที่คุณจินตนาการได้ ผู้โจมตีมักจะใช้ประโยชน์จากช่องโหว่ดังกล่าวเพื่อฝังมัลแวร์ ไม่ว่าจะชั่วคราวหรือถาวร เนื่องจากพวกเขาจะต้องใส่รหัสที่ไม่น่าเชื่อถือลงในคอมพิวเตอร์ของคุณโดยไม่แสดงคำเตือนป๊อปอัปเพื่อขออนุญาตก่อน

จะทำอย่างไร?

อัปเดตเป็นไฟล์ รุ่นล่าสุด ของ GnuTLS ซึ่งก็คือ 3.7.7 ในขณะที่เขียน

(จุดบกพร่องนี้เปิดตัวใน GnuTLS 3.6.0 อย่างเห็นได้ชัด และมีอยู่ในทุกเวอร์ชันนับจากนั้น จนถึงและรวมถึง 3.7.6)

โปรดทราบว่าแอปพลิเคชั่นและชุดเครื่องมือการเขียนโปรแกรมยอดนิยมจำนวนมากอาจมีหรือสร้างขึ้นเพื่อใช้ GnuTLS แม้ว่าคุณอาจไม่ทราบ ซึ่งรวมถึงแต่ไม่จำกัดเพียง: FFmpeg, GnuPG, Mplayer, QEMU, Rdesktop, Samba, Wget, Wireshark และ Zlib

แพ็คเกจ Linux หรือ *BSD จำนวนมากที่ใช้ GnuTLS จะใช้เวอร์ชันกลางที่จัดการโดย distro ของคุณ ดังนั้นโปรดอัปเดตทันทีที่ distro ของคุณมีเวอร์ชันนี้ให้ใช้งานได้

มีความสุขในการปะ!


ประทับเวลา:

เพิ่มเติมจาก ความปลอดภัยเปล่า