ช่องโหว่รูทในเคอร์เนล Linux และการปฏิเสธการให้บริการใน systemd

นักวิจัยด้านความปลอดภัยจาก Qualys ได้เปิดเผยรายละเอียดของช่องโหว่ 2021 รายการที่ส่งผลกระทบต่อเคอร์เนล Linux และตัวจัดการระบบ systemd ช่องโหว่ในเคอร์เนล (CVE-33909-XNUMX) ช่วยให้ผู้ใช้ภายในเครื่องสามารถเรียกใช้โค้ดด้วยสิทธิ์รูทผ่านการจัดการไดเร็กทอรีที่ซ้อนกันสูง

อันตรายของช่องโหว่นั้นรุนแรงขึ้นจากการที่นักวิจัยสามารถเตรียมช่องโหว่ในการทำงานที่ทำงานบน Ubuntu 20.04/20.10/21.04, Debian 11 และ Fedora 34 ในการกำหนดค่าเริ่มต้น มีข้อสังเกตว่าการกระจายอื่นๆ ยังไม่ได้รับการทดสอบ แต่ในทางทฤษฎีก็มีความอ่อนไหวต่อปัญหาเช่นกันและสามารถถูกโจมตีได้ รหัสแบบเต็มของช่องโหว่นี้สัญญาว่าจะเผยแพร่หลังจากปัญหาหมดไปทุกที่ แต่ขณะนี้มีเพียงต้นแบบของฟังก์ชันการทำงานที่จำกัดเท่านั้น ส่งผลให้ระบบล่ม ปัญหานี้เกิดขึ้นตั้งแต่เดือนกรกฎาคม 2014 และส่งผลต่อการเผยแพร่เคอร์เนลตั้งแต่เวอร์ชัน 3.16 การแก้ไขช่องโหว่ได้รับการประสานงานกับชุมชนและได้รับการยอมรับในเคอร์เนลเมื่อวันที่ 19 กรกฎาคม การแจกแจงหลักได้สร้างการอัปเดตแพ็คเกจเคอร์เนลแล้ว (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch)

ช่องโหว่นี้เกิดจากความล้มเหลวในการตรวจสอบผลลัพธ์ของการแปลง size_t เป็น int ก่อนที่จะดำเนินการในโค้ด seq_file ซึ่งสร้างไฟล์จากลำดับของบันทึก ความล้มเหลวในการตรวจสอบอาจส่งผลให้มีการเขียนนอกขอบเขตไปยังบัฟเฟอร์เมื่อสร้าง ติดตั้ง และลบโครงสร้างไดเร็กทอรีที่ซ้อนกันมาก (ขนาดพาธมากกว่า 1 GB) เป็นผลให้ผู้โจมตีสามารถบรรลุสตริงขนาด 10 ไบต์ "//deleted" ซึ่งเขียนที่ออฟเซ็ต "-2 GB - 10 ไบต์" ซึ่งชี้ไปยังพื้นที่ที่อยู่ด้านหน้าบัฟเฟอร์ที่จัดสรรทันที

การใช้ประโยชน์ที่เตรียมไว้ต้องใช้หน่วยความจำ 5 GB และ inode ฟรี 1 ล้านเพื่อดำเนินการ การใช้ประโยชน์นี้ทำงานโดยการเรียก mkdir() เพื่อสร้างลำดับชั้นของไดเร็กทอรีย่อยประมาณล้านไดเร็กทอรีเพื่อให้ได้ขนาดพาธของไฟล์เกิน 1 GB ไดเร็กทอรีนี้ถูกเมาท์ผ่าน bind-mount ในเนมสเปซผู้ใช้ที่แยกต่างหาก หลังจากนั้นฟังก์ชัน rmdir() จะถูกรันเพื่อลบออก ในแบบคู่ขนาน เธรดจะถูกสร้างขึ้นเพื่อโหลดโปรแกรม eBPF ขนาดเล็ก ซึ่งถูกบล็อกที่สเตจหลังจากตรวจสอบรหัสเทียม eBPF แต่ก่อนการคอมไพล์ JIT

ในเนมสเปซ ID ผู้ใช้ที่ไม่มีสิทธิ์ ไฟล์ /proc/self/mountinfo จะถูกเปิดและอ่านชื่อพาธแบบยาวของไดเร็กทอรีที่ mount เข้าด้วยกัน ส่งผลให้สตริง "//deleted" ถูกเขียนลงในพื้นที่ก่อนที่จะเริ่มบัฟเฟอร์ ตำแหน่งสำหรับการเขียนบรรทัดถูกเลือกเพื่อให้เขียนทับคำสั่งในโปรแกรม eBPF ที่ทดสอบแล้วแต่ยังไม่ได้คอมไพล์

ถัดไป ที่ระดับโปรแกรม eBPF การเขียนนอกบัฟเฟอร์ที่ไม่สามารถควบคุมได้จะถูกแปลงเป็นความสามารถในการควบคุมในการอ่านและเขียนไปยังโครงสร้างเคอร์เนลอื่นๆ ผ่านการยักย้ายโครงสร้าง btf และ map_push_elem ผลที่ได้คือการหาประโยชน์จะกำหนดตำแหน่งของบัฟเฟอร์ modprobe_path[] ในหน่วยความจำเคอร์เนลและเขียนทับเส้นทาง “/sbin/modprobe” ในนั้น ซึ่งช่วยให้คุณสามารถเริ่มต้นการเปิดตัวไฟล์ปฏิบัติการใด ๆ ที่มีสิทธิ์การใช้งานรูทในกรณีที่ การเรียก request_module() ซึ่งจะดำเนินการ เช่น เมื่อสร้างซ็อกเก็ต netlink

นักวิจัยได้เสนอวิธีแก้ปัญหาหลายอย่างที่มีประสิทธิภาพเฉพาะสำหรับการใช้ประโยชน์เฉพาะเจาะจงเท่านั้น แต่ไม่ได้ขจัดปัญหาออกไป ขอแนะนำให้ตั้งค่า "/proc/sys/kernel/unprivileged_userns_clone" เป็น 0 เพื่อปิดใช้งานไดเร็กทอรีการเมาท์ในเนมสเปซ ID ผู้ใช้แยกต่างหาก และ "/proc/sys/kernel/unprivileged_bpf_disabled" เป็น 1 เพื่อปิดใช้งานการโหลดโปรแกรม eBPF ลงในเคอร์เนล

เป็นที่น่าสังเกตว่าในขณะที่วิเคราะห์การโจมตีทางเลือกที่เกี่ยวข้องกับการใช้กลไก FUSE แทนการผูกมัดเพื่อติดตั้งไดเร็กทอรีขนาดใหญ่ นักวิจัยพบช่องโหว่อื่น (CVE-2021-33910) ที่ส่งผลกระทบต่อตัวจัดการระบบ systemd ปรากฎว่าเมื่อพยายามเมานต์ไดเร็กทอรีที่มีขนาดพาธเกิน 8 MB ผ่าน FUSE กระบวนการเริ่มต้นการควบคุม (PID1) จะหมดหน่วยความจำสแต็กและขัดข้อง ซึ่งทำให้ระบบอยู่ในสถานะ "ตื่นตระหนก"

ปัญหาคือ systemd ติดตามและแยกวิเคราะห์เนื้อหาของ /proc/self/mountinfo และประมวลผลแต่ละจุดเมานท์ในฟังก์ชัน unit_name_path_escape() ซึ่งดำเนินการ strdupa() ที่วางข้อมูลบนสแต็กแทนที่จะเป็นในหน่วยความจำที่จัดสรรแบบไดนามิก . เนื่องจากขนาดสแต็กสูงสุดถูกจำกัดผ่าน RLIMIT_STACK การประมวลผลเส้นทางไปยังจุดเมานท์ที่ใหญ่เกินไปทำให้กระบวนการ PID1 หยุดทำงานและหยุดระบบ สำหรับการโจมตี คุณสามารถใช้โมดูล FUSE ที่ง่ายที่สุดร่วมกับการใช้ไดเร็กทอรีที่ซ้อนกันสูงเป็นจุดเมานท์ ซึ่งมีขนาดพาธเกิน 8 MB

ปัญหาเกิดขึ้นตั้งแต่ systemd 220 (เมษายน 2015) ได้รับการแก้ไขแล้วในที่เก็บ systemd หลักและแก้ไขในการแจกแจง (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch) โดยเฉพาะอย่างยิ่งใน systemd release 248 การใช้ประโยชน์ไม่ทำงานเนื่องจากข้อบกพร่องในโค้ด systemd ที่ทำให้การประมวลผล /proc/self/mountinfo ล้มเหลว เป็นที่น่าสนใจว่าในปี 2018 สถานการณ์ที่คล้ายกันเกิดขึ้น และเมื่อพยายามเขียนช่องโหว่ CVE-2018-14634 ในเคอร์เนล Linux นักวิจัยของ Qualys ได้พบช่องโหว่ร้ายแรงสามช่องโหว่ใน systemd

ที่มา: opennet.ru

เพิ่มความคิดเห็น