ข่าวไอที Blognone » รู้จักการโจมตี Meltdown เมื่อการเร่งความเร็วซีพียูเปิดทางให้แฮกเกอร์เจาะระบบ

รู้จักการโจมตี Meltdown เมื่อการเร่งความเร็วซีพียูเปิดทางให้แฮกเกอร์เจาะระบบ

7 มกราคม 2018
40   0

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

การสาธิตที่ชัดเจนที่สุดคงเป็นการขโมยรหัสผ่านที่ผู้ใช้พิมพ์บนโปรแกรมอื่นดังวิดีโอต่อไปนี้

Speculative Execution

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

alt="upic.me"

ขณะที่โค้ดกำลังรออ่านค่าตัวแปร untrusted_offset_from_caller ในบรรทัดที่ 6 ก่อนจะตรวจสอบเงื่อนไข if ในบรรทัดที่ 7 ในซีพียูยุคใหม่ บรรทัดที่ 8 ที่เป็นการอ่านค่าจากหน่วยความจำจะเริ่มทำงานไปทันทีโดยไม่สนใจว่าการตรวจสอบเงื่อนไข if เป็นจริงหรือไม่

ที่ผู้ออกแบบซีพียูออกแบบให้ทำเช่นนี้ เป็นการเตรียมข้อมูลมาไว้ล่วงหน้า เนื่องจากการเรียกข้อมูลจากหน่วยความจำอาจใช้เวลานาน (ประมาณ 400-500 CPU cycle) หากเงื่อนไข if ไม่เป็นจริง ซีพียูจะล้างข้อมูลออกเหมือนไม่เคยเกิดขึ้น ตัวโปรแกรมจะไม่เคยรับรู้ว่ามีการอ่านค่าในหน่วยความจำขึ้นมาแล้วและไม่สามารถเขียนโค้ดใดๆ เพื่อพิจารณาค่าในหน่วยความจำที่ซีพียูล้างออกไปนั้นได้

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

การโจมตี FLUSH+RELOAD

เมื่อปี 2014 Yuval Yarom และ Katrina Falkner นักวิจัยจากมหาวิทยาลัย Adelaide นำเสนอการโจมตีที่ชื่อว่า FLUSH+RELOAD ที่เปิดให้โปรเซสของแฮกเกอร์ที่รันบนเครื่องเดียวกับเหยื่อ สามารถอ่านพฤติกรรมและคาดเดาข้อมูลในโปรเซสของเหยื่อได้ โดยสาธิตการอ่านกุญแจ PGP ออกมาจากโปแกรม GnuPG ที่กำลังเซ็นเอกสารอยู่

การโจมตี FLUSH+RELOAD อาศัยพฤติกรรมของระบบปฎิบัติการยุคใหม่ ที่หากโปรแกรมมีการเรียกใช้ไบนารีเดียวกัน เช่น ไลบรารีเดียวกันหรือไบนารีของตัวโปรแกรมเดียวกัน (แม้จะเรียกใช้โดยผู้ใช้คนละคนที่ไม่มีสิทธิ์อ่านข้อมูลข้ามกัน) ตัวระบบปฎิบัติการก็จะโหลดไบนารีนั้นๆ ขึ้นไปยังหน่วยความจำเพียงครั้งเดียว และแชร์ร่วมกันระหว่างผู้ใช้ทั้งหมด เพื่อประหยัดหน่วยความจำ และทำให้กระบวนการโหลดโปรแกรมโดยทั่วไปเร็วขึ้น

นอกจากพฤติกรรมของระบบปฎิบัติการ FLUSH+RELOAD ยังอาศัยคำสั่ง CLFLUSH (Flush Cache Line) ที่โปรแกรมสามารถสั่งยกเลิกแคชของหน่วยความจำตำแหน่งใดๆ ได้ ทำให้เมื่อโปรเซสอื่นต้องการใช้หน่วยความจำตำแหน่งเดียวกัน ต้องโหลดใหม่จากหน่วยความจำ

กระบวนการโจมตีของ FLUSH+RELOAD คือการสั่ง CLFLUSH หน่วยความจำที่เป็นโค้ดที่เหยื่อกำลังจะรันออกจากแคชทั้งหมด แล้วทดสอบอ่านหน่วยความจำตำแหน่งนั้นอีกครั้งภายหลัง หากอ่านได้เร็วแสดงว่าเหยื่อเคยรันโค้ดในส่วนนั้นมาแล้ว

alt="upic.me"

ภาพตัวอย่างจากรายงาน FLUSH+RELOAD ภาพ (A) เริ่มต้นด้วยแฮกเกอร์ล้างโค้ดส่วนที่ต้องการดูว่าเหยื่อเรียกหรือไม่ออกจากแคช หลังจากช่วงเวลาหนึ่งแฮกเกอร์ก็เรียกหน่วยความจำส่วนนั้นด้วยตัวเอง เมื่อใช้เวลานาน (สีส้ม) จึงรู้ได้ว่าเหยื่อไม่เคยรันโค้ดส่วนนั้นในช่วงเวลาที่รอ ภาพ (B) แสดงถึงกรณีที่เหยื่อรันโค้ดส่วนนั้น เมื่อแฮกเกอร์เรียกอ่านหน่วยความจำก็จะอ่านได้เร็วเพราะโค้ดอยู่ในแคชอยู่แล้ว

แม้ว่า FLUSH+RELOAD จะน่าสนใจ แต่กระบวนการโจมตียังจำกัด แฮกเกอร์ต้องเข้าใจพฤติกรรมของโปรแกรมอย่างชัดเจนเพื่อหาพฤติกรรมที่ต้องการ โดยไม่สามารถไปอ่านหน่วยความจำของเหยื่อได้โดยตรง

การโจมตี Meltdown

การโจมตี Meltdown มุ่งไปที่การอ่านหน่วยความจำที่โปรเซสไม่ได้รับอนุญาต เช่นหน่วยความจำของเคอร์เนล ที่ปกติแล้วหากโปรแกรมพยายามอ่านหน่วยความจำในตำแหน่งเหล่านั้น ระบบปฎิบัติการจะปิดการทำงานของโปรแกรมทันที

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

Meltdown อาศัยพฤติกรรมนี้ด้วยการสร้างโค้ดที่โหลดหน่วยความจำโดยอาศัยข้อมูลในตำแหน่งที่ไม่มีสิทธิ์อ่าน เพื่อสร้างกระบวนการส่งข้อมูลออกไปภายนอกโปรเซสที่พยายามอ่านข้อมูลนั้น

ดูโค้ดตัวอย่างจาก Project Zero โค้ดที่สอง ต่อไปนี้

No Description

โค้ดพยายามเข้าถึงหน่วยความจำส่วนที่ไม่ได้รับอนุญาต โดยอาศัยตัวแปร untrusted_offset_from_caller เมื่อค่าตำแหน่งผิดไป หากโหลดหน่วยความจำจากคำสั่ง value = arr1->data[untrusted_offset_from_caller] ขึ้นมาจริง ระบบปฎิบัติการก็จะปิดโปรแกรมลง เนื่องจากละเมิดการจำกัดสิทธิ์การเข้าถึงหน่วยความจำ

อย่างไรก็ดี เนื่องจากซีพียูพยายามรันคำสั่งไปล่วงหน้า ค่าในหน่วยความจำนี้จะถูกอ่านขึ้นมา และถูกคำนวณต่อไปในโดยที่ตัวโปรแกรมจริงๆ ยังไม่รับรู้ และคำนวณหาค่าตัวแปร index2 (บรรทัดที่ 10) ต่อไปทันที หากค่าในตัวแปร value มีบิตสุดท้ายเป็น 0 ค่า
index2 จะมีค่าเป็น 0x200 หากเป็น 1 จะเป็น 0x300

หลังจากนั้นกระบวนการรันคำสั่งล่วงหน้าจะโหลดหน่วยความจำตามบรรทัดที่ 13 ขึ้นมารอเอาไว้

เนื่องจากค่าตัวแปร untrusted_offset_from_caller เป็นค่าที่ไม่ถูกต้อง เช่น ค่าใหญ่เกินไปมากจนเกินขอบเขตหน่วยความจำซอฟต์แวร์ ทำให้ตัวโปรแกรมเหมือนไม่เคยรันโค้ดบรรทัดที่ 9-15 แต่อย่างใด แต่ในเนื่องจากระบบการรันคำสั่งล่วงหน้าของซีพียูได้รันคำสั่งเหล่านี้ไปแล้ว (และทิ้งผลลัพธ์ทั้งหมดไป) ทำให้หน่วยความจำของ arr2->data ถูกโหลดขึ้นแคชทิ้งเอาไว้

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

กระบวนการนี้เป็นกระบวนการที่ช้า Project Zero รายงานว่าสามารถอ่านหน่วยความจำเคอร์เนลได้ด้วยอัตรา 2 KB/s ขณะที่ทีมวิจัยจาก Graz University of Technology สามารถปรับปรุงโดยใช้ชุดคำสั่ง TSX ของอินเทลจนเร่งความเร็วการอ่านหน่วยความจำได้ถึง 503 KB/s

คนทั่วไปควรทำอย่างไรเพื่อรับมือกับ Meltdown

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

อย่างไรก็ดีแพตช์ที่ออกมาจะกระทบต่องานบางประเภทมากเป็นพิเศษ โดยเฉพาะงานฐานข้อมูลอย่าง PostgreSQL ทางลดผลกระทบหากใช้ซีพียูรุ่นใหม่ๆ ที่มีฟีเจอร์ PCID (Process-Context Identifiers) จะช่วยลดผลกระทบไปได้มาก รายงานทดสอบ PostgreSQL ระบุว่าหากใช้ PCID สามารถลดผลกระทบจาก 23% เหลือ 17% ในการทดสอบที่แย่ที่สุด (อีกการทดสอบหนึ่งเมื่อเปิด PCID ผลกระทบอยู่ที่ 7%)

Phoronix ทดสอบงานรูปแบบต่างๆ ที่ได้รับผลกระทบจากแพตช์ KPTI ที่แก้การโจมตี Meltdown พบว่าเกมนั้นแทบไม่มีผลกระทบใดๆ รวมไปถึงงานตกแต่งรูปภาพ (ทดสอบด้วย Darktable) โดยทั่วไปแล้วสำหรับผู้ใช้เดสก์ทอปคงแทบไม่มีอะไรต้องกังวล

[source: https://www.blognone.com/node/98857]