Preface

Yesterday, my nephew asked me to look into a program. He wanted to learn what this app doing and how it was doing. I swear, I am not making this up and I really have a nephew 😃

First Analysis

This Android application allows you to watch illegal streams on your Android devices. Since I don’t have an Android device, and most of the RCE tools require, a rooted device so I will use an Android emulator for this journey. We open the app, and we see the following error message.

Root Error

It says our device is rooted. I find it ironic that the ones who complain about freedom, the right to jailbreak, etc, put more protection than the others. Ok let’s fix that, we don’t need to analyze the app yet. Let’s use some Frida script to bypass the root check.

frida --codeshare AnonymousVip/theunpin -f com.xx.yy

The app starts but this time we see another error.

Proxy Error

It says, our device is using a proxy. Wow. Probably, it’s checking if it can get the property of HTTP_PROXY and it’s failing. Let’s fix that too. I downloaded the above script and modified it. I put the following snippet inside

// Old code from theunpin

function bypass_proxy(){
    var system_class = Java.use("java.lang.System"); 
    system_class.getProperty.overload('java.lang.String').implementation = function(str) {
      if(str == "http.proxyHost" || str == "http.proxyPort"){
        return null;
      }
      var retval = this.getProperty(str);
      return retval;      
    }
}
bypass_proxy()

This script returns null when the app asks for http.proxyHost or http.proxyPort. Now the app starts but we can’t see the traffic. They added SSLPinning as well. That’s it I am bringing the big guns to the battle.

Deep Analysis

We open the apk file with jadx and check what’s going on. Most Android applications use okhttp3 nowadays. We need to find out how it uses the library and disable the pinning. They obfuscated the app, so usual candidates such as okhttp3.CertificatePinner can’t be seen in the app. However, we know the function signature and Jadx can recover the file names from the decompiled app. Let’s search CertificatePinner.

Proxy Error

    /* compiled from: CertificatePinner.kt */
    public static final class b {
        private b() {
        }

        public /* synthetic */ b(kotlin.jvm.internal.g gVar) {
            this();
        }

        public final String a(Certificate certificate) {
            i.e(certificate, "certificate");
            if (certificate instanceof X509Certificate) {
                return "sha256/" + c((X509Certificate) certificate).c();
            }
            throw new IllegalArgumentException("Certificate pinning requires X509 certificates".toString());
        }

        public final f b(X509Certificate x509Certificate) {
            i.e(x509Certificate, "<this>");
            f.a aVar = f.i;
            byte[] encoded = x509Certificate.getPublicKey().getEncoded();
            i.d(encoded, "publicKey.encoded");
            return f.a.f(aVar, encoded, 0, 0, 3, (Object) null).D();
        }

        public final f c(X509Certificate x509Certificate) {
            i.e(x509Certificate, "<this>");
            f.a aVar = f.i;
            byte[] encoded = x509Certificate.getPublicKey().getEncoded();
            i.d(encoded, "publicKey.encoded");
            return f.a.f(aVar, encoded, 0, 0, 3, (Object) null).E();
        }
    }

It seems we need to patch okhttp3.g.b class. Let’s add our new addition to the above script.

// previous script

function ssl_patch() {

    Java.perform(function() {

    var callingMethod = Java.use("okhttp3.g"); 
    callingMethod.b.implementation = function() {
        return true;
    };
    });
}
ssl_patch();

The above 3 scripts are enough to patch the application and see the traffic. Traffic isn’t interesting. They have one main server which gives the URL of the second server. The second server delivers the stream URLs. This application also uses external libraries to hide sensitive information. They even hide HTTP headers such as Accept-Encoding: gzip with AES. 🤣 Why!? Just why!? They hide each header with single export as well. You can easily see the key for the decryption and see their main server address but I don’t want to waste my time anymore. I was doing so many experiments, they banned my IP as well 🤣 I guess banning my IP can stop me 🤣

It took a couple of hours to analyze this application and I am glad that I worked on this. I learned how to hook obfuscated functions, inner details of OKHTTP3’s pinning mechanism, and a couple of new tricks related to Frida. It’s a good exercise before my favorite event of the year, Flare-on. I hope I can find time to solve a couple of challenges and document them as well.

I am available for new work
Interested? Feel free to reach