Home Blogs Profile Contribution Policies Contact About

Sky is the limit: Frida



Frida - A world-class dynamic instrumentation framework:

Frida is used for dynamic testing of application which supports Android, iOS, and OS applications. For more, you can visit the Frida Docs page. Below I have shown the complete demonstration of the Frida tool with the android app.


Deep dive into Frida Framework:

I have developed a simple SSL pinning android application. Firstly, we will look into the code.


// I have simplify code for your understanding. You need to modify as per your need in order to use this code.public class MainActivity extends AppCompatActivity {
    Button On_Click;
    Reseponse response_data;
    private OkHttpClient okHttpClient;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView mytextview = (TextView) findViewById(R.id.response_textview);
        On_Click = findViewById(R.id.On_Click);
        On_Click.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                ssl_pinning_test();
            }
        });
    }
    private void ssl_pinning_test(){
        Thread sending_https_request = new Thread(){
                @Override
                public void run() {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            final TextView mytextview = (TextView) findViewById(R.id.response_textview);
                            String hostname = "www.google.com";
                            final CertificatePinner certificatePinner = new CertificatePinner.Builder().add(hostname,"sha256/hOokvnMxDPQLqjFuiypNhVVd3vKmfbeJsYCoVBI2asI=").add(hostname,"sha256/YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=").add(hostname,"sha256/Vjs8r4z+80wjNcr1YKj7WQboSIRi63WsWXhIMN+eWys=").build();
                            okHttpClient = new OkHttpClient.Builder().certificatePinner(certificatePinner).build();
                            final Request request = new Request.Builder().url("https://"+hostname).build();
                            final Thread t = new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        response_data = okHttpClient.newCall(request).execute();
                                        mytextview.setText("Connection establish successfully"+response_data.toString());
                                    } catch (IOException e) {
                                        mytextview.setText("Connection can not able to established : "+e.toString());
                                        e.printStackTrace();
                                    }
                                }
                            });
                        t.start();
                        }
                    });
                }
            };
        sending_https_request.start();
    }
};

Let me explain you code (for those who don't know to code),
I am using the OkHttpClient library for an HTTPS connection from an Android device to a server. There are multiple ways to implement SSL Pinning but here we are verifying via hardcoded server certificate fingerprint. (Click here to read the in-detail blog to implement SSL pinning methods)
When we open the application we can view a button that triggers an HTTPS connection with "Google.com".

On the left side, you can view the output of the "logcat" command via the ADB shell. On the right side, you can view my android mobile screen.

adb shell
logcat

Let's try to capture this request in BurpSuite. Start burp and configure the proxy in android mobile as shown below.


About SSL Pinning,
SSL pinning is the method to prevent MITM attacks and establish a secure connection between server and mobile. SSL pinning allows the application to only trust the valid or pre-defined certificate or Public Key. For more understanding read This Blog.

However, this verification is happening on the client-side means we can bypass the SSL Pinning logic. Now a day, there are many automated tools like objection(Frida) and SSLKillSwitch(iOS) available but still, sometimes we need to build our own script to bypass client-side verifications like pinning biometric and app pin.

In very rare scenarios, you need to do reverse engineering of the APK/IPA file and manipulate variables value. JadxGui can help you to retrieve the Java code from the APK file. (This similar process is not available for IPA files.)

After configuring the proxy of the android device via burp we can capture the entire communication. But, because of SSL pinning failing on the client-side (Because of burp certification), we can view below SSL HandShake error.

Observe below "logcat" output.

Starting Frida server,

# Commands to run on Linux
wget https://github.com/frida/frida/releases/download/14.0.8/frida-server-14.0.8-android-x86.xz
unxz frida-server-14.0.8-android-x86.xz
adb push "frida-server-14.0.8-android-x86" "/data/local/tmp/frida_server"
adb shell
# Commands to run on Android (Make sure you have connnected android device via USB to Laptop)
cd /data/local/tmp/
chmod +x frida_server
./frida_server &
# for more you can visit "https://frida.re/docs/android/"

With the help of the above commands, you can download and start the Frida server on an Android device. You can find many blogs to understanding the working of Frida server.

Still, let me briefly explain the working of Frida framework. You need to install Frida on a Linux system via "pip install Frida-tools". Frida is a python based application and supports javascript injection on runtime. Linux installed Frida application communicate with Frida server installed on android device via USB connection. We will send scripts from the Frida app to the Frida server.

Observe the below screenshot of the command to start the Frida server.

Before bypass SSL pinning I want you to show that how can we change the parameter value via Frida on runtime.

I have written a small Frida script to change the text area value during the runtime.


Java.perform(function() { 
    try { 
        var textViewClass = Java.use('android.widget.TextView');
        textViewClass.setText.overload("java.lang.CharSequence").implementation = function(x) { 
            var string = Java.use('java.lang.String'); 
            return this.setText(string.$new("Data is changed !!"));
        } 
    }
    catch (err) {
        console.log("Error"); 
    }
    console.log("Done !!"); 
});

Start application via Frida and click on the button.

frida -U -f [app_name] -l [path_to_js_file] --no-pause
# -U -> Indicate the Frida server is connected via USB cabble(You can give remote server ip&port)
# -f -> application name you can find via "adb shell cmd package list packages"
# -l -> file path where you have saved the script
# --no-pause -> If flag isn't set, you will be dropped into a Frida shell, where the program will sit without executing.

At the same time, you observe the log file output the same as before.
That's means is an error occurs but we hide via changing the parameter value.



SSL Pinning Bypass:

Let's bypass SSL pinning via Frida. I have write code to bypass via okHTTP and TrustManager library.


// below code will toggle the return value of SSL pinning and  trust the all certificatation.
Java.perform(function(){
    console.log("");
    console.log("Try to bypass SSL Pinning");
    var SSLContext = Java.use("javax.net.ssl.SSLContext");
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var TrustManager = Java.registerClass({
        name: 'com.sensepost.test.TrustManager',
        implements: [X509TrustManager],
        methods: {
            checkClientTrusted: function(chain, authType) {},
            checkServerTrusted: function(chain, authType) {},
            getAcceptedIssuers: function() {
                return [];
            }
        }
    });
    var TrustManagers = [TrustManager.$new()];
    var SSLContext_init = SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');
    try {
        SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {
            SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
            console.log("[+] Bypass with TrustManagers");
        };
    } catch (err) {
        console.log("[-] TrustManager Not Found");
    }
    try {
        var CertificatePinner = Java.use('okhttp3.CertificatePinner');
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
            console.log("[+] OkHTTP Bypass");    
        };
    } catch (err) {
        console.log("[-] OkHTTP 3.x Not Found")
    }
});
        

Run the Frida command to hook this script and click on button. Observe below screenshot.


We have successfully bypass SSL Pinning and able to intercept the HTTPS traffic in burpsuite.


Curious what happend at backend side!,
We have change the return value of okHTTP function and with the help of trustManager we have trust all certification including the burp. So, application validation function return the true value and start communicating with the server(via burp).


Hooking with thick client application:

Frida support all cross-platform and we are hooking Windows application with the help of Fermion. Fermion helps to create a simple script and bind with the running application.

We will attach to a simple notepad file and view all registry activity of notepad. I have written code and ProcessID of the "Notepad.exe" application. View screenshot when I clicked on attach button.

Write something and save the notepad file. Simultaneously, observe the logs generated from the below terminal.

Also, you can attached other windows application like calculator, browsers etc.

Let's capture the network logs of the Mozilla browser via Frida script only. I have written the below code to print the network packages into the Frida console.

Start the browser and capture the ProcessID via task manager. Attach the process via Frida using below command.

Navigate to browser and reload the Mozilla Firefox page.

Return to Frida console to view the network packages.




Ending notes:

We have just scratch the surface of Frida and there are many things like Biometric bypass of IOS application and client-side security control bypass.

Also, during this research, I have faced hundreds of issues that I have not discussed yet but I will update this blog in the future. Still, I hope you have learned many new things.


Thanks For Reading
Husseni Muzkkir




References:

https://frida.re/docs/home/
https://www.netguru.com/codestories/3-ways-how-to-implement-certificate-pinning-on-android
https://github.com/FuzzySecurity/Fermion
https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc



Comment Section:

Writer: You can write a comment to help me to improve this blog or ask below


Write a Comment








I also think you'll like...





More Blogs
Back to top ↑