ทีมความปลอดภัยไซเบอร์ Section 52 ของไมโครซอฟท์ที่มีหน้าที่วิจัยความปลอดภัยในอุปกรณ์กลุ่ม IoT รายงานถึงช่องโหว่ BadAlloc กลุ่มช่องโหว่ของซอฟต์แวร์ IoT สำคัญๆ จำนวนมากที่ไม่ตรวจสอบอินพุตก่อนจองหน่วยความจำจนกลายเป็นช่องโหว่ heap overflow นำไปสู่การโจมตีแบบรันโค้ดระยะไกลหรือไม่ก็ทำให้อุปกรณ์แครชไปได้
ตัวอย่างของช่องโหว่ BadAlloc เช่น ฟังก์ชั่น malloc สำหรับจองหน่วยความจำเมื่อรับค่าขนาดหน่วยความจำที่ต้องการมาแล้วก็นำค่าเป็นบวกกับค่าคงที่ เช่น ขนาด struct สำหรับเก็บข้อมูล heap โดยไม่ได้ตรวจสอบว่าขนาดหน่วยความจำใหญ่เกินไปหรือไม่ ทำให้เมื่อนำค่าไปบวกกับค่าคงที่ต่างๆ แล้วเกิด integer overflow ทำให้ค่าที่ได้วนกลับไปเริ่มจากศูนย์หรือติดลบ
ทาง Section 52 แนะนำว่าผู้ใช้อุปกรณ์ IoT ควรติดตั้งแพตช์จากผู้ผลิตเสมอ, มอนิเตอร์การทำงานผ่านระบบเก็บ log, จำกัดการเข้าถึงอุปกรณ์ เช่น บังคับต้อง VPN ก่อน, แบ่งวงเน็ตเวิร์คออกจากวงอื่นๆ
ซอฟต์แวร์ที่ยืนยันว่ามีช่องโหว่ BadAlloc มีซอฟต์แวร์ดังๆ หลายตัว เช่น Amazon FreeRTOS, ARM Mbed OS, Google Cloud IoT Device SDK, Linux Zephyr RTOS, Samsung Tizen RTOS, TencentOS-tiny
Comments
Rust ต้องมาแล้วแบบนี้
ผมว่ามันก็ปกติรึเปล่าครับ c เป็นภาษาระดับกลาง คนเขียนโปรแกรมต้องดูเองไม่ให้จองเม็มเกิน ไม่เขียนเม็มเกินที่จองอะไรแบบนี้
ที่ไม่ปกติคือไม่ควรปล่อยช่องโหว่นี้ออกมาครับ
ปกติครับแต่ os ต้องเช็คก่อน ไม่งั้นปล่อยให้ crash (เช่นจอฟ้า) ก็ไม่ควร
เพราะอาจเกิดโปรแกรมประสงค์ร้าย ที่จงใจทำการ overflow ก็ทำให้ไปอ่าน mem ของส่วนอื่น ทำให้เกิดการ hack ได้อีกด้วย
ผมมองว่างี้
ฟังก์ชันนี้ปรกติจะ allocate ข้อมูลก้อนนึงมาบน heap ตามที่ขอ ถ้ามันใหญ่เกินไป allocate ไม่ก็ ก็จะคืนค่า NULL กลับมา
การที่มันไม่เช็คขนาดเลยแล้ว allocate เลย จริง ๆ ต่อให้เป็นก้อนที่เล็กแค่ไหนก็ตามก็มีโอกาสที่จะ overflow ได้ ยกเว้นแต่ว่ามัน hardcode ไว้เลยว่าจะให้ก้อนใหญ่ขนาดไหน (จริง ๆ ก็มี memory allocator ที่ทำงานแบบนี้เหมือนกัน แต่ปรกติมันก็จะคืนก้อนที่ใหญ่กว่าที่ขอมาอยู่ดี)
ผมก็เลยรู้สึกว่าถ้ามันไม่เช็คเลยแล้วมันจะผ่าน unit test มาได้ไงหว่า??
เท่าที่ผมอ่านเข้าใจจากโค้ดตัวอย่างในบล็อคต้นทางคือ ฟังค์ชั่นพวก malloc ต่างๆ มันจะมี overhead อยู่ซึ่งเวลา malloc มันจะเอา input เราไปบวก overhead เข้าไปซึ่งเราอาจจะ validate input มาแล้วว่า fit ภายใน max value ของ data type ที่ใช้ แต่เราไม่รู้ว่าค่าที่ใช้จริงๆ ถูกบวก overhead เข้าไปอีก (หรือรู้ก็ไม่รู้ว่าเท่าไรคือ max value ที่ safe)
ผมคิดว่า overhead เป็น implementation detail ของ malloc ที่แต่ละ OS หรือ CPU architecture ก็อาจจะไม่เท่ากัน มันก็เลยไม่รู้ว่าจะดักเท่าไรคือค่าที่ปลอดภัยนอกไปจากว่า input นั้นมี sane value ตามธรรมชาติอยู่แล้ว
แล้วผู้ประสงค์ร้ายจะเข้าถึงฟังก์ชันนี้ได้อย่างไรครับ?
ไม่รู้ใช่คำตอบที่อยากรู้ป่าวนะครับ (เห็นตอบไว้เหมือนเข้าใจดีอยู่แล้ว)
ถ้าผมเป็นผู้ประสงค์ร้ายก็ทำให้มันเกิด overflow ด้วยวิธีนี้(ถ้าเป็น linux ก็เหมือนได้สิทธิ์รูท)แล้วอยากจะอ่าน mem ส่วนไหนก็ได้หมดและ
อันนี้แล้วแต่ระดับ application อีกทีครับ แต่โดยทั่วไปแล้วหากหน่วยความจำไม่พอ ฟ้งก์ชั่น malloc มันควรแจ้งความผิดพลาดได้เอง (เช่น return -1) ระดับ application นั้นมีหน้าที่ตรวจสอบค่าผิดปกติ เช่น เลขติดลบหรือข้อมูลไม่ใช่ตัวเลข แต่เมื่อต้องขอหน่วยความจำแล้วขนาดมันใหญ่เกินไป malloc ก็ต้องแจ้งว่าผิดพลาด ไม่ใช่คืนค่าแบบคาดเดาไม่ได้จนกลายเป็น buffer overflow แบบนี้
พอ lib ระดับล่างมันไม่ทำหน้าที่ของมัน ก็กลายเป็นช่องทางของแฮกเกอร์ใช้ร่วมกับช่องโหว่อื่นๆ ได้ เช่น กระตุ้นผ่านข้อมูลขนาดใหญ่ให้เกิด buffer overflow ก่อน
lewcpe.com, @wasonliw