Frida Enable Webview Debugging on Android

Webview debugging via chrome://inspect can be very useful when reverse engineering hybrid applications (Cordova etc). Using Frida we can overwrite the constructors and always enable debugging. // Enable debugging on Android webviews /* You might not need to hook all of the constructors, assuming that the ones with less parameters just use defaults; you would be able to only hook the root one (ie, the constructor that is called by all the other constructors). */ Java.perform(() => { let android_webkit_WebView = Java.use("android.webkit.WebView") android_webkit_WebView.$init.overload("android.content.Context").implementation = function (android_content_Context_0) { let returnValue = this.$init.apply(this, arguments) this.setWebContentsDebuggingEnabled(true) console.log("Enabling debugging") return returnValue } android_webkit_WebView.$init.overload("android.content.Context", "android.util.AttributeSet").implementation = function (android_content_Context_0, android_util_AttributeSet_1) { let returnValue = this.$init.apply(this, arguments) this.setWebContentsDebuggingEnabled(true) console.log("Enabling debugging") return returnValue } android_webkit_WebView.$init.overload("android.content.Context", "android.util.AttributeSet", "int").implementation = function (android_content_Context_0, android_util_AttributeSet_1, int_2) { let returnValue = this.$init.apply(this, arguments) this.setWebContentsDebuggingEnabled(true) console.log("Enabling debugging") return returnValue } android_webkit_WebView.$init.overload("android.content.Context", "android.util.AttributeSet", "int", "int").implementation = function (android_content_Context_0, android_util_AttributeSet_1, int_2, int_3) { let returnValue = this.$init.apply(this, arguments) this.setWebContentsDebuggingEnabled(true) console.log("Enabling debugging") return returnValue } android_webkit_WebView.$init.overload("android.content.Context", "android.util.AttributeSet", "int", "int", "java.util.Map", "boolean").implementation = function (android_content_Context_0, android_util_AttributeSet_1, int_2, int_3, java_util_Map_4, boolean_5) { let returnValue = this.$init.apply(this, arguments) this.setWebContentsDebuggingEnabled(true) console.log("Enabling debugging") return returnValue } android_webkit_WebView.$init.overload("android.content.Context", "android.util.AttributeSet", "int", "java.util.Map", "boolean").implementation = function (android_content_Context_0, android_util_AttributeSet_1, int_2, java_util_Map_3, boolean_4) { let returnValue = this.$init.apply(this, arguments) this.setWebContentsDebuggingEnabled(true) console.log("Enabling debugging") return returnValue } })

September 6, 2021

Frida Finding Jwts in Memory

The below C program will serve as our example, it contains a JWT in the binary that can be trivially found using strings, however lets try a different approach! #include <stdlib.h> #include <stdio.h> int main(){ char *jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"; puts(jwt); return 0; } We may not always be fortunate enough, that the JWT is embedded directly in the binary. Normally they are served by various different APIs on authentication. If you’d like to check whether or not a particular application has any JWT’s in memory, you could use something like the below. ...

August 26, 2021

Frida Childgating

Child gating refers to the process by which the same hooks applied to a parent process, are reapplied to any children spawned by the parent. Child gating should be useful in any scenario where your target is spawning multiple other binaries, for example a root detection technique may involve spawning the which binary and checking for su; This can be bypassed by: ...

August 8, 2021

Frida Cheatsheet

Precut corners and other tidbits all about Frida. Android Hook an overloaded Java function Java.perform(function() { var str = Java.use('java.lang.String'), objectClass = 'java.lang.Object'; str.equals.overload(objectClass).implementation = function(obj) { var response = str.equals.overload(objectClass).call(this, obj); if (obj) { if (obj.toString().length > 5) { console.log('what was I doing here') } } return response; } }); Hook two functions that have the same parameters and name, but different return types Say we have the following decompiled Java class: ...

July 8, 2021