การวิเคราะห์ช่องโหว่ความปลอดภัยของ Lua ใน Factorio
Factorio คืออะไร?
- Factorio เป็นเกมที่ให้ผู้เล่นทำระบบโรงงานอัตโนมัติเพื่อสร้างจรวดและหลบหนีออกจากดาวเคราะห์
- มียอดขายเกมมากกว่า 3,500,000 ชุด จึงกลายเป็นเป้าหมายที่น่าสนใจสำหรับนักวิจัยด้านความปลอดภัย
วิธีที่ Lua ถูกใช้งานในเกม
- Lua ถูกใช้เพื่อพัฒนาเกมลอจิก รวมถึงสร้างม็อดและแผนที่แบบกำหนดเอง
- ชุมชนม็อดมีความคึกคักอย่างมาก และมีม็อดอยู่หลายพันรายการ
- ม็อด Alien Biomes มียอดดาวน์โหลด 551K ครั้ง
การเปิดรับ Lua interpreter ผ่านเครือข่าย
- โหมดผู้เล่นหลายคนของ Factorio ใช้ deterministic lockstep เพื่อซิงก์ไคลเอนต์
- เมื่อผู้เล่นคนหนึ่งรันโค้ด Lua ผู้เล่นคนอื่นก็ต้องรันโค้ดเดียวกันด้วย
- สิ่งนี้ทำให้เกิดความเป็นไปได้ที่จะรันโค้ด Lua อันตรายผ่านเครือข่ายได้
เส้นทางการโจมตีที่พบได้ทั่วไป
- โฮสต์เซิร์ฟเวอร์ Factorio ที่แจกแผนที่อันตราย
- เมื่อไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์ ก็จะดาวน์โหลดแผนที่และรันโค้ด Lua
- ใช้ประโยชน์จากจุดอ่อนของการติดตั้งใช้งาน Lua เพื่อสร้างอ็อบเจ็กต์ปลอม
- เปลี่ยนพฤติกรรมของโปรแกรมผ่านการรั่วไหล/การเสียหายของหน่วยความจำ
- ใช้ primitive ที่ทรงพลังเหล่านี้เพื่อให้ได้ความสามารถในการรันโค้ด
ความเสี่ยงของ Lua bytecode
- Lua เป็นภาษาแบบ interpreter โดยจะไม่รันโค้ดที่เขียนขึ้นโดยตรง แต่คอมไพล์เป็น bytecode ก่อน
- หากสามารถรัน bytecode ได้โดยตรง ก็อาจรัน bytecode ที่ผิดรูปเพื่อทำให้เกิดการรั่วไหลหรือความเสียหายของหน่วยความจำได้
ตัวตรวจสอบ bytecode
- นักพัฒนา Lua เคยสร้างตัวตรวจสอบ bytecode เพื่อปกป้อง interpreter จาก bytecode อันตราย แต่มีการค้นพบวิธีหลบเลี่ยงซ้ำหลายครั้ง จึงถูกถอดออกใน Lua 5.2
- นักพัฒนา Factorio ได้สร้างตัวตรวจสอบ bytecode ของตนเอง แต่ยังไม่สมบูรณ์เนื่องจากมีปัญหา off-by-one บางส่วน
การสร้างอ็อบเจ็กต์ปลอม
- การสร้างอ็อบเจ็กต์ปลอมทำให้สามารถใช้ความสามารถทั้งหมดของ interpreter ได้
- สามารถใช้สตริงเพื่อรั่วข้อมูลตามอำเภอใจ และใช้อาร์เรย์เพื่อเขียนไปยังหน่วยความจำตามอำเภอใจ
- หากสามารถเรียก native function ได้ ก็จะควบคุมลำดับการทำงานได้
การรั่วไหลของแอดเดรส
- ฟังก์ชัน print ของ Lua สามารถทำให้แอดเดรสรั่วไหลได้
- ใน Factorio ฟังก์ชันนี้ถูกนำออกไปแล้ว จึงใช้วิธีรั่วแอดเดรสผ่าน type confusion แทน
ทำความเข้าใจ TValues
- Lua เป็นภาษาแบบไดนามิก ดังนั้นชนิดของตัวแปรสามารถเปลี่ยนได้ระหว่างรันไทม์
- ภายใน Lua ใช้โครงสร้าง TValue เพื่อแทนอ็อบเจ็กต์
- TValue มีคุณสมบัติ type (
tt_) และ value (value_)
type confusion ด้วย FORLOOP
- opcode FORLOOP อาจทำให้เกิด type confusion ได้ เพราะถือว่าค่าเริ่มต้นของลูปเป็นตัวเลข
- สิ่งนี้สามารถใช้เพื่อรั่วแอดเดรสได้
IEEE 754 double precision
- double precision ประกอบด้วยเครื่องหมาย เลขชี้กำลัง และแมนทิสซา
- Lua ไม่ได้แทนค่าจำนวนเต็มโดยเฉพาะ ดังนั้นจึงสามารถรั่วแอดเดรสได้สูงถึง 53 บิตโดยไม่สูญเสียความแม่นยำ
การค้นหาอ็อบเจ็กต์ปลอม
- สามารถค้นหาอ็อบเจ็กต์ปลอมได้โดยทำความเข้าใจ Upvalues และ Closures
- Upvalues ช่วยให้เข้าถึงตัวแปรของฟังก์ชันภายนอกได้
- หากแก้ไข bytecode เพื่อเปลี่ยนดัชนีของ Upvalue ก็จะสามารถค้นหาอ็อบเจ็กต์ปลอมได้
ความเห็นของ GN⁺
- บทความนี้มีประโยชน์มากในการทำความเข้าใจช่องโหว่ความปลอดภัยของภาษาแบบไดนามิก
- อธิบายปัญหาความปลอดภัยที่อาจเกิดขึ้นในเกมยอดนิยมอย่าง Factorio ได้เป็นอย่างดี
- โครงการอื่นที่ใช้ภาษาอย่าง Lua ก็อาจมีช่องโหว่ลักษณะคล้ายกันได้เช่นกัน
- เมื่อจะนำเทคโนโลยีใหม่หรือโอเพนซอร์สมาใช้ การทบทวนด้านความปลอดภัยเป็นสิ่งจำเป็น
- โครงการอื่นที่มีความสามารถคล้ายกัน ได้แก่ ระบบม็อดของ Minecraft
ยังไม่มีความคิดเห็น