紀錄一下脫機的過程,因為一些因素所以,沒有追完全全部,等最近有空再說
反正主要目的就是假設一個APP 我要提取目標其中功能,我是否可以透過 HOOK的方式 將所有APP 流程轉成 API
也就是我要攔截 APP的 HTTPS 的流量 得到 請求的 request 然後在透過 攔截 app 的 簽章加密的 function 試圖找出簽這個 request 的 方法 ,這樣的步驟都做到的話基本上,你就可以偽造 這個 https 的請求了,當然有些情況可能變得更加棘手,有空再研究
frida -U \
-l ./config.js \
-l ./native-connect-hook.js \
-l ./native-tls-hook.js \
-l ./android/android-proxy-override.js \
-l ./android/android-system-certificate-injection.js \
-l ./android/android-certificate-unpinning.js \
-l ./android/android-certificate-unpinning-fallback.js \
-f $PACKAGE_ID
按照之前的下法找個安全的地方 進行 hook就可以繞過去了
Java.perform(function () {
const log = (tag, message) => console.log(`[${tag}] ${message}`);
const printStackTrace = () => {
const Thread = Java.use("java.lang.Thread");
const stackTrace = Thread.currentThread().getStackTrace();
log("STACK", "Current Call Stack:");
stackTrace.forEach(trace => console.log("\t" + trace.toString()));
};
// Hook Runtime.exec
const hookRuntimeExec = () => {
const Runtime = Java.use("java.lang.Runtime");
Runtime.exec.overload("java.lang.String").implementation = function (cmd) {
log("HOOK", `Blocked Command: ${cmd}`);
if (cmd.includes("su")) {
return null; // Block 'su' commands
}
return this.exec(cmd);
};
log("HOOK", "Runtime.exec hooked");
};
// Hook File.exists
const hookFileExists = () => {
const File = Java.use("java.io.File");
File.exists.implementation = function () {
const path = this.getPath();
if (path.includes("/system/app/Superuser.apk") || path.includes("/su")) {
log("HOOK", `Fake File.exists for path: ${path}`);
return false;
}
return this.exists();
};
log("HOOK", "File.exists hooked");
};
// Hook URL.openConnection
const hookUrlOpenConnection = () => {
const URL = Java.use("java.net.URL");
URL.openConnection.overload().implementation = function () {
const connection = this.openConnection();
log("HOOK", `Opening connection to URL: ${this.toString()}`);
printStackTrace(); // Print call stack
return connection;
};
log("HOOK", "URL.openConnection hooked");
};
// Hook SSLPinningManager
const hookSSLPinningManager = () => {
const SSLPinningManager = Java.use("com.alipay.imobile.network.sslpinning.SSLPinningManager");
SSLPinningManager.c.implementation = function (arg1, arg2) {
log("HOOK", "Bypassed SSLPinningManager.c");
printStackTrace();
return; // Skip original logic
};
log("HOOK", "SSLPinningManager.c hooked");
};
// Hook TrustManagerImpl.verifyChain
const hookTrustManagerImpl = () => {
const TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
TrustManagerImpl.verifyChain.implementation = function (chain, authType, session, hostname) {
log("HOOK", `Bypassed TrustManagerImpl.verifyChain for hostname: ${hostname}`);
printStackTrace();
return chain; // Force return valid chain
};
log("HOOK", "TrustManagerImpl.verifyChain hooked");
};
// Hook AbstractHttpTransport.signRequest
const hookAbstractHttpTransport = () => {
const AbstractHttpTransport = Java.use("com.alipay.imobile.network.quake.transport.http.AbstractHttpTransport");
AbstractHttpTransport.signRequest.overload(
"com.alipay.imobile.network.quake.Request",
"com.alipay.imobile.network.quake.util.SignUtil$SignInfo"
).implementation = function (request, signInfo) {
log("HOOK", "AbstractHttpTransport.signRequest called");
log("INFO", `Request: ${request.toString()}`);
log("INFO", `SignInfo: ${signInfo}`);
printStackTrace();
const signedString = this.signRequest(request, signInfo);
log("INFO", `Signed String: ${signedString}`);
return signedString;
};
log("HOOK", "AbstractHttpTransport.signRequest hooked");
};
// Hook SignUtil.a
const hookSignUtil = () => {
const SignUtil = Java.use("com.alipay.imobile.network.quake.util.SignUtil");
SignUtil.a.overload(
"android.content.Context",
"com.alipay.imobile.network.quake.util.SignUtil$SignInfo",
"java.lang.String",
"java.lang.String"
).implementation = function (context, signInfo, param1, param2) {
log("HOOK", "SignUtil.a hooked");
log("INFO", `Context: ${context}`);
log("INFO", `SignInfo: ${signInfo}`);
log("INFO", `Param1: ${param1}`);
log("INFO", `Param2: ${param2}`);
printStackTrace();
const result = this.a(context, signInfo, param1, param2);
log("INFO", `Result (Signature): ${result}`);
return result;
};
log("HOOK", "SignUtil.a(Context, SignInfo, String, String) hooked");
};
// Hook SignedJsonProtocolV1.serialize
const hookSignedJsonProtocol = () => {
const SignedJsonProtocolV1 = Java.use("com.alipay.imobile.network.quake.protocol.json.SignedJsonProtocolV1");
SignedJsonProtocolV1.serialize.implementation = function (request) {
log("HOOK", "SignedJsonProtocolV1.serialize hooked");
log("INFO", `Request: ${request.toString()}`);
printStackTrace();
const result = this.serialize(request);
log("INFO", `Serialized Data: ${Java.use("java.lang.String").$new(result)}`);
return result;
};
log("HOOK", "SignedJsonProtocolV1.serialize hooked");
};
// Initialize all hooks
const initializeHooks = () => {
hookRuntimeExec();
hookFileExists();
hookUrlOpenConnection();
hookSSLPinningManager();
hookTrustManagerImpl();
hookAbstractHttpTransport();
hookSignUtil();
hookSignedJsonProtocol();
log("INIT", "All hooks initialized successfully");
};
initializeHooks();
});
Java.perform(function () {
var SignUtil = Java.use('com.alipay.imobile.network.quake.util.SignUtil');
var SecurityGuardParamContext = Java.use('com.alibaba.wireless.security.open.SecurityGuardParamContext');
// Hook 私有静态方法
var method = SignUtil.a.overload(
'com.alibaba.wireless.security.open.SecurityGuardParamContext',
'java.lang.String',
'boolean',
'android.content.Context'
);
method.implementation = function (securityGuardParamContext, stringParam, booleanParam, context) {
console.log('Hooked SignUtil.a (private static method)');
console.log('String Parameter: ' + stringParam);
console.log('Boolean Parameter: ' + booleanParam);
console.log('Context: ' + context);
// 获取 SecurityGuardParamContext 的 appKey
try {
var appKey = securityGuardParamContext.appKey.value;
console.log('SecurityGuardParamContext.appKey: ' + appKey);
} catch (e) {
console.log('Failed to access appKey: ' + e);
}
// 调用原始方法
var result = method.call(this, securityGuardParamContext, stringParam, booleanParam, context);
console.log('Result: ' + result);
return result;
};
});
Java.perform(function () {
var SignUtil = Java.use('com.alipay.imobile.network.quake.util.SignUtil');
console.log('Methods in com.alipay.imobile.network.quake.util.SignUtil:');
var methods = SignUtil.class.getDeclaredMethods();
for (var i = 0; i < methods.length; i++) {
console.log(methods[i].toString());
}
});
Java.perform(function () {
var AbstractHttpTransport = Java.use('com.alipay.imobile.network.quake.transport.http.AbstractHttpTransport');
// Hook executeRequest 方法
AbstractHttpTransport.executeRequest.overload('com.alipay.imobile.network.quake.Request').implementation = function (request) {
console.log('[HOOwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwK] executeRequest called');
// 打印传入的 Request 对象内容
console.log('Request: ' + request.toString());
// 打印堆栈信息
console.log('[STACK] Current Call Stack:');
var stack = Java.use('java.lang.Thread').currentThread().getStackTrace();
for (var i = 0; i < stack.length; i++) {
console.log(stack[i].toString());
}
// 调用原始方法并获取结果
var result = this.executeRequest(request);
// 打印返回结果
console.log('NetworkResponse: ' + result.toString());
return result;
};
});
Java.perform(function () {
var AbstractHttpTransport = Java.use('com.alipay.imobile.network.quake.transport.http.AbstractHttpTransport');
AbstractHttpTransport.addRequestHeaders.overload('java.util.Map', 'com.alipay.imobile.network.quake.Request').implementation = function (headers, request) {
console.log('[HOOwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwK] addRequestHeaders called');
try {
// 確認 headers 是否為 Java 對象
if (headers && headers.getClass) {
console.log('Headers Class: ' + headers.getClass().getName());
// 嘗試遍歷 headers 的鍵值對
if (headers.entrySet) {
console.log('Headers Content:');
var iterator = headers.entrySet().iterator();
while (iterator.hasNext()) {
var entry = iterator.next();
console.log(' Key: ' + entry.getKey() + ', Value: ' + entry.getValue());
}
} else {
console.log('[WARNING] headers does not have an entrySet method, cannot iterate over it.');
}
} else {
console.log('[WARNING] headers is not a valid Java object.');
}
// 確認 request 是否為 Java 對象
if (request && request.getClass) {
console.log('Request Class: ' + request.getClass().getName());
} else {
console.log('[WARNING] request is not a valid Java object.');
}
} catch (e) {
console.log('[ERROR] Exception while processing addRequestHeaders: ' + e.message);
}
// 調用原始方法
this.addRequestHeaders(headers, request);
};
});
Java.perform(function () {
var RpcRequest = Java.use('com.alipay.imobile.network.quake.rpc.RpcRequest');
// Hook RpcRequest 構造方法
RpcRequest.$init.overload('java.lang.String', 'java.lang.reflect.Type', 'com.alipay.imobile.network.quake.Request$Listener', 'com.alipay.imobile.network.quake.Request$ErrorListener').implementation = function (arg1, arg2, arg3, arg4) {
console.log('[HOOK] RpcRequest constructor called');
// 安全檢查並列印參數
console.log(' arg1 (String): ' + (arg1 !== null ? arg1 : 'null'));
console.log(' arg2 (Type): ' + (arg2 !== null ? arg2.toString() : 'null'));
console.log(' arg3 (Listener): ' + (arg3 !== null ? arg3.toString() : 'null'));
console.log(' arg4 (ErrorListener): ' + (arg4 !== null ? arg4.toString() : 'null'));
// 調用原始構造方法
var instance = this.$init(arg1, arg2, arg3, arg4);
return instance;
};
});