diff --git a/androguard/pentest/internal/utils.js b/androguard/pentest/internal/utils.js index b87bf5d8..7e5e9609 100644 --- a/androguard/pentest/internal/utils.js +++ b/androguard/pentest/internal/utils.js @@ -1,8 +1,8 @@ // Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets -console.log('[+] LOADING INTERNAL/UTILS.JS'); +console.log("[+] LOADING INTERNAL/UTILS.JS"); -'use strict'; +("use strict"); var FLAG_SECURE_VALUE = ""; var mode = ""; @@ -12,727 +12,762 @@ var requestBody = ""; var responseHeaders = ""; var responseBody = ""; -const java_lang_threadObj = Java.use('java.lang.Thread').$new(); +const java_lang_threadObj = Java.use("java.lang.Thread").$new(); function getStackTrace() { - const stack = java_lang_threadObj.currentThread().getStackTrace(); - var buff = []; - //for (var i = 2; i < stack.length; i++) { - for (var i = 2; i < 4; i++) { - buff.push(stack[i].toString()); - } - return buff; + const stack = java_lang_threadObj.currentThread().getStackTrace(); + var buff = []; + //for (var i = 2; i < stack.length; i++) { + for (var i = 2; i < 4; i++) { + buff.push(stack[i].toString()); + } + return buff; } function flatten(obj) { - var ret = {}; - for (var i in obj) { - ret[i] = obj[i]; - } - return ret; + var ret = {}; + for (var i in obj) { + ret[i] = obj[i]; + } + return ret; } const Packet = { - id: 'AG-EVENT', - payload: '', + id: "AG-EVENT", + payload: "", - toString() { - return JSON.stringify(flatten(this)); - }, + toString() { + return JSON.stringify(flatten(this)); + }, - send() { - send(this.toString(), this.payload); - }, + send() { + send(this.toString(), this.payload); + }, }; // Create a new Androguard Packet function agPacket(source) { - const obj = Object.create(Packet); + const obj = Object.create(Packet); - obj.timestamp = Date.now(); - obj.stacktrace = getStackTrace(); + obj.timestamp = Date.now(); + obj.stacktrace = getStackTrace(); - // Assign dynamic data from hooks to the packet - Object.assign(obj, source); - - return obj; + // Assign dynamic data from hooks to the packet + Object.assign(obj, source); + + return obj; } // Create a new Androguard System Packet function agSysPacket(source) { - const obj = Object.create(Packet); - obj.id = "AG-SYSTEM"; - obj.timestamp = Date.now(); + const obj = Object.create(Packet); + obj.id = "AG-SYSTEM"; + obj.timestamp = Date.now(); - // Assign dynamic data from hooks to the packet - Object.assign(obj, source); - - return obj; + // Assign dynamic data from hooks to the packet + Object.assign(obj, source); + + return obj; } // Create a new Androguard Binder Packet function agBinderPacket(source, payload) { - const obj = Object.create(Packet); - obj.id = "AG-BINDER"; - obj.timestamp = Date.now(); - obj.payload = payload; + const obj = Object.create(Packet); + obj.id = "AG-BINDER"; + obj.timestamp = Date.now(); + obj.payload = payload; - // Assign dynamic data from hooks to the packet - Object.assign(obj, source); - - return obj; + // Assign dynamic data from hooks to the packet + Object.assign(obj, source); + + return obj; } function dumpIntent(intent) { - var cmp = "" - if (intent.getComponent()) { - cmp = intent.getComponent().getClassName() - } + var cmp = ""; + if (intent.getComponent()) { + cmp = intent.getComponent().getClassName(); + } - return {action: intent.getAction(), cmp: cmp, flags: intent.getFlags()} + return { action: intent.getAction(), cmp: cmp, flags: intent.getFlags() }; } function dumpReceiver(receiver) { - if (receiver != null) { - return { name: receiver.getClass().toString() } - } + if (receiver != null) { + return { name: receiver.getClass().toString() }; + } - return {} + return {}; } function dumpFilter(filter) { - if (filter != null) { - actions_list = [] - categories_list = [] + if (filter != null) { + actions_list = []; + categories_list = []; - for (iAction = 0; iAction < filter.countActions(); iAction++) { - actions_list.push(filter.getAction(iAction)); + for (iAction = 0; iAction < filter.countActions(); iAction++) { + actions_list.push(filter.getAction(iAction)); + } + + for (iCategory = 0; iCategory < filter.countCategories(); iCategory++) { + categories_list.push(filter.getCategory(iCategory)); + } + + return { actions: actions_list, categories: categories_list }; } - for (iCategory = 0; iCategory < filter.countCategories(); iCategory++) { - categories_list.push(filter.getCategory(iCategory)); - } - - return {actions: actions_list, categories: categories_list} - } - - return {} + return {}; } -function dumpWebview(wv){ - return { - getAllowContentAccess: wv.getSettings().getAllowContentAccess(), getJavaScriptEnabled: wv.getSettings().getJavaScriptEnabled(), getAllowFileAccess: wv.getSettings().getAllowFileAccess(), - getAllowFileAccessFromFileURLs: wv.getSettings().getAllowFileAccessFromFileURLs(), getAllowUniversalAccessFromFileURLs: wv.getSettings().getAllowUniversalAccessFromFileURLs() - } +function dumpWebview(wv) { + return { + getAllowContentAccess: wv.getSettings().getAllowContentAccess(), + getJavaScriptEnabled: wv.getSettings().getJavaScriptEnabled(), + getAllowFileAccess: wv.getSettings().getAllowFileAccess(), + getAllowFileAccessFromFileURLs: wv + .getSettings() + .getAllowFileAccessFromFileURLs(), + getAllowUniversalAccessFromFileURLs: wv + .getSettings() + .getAllowUniversalAccessFromFileURLs(), + }; } var Color = { - RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", Green: "2;01", Purple: "5;01", Red: "1;01", Yellow: "3;01", - Light: { - Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", Green: "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11" - } + RESET: "\x1b[39;49;00m", + Black: "0;01", + Blue: "4;01", + Cyan: "6;01", + Gray: "7;11", + Green: "2;01", + Purple: "5;01", + Red: "1;01", + Yellow: "3;01", + Light: { + Black: "0;11", + Blue: "4;11", + Cyan: "6;11", + Gray: "7;01", + Green: "2;11", + Purple: "5;11", + Red: "1;11", + Yellow: "3;11", + }, }; -function enumerateModules(){ - - var modules = Process.enumerateModules(); - colorLog('[+] Enumerating loaded modules:',{c: Color.Blue}); +function enumerateModules() { + var modules = Process.enumerateModules(); + colorLog("[+] Enumerating loaded modules:", { c: Color.Blue }); - for (var i = 0; i < modules.length; i++) - console.log(modules[i].path + modules[i].name); - - + for (var i = 0; i < modules.length; i++) + console.log(modules[i].path + modules[i].name); } - function getApplicationContext() { - return Java.use('android.app.ActivityThread').currentApplication().getApplicationContext(); - } - -function traceClass(targetClass) -{ - - console.log("entering traceClass") - - var hook = Java.use(targetClass); - var methods = hook.class.getDeclaredMethods(); - hook.$dispose(); - - console.log("entering pasedMethods") - - var parsedMethods = []; - methods.forEach(function(method) { - try{ - parsedMethods.push(method.toString().replace(targetClass + ".", "TOKEN").match(/\sTOKEN(.*)\(/)[1]); - } - catch(err){} - }); - - console.log("entering traceMethods") - - - var targets = uniqBy(parsedMethods, JSON.stringify); - targets.forEach(function(targetMethod) { - try{ - traceMethod(targetClass + "." + targetMethod); - } - catch(err){} - }); + return Java.use("android.app.ActivityThread") + .currentApplication() + .getApplicationContext(); } -function uniqBy(array, key) -{ - var seen = {}; - return array.filter(function(item) { - var k = key(item); - return seen.hasOwnProperty(k) ? false : (seen[k] = true); - }); +function traceClass(targetClass) { + colorLog("[+] entering traceClass", { c: Color.Red }); + + var hook = Java.use(targetClass); + var methods = hook.class.getDeclaredMethods(); + hook.$dispose(); + + colorLog("[+] entering parsedMethods", { c: Color.Blue }); + + var parsedMethods = []; + methods.forEach(function (method) { + try { + parsedMethods.push( + method + .toString() + .replace(targetClass + ".", "TOKEN") + .match(/\sTOKEN(.*)\(/)[1], + ); + } catch (err) {} + }); + + colorLog("[+] entering traceMethods", { c: Color.Blue }); + + var targets = uniqBy(parsedMethods, JSON.stringify); + targets.forEach(function (targetMethod) { + try { + traceMethod(targetClass + "." + targetMethod); + } catch (err) {} + }); } -function traceMethod(targetClassMethod) -{ - var delim = targetClassMethod.lastIndexOf("."); - if (delim === -1) return; - - var targetClass = targetClassMethod.slice(0, delim) - var targetMethod = targetClassMethod.slice(delim + 1, targetClassMethod.length) - - var hook = Java.use(targetClass); - var overloadCount = hook[targetMethod].overloads.length; - - colorLog("Tracing " + targetClassMethod + " [" + overloadCount + " overload(s)]",{c: Color.Green}); - - for (var i = 0; i < overloadCount; i++) { - - hook[targetMethod].overloads[i].implementation = function() { - colorLog("\n[+] Entering: " + targetClassMethod,{c: Color.Red}); - - if (arguments.length) console.log(); - for (var j = 0; j < arguments.length; j++) { - console.log("\targ[" + j + "]: " + arguments[j]); - } - - // print retval - var retval = this[targetMethod].apply(this, arguments); // rare crash (Frida bug?) - console.log("\n\tRetval: " + retval); - colorLog("\n[-] Exiting " + targetClassMethod); - return retval; - } - } +function uniqBy(array, key) { + var seen = {}; + return array.filter(function (item) { + var k = key(item); + return seen.hasOwnProperty(k) ? false : (seen[k] = true); + }); } +function traceMethod(targetClassMethod) { + var delim = targetClassMethod.lastIndexOf("."); + if (delim === -1) return; + + var targetClass = targetClassMethod.slice(0, delim); + var targetMethod = targetClassMethod.slice( + delim + 1, + targetClassMethod.length, + ); + + var hook = Java.use(targetClass); + var overloadCount = hook[targetMethod].overloads.length; + + colorLog( + "Tracing " + targetClassMethod + " [" + overloadCount + " overload(s)]", + { c: Color.Green }, + ); + + for (var i = 0; i < overloadCount; i++) { + hook[targetMethod].overloads[i].implementation = function () { + colorLog("\n[+] Entering: " + targetClassMethod, { + c: Color.Yellow, + }); + + if (arguments.length) console.log(); + for (var j = 0; j < arguments.length; j++) { + agPacket({ arg: arguments[j] }).send(); + } + + var retval = this[targetMethod].apply(this, arguments); + agPacket({ ret: retval }).send(); + colorLog("\n[-] Exiting " + targetClassMethod); + return retval; + }; + } +} var Utf8 = { - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - } - return utftext; - }, - // publi - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string += String.fromCharCode(c); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} - + encode: function (string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } else if (c > 127 && c < 2048) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + }, + // publi + decode: function (utftext) { + var string = ""; + var i = 0; + var c = (c1 = c2 = 0); + while (i < utftext.length) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } else if (c > 191 && c < 224) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode( + ((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63), + ); + i += 3; + } + } + return string; + }, +}; function describeJavaClass(className) { - var jClass = Java.use(className); - console.log(JSON.stringify({ - _name: className, - _methods: Object.getOwnPropertyNames(jClass.__proto__).filter(function(m) { - return !m.startsWith('$') // filter out Frida related special properties - || m == 'class' || m == 'constructor' // optional - }), - _fields: jClass.class.getFields().map(function(f) { - return f.toString() - }) - }, null, 2)); + var jClass = Java.use(className); + console.log( + JSON.stringify( + { + _name: className, + _methods: Object.getOwnPropertyNames(jClass.__proto__).filter( + function (m) { + return ( + !m.startsWith("$") || // filter out Frida related special properties + m == "class" || + m == "constructor" + ); // optional + }, + ), + _fields: jClass.class.getFields().map(function (f) { + return f.toString(); + }), + }, + null, + 2, + ), + ); } var colorLog = function (input, kwargs) { - kwargs = kwargs || {}; - var logLevel = kwargs['l'] || 'log', colorPrefix = '\x1b[3', colorSuffix = 'm'; - if (typeof input === 'object') - input = JSON.stringify(input, null, kwargs['i'] ? 2 : null); - if (kwargs['c']) - input = colorPrefix + kwargs['c'] + colorSuffix + input + Color.RESET; - console[logLevel](input); + kwargs = kwargs || {}; + var logLevel = kwargs["l"] || "log", + colorPrefix = "\x1b[3", + colorSuffix = "m"; + if (typeof input === "object") + input = JSON.stringify(input, null, kwargs["i"] ? 2 : null); + if (kwargs["c"]) + input = colorPrefix + kwargs["c"] + colorSuffix + input + Color.RESET; + console[logLevel](input); }; -var processArgs = function(command, envp, dir) { +var processArgs = function (command, envp, dir) { var output = {}; if (command) { - console.log("Command: " + command); - // output.command = command; + console.log("Command: " + command); + // output.command = command; } if (envp) { - console.log("Environment: " + envp); - // output.envp = envp; + console.log("Environment: " + envp); + // output.envp = envp; } if (dir) { - console.log("Working Directory: " + dir); - // output.dir = dir; + console.log("Working Directory: " + dir); + // output.dir = dir; } // return output; - } - +}; -var _byteArraytoHexString = function(byteArray) { - if (!byteArray) { return 'null'; } +var _byteArraytoHexString = function (byteArray) { + if (!byteArray) { + return "null"; + } if (byteArray.map) { - return byteArray.map(function(byte) { - return ('0' + (byte & 0xFF).toString(16)).slice(-2); - }).join(''); + return byteArray + .map(function (byte) { + return ("0" + (byte & 0xff).toString(16)).slice(-2); + }) + .join(""); } else { - return byteArray + ""; + return byteArray + ""; } - } - - var updateInput = function(input) { +}; + +var updateInput = function (input) { if (input.length && input.length > 0) { - var normalized = byteArraytoHexString(input); + var normalized = byteArraytoHexString(input); } else if (input.array) { - var normalized = byteArraytoHexString(input.array()); + var normalized = byteArraytoHexString(input.array()); } else { - var normalized = input.toString(); + var normalized = input.toString(); } return normalized; - } - +}; -var byteArraytoHexString = function(byteArray) { - if (byteArray && byteArray.map) { - return byteArray.map(function(byte) { - return ('0' + (byte & 0xFF).toString(16)).slice(-2); - }).join('') - } else { - return JSON.stringify(byteArray); - } -} - -var hexToAscii = function(input) { - var hex = input.toString(); - var str = ''; - for (var i = 0; i < hex.length; i += 2) - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - return str; -} - -var displayString = function(input){ - var str = input.replace('[',''); - var str1 = str.replace(']',''); - var res = str1.split(','); - var ret = ''; - for(var i = 0; i 31 && res[i]<127) - ret += String.fromCharCode(res[i]); - else ret += ' '; - - } - - colorLog("[+] PARSING TO STRING: " + ret,{c:Color.Green}); - colorLog('',{c:Color.RESET}); -} -var normalize = function(input) { - if (input.length && input.length > 0) { - var normalized = byteArraytoHexString(input); - } else if (input.array) { - var normalized = byteArraytoHexString(input.array()); +var byteArraytoHexString = function (byteArray) { + if (byteArray && byteArray.map) { + return byteArray + .map(function (byte) { + return ("0" + (byte & 0xff).toString(16)).slice(-2); + }) + .join(""); } else { - var normalized = input.toString(); + return JSON.stringify(byteArray); + } +}; + +var hexToAscii = function (input) { + var hex = input.toString(); + var str = ""; + for (var i = 0; i < hex.length; i += 2) + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + return str; +}; + +var displayString = function (input) { + var str = input.replace("[", ""); + var str1 = str.replace("]", ""); + var res = str1.split(","); + var ret = ""; + for (var i = 0; i < res.length; i++) { + if (res[i] > 31 && res[i] < 127) ret += String.fromCharCode(res[i]); + else ret += " "; + } + + colorLog("[+] PARSING TO STRING: " + ret, { c: Color.Green }); + colorLog("", { c: Color.RESET }); +}; +var normalize = function (input) { + if (input.length && input.length > 0) { + var normalized = byteArraytoHexString(input); + } else if (input.array) { + var normalized = byteArraytoHexString(input.array()); + } else { + var normalized = input.toString(); } return normalized; - } +}; -var normalizeInput = function(input) { - if (input.array) { - var normalized = byteArraytoHexString(input.array()); - } else if (input.length && input.length > 0) { - var normalized = byteArraytoHexString(input); - } else { - var normalized = JSON.stringify(input); - } - return normalized; -} - -var getMode = function(Cipher, mode) { - if (mode === 2) { - mode = "DECRYPT"; - } else if (mode === 1) { - mode = "ENCRYPT"; - } - return mode; -} - -var getRandomValue = function(arg) { - if (!arg) { return 'null'; } - var type = arg.toString().split('@')[0].split('.'); - type = type[type.length - 1]; - if (type === "SecureRandom") { - if (arg.getSeed) { - return byteArraytoHexString(arg.getSeed(10)); +var normalizeInput = function (input) { + if (input.array) { + var normalized = byteArraytoHexString(input.array()); + } else if (input.length && input.length > 0) { + var normalized = byteArraytoHexString(input); + } else { + var normalized = JSON.stringify(input); } - } -} + return normalized; +}; -var normalizeKey = function(cert_or_key) { - var type = cert_or_key.toString().split('@')[0].split('.'); - type = type[type.length - 1]; - if (type === "SecretKeySpec") { - return byteArraytoHexString(cert_or_key.getEncoded()); - } else { - return "non-SecretKeySpec: " + cert_or_key.toString() + ", encoded: " + byteArraytoHexString(cert_or_key.getEncoded()) + ", object: " + JSON.stringify(cert_or_key); - } - -} -var byteArrayToString = function(input) { - var buffer = Java.array('byte', input); - - var result = ""; - - for(var i = 0; i < buffer.length; i++) { - if(buffer[i] > 31 && buffer[i]<127) { - result += (String.fromCharCode(buffer[i])); - } - else { - result += ' '; - } - } - - return result; -} - -var byteArrayToStringE = function(input){ - var buffer = Java.array('byte', input); - var result = ""; - var unprintable = false; - for(var i = 0; i < buffer.length; ++i){ - if(buffer[i] > 31 && buffer[i]<127) - result+= (String.fromCharCode(buffer[i])); - else { - unprintable = true; - result = "Input cant be transformed to ascii string"; - break; - } - +var getMode = function (Cipher, mode) { + if (mode === 2) { + mode = "DECRYPT"; + } else if (mode === 1) { + mode = "ENCRYPT"; } - return result; -} + return mode; +}; +var getRandomValue = function (arg) { + if (!arg) { + return "null"; + } + var type = arg.toString().split("@")[0].split("."); + type = type[type.length - 1]; + if (type === "SecureRandom") { + if (arg.getSeed) { + return byteArraytoHexString(arg.getSeed(10)); + } + } +}; -function readStreamToHex (stream) { +var normalizeKey = function (cert_or_key) { + var type = cert_or_key.toString().split("@")[0].split("."); + type = type[type.length - 1]; + if (type === "SecretKeySpec") { + return byteArraytoHexString(cert_or_key.getEncoded()); + } else { + return ( + "non-SecretKeySpec: " + + cert_or_key.toString() + + ", encoded: " + + byteArraytoHexString(cert_or_key.getEncoded()) + + ", object: " + + JSON.stringify(cert_or_key) + ); + } +}; +var byteArrayToString = function (input) { + var buffer = Java.array("byte", input); + + var result = ""; + + for (var i = 0; i < buffer.length; i++) { + if (buffer[i] > 31 && buffer[i] < 127) { + result += String.fromCharCode(buffer[i]); + } else { + result += " "; + } + } + + return result; +}; + +var byteArrayToStringE = function (input) { + var buffer = Java.array("byte", input); + var result = ""; + var unprintable = false; + for (var i = 0; i < buffer.length; ++i) { + if (buffer[i] > 31 && buffer[i] < 127) + result += String.fromCharCode(buffer[i]); + else { + unprintable = true; + result = "Input cant be transformed to ascii string"; + break; + } + } + return result; +}; + +function readStreamToHex(stream) { var data = []; var byteRead = stream.read(); - while (byteRead != -1) - { - data.push( ('0' + (byteRead & 0xFF).toString(16)).slice(-2) ); - /* <---------------- binary to hex ---------------> */ + while (byteRead != -1) { + data.push(("0" + (byteRead & 0xff).toString(16)).slice(-2)); + /* <---------------- binary to hex ---------------> */ byteRead = stream.read(); } stream.close(); - return data.join(''); + return data.join(""); } - - const jni_struct_array = [ - "reserved0", - "reserved1", - "reserved2", - "reserved3", - "GetVersion", - "DefineClass", - "FindClass", - "FromReflectedMethod", - "FromReflectedField", - "ToReflectedMethod", - "GetSuperclass", - "IsAssignableFrom", - "ToReflectedField", - "Throw", - "ThrowNew", - "ExceptionOccurred", - "ExceptionDescribe", - "ExceptionClear", - "FatalError", - "PushLocalFrame", - "PopLocalFrame", - "NewGlobalRef", - "DeleteGlobalRef", - "DeleteLocalRef", - "IsSameObject", - "NewLocalRef", - "EnsureLocalCapacity", - "AllocObject", - "NewObject", - "NewObjectV", - "NewObjectA", - "GetObjectClass", - "IsInstanceOf", - "GetMethodID", - "CallObjectMethod", - "CallObjectMethodV", - "CallObjectMethodA", - "CallBooleanMethod", - "CallBooleanMethodV", - "CallBooleanMethodA", - "CallByteMethod", - "CallByteMethodV", - "CallByteMethodA", - "CallCharMethod", - "CallCharMethodV", - "CallCharMethodA", - "CallShortMethod", - "CallShortMethodV", - "CallShortMethodA", - "CallIntMethod", - "CallIntMethodV", - "CallIntMethodA", - "CallLongMethod", - "CallLongMethodV", - "CallLongMethodA", - "CallFloatMethod", - "CallFloatMethodV", - "CallFloatMethodA", - "CallDoubleMethod", - "CallDoubleMethodV", - "CallDoubleMethodA", - "CallVoidMethod", - "CallVoidMethodV", - "CallVoidMethodA", - "CallNonvirtualObjectMethod", - "CallNonvirtualObjectMethodV", - "CallNonvirtualObjectMethodA", - "CallNonvirtualBooleanMethod", - "CallNonvirtualBooleanMethodV", - "CallNonvirtualBooleanMethodA", - "CallNonvirtualByteMethod", - "CallNonvirtualByteMethodV", - "CallNonvirtualByteMethodA", - "CallNonvirtualCharMethod", - "CallNonvirtualCharMethodV", - "CallNonvirtualCharMethodA", - "CallNonvirtualShortMethod", - "CallNonvirtualShortMethodV", - "CallNonvirtualShortMethodA", - "CallNonvirtualIntMethod", - "CallNonvirtualIntMethodV", - "CallNonvirtualIntMethodA", - "CallNonvirtualLongMethod", - "CallNonvirtualLongMethodV", - "CallNonvirtualLongMethodA", - "CallNonvirtualFloatMethod", - "CallNonvirtualFloatMethodV", - "CallNonvirtualFloatMethodA", - "CallNonvirtualDoubleMethod", - "CallNonvirtualDoubleMethodV", - "CallNonvirtualDoubleMethodA", - "CallNonvirtualVoidMethod", - "CallNonvirtualVoidMethodV", - "CallNonvirtualVoidMethodA", - "GetFieldID", - "GetObjectField", - "GetBooleanField", - "GetByteField", - "GetCharField", - "GetShortField", - "GetIntField", - "GetLongField", - "GetFloatField", - "GetDoubleField", - "SetObjectField", - "SetBooleanField", - "SetByteField", - "SetCharField", - "SetShortField", - "SetIntField", - "SetLongField", - "SetFloatField", - "SetDoubleField", - "GetStaticMethodID", - "CallStaticObjectMethod", - "CallStaticObjectMethodV", - "CallStaticObjectMethodA", - "CallStaticBooleanMethod", - "CallStaticBooleanMethodV", - "CallStaticBooleanMethodA", - "CallStaticByteMethod", - "CallStaticByteMethodV", - "CallStaticByteMethodA", - "CallStaticCharMethod", - "CallStaticCharMethodV", - "CallStaticCharMethodA", - "CallStaticShortMethod", - "CallStaticShortMethodV", - "CallStaticShortMethodA", - "CallStaticIntMethod", - "CallStaticIntMethodV", - "CallStaticIntMethodA", - "CallStaticLongMethod", - "CallStaticLongMethodV", - "CallStaticLongMethodA", - "CallStaticFloatMethod", - "CallStaticFloatMethodV", - "CallStaticFloatMethodA", - "CallStaticDoubleMethod", - "CallStaticDoubleMethodV", - "CallStaticDoubleMethodA", - "CallStaticVoidMethod", - "CallStaticVoidMethodV", - "CallStaticVoidMethodA", - "GetStaticFieldID", - "GetStaticObjectField", - "GetStaticBooleanField", - "GetStaticByteField", - "GetStaticCharField", - "GetStaticShortField", - "GetStaticIntField", - "GetStaticLongField", - "GetStaticFloatField", - "GetStaticDoubleField", - "SetStaticObjectField", - "SetStaticBooleanField", - "SetStaticByteField", - "SetStaticCharField", - "SetStaticShortField", - "SetStaticIntField", - "SetStaticLongField", - "SetStaticFloatField", - "SetStaticDoubleField", - "NewString", - "GetStringLength", - "GetStringChars", - "ReleaseStringChars", - "NewStringUTF", - "GetStringUTFLength", - "GetStringUTFChars", - "ReleaseStringUTFChars", - "GetArrayLength", - "NewObjectArray", - "GetObjectArrayElement", - "SetObjectArrayElement", - "NewBooleanArray", - "NewByteArray", - "NewCharArray", - "NewShortArray", - "NewIntArray", - "NewLongArray", - "NewFloatArray", - "NewDoubleArray", - "GetBooleanArrayElements", - "GetByteArrayElements", - "GetCharArrayElements", - "GetShortArrayElements", - "GetIntArrayElements", - "GetLongArrayElements", - "GetFloatArrayElements", - "GetDoubleArrayElements", - "ReleaseBooleanArrayElements", - "ReleaseByteArrayElements", - "ReleaseCharArrayElements", - "ReleaseShortArrayElements", - "ReleaseIntArrayElements", - "ReleaseLongArrayElements", - "ReleaseFloatArrayElements", - "ReleaseDoubleArrayElements", - "GetBooleanArrayRegion", - "GetByteArrayRegion", - "GetCharArrayRegion", - "GetShortArrayRegion", - "GetIntArrayRegion", - "GetLongArrayRegion", - "GetFloatArrayRegion", - "GetDoubleArrayRegion", - "SetBooleanArrayRegion", - "SetByteArrayRegion", - "SetCharArrayRegion", - "SetShortArrayRegion", - "SetIntArrayRegion", - "SetLongArrayRegion", - "SetFloatArrayRegion", - "SetDoubleArrayRegion", - "RegisterNatives", - "UnregisterNatives", - "MonitorEnter", - "MonitorExit", - "GetJavaVM", - "GetStringRegion", - "GetStringUTFRegion", - "GetPrimitiveArrayCritical", - "ReleasePrimitiveArrayCritical", - "GetStringCritical", - "ReleaseStringCritical", - "NewWeakGlobalRef", - "DeleteWeakGlobalRef", - "ExceptionCheck", - "NewDirectByteBuffer", - "GetDirectBufferAddress", - "GetDirectBufferCapacity", - "GetObjectRefType" -] + "reserved0", + "reserved1", + "reserved2", + "reserved3", + "GetVersion", + "DefineClass", + "FindClass", + "FromReflectedMethod", + "FromReflectedField", + "ToReflectedMethod", + "GetSuperclass", + "IsAssignableFrom", + "ToReflectedField", + "Throw", + "ThrowNew", + "ExceptionOccurred", + "ExceptionDescribe", + "ExceptionClear", + "FatalError", + "PushLocalFrame", + "PopLocalFrame", + "NewGlobalRef", + "DeleteGlobalRef", + "DeleteLocalRef", + "IsSameObject", + "NewLocalRef", + "EnsureLocalCapacity", + "AllocObject", + "NewObject", + "NewObjectV", + "NewObjectA", + "GetObjectClass", + "IsInstanceOf", + "GetMethodID", + "CallObjectMethod", + "CallObjectMethodV", + "CallObjectMethodA", + "CallBooleanMethod", + "CallBooleanMethodV", + "CallBooleanMethodA", + "CallByteMethod", + "CallByteMethodV", + "CallByteMethodA", + "CallCharMethod", + "CallCharMethodV", + "CallCharMethodA", + "CallShortMethod", + "CallShortMethodV", + "CallShortMethodA", + "CallIntMethod", + "CallIntMethodV", + "CallIntMethodA", + "CallLongMethod", + "CallLongMethodV", + "CallLongMethodA", + "CallFloatMethod", + "CallFloatMethodV", + "CallFloatMethodA", + "CallDoubleMethod", + "CallDoubleMethodV", + "CallDoubleMethodA", + "CallVoidMethod", + "CallVoidMethodV", + "CallVoidMethodA", + "CallNonvirtualObjectMethod", + "CallNonvirtualObjectMethodV", + "CallNonvirtualObjectMethodA", + "CallNonvirtualBooleanMethod", + "CallNonvirtualBooleanMethodV", + "CallNonvirtualBooleanMethodA", + "CallNonvirtualByteMethod", + "CallNonvirtualByteMethodV", + "CallNonvirtualByteMethodA", + "CallNonvirtualCharMethod", + "CallNonvirtualCharMethodV", + "CallNonvirtualCharMethodA", + "CallNonvirtualShortMethod", + "CallNonvirtualShortMethodV", + "CallNonvirtualShortMethodA", + "CallNonvirtualIntMethod", + "CallNonvirtualIntMethodV", + "CallNonvirtualIntMethodA", + "CallNonvirtualLongMethod", + "CallNonvirtualLongMethodV", + "CallNonvirtualLongMethodA", + "CallNonvirtualFloatMethod", + "CallNonvirtualFloatMethodV", + "CallNonvirtualFloatMethodA", + "CallNonvirtualDoubleMethod", + "CallNonvirtualDoubleMethodV", + "CallNonvirtualDoubleMethodA", + "CallNonvirtualVoidMethod", + "CallNonvirtualVoidMethodV", + "CallNonvirtualVoidMethodA", + "GetFieldID", + "GetObjectField", + "GetBooleanField", + "GetByteField", + "GetCharField", + "GetShortField", + "GetIntField", + "GetLongField", + "GetFloatField", + "GetDoubleField", + "SetObjectField", + "SetBooleanField", + "SetByteField", + "SetCharField", + "SetShortField", + "SetIntField", + "SetLongField", + "SetFloatField", + "SetDoubleField", + "GetStaticMethodID", + "CallStaticObjectMethod", + "CallStaticObjectMethodV", + "CallStaticObjectMethodA", + "CallStaticBooleanMethod", + "CallStaticBooleanMethodV", + "CallStaticBooleanMethodA", + "CallStaticByteMethod", + "CallStaticByteMethodV", + "CallStaticByteMethodA", + "CallStaticCharMethod", + "CallStaticCharMethodV", + "CallStaticCharMethodA", + "CallStaticShortMethod", + "CallStaticShortMethodV", + "CallStaticShortMethodA", + "CallStaticIntMethod", + "CallStaticIntMethodV", + "CallStaticIntMethodA", + "CallStaticLongMethod", + "CallStaticLongMethodV", + "CallStaticLongMethodA", + "CallStaticFloatMethod", + "CallStaticFloatMethodV", + "CallStaticFloatMethodA", + "CallStaticDoubleMethod", + "CallStaticDoubleMethodV", + "CallStaticDoubleMethodA", + "CallStaticVoidMethod", + "CallStaticVoidMethodV", + "CallStaticVoidMethodA", + "GetStaticFieldID", + "GetStaticObjectField", + "GetStaticBooleanField", + "GetStaticByteField", + "GetStaticCharField", + "GetStaticShortField", + "GetStaticIntField", + "GetStaticLongField", + "GetStaticFloatField", + "GetStaticDoubleField", + "SetStaticObjectField", + "SetStaticBooleanField", + "SetStaticByteField", + "SetStaticCharField", + "SetStaticShortField", + "SetStaticIntField", + "SetStaticLongField", + "SetStaticFloatField", + "SetStaticDoubleField", + "NewString", + "GetStringLength", + "GetStringChars", + "ReleaseStringChars", + "NewStringUTF", + "GetStringUTFLength", + "GetStringUTFChars", + "ReleaseStringUTFChars", + "GetArrayLength", + "NewObjectArray", + "GetObjectArrayElement", + "SetObjectArrayElement", + "NewBooleanArray", + "NewByteArray", + "NewCharArray", + "NewShortArray", + "NewIntArray", + "NewLongArray", + "NewFloatArray", + "NewDoubleArray", + "GetBooleanArrayElements", + "GetByteArrayElements", + "GetCharArrayElements", + "GetShortArrayElements", + "GetIntArrayElements", + "GetLongArrayElements", + "GetFloatArrayElements", + "GetDoubleArrayElements", + "ReleaseBooleanArrayElements", + "ReleaseByteArrayElements", + "ReleaseCharArrayElements", + "ReleaseShortArrayElements", + "ReleaseIntArrayElements", + "ReleaseLongArrayElements", + "ReleaseFloatArrayElements", + "ReleaseDoubleArrayElements", + "GetBooleanArrayRegion", + "GetByteArrayRegion", + "GetCharArrayRegion", + "GetShortArrayRegion", + "GetIntArrayRegion", + "GetLongArrayRegion", + "GetFloatArrayRegion", + "GetDoubleArrayRegion", + "SetBooleanArrayRegion", + "SetByteArrayRegion", + "SetCharArrayRegion", + "SetShortArrayRegion", + "SetIntArrayRegion", + "SetLongArrayRegion", + "SetFloatArrayRegion", + "SetDoubleArrayRegion", + "RegisterNatives", + "UnregisterNatives", + "MonitorEnter", + "MonitorExit", + "GetJavaVM", + "GetStringRegion", + "GetStringUTFRegion", + "GetPrimitiveArrayCritical", + "ReleasePrimitiveArrayCritical", + "GetStringCritical", + "ReleaseStringCritical", + "NewWeakGlobalRef", + "DeleteWeakGlobalRef", + "ExceptionCheck", + "NewDirectByteBuffer", + "GetDirectBufferAddress", + "GetDirectBufferCapacity", + "GetObjectRefType", +]; /* Calculate the given funcName address from the JNIEnv pointer */ -function getJNIFunctionAdress(jnienv_addr,func_name){ - var offset = jni_struct_array.indexOf(func_name) * Process.pointerSize - - // console.log("offset : 0x" + offset.toString(16)) - - return Memory.readPointer(jnienv_addr.add(offset)) +function getJNIFunctionAdress(jnienv_addr, func_name) { + var offset = jni_struct_array.indexOf(func_name) * Process.pointerSize; + + // console.log("offset : 0x" + offset.toString(16)) + + return Memory.readPointer(jnienv_addr.add(offset)); } - // Hook all function to have an overview of the function called -function hook_all(jnienv_addr){ - jni_struct_array.forEach(function(func_name){ - // Calculating the address of the function - if(!func_name.includes("reserved")) - { - var func_addr = getJNIFunctionAdress(jnienv_addr,func_name) - Interceptor.attach(func_addr,{ - onEnter: function(args){ - console.log("[+] Entered : " + func_name) - } - }) - } - }) +function hook_all(jnienv_addr) { + jni_struct_array.forEach(function (func_name) { + // Calculating the address of the function + if (!func_name.includes("reserved")) { + var func_addr = getJNIFunctionAdress(jnienv_addr, func_name); + Interceptor.attach(func_addr, { + onEnter: function (args) { + console.log("[+] Entered : " + func_name); + }, + }); + } + }); } function inspectObject(obj) { @@ -742,123 +777,147 @@ function inspectObject(obj) { const fields = obj_class.getDeclaredFields(); const methods = obj_class.getMethods(); console.log("Inspecting " + obj.getClass().toString()); - console.log("[+]------------------------------Fields------------------------------:"); - for (var i in fields) - console.log("\t\t" + fields[i].toString()); - console.log("[+]------------------------------Methods-----------------------------:"); - for (var i in methods) - console.log("\t\t" + methods[i].toString()); + console.log( + "[+]------------------------------Fields------------------------------:", + ); + for (var i in fields) console.log("\t\t" + fields[i].toString()); + console.log( + "[+]------------------------------Methods-----------------------------:", + ); + for (var i in methods) console.log("\t\t" + methods[i].toString()); } - //------------------------https://github.com/CreditTone/hooker---------------------------- function classExists(className) { - var exists = false; - try { - var clz = Java.use(className); - exists = true; - } catch(err) { - //console.log(err); - } - return exists; -}; - -function methodInBeat(invokeId, timestamp, methodName, executor) { -var startTime = timestamp; - var androidLogClz = Java.use("android.util.Log"); - var exceptionClz = Java.use("java.lang.Exception"); - var threadClz = Java.use("java.lang.Thread"); - var currentThread = threadClz.currentThread(); - var stackInfo = androidLogClz.getStackTraceString(exceptionClz.$new()); - var str = ("------------startFlag:" + invokeId + ",objectHash:"+executor+",thread(id:" + currentThread.getId() +",name:" + currentThread.getName() + "),timestamp:" + startTime+"---------------\n"); - str += methodName + "\n"; - str += stackInfo.substring(20); - str += ("------------endFlag:" + invokeId + ",usedtime:" + (new Date().getTime() - startTime) +"---------------\n"); -console.log(str); -}; - -function log(str) { - console.log(str); -}; - -function tryGetClass(className) { - var clz = undefined; - try { - clz = Java.use(className); - } catch(e) {} - return clz; + var exists = false; + try { + var clz = Java.use(className); + exists = true; + } catch (err) { + //console.log(err); + } + return exists; } -var containRegExps = new Array() +function methodInBeat(invokeId, timestamp, methodName, executor) { + var startTime = timestamp; + var androidLogClz = Java.use("android.util.Log"); + var exceptionClz = Java.use("java.lang.Exception"); + var threadClz = Java.use("java.lang.Thread"); + var currentThread = threadClz.currentThread(); + var stackInfo = androidLogClz.getStackTraceString(exceptionClz.$new()); + var str = + "------------startFlag:" + + invokeId + + ",objectHash:" + + executor + + ",thread(id:" + + currentThread.getId() + + ",name:" + + currentThread.getName() + + "),timestamp:" + + startTime + + "---------------\n"; + str += methodName + "\n"; + str += stackInfo.substring(20); + str += + "------------endFlag:" + + invokeId + + ",usedtime:" + + (new Date().getTime() - startTime) + + "---------------\n"; + console.log(str); +} -var notContainRegExps = new Array(RegExp(/\.jpg/), RegExp(/\.png/)) +function log(str) { + console.log(str); +} + +function tryGetClass(className) { + var clz = undefined; + try { + clz = Java.use(className); + } catch (e) {} + return clz; +} + +var containRegExps = new Array(); + +var notContainRegExps = new Array(RegExp(/\.jpg/), RegExp(/\.png/)); function check(str) { - str = str.toString(); - if (! (str && str.match)) { - return false; - } - for (var i = 0; i < containRegExps.length; i++) { - if (!str.match(containRegExps[i])) { - return false; - } - } - for (var i = 0; i < notContainRegExps.length; i++) { - if (str.match(notContainRegExps[i])) { - return false; - } - } - return true; + str = str.toString(); + if (!(str && str.match)) { + return false; + } + for (var i = 0; i < containRegExps.length; i++) { + if (!str.match(containRegExps[i])) { + return false; + } + } + for (var i = 0; i < notContainRegExps.length; i++) { + if (str.match(notContainRegExps[i])) { + return false; + } + } + return true; } //------------------------https://github.com/CreditTone/hooker EOF---------------------------- -function sendAppInfo(){ - var context = null - var ActivityThread = Java.use('android.app.ActivityThread'); - var app = ActivityThread.currentApplication(); +function sendAppInfo() { + var context = null; + var ActivityThread = Java.use("android.app.ActivityThread"); + var app = ActivityThread.currentApplication(); - if (app != null) { - context = app.getApplicationContext(); - var app_classname = app.getClass().toString().split(' ')[1]; - - var filesDirectory= context.getFilesDir().getAbsolutePath().toString(); - var cacheDirectory= context.getCacheDir().getAbsolutePath().toString(); - var externalCacheDirectory= context.getExternalCacheDir().getAbsolutePath().toString(); - var codeCacheDirectory= 'getCodeCacheDir' in context ? context.getCodeCacheDir().getAbsolutePath().toString() : 'N/A'; - var obbDir= context.getObbDir().getAbsolutePath().toString(); - var packageCodePath= context.getPackageCodePath().toString(); - var applicationName= app_classname; + if (app != null) { + context = app.getApplicationContext(); + var app_classname = app.getClass().toString().split(" ")[1]; - var info = {}; - info.applicationName = applicationName; - info.filesDirectory = filesDirectory; - info.cacheDirectory = cacheDirectory; - info.externalCacheDirectory = externalCacheDirectory; - info.codeCacheDirectory = codeCacheDirectory; - info.obbDir = obbDir; - info.packageCodePath = packageCodePath; + var filesDirectory = context.getFilesDir().getAbsolutePath().toString(); + var cacheDirectory = context.getCacheDir().getAbsolutePath().toString(); + var externalCacheDirectory = context + .getExternalCacheDir() + .getAbsolutePath() + .toString(); + var codeCacheDirectory = + "getCodeCacheDir" in context + ? context.getCodeCacheDir().getAbsolutePath().toString() + : "N/A"; + var obbDir = context.getObbDir().getAbsolutePath().toString(); + var packageCodePath = context.getPackageCodePath().toString(); + var applicationName = app_classname; - agSysPacket({information: "app", info: info}).send(); + var info = {}; + info.applicationName = applicationName; + info.filesDirectory = filesDirectory; + info.cacheDirectory = cacheDirectory; + info.externalCacheDirectory = externalCacheDirectory; + info.codeCacheDirectory = codeCacheDirectory; + info.obbDir = obbDir; + info.packageCodePath = packageCodePath; - } else { - console.log("No context yet!") - } + agSysPacket({ information: "app", info: info }).send(); + } else { + console.log("No context yet!"); + } } - //------------------------https://github.com/CreditTone/hooker EOF---------------------------- function notifyNewSharedPreference(key, value) { - var k = key; - var v = value; - Java.use('android.app.SharedPreferencesImpl$EditorImpl').putString.overload('java.lang.String', 'java.lang.String').implementation = function(k, v) { - console.log('[SharedPreferencesImpl]', k, '=', v); - return this.putString(k, v); - } + var k = key; + var v = value; + Java.use("android.app.SharedPreferencesImpl$EditorImpl").putString.overload( + "java.lang.String", + "java.lang.String", + ).implementation = function (k, v) { + console.log("[SharedPreferencesImpl]", k, "=", v); + return this.putString(k, v); + }; } // Send some stuff about the app -setTimeout(function() { - sendAppInfo(); +setTimeout(function () { + sendAppInfo(); }, 1000); diff --git a/androguard/pentest/modules/encryption/cipher.js b/androguard/pentest/modules/encryption/cipher.js index daf032a3..482dc761 100644 --- a/androguard/pentest/modules/encryption/cipher.js +++ b/androguard/pentest/modules/encryption/cipher.js @@ -1,86 +1,142 @@ // Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets -colorLog('[+] LOADING ENCRYPTION/CIPHER.JS', {c: Color.Red}); +colorLog("[+] LOADING ENCRYPTION/CIPHER.JS", { c: Color.Red }); -var cipher = Java.use('javax.crypto.Cipher'); +var cipher = Java.use("javax.crypto.Cipher"); - - -cipher.init.overload('int', 'java.security.Key').implementation = function(mode, key) { - var operation = ''; +cipher.init.overload("int", "java.security.Key").implementation = function ( + mode, + key, +) { + var operation = ""; var algorithm = this.getAlgorithm(); - if(mode == 1) - operation = "Encrypting"; - else if(mode == 2) - operation = "Decrypting"; + if (mode == 1) operation = "Encrypting"; + else if (mode == 2) operation = "Decrypting"; - agPacket({algorithm: algorithm, operation: operation, mode: mode, key: byteArraytoHexString(key.getEncoded())}).send(); + agPacket({ + algorithm: algorithm, + operation: operation, + mode: mode, + key: byteArraytoHexString(key.getEncoded()), + }).send(); return this.init(mode, key); -} +}; -cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function(mode, key, paramsec) { - var operation = ''; +cipher.init.overload( + "int", + "java.security.Key", + "java.security.spec.AlgorithmParameterSpec", +).implementation = function (mode, key, paramsec) { + var operation = ""; var algorithm = this.getAlgorithm(); - var castedToIv = Java.cast(paramsec, Java.use('javax.crypto.spec.IvParameterSpec')); - if(mode == 1) - operation = "Encrypting"; - else if(mode == 2) - operation = "Decrypting"; + if (mode == 1) operation = "Encrypting"; + else if (mode == 2) operation = "Decrypting"; - agPacket({algorithm: algorithm, mode: mode, operation: operation, key: byteArraytoHexString(key.getEncoded()), iv: byteArraytoHexString(castedToIv.getIV())}).send(); - return this.init(mode, key, paramsec); -} + agPacket({ + algorithm: algorithm, + mode: mode, + operation: operation, + key: byteArraytoHexString(key.getEncoded()), + iv: paramsec, + }).send(); + return this.init(mode, key, paramsec); +}; - -cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function(mode, key, paramsec, secRnd){ - var operation = ''; +cipher.init.overload( + "int", + "java.security.Key", + "java.security.AlgorithmParameters", + "java.security.SecureRandom", +).implementation = function (mode, key, paramsec, secRnd) { + var operation = ""; var algorithm = this.getAlgorithm(); - var castedToIv = Java.cast(paramsec, Java.use('javax.crypto.spec.IvParameterSpec')); - if(mode == 1) - operation = "Encrypting"; - else if(mode == 2) - operation = "Decrypting"; - - agPacket({algorithm: algorithm, mode: mode, operation: operation, key: byteArraytoHexString(key.getEncoded()), iv: byteArraytoHexString(castedToIv.getIV())}).send(); - return this.init(mode, key, paramsec, secRnd); -} + if (mode == 1) operation = "Encrypting"; + else if (mode == 2) operation = "Decrypting"; + agPacket({ + algorithm: algorithm, + mode: mode, + operation: operation, + key: byteArraytoHexString(key.getEncoded()), + iv: paramsec, + secRnd: secRnd, + }).send(); + return this.init(mode, key, paramsec, secRnd); +}; //DO FINAL-------------------------------- -cipher.doFinal.overload('[B').implementation = function(byteArray) { +cipher.doFinal.overload("[B").implementation = function (byteArray) { var ret = this.doFinal(byteArray); - agPacket({in: byteArray, ret: ret}).send(); + agPacket({ + in: byteArraytoHexString(byteArray), + ret: byteArraytoHexString(ret), + }).send(); return ret; -} +}; - -cipher.doFinal.overload('[B', 'int').implementation = function(byteArray, outputOffset) { +cipher.doFinal.overload("[B", "int").implementation = function ( + byteArray, + outputOffset, +) { var ret = this.doFinal(byteArray, outputOffset); - agPacket({in: byteArray, outputOffset: outputOffset, ret: ret}).send(); + agPacket({ in: byteArray, outputOffset: outputOffset, ret: ret }).send(); return ret; -} +}; - -cipher.doFinal.overload('[B', 'int', 'int').implementation = function(byteArray, outputOffset, inputlen) { +cipher.doFinal.overload("[B", "int", "int").implementation = function ( + byteArray, + outputOffset, + inputlen, +) { var ret = this.doFinal(byteArray, outputOffset, inputlen); - agPacket({in: byteArray, outputOffset: outputOffset, inputlen: inputlen, ret: ret}).send(); + agPacket({ + in: byteArray, + outputOffset: outputOffset, + inputlen: inputlen, + ret: ret, + }).send(); return ret; -} +}; -cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function(byteArray, outputOffset, inputlen, output) { +cipher.doFinal.overload("[B", "int", "int", "[B").implementation = function ( + byteArray, + outputOffset, + inputlen, + output, +) { var ret = this.doFinal(byteArray, outputOffset, inputlen, output); - agPacket({in: byteArray, out: output, outputOffset: outputOffset, inputlen: inputlen, ret: ret}).send(); + agPacket({ + in: byteArray, + out: output, + outputOffset: outputOffset, + inputlen: inputlen, + ret: ret, + }).send(); return ret; -} +}; -cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function(byteArray, outputOffset, inputlen, output, outoffset) { - var ret = this.doFinal(byteArray, outputOffset ,inputlen, output, outoffset); - agPacket({in: byteArray, out: output, outputOffset: outputOffset, inputlen: inputlen, outoffset: outoffset, ret: ret}).send(); - return ret; -} \ No newline at end of file +cipher.doFinal.overload("[B", "int", "int", "[B", "int").implementation = + function (byteArray, outputOffset, inputlen, output, outoffset) { + var ret = this.doFinal( + byteArray, + outputOffset, + inputlen, + output, + outoffset, + ); + agPacket({ + in: byteArray, + out: output, + outputOffset: outputOffset, + inputlen: inputlen, + outoffset: outoffset, + ret: ret, + }).send(); + return ret; + }; diff --git a/androguard/pentest/modules/encryption/keystore.js b/androguard/pentest/modules/encryption/keystore.js new file mode 100644 index 00000000..a89b0bd8 --- /dev/null +++ b/androguard/pentest/modules/encryption/keystore.js @@ -0,0 +1,57 @@ +// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets + +colorLog("[+] LOADING ENCRYPTION/KEYSTORE.JS", { c: Color.Red }); + +var keystore = Java.use("java.security.KeyStore"); + +keystore.containsAlias.overload("java.lang.String").implementation = function ( + alias, +) { + var ret = this.containsAlias(alias); + agPacket({ + alias: alias, + ret: ret, + }).send(); + + return ret; +}; + +keystore.getKey.overload("java.lang.String", "[C").implementation = function ( + alias, + password, +) { + var ret = this.getKey(alias, password); + agPacket({ + alias: alias, + password: password, + algorithm: ret.getAlgorithm(), + encoded: ret.getEncoded(), + ret: ret, + }).send(); + + return ret; +}; + +keystore.load.overload("java.io.InputStream", "[C").implementation = function ( + stream, + charArray, +) { + /* sometimes this happen, I have no idea why, tho... */ + if (stream == null) { + /* just to avoid interfering with app's flow */ + this.load(stream, charArray); + return; + } + + var hexString = readStreamToHex(stream); + + agPacket({ + certType: this.getType(), + password: charArray, + cert: hexString, + }).send(); + + /* call the original implementation of 'load' */ + this.load(stream, charArray); + /* no need to return anything */ +}; diff --git a/androguard/pentest/modules/preferences/preferences.js b/androguard/pentest/modules/preferences/preferences.js new file mode 100644 index 00000000..a4330b07 --- /dev/null +++ b/androguard/pentest/modules/preferences/preferences.js @@ -0,0 +1,14 @@ +// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets + +colorLog("[+] LOADING PREFERENCES/PREFERENCES.JS", { c: Color.Red }); + +var ContextWrapper = Java.use("android.content.ContextWrapper"); + +ContextWrapper.getSharedPreferences.overload( + "java.lang.String", + "int", +).implementation = function (var0, var1) { + var sharedPreferences = this.getSharedPreferences(var0, var1); + agPacket({ name: var0, mode: var1, ret: sharedPreferences }).send(); + return sharedPreferences; +};