Primer paso de la investigacion. Se aportan el .apk, las carpetas con el apk extraido y el apk descompilado. El archivo API_DOCUMENTATION.md es un archivo donde se anotaran los descubrimientos del funcionamiento de la API, y los .py son scripts para probar la funcionalidad de la API con los métodos que vayamos encontrando. Finalmente, los archivos .js son scripts de Frida para extraer informacion de la APP durante la ejecucion.

This commit is contained in:
2025-12-04 13:59:22 +01:00
parent 8b8ff223fb
commit f2fd1c3bf5
1055 changed files with 1202 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
/**
* Capture REQUEST BODY using writeTo() method
*/
console.log("\n[*] Capturing REQUEST Bodies\n");
Java.perform(function() {
try {
var AuthHeaderInterceptor = Java.use("com.adif.elcanomovil.serviceNetworking.interceptors.AuthHeaderInterceptor");
console.log("[+] Found AuthHeaderInterceptor");
// Try to find Buffer class
var Buffer = null;
var bufferNames = ["r.f", "r3.f", "okio.Buffer", "r3.Buffer"];
for (var i = 0; i < bufferNames.length; i++) {
try {
Buffer = Java.use(bufferNames[i]);
console.log("[+] Found Buffer class: " + bufferNames[i]);
break;
} catch (e) {
// Try next
}
}
if (!Buffer) {
console.log("[-] Could not find Buffer class, trying without pre-loading");
}
AuthHeaderInterceptor.intercept.implementation = function(chain) {
console.log("\n" + "=".repeat(80));
console.log("[HTTP REQUEST]");
try {
// Cast chain
var ChainClass = Java.use("j3.g");
var chainObj = Java.cast(chain, ChainClass);
// Get request
var requestField = chainObj.getClass().getDeclaredField("e");
requestField.setAccessible(true);
var request = requestField.get(chainObj);
if (request) {
// Get URL
var urlField = request.getClass().getDeclaredField("a");
urlField.setAccessible(true);
var urlObj = urlField.get(request);
console.log("[URL] " + urlObj.toString());
// Get method
var methodField = request.getClass().getDeclaredField("b");
methodField.setAccessible(true);
var method = methodField.get(request);
console.log("[METHOD] " + method);
// Get request body
var bodyField = request.getClass().getDeclaredField("d");
bodyField.setAccessible(true);
var reqBody = bodyField.get(request);
if (reqBody) {
try {
// If Buffer wasn't found, try to load it now
if (!Buffer) {
var bufferNames = ["r.f", "r3.f", "okio.Buffer", "r3.Buffer"];
for (var i = 0; i < bufferNames.length; i++) {
try {
Buffer = Java.use(bufferNames[i]);
break;
} catch (e) {}
}
}
if (Buffer) {
// Create a temporary buffer
var buffer = Buffer.$new();
// Try to cast buffer to BufferedSink if needed
try {
var BufferedSink = Java.use("r3.i");
var sink = Java.cast(buffer, BufferedSink);
// Call writeTo passing the sink
reqBody.writeTo(sink);
} catch (e) {
// If cast fails, try direct call
reqBody.writeTo(buffer);
}
// Read the content as UTF-8 string
var bodyContent = buffer.B0(); // readUtf8()
console.log("\n[REQUEST BODY]");
if (bodyContent && bodyContent.length > 0) {
if (bodyContent.length > 2000) {
console.log(bodyContent.substring(0, 2000));
console.log("\n... (truncated, total: " + bodyContent.length + " chars)");
} else {
console.log(bodyContent);
}
} else {
console.log("(empty)");
}
} else {
console.log("\n[REQUEST BODY] Could not load Buffer class");
}
} catch (e) {
console.log("[REQUEST BODY ERROR] " + e);
}
} else {
console.log("[REQUEST BODY] null");
}
}
} catch (e) {
console.log("[ERROR] " + e);
}
console.log("=".repeat(80) + "\n");
// Call original
return this.intercept(chain);
};
console.log("[*] Hook installed!\n");
} catch (e) {
console.log("[-] Failed: " + e);
}
});

View File

@@ -0,0 +1,133 @@
/**
* HTTP Traffic Capture - FINAL WORKING VERSION
* Using correct method names from ResponseBody
*/
console.log("\n[*] HTTP Traffic Capture - Final Working\n");
Java.perform(function() {
try {
var AuthHeaderInterceptor = Java.use("com.adif.elcanomovil.serviceNetworking.interceptors.AuthHeaderInterceptor");
console.log("[+] Found AuthHeaderInterceptor");
AuthHeaderInterceptor.intercept.implementation = function(chain) {
console.log("\n" + "=".repeat(80));
console.log("[HTTP REQUEST]");
try {
// Cast chain to j3.g
var ChainClass = Java.use("j3.g");
var chainObj = Java.cast(chain, ChainClass);
// Get request from field "e"
var requestField = chainObj.getClass().getDeclaredField("e");
requestField.setAccessible(true);
var request = requestField.get(chainObj);
if (request) {
// Get URL
var urlField = request.getClass().getDeclaredField("a");
urlField.setAccessible(true);
var urlObj = urlField.get(request);
console.log("[URL] " + urlObj.toString());
// Get method
var methodField = request.getClass().getDeclaredField("b");
methodField.setAccessible(true);
var method = methodField.get(request);
console.log("[METHOD] " + method);
}
} catch (e) {
console.log("[ERROR] " + e);
}
// Call original interceptor
var response = this.intercept(chain);
console.log("\n[HTTP RESPONSE]");
try {
if (response) {
// Get status code
var codeField = response.getClass().getDeclaredField("d");
codeField.setAccessible(true);
var code = codeField.get(response);
console.log("[CODE] " + code);
// Get message
var msgField = response.getClass().getDeclaredField("c");
msgField.setAccessible(true);
var message = msgField.get(response);
console.log("[MESSAGE] " + message);
// Get response body
var responseBodyField = response.getClass().getDeclaredField("g");
responseBodyField.setAccessible(true);
var responseBody = responseBodyField.get(response);
if (responseBody != null) {
try {
// Get source using source() method
var source = responseBody.source(); // CORRECT METHOD NAME
if (source) {
// List methods on source to see what's available
try {
var sourceMethods = source.getClass().getDeclaredMethods();
var methodNames = [];
for (var i = 0; i < sourceMethods.length; i++) {
methodNames.push(sourceMethods[i].getName());
}
console.log("[SOURCE METHODS] " + methodNames.join(", "));
} catch (e) {}
try {
// Try different method patterns
// Pattern 1: request all
var Long = Java.use("java.lang.Long");
source.request(Long.MAX_VALUE.value);
// Get buffer
var buffer = source.buffer();
// Clone buffer
var clone = buffer.clone();
// Read UTF8
var bodyStr = clone.readUtf8();
if (bodyStr && bodyStr.length > 0) {
console.log("\n[RESPONSE BODY]");
if (bodyStr.length > 2000) {
console.log(bodyStr.substring(0, 2000));
console.log("\n... (truncated, total: " + bodyStr.length + " chars)");
} else {
console.log(bodyStr);
}
}
} catch (e) {
console.log("[BODY READ ERROR] " + e);
}
}
} catch (e) {
console.log("[SOURCE ERROR] " + e);
}
}
}
} catch (e) {
console.log("[RESPONSE ERROR] " + e);
}
console.log("=".repeat(80) + "\n");
return response;
};
console.log("[*] Hook installed!\n");
} catch (e) {
console.log("[-] Failed: " + e);
}
});

View File

@@ -0,0 +1,70 @@
/**
* Inspect RequestBody to see what methods we can use
*/
console.log("\n[*] Inspecting RequestBody\n");
Java.perform(function() {
try {
var AuthHeaderInterceptor = Java.use("com.adif.elcanomovil.serviceNetworking.interceptors.AuthHeaderInterceptor");
console.log("[+] Found AuthHeaderInterceptor");
AuthHeaderInterceptor.intercept.implementation = function(chain) {
try {
// Cast chain
var ChainClass = Java.use("j3.g");
var chainObj = Java.cast(chain, ChainClass);
// Get request
var requestField = chainObj.getClass().getDeclaredField("e");
requestField.setAccessible(true);
var request = requestField.get(chainObj);
if (request) {
// Get request body from field "d"
var bodyField = request.getClass().getDeclaredField("d");
bodyField.setAccessible(true);
var reqBody = bodyField.get(request);
if (reqBody) {
console.log("\n" + "=".repeat(80));
console.log("[REQUEST BODY CLASS] " + reqBody.$className);
// List ALL methods
console.log("\n[ALL METHODS]:");
var methods = reqBody.getClass().getMethods();
for (var i = 0; i < methods.length; i++) {
var method = methods[i];
var paramTypes = method.getParameterTypes();
var paramStr = "";
for (var j = 0; j < paramTypes.length; j++) {
if (j > 0) paramStr += ", ";
paramStr += paramTypes[j].getName();
}
console.log(" " + method.getName() + "(" + paramStr + ") -> " + method.getReturnType().getName());
}
console.log("=".repeat(80) + "\n");
// Only print once
AuthHeaderInterceptor.intercept.implementation = this.intercept;
}
}
} catch (e) {
console.log("[ERROR] " + e);
console.log("[STACK] " + e.stack);
}
// Call original
return this.intercept(chain);
};
console.log("[*] Hook installed!\n");
} catch (e) {
console.log("[-] Failed: " + e);
}
});