การแฮ็กเกม Pro Strcpy ของ Tony Hawk
(icode4.coffee)- Create-A-Park ช่องโหว่ buffer overflow จาก
strcpyในการประมวลผล gap name ของไฟล์เซฟ นำไปสู่ exploit ผ่านไฟล์เซฟและเครือข่ายบนหลายแพลตฟอร์ม เช่น original Xbox, Xbox 360, PS2, GameCube - THPS4 เวอร์ชัน original Xbox คัดลอกสตริงที่จำกัด 31 ตัวอักษรไปยัง stack buffer ขนาด 32 ไบต์โดยไม่ตรวจสอบขอบเขต ทำให้เขียนทับ return address ได้ และใช้ส่วนหัวไฟล์เซฟกับ data segment ที่รันได้เพื่อเรียกใช้ shellcode
- ใน THPS3 อินพุตเดียวกันไม่ได้ทำให้ stack เสียหาย แต่ทำให้ heap เสียหาย จึงต้องใช้ ROP chain ที่ผ่าน custom allocator และเส้นทาง vtable ส่วน THUG 1·2 เวอร์ชัน Xbox ถูกปิดเส้นทาง gap name ด้วย stack cookie
- ในโหมด multiplayer ของ THPS4 โฮสต์ที่เป็นอันตรายส่งไฟล์ park ไปยังไคลเอนต์เพื่อทำ remote code execution และการถ่ายโอนไฟล์แบบ asynchronous ส่วน memory leak ทางเครือข่ายที่เผยออกมาระหว่างการส่งถูกหลบเลี่ยงภายใน exploit ด้วย hot patch
- Tony Hawk’s American Wasteland บน Xbox 360 ก็สามารถรัน ROP ผ่าน gap name overflow ได้เช่นกัน แต่การรันโค้ดใน hypervisor แบบเต็มทำได้เฉพาะเมื่อผนวกกับบั๊ก system call handler ของ 4548 kernel และมีการเผยแพร่ซอร์สกับไฟล์เซฟที่แพตช์แล้วบน GitHub
จุดเริ่มต้น: gap name และ strcpy
- ในปี 2016 ระหว่างการค้นหาบั๊กแฮ็กไฟล์เซฟใหม่สำหรับ original Xbox ไฟล์เซฟ custom park ของ Tony Hawk’s Pro Skater 4 กลายเป็นเป้าหมายในการวิเคราะห์
- ฟีเจอร์ Create-A-Park ของ THPS4 ให้ผู้เล่นสร้าง skate park เอง และตั้งชื่อให้ gap ซึ่งเป็นช่วงกระโดดได้
- gap name คือสตริงกำหนดเองของผู้ใช้ที่มีความยาวสูงสุด 31 ตัวอักษรพร้อม null terminator
- หากสตริงนี้ถูกประมวลผลด้วยฟังก์ชันอย่าง
strcpyก็อาจกลายเป็น primitive สำหรับทำให้หน่วยความจำเสียหายได้
- เมื่อนำไฟล์เซฟอันตรายที่เปลี่ยน gap name เป็นสตริงยาวซ้ำด้วย
0x41ไปคัดลอกลง Xbox แล้วโหลด คอนโซลเกิด crash และ instruction pointer ถูกตั้งเป็น0x41414141- นี่เป็นสัญญาณว่า gap name ถูกคัดลอกไปยัง stack และเขียนทับไปถึง return address
- ผลการวิเคราะห์ด้วย IDA พบว่า ขณะวนผ่านรายการ gap ในไฟล์เซฟ เกมคัดลอก
gap_nameของsave_file_gap_dataไปยังgap_description gapDescบน stack ด้วยstrcpy- ไม่มีการตรวจสอบขอบเขต ทำให้การคัดลอกดำเนินต่อไปจนกว่าจะพบ null terminator
- เกมเวอร์ชันนี้คอมไพล์โดยไม่มี stack cookie จึงสามารถเขียนทับข้อมูลบน stack และ return address ได้
original Xbox THPS4: ย้าย shellcode ไปยังพื้นที่ที่รันได้
- original Xbox ไม่มีฮาร์ดแวร์ DEP ที่ป้องกันการรันข้อมูลตามอำเภอใจเหมือนอุปกรณ์สมัยใหม่ แต่ใน kernel ช่วงหลังและบางเกมมี soft DEP อยู่บางส่วน
- เป็นวิธีเปลี่ยนที่อยู่ของ code segment selector เพื่อให้รันได้เฉพาะที่อยู่ต่ำกว่าค่าหนึ่งเท่านั้น
- stack และ heap allocation ที่มีไฟล์เซฟอยู่ อยู่นอกพื้นที่ที่รันได้
- read-write data segment ของไฟล์ executable เกมอยู่ภายในพื้นที่ที่รันได้ จึงใช้กลยุทธ์คัดลอกโค้ดไปไว้ที่นั่นแล้วจึงรัน
- ชื่อ park อยู่ในส่วนหัวไฟล์เซฟ และเมื่อผู้เล่นเลือกไฟล์เซฟ 136 ไบต์แรกของส่วนหัวจะถูกคัดลอกไปยัง struct ใน data segment ของไฟล์ executable เพื่อแสดงผลใน UI
- แม้จะเปลี่ยนส่วนหัวทั้งหมดตามใจไม่ได้ แต่มีพื้นที่พอสำหรับใส่ stub
memcpyขนาดเล็ก
- แม้จะเปลี่ยนส่วนหัวทั้งหมดตามใจไม่ได้ แต่มีพื้นที่พอสำหรับใส่ stub
- ลำดับการทำงานของ exploit THPS4 บน original Xbox
- หลังโหลดไฟล์เซฟ ก่อนกด “Start Game” 136 ไบต์แรกจะถูกคัดลอกไปยัง data segment ของไฟล์ executable เกม
- เมื่อกด “Start Game” gap name อันตรายจะถูกคัดลอกไปยัง stack และ return address ถูกเขียนทับด้วยที่อยู่ของ stub คัดลอก shellcode
- เมื่อฟังก์ชัน return จะกระโดดไปยัง stub คัดลอก เพื่อคัดลอก payload ขนาดใหญ่จาก buffer ไฟล์เซฟไปยัง data segment ที่รันได้
- หลังคัดลอกเสร็จจะกระโดดไปยัง payload และได้ การรันโค้ดตามอำเภอใจ
การเลี่ยงลายเซ็นและ habibi key
- หลังจากได้การรันโค้ดบน original Xbox แล้ว จำเป็นต้องปิดใช้งานการตรวจสอบลายเซ็นและรัน unsigned executable
- payload ถูกสร้างโดยอิงจาก payload ของไฟล์เซฟ softmod installer 007 Agent Under Fire ที่มีอยู่เดิม
- ค้นหา kernel function และที่อยู่ข้อมูล รวมถึงที่อยู่ของ RSA public key ที่ใช้ตรวจสอบลายเซ็นไฟล์ executable
- ปิดใช้งาน write protection ของ machine state register แล้วแพตช์ RSA public key เป็น habibi key
- รันไฟล์ executable เสริมที่รวมอยู่ในไฟล์เซฟ โดยระหว่างทดสอบใช้ไฟล์ executable
nyan cat
- habibi key pair เป็นคีย์ RSA ที่คาดว่าสร้างโดยกลุ่ม original Xbox Linux hacking ในช่วงต้นทศวรรษ 2000
- แทนที่จะทำให้การตรวจสอบลายเซ็น RSA ของ kernel ผ่านเสมอโดยไม่มีเงื่อนไข วิธีนี้เปลี่ยน public key เป็นคีย์ของตนเองเพื่อรัน Linux loader
- เป็นการเลือกทำเพื่อป้องกันการใช้ไฟล์เซฟดังกล่าวรัน pirated content แต่ต่อมากลุ่มอื่น ๆ ก็เผยแพร่ไฟล์ exploit สำหรับติดตั้ง persistent hack
- จุดที่น่าสนใจคือ modulus ของ habibi public key ต่างจาก Microsoft RSA public key เพียง 4 ไบต์
- ดูเหมือนว่า exponent ควรต้องเปลี่ยนเป็น 3 แต่ payload shell code เดิม ๆ ไม่ได้เปลี่ยน exponent
- ยังไม่ชัดเจนว่ามันทำงานได้อย่างไรอย่างแม่นยำ
- วิธี habibi key ถูกเลือกเพราะเข้ากันได้กับ Xbox kernel หลายเวอร์ชัน
- หากจะแพตช์ฟังก์ชันตรวจสอบลายเซ็นให้คืนค่า true เสมอ ต้องจับคู่ instruction pattern แยกตาม kernel แต่ละเวอร์ชัน
- habibi key ต้องทำเพียง patch 4 ไบต์ ในหน่วยความจำที่หาได้ง่าย
การวิเคราะห์เวอร์ชันย่อย: THPS3, THUG, THAW
-
Tony Hawk’s Pro Skater 3
- THPS3 ก็มี Create-A-Park และชื่อ gap เช่นกัน แต่ไม่ได้แครชทันทีหลังโหลดไฟล์เซฟอันตราย
- ยังสามารถ skate ในเกมได้ และคอนโซลจะแครชเมื่อเลือก “quit game”
- ชื่อ gap ถูกคัดลอกไปยัง ฮีป ไม่ใช่สแตก และ overflow ไปเขียนทับ allocation header ของการจัดสรรฮีปถัดไป
- เมื่อ allocation ถัดไปถูก free ค่า pointer ใน header จะชี้ต่อไปยัง vtable ที่มี cleanup routine function pointer
- THPS3 ไม่ได้คัดลอก header ของไฟล์เซฟไปยัง data segment ที่ execute ได้เหมือน THPS4 และข้อมูลไฟล์เซฟก็อยู่ในหน่วยความจำฮีปที่ execute ไม่ได้
- เขียนทับ pointer
pAllocOwnerเพื่อควบคุมตำแหน่งที่โหลด cleanup function pointer และใช้ ROP chain ในหน่วยความจำไฟล์เซฟผ่าน stack pivot - ROP chain ใช้ gadget เพียงไม่กี่ตัวเพื่อคัดลอก shellcode ในฮีปไปยัง data segment ที่ execute ได้ แล้ว jump ไปที่นั่น
- หลังจากนั้นดำเนินการ patch habibi key และรัน unsigned executable เช่นเดียวกับ generic payload “hack xbox kernel” สำหรับ THPS4
-
Tony Hawk’s Underground 1 & 2
- เมื่อ fuzzing ชื่อ gap ใน THUG จะเกิด full bug check พร้อมข้อความ
Buffer overrun detected!แทนที่จะเป็น access violation - ในไฟล์ executable มีการตรวจสอบ stack cookie
- stack cookie คือค่าสุ่มที่วางไว้หน้า return address และจะตรวจสอบว่าค่าเปลี่ยนไปหรือไม่ก่อนฟังก์ชัน return
- หากต้องการเขียนทับ return address ต้องรู้ค่า cookie แต่ในเส้นทางชื่อ gap ไม่มีวิธี leak ค่านี้
- หลัง buffer ของชื่อ gap และก่อน stack cookie มีตัวแปรที่สามารถถูกทำให้เสียหายได้ แต่ไม่นานก็ถูกโค้ดเกมเขียนทับ จึงไม่เป็นประโยชน์ต่อการ exploit
- มีการพิจารณา SEH exploitation ด้วย แต่ในโค้ดที่เหลือก่อนการตรวจสอบ stack cookie ไม่มีวิธีทำให้เกิด exception และ ณ จุดนั้นก็ยังไม่มี exception handler ที่เดิน SEH chain ถูกลงทะเบียนไว้
- THUG2 บนเวอร์ชัน Xbox ก็ exploit ผ่านชื่อ gap ไม่ได้ด้วยเหตุผลเดียวกัน
- อย่างไรก็ตาม ยังมีบั๊ก
strcpyอื่นและบั๊กที่ exploit ได้บนฮีปอยู่ - เวอร์ชัน PlayStation 2, PC และอาจรวมถึง GameCube ถูกคอมไพล์โดยไม่มี stack cookie จึง exploit ผ่าน buffer ของชื่อ gap ได้
- เมื่อ fuzzing ชื่อ gap ใน THUG จะเกิด full bug check พร้อมข้อความ
-
Tony Hawk’s American Wasteland
- THAW เป็นเกมหลัง THUG 1·2 จึงคาดว่าน่าจะมี stack cookie แต่เวอร์ชัน Xbox ถูกคอมไพล์โดยไม่มี stack cookie
- มีช่องโหว่ gap name buffer overflow และโครงสร้าง exploit แทบเหมือนกับ THPS4
THPS4 network RCE: แฮ็ก client โดยไม่ต้องใช้ไฟล์เซฟ
- เนื่องจาก exploit ผ่านไฟล์เซฟต้องใช้ memory card จึงเลือก เกม multiplayer LAN เป็นพื้นผิวโจมตีที่มีอุปสรรคในการเริ่มต้นต่ำกว่า
- เมื่อใช้ park ที่สร้างด้วย Create-A-Park ใน LAN multiplayer host จะส่งไฟล์เซฟผ่านเครือข่าย และ client จะโหลดไฟล์นั้น
- จึงตั้งสมมติฐานว่าสามารถส่งไฟล์ park อันตรายเพื่อแฮ็ก client console ได้
- แก้ไขไฟล์ executable ของเกมเพื่อปิดบั๊ก
strcpyไม่ให้ host แฮ็กตัวเอง และเพิ่ม code segment สำหรับฟังก์ชันเพิ่มเติมด้วย - ตอนแรก client เชื่อมต่อกับ host และ skate ได้ตามปกติ แต่ payload ไม่ถูก execute และ buffer overflow ก็ไม่ถูก trigger
- ข้อมูล park file ในหน่วยความจำของ client ถูกเปลี่ยนแปลงไปจากไฟล์ exploit
- หลังจาก host โหลด park file แล้ว เกม save ใหม่จากหน่วยความจำและส่งผลลัพธ์นั้นไปยัง client ทำให้ข้อมูล exploit เสียหาย
- เมื่อเปลี่ยน function call นั้นเป็น NOP แล้ว client ได้รับ park file อันตรายและถูก compromise จนสี LED เปลี่ยน
- ในเส้นทางเครือข่าย header ของไฟล์เซฟไม่ได้ถูกคัดลอกไปยัง data segment จึงไม่สามารถใช้สตับคัดลอก shellcode ของ local exploit ใน THPS4 ได้
- ใช้ ROP chain คล้ายกับ THPS3 เพื่อคัดลอก shellcode ไปยังหน่วยความจำที่ execute ได้
การพบซอร์สโค้ด THUG และการใช้โค้ดเครือข่าย
- ต้องส่ง executable ของ payload เสริมไปยัง client ผ่านเครือข่าย แต่ไม่สามารถใส่ไฟล์ไว้ใน save game folder ร่วมกันได้เหมือน local save file exploit
- มีการพิจารณาวิธีโหลด executable จาก burned CD หรือที่อยู่เครือข่ายภายใน แต่ไม่ได้เลือกใช้
- Xbox winsock implementation ใช้ secure socket connection เป็นค่าเริ่มต้น จึงต้องจำลอง Xbox security layer ด้วย Python script
- ระหว่างค้นหาข้อมูลเกี่ยวกับ park save file พบ repository
thugบน GitHub จากการค้นหาสตริงSk4Ed_Dead- พบว่าไม่ใช่ homebrew tool แต่เป็น ซอร์สโค้ดเกม Tony Hawk’s Underground ทั้งเกม
- แม้ไม่ใช่ THPS4 เอง แต่ codebase คล้ายกันมากพอที่จะนำ networking code และการเขียน hook มาใช้ได้
- ในซอร์สโค้ดมี park file loading code และบรรทัดที่แน่นอนซึ่งมีบั๊ก
strcpy- สามารถประกอบ Visual Studio project file ขึ้นใหม่และแก้ compiler error บางจุด เพื่อสร้าง build ที่รันได้ด้วย final game asset
- ดูเหมือนเป็นโค้ดที่ใกล้เคียงกับเวอร์ชันสุดท้ายมาก แม้ไม่เหมือนกันทั้งหมด
- เป้าหมายเปลี่ยนจาก RCE แบบง่าย ไปเป็นการได้ RCE อย่างเงียบ ๆ บน console ที่เข้าร่วม match เปิดให้รัน unsigned code ได้ แล้วส่ง executable เสริมระหว่างเล่นเกม
การกู้คืนการทำงานและการส่งไฟล์แบบ asynchronous
- หากต้องการส่ง payload ในขณะที่ client เล่นเกมต่อไปได้ จำเป็นต้อง กู้คืน flow การทำงานของเกม หลังจาก shell code execute แล้ว
- ปรับ ROP chain ให้บันทึก stack pointer เดิมก่อน stack pivot และกู้คืนในภายหลังหลังจาก shell code execute เสร็จ
- จากนั้นคัดลอก shell code ไปยังหน่วยความจำที่ execute ได้แล้ว jump ไป
- networking system ของเกมมีโครงสร้างที่ลงทะเบียน message ID กับ handler function และเรียก handler ที่ตรงกับ ID ของข้อความที่ได้รับ
- ใช้ message ID ที่ไม่ได้ใช้งานมาลงทะเบียนเพื่อสร้างโปรโตคอลส่งไฟล์อย่างง่าย
- เมื่อ client เชื่อมต่อ จะส่ง
MSG_ID_PAYLOAD_REQUESTไปยัง host เพื่อเริ่มการส่ง - host ส่งข้อมูล payload ด้วยข้อความ
MSG_ID_PAYLOAD_DATA - เมื่อ client ได้รับ
PAYLOAD_MSG_ID_ENDการส่งก็เสร็จสมบูรณ์
- เมื่อ client เชื่อมต่อ จะส่ง
memory leak อายุ 15 ปีและ hot patch
- ระหว่างส่งไฟล์ client console แครชจาก null pointer dereference
- network data allocator คืนค่า NULL และ free byte ของ networking memory pool กลายเป็น 0
- ในซอร์สโค้ด THUG มีโค้ดที่ free message data buffer แต่ใน shipped build ของ THPS4 ไม่มีการแก้ไขดังกล่าว
- buffer
p_dataของstream_descไม่ถูกปล่อยในแต่ละข้อความ ทำให้ networking memory pool ถูกใช้จนหมด - ในการเล่น multiplayer ทั่วไป ปัญหานี้อาจไม่เกิดขึ้น เว้นแต่จะอยู่ในเกมนานมาก
- buffer
- exploit hook client code เพื่อ hot patch ให้ปล่อย buffer
p_desc->p_dataด้วย free function ที่ถูกต้อง - หลัง hot patch การส่งไฟล์บนคอนโซล host และ client สำเร็จ และ client รัน executable
nyan-cat- ใช้ tunneling app เพื่อทดสอบ exploit เดียวกันจากระยะไกลกับ console ของเพื่อนในภูมิภาคอื่นด้วย
ขั้นตอน exploit เครือข่ายสุดท้ายของ Xbox รุ่นดั้งเดิม
- client เชื่อมต่อกับ host console ที่เป็นอันตราย และรับไฟล์ park “Hack Xbox” ผ่านเครือข่าย
- ขณะที่ client parse ไฟล์ park จะเกิด buffer overflow และ return address บนสแตกถูกเขียนทับ ทำให้ ROP chain เริ่มทำงาน
- ROP chain คัดลอก payload ของ shell code แบบเต็มไปยังพื้นที่หน่วยความจำที่ execute ได้ แล้ว jump ไปยังจุดนั้น
- shell code ตั้งค่า hook และ patch ที่จำเป็นก่อนกลับไปสู่การรันเกม และ spawn ผู้เล่นเข้าสู่ match
- ระหว่างที่ผู้เล่น skate อยู่ในเกม host จะส่ง executable file ไปยัง client และ client จะบันทึกไว้ใน HDD
- หลังการถ่ายโอนไฟล์เสร็จ shell code จะ patch kernel ของ client ให้ใช้ habibi key แล้ว boot secondary executable ที่ถูกส่งมา
- หากไม่เปลี่ยนสี LED ผู้ใช้จะสังเกตความคืบหน้าได้ยากจนกว่า application อื่นจะ boot ขึ้นมาแบบกะทันหัน
Xbox 360: THAW และ 4548 kernel
- Tony Hawk’s American Wasteland สำหรับ Xbox 360 ก็มีช่องโหว่ gap name buffer overflow เช่นกัน
- เป้าหมายคือ exploit console บน kernel version ใหม่ แต่เป็นไปไม่ได้หากไม่มี hypervisor bug ใหม่
- แทนที่จะทำเช่นนั้น จึงสามารถรวมบั๊ก
strcpyของ THAW เข้ากับบั๊ก system call handler ของ 4548 kernel ที่มีอยู่เดิม เพื่อสร้าง exploit แบบ software-only ตัวแรกของ Xbox 360 ได้ - King Kong hack เดิมของ Xbox 360 ใช้ modified shader file เพื่อทำ arbitrary write ไปยัง kernel memory และ exploit บั๊ก system call handler
- วิธีนี้ต้องเปิด console และแก้ไข firmware ของ DVD drive เพื่อใช้แผ่น King Kong ที่ถูกดัดแปลง
- game save bug สามารถเป็น entry point อีกแบบหนึ่งสำหรับเริ่ม ROP chain ได้
ลายเซ็นไฟล์บันทึกของ Xbox 360 และบทบาทของคอนโซลสำหรับนักพัฒนา
- game save file ของ Xbox 360 ถูกลงนามด้วย RSA key pair ที่ไม่ซ้ำกันในแต่ละ console
- key store ของแต่ละ console มี cryptographic key ที่ใช้ลงนาม game save
- เหตุผลที่ console เครื่องอื่นตรวจสอบไฟล์บันทึกได้ คือ RSA public key ถูกใส่อยู่ใน save file header
- public key นี้เองถูกลงนามด้วย RSA key pair อีกชุดหนึ่งที่มีเพียง Microsoft เท่านั้นที่มี
- จึงไม่สามารถใส่ public key ใด ๆ ลงใน header แล้วให้ผ่านการตรวจสอบได้
- หากต้องการใช้ save file ที่แก้ไขเองบน console เครื่องอื่น จำเป็นต้องมี decrypted key store ของ Xbox 360 console เครื่องใดเครื่องหนึ่ง
- จุดเริ่มต้นของการ hacking Xbox 360 คือการรั่วไหลของ development console และ SDK
- เนื่องจาก executable code ถูกเข้ารหัสไว้ หากไม่สามารถ inspect code จากภายนอก ก็ไม่อาจหาบั๊กได้
- development console และ SDK ให้ข้อมูลที่จำเป็นสำหรับการ decrypt executable code และ reverse engineering ของ boot chain, hypervisor และ game code
บั๊ก 4548 system call handler
- Xbox 360 มี hypervisor real mode และ kernel mode
- hypervisor real mode เป็น mode ที่มี privilege สูงสุด
- ใน kernel mode จะมี OS และ game ทำงานอยู่
- CPU มี cryptography unit ข้าง L2 cache ที่รับผิดชอบ memory encryption และ hashing
- ใน kernel mode หน้า hypervisor จะมองเห็นเป็นสถานะ encrypted + hashed และหากเขียนทับตามอำเภอใจ เมื่อ hypervisor เข้าถึง console จะ halt
- ใน real mode บิตบน 32 บิตของ 64-bit physical address ใช้ควบคุม encryption และ hashing
- เมื่อใช้ mask
0x80000000.00000000จะสามารถ access memory โดยข้าม encryption และ hashing ได้ - ในจุดที่ kernel mode สามารถส่ง physical address ให้ hypervisor ได้ จะต้อง clear บิตบน 32 บิตเสมอ
- เมื่อใช้ mask
- system call handler ปกติจะใช้คำสั่ง
slwiเพื่อ shift system call ordinal ไปทางซ้าย 2 บิต และทิ้งบิตบน 32 บิตของผลลัพธ์ ใช้เฉพาะ 32-bit offset - system call handler ของ 4548 kernel ใช้
sldiแทนslwisldiทำงานแบบ 64-bit ดังนั้นบิตบน 32 บิตของ r0 จึงถูกนำไปรวมในการคำนวณ table index offset ด้วย- ordinal range check ใช้กับเฉพาะบิตล่าง 32 บิตของ r0 เท่านั้น
- ตัวอย่างเช่น
0x20000000.0000003Fสามารถผ่าน range check ขณะสร้าง offset0x80000000.000000FCเพื่อชักนำให้เกิด unprotected memory access ได้
- การเปลี่ยนแปลงนี้ถูกประเมินว่ามีแนวโน้มเป็น compiler bug มากกว่าการแก้ไขโดยตั้งใจของ developer
โครงสร้าง exploit ของ Xbox 360
- โดยปกติแล้ว หากเขียนทับ encrypted hypervisor memory view ใน kernel mode เครื่อง console จะ halt แต่ถ้าทำให้ system call handler อ่าน function pointer จาก address ที่ตั้งค่า protection bit ระดับสูงไว้ได้ ก็จะสามารถอ่านค่าที่เขียนทับไว้ได้โดยไม่เกิด fault
- ขั้นตอน exploit
- โหลด shell code ลงใน memory และรับ physical address
- เปลี่ยน kernel memory manager variable เพื่อเปิดเผย encrypted hypervisor memory view เป็น address range ที่เขียนได้
- เขียนทับ hypervisor system call function pointer ด้วย address ของ instruction sequence
mtctr r4; bctr - ใส่ ordinal อันตรายใน r0 และใน r4 ใส่ค่าที่นำ
0x80000000.00000000mask ไป OR กับ physical address ของ shell code - รัน system call instruction เพื่อให้ hypervisor อ่าน function pointer ที่ถูกเขียนทับ และกระโดดไปยัง shell code ผ่าน
mtctr r4; bctr
- exploit ไฟล์เซฟของ THAW ใช้ PowerPC ROP chain
- แก้ไข IDA plugin Ida-Sploiter ให้รองรับการค้นหา PowerPC gadget
- exploit ทั้งหมดประกอบด้วย ROP gadget 24 ตัว
- ลำดับการทำงานทั้งหมดของ THAW บน Xbox 360
- ใช้ gap name buffer overflow เพื่อเขียนทับ return address ให้เป็น ROP gadget ตัวแรก
- pivot stack pointer ไปยัง ROP chain ภายใน save buffer
- จัดสรร physical memory สำหรับ hypervisor shell code ด้วย
MmAllocatePhysicalMemoryEx - คัดลอก shell code ด้วย
memcpyและรับ physical address ด้วยMmGetPhysicalAddress - mapping ให้ encrypted hypervisor memory view เขียนได้
- เขียนทับ system call function address ด้วย sequence
mtctr r4; bctr - รัน
syscallด้วย malicious system call ordinal และ physical address ของ shell code - หลังได้ hypervisor code execution แล้ว เปลี่ยนสี LED และ patch การตรวจสอบ executable RSA signature
- กลับไปยัง kernel mode ROP chain แล้วใช้
ObCreateSymbolicLinkเพื่อ mapping HDD folder และใช้XLaunchNewImageเพื่อรัน unsigned secondary payload
- วิธีนี้สามารถได้ ROP execution ผ่านบั๊ก
strcpyของ THAW บน Xbox 360 OS version ใดก็ได้ แต่ full hypervisor code execution ทำได้เฉพาะบน 4548 kernel เท่านั้น- หากพบ hypervisor bug ใหม่ ก็สามารถนำมารวมกับ entry point นี้เพื่อใช้กับ kernel version ที่ใหม่กว่าได้
การเปิดเผยในปี 2024 และการพอร์ตไปยังแพลตฟอร์มเพิ่มเติม
- ในปี 2024 มีการรวบรวมและเปิดเผย Tony Hawk exploits
- บั๊ก
strcpyเดียวกันมีอยู่ใน 5 iteration ของซีรีส์ Tony Hawk และในหลาย console·handheld platform -
PlayStation 2
- THPS4 network RCE exploit ถูกพอร์ตไปยังเวอร์ชัน PlayStation 2
- หากมี PCSX2 หรือ console อื่น และมีแผ่น THPS4 ก็สามารถ hack console ผ่าน network ได้
- exploit จะส่ง uLaunchElf ผ่าน network และรันเมื่อส่งเสร็จ
- จากนั้นสามารถโหลด FreeMcBoot หรือ FreeHDBoot installer จาก media อื่น เช่น USB stick ได้
- PS2 save game exploit มีประโยชน์น้อยกว่า
- หากมีวิธีคัดลอกไฟล์ลง memory card ก็สามารถติดตั้ง FreeMcBoot ได้โดยตรง
- สามารถซื้อ FreeMcBoot memory card จาก Amazon ในราคา 15 ดอลลาร์ หรือใช้ FreeHDBoot กับ phat console และ network adapter ได้
-
GameCube
- THPS4 save game exploit ถูกพอร์ตไปยังเวอร์ชัน GameCube
- network RCE หรือ save game exploit เวอร์ชันอื่นไม่ได้ถูกพอร์ต
- การคัดลอกไฟล์ลง GameCube memory card ไม่ใช่เรื่องง่าย และ memory card ที่มี pre-hacked save file เคยถูกขายบน eBay ในราคามากกว่า 50 ดอลลาร์
- Tony Hawk game เวอร์ชัน GameCube ไม่มี network support ดังนั้นแม้จะมี network adapter ก็ใช้ network exploit ไม่ได้
- เนื่องจากมี game save exploit อยู่แล้วหลายตัว และไม่มี persistent software hack ผู้ใช้จำนวนมากจึงเลือกใช้ modchip
-
Windows
- มีการสร้าง game save exploit สำหรับ THUG PRO ด้วย และมีการส่ง bug report ไปเมื่อ 7 ปีก่อน แต่ในตอนนั้นไม่มีความสนใจที่จะแก้ไข
- ไม่ได้เปิดเผย เพราะ exploit ไม่มีคุณค่าในการใช้งานบน Windows
- Tony Hawk game สำหรับ PC มีบั๊ก
strcpyเดียวกันและ exploit ได้ - ยังมีบั๊ก
strcpyอื่นที่ exploit ได้ในการเล่นผ่าน network - แนะนำให้บังคับใช้ ASLR และไม่รันในฐานะ Administrator
เอกสารและโค้ดที่เปิดเผย
- source code ทั้งหมดและ patched game save files เผยแพร่บน GitHub
- บั๊ก
strcpyเพียงตัวเดียวนำไปสู่ save file exploit, network RCE และ entry point สำหรับ software-only exploit บน Xbox 360 ในหลายแพลตฟอร์ม
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
สิ่งที่น่าสนใจกว่าเกี่ยวกับ คีย์ Habibi คือโมดูลัสกุญแจสาธารณะต่างจากกุญแจสาธารณะ RSA ของ Microsoft แค่ 4 ไบต์
จำนวนเต็ม 2048 บิตแบบสุ่มมีโอกาสถูกแยกตัวประกอบได้แบบง่าย ๆ อยู่พอสมควร และแม้ไม่รู้ความน่าจะเป็นจริง ๆ แต่ก็น่าจะประมาณระดับ 2^-32
คงใช้โค้ดทำนองสุ่มเปลี่ยนหรือเพิ่มค่า 4 ไบต์ของโมดูลัสสาธารณะ แล้วลองแยกตัวประกอบสักประมาณ 1 มิลลิวินาที ถ้าสำเร็จก็หยุด
ผลคือโมดูลัสสาธารณะน่าจะมีตัวประกอบขนาดเล็กอยู่จำนวนมาก และแม้โมดูลัส RSA ปกติจะเป็นผลคูณของจำนวนเฉพาะสองตัวพอดี แต่ตราบใดที่ยังเป็นจำนวนเฉพาะสัมพัทธ์กับ e คณิตศาสตร์ก็ยังทำงานได้แม้มีตัวประกอบมากกว่านั้น
ถ้าโชคดีที่ implementation ของ RSA ใช้วิธีที่มีตัวประกอบเฉพาะแค่สองตัวพอดี เมื่อรู้อยู่แล้วว่าตัวประกอบหนึ่งคือ 3 ก็แค่เอากุญแจสาธารณะหารด้วย 3 เพื่อได้ตัวประกอบเฉพาะอีกตัว
ตาม Wikipedia โครงสร้างกุญแจสาธารณะ RSA คือ N ต้องเป็น semiprime ขนาดใหญ่ และ e ต้องเป็นจำนวนเฉพาะสัมพัทธ์กับ φ(N); ใครก็ตามที่แยกตัวประกอบ N ได้ก็จะได้กุญแจส่วนตัว ในบริบทการแฮ็ก Xbox ถ้าทำให้ N หารด้วยจำนวนเฉพาะ 3 ลงตัว จำนวนเฉพาะอีกตัวก็คือ N/3 จึงถือว่าแยกตัวประกอบสำเร็จแล้ว
โค้ดที่ใช้เซ็นด้วยคีย์ Habibi อยู่ที่ https://github.com/XboxDev/xbedump/blob/b8cd5cd0f8b1cbc4e64f... โดยเปลี่ยน 4 ไบต์สุดท้ายเป็น 0x89, 0x9c, 0x90, 0x6b จากนั้นหารด้วย 3 แล้วใช้ค่านั้นสร้างกุญแจส่วนตัวที่เหมาะสม
การประยุกต์ใช้คือทำให้กุญแจสาธารณะเสียหายด้วย rowhammer แล้วใช้การแยกตัวประกอบของมันเพื่อสร้างกุญแจส่วนตัวตัวใหม่ที่สอดคล้องกัน วิธีนี้ใช้ได้กับคีย์ SSH และ GPG และเพื่อให้ใช้งานได้จริงก็มีสมมติฐาน เช่น รู้เนื้อหาของเพจที่มีคีย์อยู่
อัตราความสำเร็จเชิงประจักษ์ตามเวลาคำนวณที่ใช้ได้อยู่ใน Figure 7 ส่วนการวิเคราะห์เชิงคณิตศาสตร์อยู่ในบทที่ 3 และคำอธิบายวิธีจริงอยู่ในบทที่ 4.4
https://www.usenix.org/system/files/conference/usenixsecurit...
ตัวอย่างเช่น ถ้าลองหารด้วยจำนวนเฉพาะตั้งแต่ 2 ถึง 499 แล้วถ้าค่าเหลือเป็น 1 ก็สำเร็จ มิฉะนั้นก็รัน Miller–Rabin 20 รอบ โค้ดแบบนี้ในเครื่องผมใช้ประมาณ 100 ครั้งก็แยกตัวประกอบจำนวนเต็ม 2048 บิตแบบสุ่มได้ครบถ้วนแล้ว
ยากจะอธิบายได้เลยว่าผลงานนี้เหลือเชื่อขนาดไหน
การ softmod Xbox 360 ด้วยชื่อสวนในเกม Tony Hawk และยังใช้ ROP chain ถึง 24 ขั้นนั้นสุดยอดมาก
ทั้งการไว้อาลัยสั้น ๆ ให้ hypervisor, การวิเคราะห์ที่กระชับและใช้งานได้จริง, ไปจนถึงบอตเน็ต x360 ที่ผุดขึ้นมาในหัวทันที รวมกันแล้วให้ความรู้สึกเหมือนโดนความคิดถึง Xbox 360 ระดับตำนานพุ่งชนเต็ม ๆ
ประโยคที่ว่า “ถ้าโชคดีก็คงเป็น strcpy” น่าสนุกดี จริง ๆ แล้วมันควรเป็น strncpy มากกว่า แต่ Tony Hawk ซึ่งขึ้นชื่อเรื่องการสนับสนุนอุปกรณ์นิรภัย ก็น่าจะอยากถูกเชื่อมโยงกับการคัดลอกสตริงที่ปลอดภัยกว่า
ต้องมีการจัดการเฉพาะแอปพลิเคชัน เช่น ถ้าต้นทางใส่ในปลายทางไม่พอ จะตัดทิ้งได้ไหม ต้องยกเลิกทั้งงานไหม หรือควรจัดสรรบัฟเฟอร์ปลายทางใหม่ ส่วน strncpy มักทำสิ่งที่ผิดแทบเสมอ
โดยพื้นฐานแล้วแทบไม่ควรใช้ strncpy เลย มันเหมาะกับฟิลด์ขนาดคงที่อย่าง
struct dirent { unsigned short inode; char name[14]; };แม้ในกรณีแบบนั้น ไบต์ padding ก็มักควรเป็นช่องว่างมากกว่า nul และ strncpy ไม่ควรถูกใส่ไว้ในไลบรารีมาตรฐานตั้งแต่แรก
ตอนใช้ C/C++ มันใช้ง่ายกว่าฟังก์ชัน C มาตรฐาน โดยช่วยจัดการกรณีล้มเหลวที่พบบ่อย เช่น บัฟเฟอร์เล็กเกินไปหรือเกิด integer overflow และทุกฟังก์ชันคืนรหัสความล้มเหลว ทำให้ตรวจสอบข้อผิดพลาดได้ง่าย
ในกรณีนี้
StringCchCopyW()หรือStringCbCopyW()เป็นตัวเลือกที่ดีกว่า strcpyน่าเสียดายนิดหน่อยที่ exploit นี้ใช้กับ THUG PRO ได้ด้วย
ฉากการแข่งขันของซีรีส์ Tony Hawk แทบตายไปเกือบ 20 ปีแล้ว ยกเว้นช่วงสั้น ๆ ของรีเมค THPS1+2 และม็อดนี้ก็ยังมีคนเล่นอยู่
ตัวม็อดเองก็อายุมากกว่า 10 ปีแล้ว และดูเหมือนผู้พัฒนาดั้งเดิมจะออกไปแล้ว จึงอธิบายได้ว่าทำไมตอน Ryan รายงานไปถึงไม่มีใครพยายามแก้ แต่ตอนนี้ม็อดนี้ใช้งานได้ยากขึ้นเพราะมีความเสี่ยงถูกยึดสิทธิ์ทั้งเครื่อง PC
หวังว่าบทความนี้จะไปถึงใครสักคนที่เต็มใจแพตช์ม็อดนี้
ซอร์สนั้นมีไว้สำหรับเวอร์ชันคอนโซลเท่านั้น และสมมติฐานเรื่องการคอมไพล์บน Windows หมายถึงสำหรับเครื่องมือ ไม่ใช่ Xbox Windows ดังนั้นหลายส่วนจึงทำงานต่างออกไปโดยสิ้นเชิง
สิ่งที่ดูเหมือนไอคอนหัวข้อของเซกชันหน้าข้อความ “So what's the habibi key?” จริง ๆ แล้วเป็นส่วน HTML details ที่คลิกเพื่อขยายได้ ดังนั้นถ้าสนใจก็ควรกดดู
ประเด็นที่สงสัยคือ ถ้าเรื่องที่ว่าคีย์ Habibi ถูกใช้แบบเฉพาะในกลุ่มคอนโซล Linux เพื่อป้องกันการใช้คอนเทนต์เถื่อนเป็นเรื่องจริง แล้ว private key ที่สอดคล้องกันถูกเปิดเผยหรือรั่วไหลออกมาจากที่ไหน เมื่อไร และอย่างไร
ผู้เขียนแพตช์ความต่าง 4 ไบต์ระหว่างคีย์ของ Microsoft กับคีย์ Habibi เพื่อรันไฟล์ปฏิบัติการที่ “ไม่ได้เซ็น” ซึ่งในความเป็นจริงคือไฟล์ปฏิบัติการที่เซ็นด้วย private key ของ Habibi ดังนั้นดูเหมือนชัดเจนว่าเขาได้ private key มาแล้ว
private key สามารถกู้คืนจาก public key ได้อย่างง่ายดาย จึงไม่ได้มีอะไรที่ต้องถูกเปิดเผยหรือรั่วไหลเป็นพิเศษ
โดยพื้นฐานแล้วมันเป็น CTF ด้านวิทยาการเข้ารหัสเล็ก ๆ ที่ฝังอยู่ในแฮ็กไฟล์เซฟของ 007: Agent Under Fire เดิม และตัวแฮ็กไฟล์เซฟนั้นเองก็ใกล้เคียงกับ CTF ที่ถูกทำให้อ่านยากพอสมควร ดูเหมือนจะมีทั้งเจตนาจะเล่นงานผู้ใช้เถื่อน และเป็นการท้าทายวิศวกรย้อนกลับคนอื่น ๆ
เจ๋งจริง ๆ ผมทำงาน ดีคอมไพล์ PSX มาบ้าง และในนั้นก็มีเรื่องคล้าย ๆ กันอยู่เยอะ
ที่น่าสนใจคืออย่าง
memmoveจะลิงก์มาจากไลบรารี SDK[0] แต่strcpyเป็นฟังก์ชันที่ BIOS ให้มาใน SDK เวอร์ชันหลัง ๆ สามารถแพตช์ให้ใช้เวอร์ชันไลบรารีแทนได้ แต่จนถึงปี 1997 ก็ยังไม่ได้เป็นแบบนั้น
0 - https://github.com/Xeeynamo/sotn-decomp/blob/master/src/main...
ตอนนี้เกม N64 กำลังถูกพอร์ตลง PC ผ่านดีคอมไพเลอร์ เลยทำให้คาดหวังขึ้นมา
อาจมีคนตอบว่า “เกมพวกนี้มีเวอร์ชัน PC อยู่แล้วนี่” แต่ถ้ารีคอมไพล์เกม N64 และเปลี่ยนเอฟเฟกต์ให้เป็นเท็กซ์เจอร์ล้วน ๆ หรือเอฟเฟกต์ที่ง่ายกว่าแทน shader ก็จะรันได้แทบทุกที่ แม้แต่อุปกรณ์ช้า ๆ อย่างเน็ตบุ๊กราคาถูกปี 2009
มีตัวอย่างการพอร์ต Super Mario 64 ไปยัง 3DFX API ด้วย เกมที่เข้าถึง framebuffer ของ N64 แบบซับซ้อนอาจต้องใช้ OpenGL 3.3 เพื่อเลียนแบบไมโครโค้ดนั้น แต่ถ้าเอนจินรันได้เร็วมากบนเครื่องตั้งแต่ Pentium III ขึ้นไปแล้ว ส่วนที่เหลือก็ไม่น่ายากนักที่จะให้รันด้วยการเร่งความเร็ว GL 2.1 และเลียนแบบบางส่วนด้วยซอฟต์แวร์
ผมอ่าน การวิเคราะห์ exploit แบบนี้มาหลายรูปแบบแล้ว และถ้าได้อ่านเพิ่มอีก 100 ชิ้นก็คิดว่าจะยิ่งดีใจ
ดูเหมือนเป็นตัวอย่างที่ดีของ กรอบคิดด้านความปลอดภัยที่ผิดพลาด ในการพัฒนาคอนโซล
ความคิดว่า “ข้อมูลเซฟมีแต่เราเท่านั้นที่ใช้ได้ ดังนั้นแค่พาร์สสิ่งที่เราเขียนเองก็พอ” เป็นเรื่องที่พบได้ทั่วไปในฝั่งคอนโซล แต่ผิดโดยพื้นฐาน เพราะผู้คนสามารถเตรียมข้อมูลเซฟที่สร้างขึ้นเองได้
แยกจากเรื่องนี้ คอนโซลไม่ควรมองผู้ใช้เป็นศัตรู แต่ถ้าจะทำเช่นนั้นอยู่ดี เกมเองก็ควรมีกรอบคิดด้านความปลอดภัยที่สอดคล้องกับจุดยืนนั้นด้วย
ถ้าไม่จำกัดสิ่งที่ผู้ใช้ทำได้ ก็ไม่รู้ว่าจะป้องกัน การโกงในเกมออนไลน์ ได้อย่างไร
ถ้าจะพูดแก้ต่างให้ Tony Hawk เขาเป็นโปรสเกตเตอร์ ไม่ใช่นักวิเคราะห์ความปลอดภัย
เวลาจำกัดที่เขาใช้หน้าแป้นพิมพ์ในช่วงปลายยุค 90 และต้นยุค 2000 คงไม่ได้เอาไว้ตรวจสอบ buffer overrun แต่ใช้ไปกับการทำให้ 900 McTwist ในเกมที่กำลังจะกลายเป็นซีรีส์ระดับไอคอนนั้นรู้สึกเป็นธรรมชาติมากกว่า
ได้โอกาสตรวจสอบตำนานที่เคยได้ยินตอนเด็ก ๆ แล้ว คนแรกที่ทำ 720 สำเร็จ คือ Tony Hawk หรือเปล่า?
น่าจะหมายถึง “ครั้งแรกที่มีการบันทึกไว้” แต่ถ้ามีใครเคยทำได้ก่อนก็คงป่าวประกาศไปทั่ว และคนที่จะทำได้ก็น่าจะเป็นโปรสเกตเตอร์อยู่ดี