Frida – iOS SSL Pinning Bypass

Hi readers, it’s been awhile since the last post. Today I will be talking about one of Frida method to bypass SSL Pinning. This same method can be also used to bypass Jailbreak detection check.
Note: Objection can be used to bypass SSL Pinning method used in this example.

Firstly, we would need to have Jailbroken iOS device (iPhone) with Frida installed. Once you have Jailbroken iPhone with Frida installed, plug the iPhone to your laptop and run the following command:

 frida-ps -Uai

The following command will list all the running application on your mobile:

List of running application on iOS device

Figure above shows the application name. The author will now list Classes used to detect SSL Pinning. Below code will be used to list Classes:

for (var className in ObjC.classes){ 
    if (ObjC.classes.hasOwnProperty(className))         
        {console.log(className);} }

The above code is saved as “Finding-Classes.js”. The following command is used to execute the above code:

frida -U -l .\Finding-Classes.js -f <snippet>.preview

Figure below shows output from Frida:

Found classes

Upon reviewing output from Frida, the author identified the following class is used to detect for SSL Pinning:

TSKPinningValidator

Since the author has the class that is used for SSL Pinning, the author will now identify the method used in that class. The following code is used:

console.log("[] Started: Find All Methods of a Specific Class"); 
if (ObjC.available) { 
    try { 
        var className = "TSKPinningValidator"; 
        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");

The above code is saved as “Finding_Method.js”. The following command is used to find methods in “TSKPinningValidator”:

frida -U -l .\Finding_Method.js -f <snippet>.preview

The following shows output from Frida:

Methods found in TSKPinningValidator

Upon reviewing output from Frida, it was identified the following method is used to check for SSL Pinning:

[-] - evaluateTrust:forHostname:

The author has Class and Method used. The author now will try to get return value from the method.
Note: Please set proxy from your mobile to Burp Suite.

if (ObjC.available) {

try { var className = "TSKPinningValidator";
var funcName = "- evaluateTrust:forHostname:";
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!"); }

The following command is used to execute the above code:

frida -U -l .\Return_value.js -f <snippet>.preview --no-pause

The following shows output from Frida:

Value returned for TSKPinningValidator class

Since the return value is “0x1”, the author won’t be able to proxy the connection to Burp Suite. Therefore the author will change the return value from “0x1” to “0x0” using the below script:

if (ObjC.available) {

        try {
        var className = "TSKPinningValidator";
        var funcName = "- evaluateTrust:forHostname";
        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);
            var newretval = "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!"); }

The following command is used to Bypass SSL Pinning check:

frida -U -l .\Bypass.js -f <snippet>.preview --no-pause

The following output shows that the author has successfully changed the return value:

Return valued changed

Once the return value is changed, the author is able to proxy the connection to Burp Suite as shown in the figure below:

SSL Pinning bypassed

Reference:
https://blog.attify.com/bypass-jailbreak-detection-frida-ios-applications/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.