สรุปสั้น
บริษัทความปลอดภัย Calif เผยแพร่รายงานโดยละเอียดพร้อมโค้ด proof-of-concept เต็มของเอ็กซ์พลอยต์ยกระดับสิทธิ์ภายในเครื่อง (local privilege escalation) ที่ได้สิทธิ์ root บน OpenBSD 7.9 เอ็กซ์พลอยต์นี้เชื่อมบั๊ก integer overflow ที่มีอายุราว 37 ปีในฟังก์ชัน shmat สำหรับแนบหน่วยความจำร่วม (shared memory) เข้ากับช่องโหว่เคอร์เนลอีกตัว จนข้ามกลไกสุ่มตำแหน่งเคอร์เนล KARL ของ OpenBSD และกลไกป้องกันระดับฮาร์ดแวร์ SMAP และ SMEP ได้ทั้งหมด โดยไม่ต้องใช้ช่องโหว่รั่วข้อมูล (information disclosure) แม้แต่ตัวเดียว
OpenBSD แพตช์ทั้งสองปัญหาแล้วเมื่อกันยายน ผ่าน syspatch สำหรับทุกสถาปัตยกรรม โดย integer overflow แก้ใน errata 018 ซึ่งจัดเป็น “reliability fix” ไม่ใช่ security fix ส่วน use-after-free ที่ปิดท้ายห่วงโซ่แก้ใน errata 026 ซึ่งจัดเป็น security fix ณ วันที่เผยแพร่ยังไม่มีการออก CVE ให้ทั้งสองช่องโหว่ และไม่มีหลักฐานว่าถูกใช้โจมตีจริง แต่เมื่อโค้ด PoC เปิดเผยบน GitHub แล้ว เครื่องที่ยังไม่แพตช์จะเสี่ยงขึ้นทันที
รายละเอียดข่าว
เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 16 ตุลาคม 2569 ว่า Calif ซึ่งเป็นผู้ค้นพบและรายงานช่องโหว่ เผยแพร่รายละเอียดหลังจาก OpenBSD ออกแพตช์ครบแล้ว โดย errata 018 ออกเมื่อวันที่ 14 กันยายน 2569 และ errata 026 ออกเมื่อวันที่ 30 กันยายน 2569 ทั้งนี้ OpenBSD 7.8 ได้รับแพตช์ integer overflow ด้วย Calif ระบุว่ารายงานช่องโหว่ให้ OpenBSD ตั้งแต่ “ต้นปีนี้”
ประเด็นที่น่าสังเกตคือจุดเริ่มต้นของห่วงโซ่การโจมตีทั้งหมดถูกจัดเป็นเพียงการแก้ปัญหาด้านความเสถียร ผู้ดูแลระบบที่เลือกติดตั้งเฉพาะแพตช์ด้านความปลอดภัยจึงอาจพลาด errata 018 ไป นอกจากนี้ Calif เสนอแนวทางเสริมความแข็งแกร่ง 4 ด้าน ได้แก่ safe-unlinking สำหรับ linked list ในเคอร์เนล (ซึ่ง FreeBSD และ NetBSD ใช้อยู่แล้ว) การสุ่มตำแหน่ง page-table self-referential mapping การสุ่มตัวจัดสรรหน่วยความจำของเคอร์เนล และการตรวจขอบเขตด้วยคอมไพเลอร์
รายละเอียดช่องโหว่
ตัวนับจำนวนการแนบหน่วยความจำร่วม shm_nattch ถูกนิยามเป็นชนิด signed 16-bit short ซึ่งมีค่าสูงสุด 32,767 มาตั้งแต่ซอร์สโค้ด BSD ต้นฉบับปี 2531 OpenBSD สืบทอดชนิดข้อมูลนี้มาโดยไม่เคยขยายขนาด ลำดับการโจมตีมีดังนี้
- เอ็กซ์พลอยต์แมปเซกเมนต์หน่วยความจำร่วม 127 เซกเมนต์และ fork โพรเซส 259 โพรเซส ดันตัวนับเกินค่าสูงสุดจนวนกลับเป็น −32,643
- race condition ทำให้เกิด use-after-free เพราะ reference count ที่เสียหายทำให้เคอร์เนลคืนหน่วยความจำที่โพรเซสอื่นยังใช้อยู่
- ช่องโหว่เขียนเกินขอบเขต (out-of-bounds write) อีกตัวเขียนทับตัวนับสมาชิก multicast ในเคอร์เนล เมื่อซ็อกเก็ตที่เกี่ยวข้องปิด การลดค่าตัวนับจะไปแก้ page-table entry ทำให้ mapping ของหน่วยความจำฝั่งผู้ใช้กลายเป็นเข้าถึงได้จากโหมด supervisor จึงข้าม SMAP และ SMEP
- เอ็กซ์พลอยต์เขียนทับพอยน์เตอร์ฟังก์ชันที่ตำแหน่งในเคอร์เนลที่คาดเดาได้ แล้วรันโค้ดของตัวเอง
นาย Andrew Griffiths นักวิจัยของ Calif อธิบายว่า “แม้ KARL ของ OpenBSD จะ relink ไบนารีเคอร์เนลเพื่อสุ่มตำแหน่งทั้งฟังก์ชันและข้อมูล แต่ตัวจัดสรรหน่วยความจำของเคอร์เนลยังทำงานแบบกำหนดแน่นอน” ทั้งตัวจัดสรรตอนบูตและตัวจัดสรรแบบ best-fit ไม่มีการสุ่มตำแหน่งฐาน โครงสร้างที่สร้างตอนบูต รวมถึงพอยน์เตอร์ฟังก์ชันในตัวจัดการอินเทอร์เฟซเครือข่าย lo0 และ enc0 จึงอยู่ที่ตำแหน่งเดิมทุกครั้งที่รีบูตบนฮาร์ดแวร์เดียวกัน
ผลกระทบ
OpenBSD มีชื่อเสียงด้านความปลอดภัยและนิยมใช้เป็นไฟร์วอลล์ เราเตอร์ เซิร์ฟเวอร์ DNS/SMTP และโฮสต์ bastion เอ็กซ์พลอยต์นี้ต้องอาศัยการรันโค้ดบนเครื่องอยู่ก่อน จึงไม่ใช่การเจาะจากระยะไกลโดยตรง แต่เมื่อผู้โจมตีได้ช่องทางเข้าในสิทธิ์ผู้ใช้ทั่วไป เช่น ผ่านบริการที่มีช่องโหว่หรือบัญชีที่ถูกขโมย ก็สามารถยกระดับเป็น root และยึดอุปกรณ์ที่มักอยู่ตำแหน่งสำคัญของเครือข่ายได้
ในเชิงเทคนิค งานวิจัยนี้ชี้ว่าการสุ่มตำแหน่งไบนารีอย่างเดียวไม่พอหากตัวจัดสรรหน่วยความจำยังคาดเดาได้ และการจัดประเภทแพตช์เป็น “reliability” อาจทำให้องค์กรประเมินความเร่งด่วนต่ำเกินจริง
คำแนะนำ
- รัน
syspatchบน OpenBSD 7.9 ให้ได้ทั้ง errata 018 และ errata 026 และตรวจว่า OpenBSD 7.8 ได้รับแพตช์ integer overflow แล้ว - อย่ากรองติดตั้งเฉพาะ errata ที่ระบุว่าเป็น security fix เพราะจุดเริ่มต้นของห่วงโซ่นี้ถูกจัดเป็น reliability fix
- จำกัดบัญชีผู้ใช้และบริการที่รันโค้ดได้บนอุปกรณ์ OpenBSD ที่ทำหน้าที่ไฟร์วอลล์หรือเกตเวย์ให้น้อยที่สุด
- เฝ้าระวังโพรเซสที่ fork จำนวนมากผิดปกติร่วมกับการแนบหน่วยความจำร่วมจำนวนมาก ซึ่งเป็นรูปแบบที่เอ็กซ์พลอยต์นี้ใช้
- ทีมที่ดูแลเคอร์เนลหรือระบบปฏิบัติการอื่น ควรพิจารณาแนวทางเสริมความแข็งแกร่งทั้ง 4 ด้านที่ Calif เสนอ
