บทนำ (Overviews)
จากบทความที่แล้วเราเสนอวิธีการข้ามการตรวจสอบ “Jailbreak” โดยวิธีต่าง ๆ คือ
- วิธีการ “Method Swizzling” (How to bypass the Jailbreak Detection – Method Swizzling)
- โปรแกรมที่ชื่อว่า “xCon” (How to bypass the Jailbreak Detection using xCon)
- โปรแกรม “tsProtector” คือ (How to bypass the Jailbreak Detection using tsProtector)
- โปรแกรม “Flex2” แต่มีความน่าสนใจคือ โปรแกรมสามารถ “Reverse Engineering” เพื่อเห็น “Obj-c class” และ “Obj-c method” แถมยังปรับค่าที่เป็น “Boolean” ได้อีก เหมือนการทำ “Method Swizzling” (How to bypass the Jailbreak Detection using Flex2)
มาในบทความนี้จะใช้โปรแกรมที่เรียกว่า “Frida” ซึ่งมีความง่ายมากในการใช้งาน
ขั้นตอน (Steps)
ติดตั้ง
- ติดตั้ง Frida สามารถติดตามวิธีการได้จากบทความ How to install Appmon on MACOS
- ติดตั้งโปรแกรมช่อง DVIA
- เสียบสายสัญญาณจากเครื่อง iOS ไปยัง เครื่อง Mac
- เปิดโปรแกรม DVIA
- เปิดหน้าจอ Command แล้วใช้คำสั่งตามข้างล่างเพื่อค้นหาว่า Process มีแสดงอยู่หรือไม่
frida-ps -U
- ลองเชื่อมต่อ Process ของ DVIA โดยใช้คำสั่งข้างล่าง ทดสอบดูว่าสามารถเชื่อมต่อกันได้หรือเปล่า
frida -U DVIA
- ดาวน์โหลดและติดตั้งโปรแกรม Sublime ซึ่งเป็น Text editor สำหรับเขียนคำสั่งที่ใช้งานกับ Frida https://www.sublimetext.com
ค้นหา Classes
- เราสามารถหา Classes ที่เกี่ยวข้องสำหรับ Application ที่จะตรวจสอบโดยวิธีต่อไปนี้
- อย่างไรก็ตามเราก็สามารถค้นหาด้วย Frida ได้เช่นกัน โดยการใช้โปรแกรม Sublime เขียน Script ตามข้าง
for (var className in ObjC.classes) { if (ObjC.classes.hasOwnProperty(className)) { console.log(className); } } }
- จากนั้นให้ Save as เป็น .js ดังรูป
- ทดลอง Run โดยใช้คำสั่งข้างล่างร่วมกับ Script ที่เราเขียนผมชื่อ Class มากมาย
frida -U -l class.js DVIA
- อย่างไรก็ตามเราสามารถกรองโดยใช้คำค้นหาที่ต้องการโดยใช้คำสั่ง grep ดังนี้
Oats-iMac:Desktop root1$ frida -U -l class.js DVIA | grep -i JailbreakDetectionVC JailbreakDetectionVC
ค้นหา Method
- เมื่อทราบแล้วว่ามี Class เป้าหมายที่จะต้องตรวจสอบจากนั้นเราต้องดึงชื่อ Method ที่มีอยู่ใน Class ที่เราสนใจโดยเขียน Script ดังนี้
console.log("[*] Started: Find All Methods of a Specific Class"); if (ObjC.available) { try { var className = "JailbreakDetectionVC"; var methods = eval('ObjC.classes.' + className + '.$methods'); for (var i = 0; i < methods.length; i++) { try { console.log("[-] "+methods[i]); } catch(err) { console.log("[!] Exception1: " + err.message); } } } catch(err) { console.log("[!] Exception2: " + err.message); } } else { console.log("Objective-C Runtime is not available!"); } console.log("[*] Completed: Find All Methods of a Specific Class");
- ทดลองโดยใช้คำสั่งเรียกใช้ Script เพื่อค้นหา method ดังนี้
frida -U -l method.js DVIA | grep -i 'jailbreak\|jailbroken'
- จากผลลัพธ์ข้างต้นเราจะเห็น Method ที่เกี่ยวข้อง 3 ตัว
[-] - isJailbroken [-] - jailbreakTest1Tapped: [-] - jailbreakTest2Tapped:
ตรวจสอบและแก้ไขค่า Return
- สร้าง script สำหรับ สำหรับตรวจสอบค่า Return ของ Method ที่ชื่อ isJailbreak โดยเราจะระบุชื่อ Class ที่เราสนใจและ Function ของมัน
if (ObjC.available) { try { var className = "JailbreakDetectionVC"; var funcName = "- isJailbroken"; var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]'); Interceptor.attach(hook.implementation, { onLeave: function(retval) { console.log("[*] Class Name: " + className); console.log("[*] Method Name: " + funcName); console.log("\t[-] Type of return value: " + typeof retval); console.log("\t[-] Return Value: " + retval); } }); } catch(err) { console.log("[!] Exception2: " + err.message); } } else { console.log("Objective-C Runtime is not available!"); }
- จากนั้นใช้คำสั่งเพื่อเรียกใช้งาน Script ดังกล่าว
frida -U -l return.js DVIA
- จากนั้นไปที่โปรแกรม DVIA ไปที่เมนู Jailbreak detection ทดลองกดปุ่ม Jailbreak Test 1 ดังภาพ
- ย้อนกลับไปที่ Command เราจะพบค่า Return คือ 0x1
- ดังนั้นเราจะทดลองเปลี่ยนแปลงค่าจาก 0x1 เป็น 0x0 (False) โดยเขียนคำสั่งดังนี้
if (ObjC.available) { try { var className = "JailbreakDetectionVC"; var funcName = "- isJailbroken"; var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]'); Interceptor.attach(hook.implementation, { onLeave: function(retval) { console.log("[*] Class Name: " + className); console.log("[*] Method Name: " + funcName); console.log("\t[-] Type of return value: " + typeof retval); console.log("\t[-] Original Return Value: " + retval); newretval = ptr("0x0") retval.replace(newretval) console.log("\t[-] New Return Value: " + newretval) } }); } catch(err) { console.log("[!] Exception2: " + err.message); } } else { console.log("Objective-C Runtime is not available!"); }
- Save และทดลองใช้งานคำสั่งอีกครั้ง
frida -U -l returnchanged.js DVIA
- จากนั้นทดลองคลิดที่ปุ่ม Jailbreak Test 1 จะพบว่าไม่สามารถตรวจสอบ Jailbreak ได้แล้ว
อ้างอิง
http://blog.attify.com/2017/05/06/bypass-jailbreak-detection-frida-ios-applications/