前言
在进行 Android 测试时会发现现在大多数 APP 都进行了加固,其中就包括 frida 防护。不能使用 frida,对 APP 渗透测试而言可以说是缺了灵魂。所以绕过 Frida 防护是我们必不可少的一步。
Frida 绕过的各种姿势
1. 使用去特征的 server
https://github.com/hluwa/strongR-frida-android/
2. 修改默认端口
./data/local/tmp/frida-* -l 0.0.0.0:800
adb forward tcp:27042 tcp:800
frida -R package_name -l hook.js
3. VA + Gadget
利用 VirtualApp 自带的延时注入功能,注入 frida-gadget,具体实现可看我 github。
github: https://github.com/jussi-sky/VirtualApp
3.1 引入 gadget.so(更改so名称,可绕过部分检测)
3.2 加载 gadget
package io.virtualapp;
import com.lody.virtual.helper.utils.VLog;
public class FridaGadget {
private static final String TAG = FridaGadget.class.getSimpleName();
static {
try {
System.loadLibrary("ijkplayer");
} catch (Throwable e) {
VLog.e(TAG, VLog.getStackTraceString(e));
}
}
public static void init() {
VLog.d(TAG, "Init Frida Gadget", new Object[0]);
}
}
3.3 重写 AppComponentDelegate,控制 gadget 加载时机
package io.virtualapp;
import android.app.Application;
import android.content.Context;
import com.lody.virtual.client.VClient;
import com.lody.virtual.client.core.AppCallback;
import com.lody.virtual.helper.utils.VLog;
import com.scorpion.IHook.XposedBridge;
import com.scorpion.IHook.callbacks.XC_LoadPackage;
import com.scorpion.reverse.dingding.DingTalk;
import com.swift.sandhook.xposedcompat.utils.ProcessUtils;
public class AppComponentDelegate implements AppCallback {
private static final String TAG = "AppComponentDelegate";
boolean isMainProcess = false;
public Application mApplication;
Context mContext;
public AppComponentDelegate(Context context) {
this.mContext = context;
}
public boolean isMainProcess() {
return this.isMainProcess;
}
public void setMainProcess(boolean mainProcess) {
this.isMainProcess = mainProcess;
boolean z = this.isMainProcess;
}
@Override // com.lody.virtual.client.core.AppCallback
public void beforeStartApplication(String packageName, String processName, Context context) {
}
@Override // com.lody.virtual.client.core.AppCallback
public void beforeApplicationCreate(String packageName, String processName, Application application) {
}
@Override // com.lody.virtual.client.core.AppCallback
public void afterApplicationCreate(String packageName, String processName, Application application) {
FridaGadget.init();
// 多进程应用使用 processName 控制只注入主进程,否则可能会出错
if (processName.equals("com.ford.cnevapp.debug")) {
FridaGadget.init();
}
if (packageName.equals("com.alibaba.android.rimet")) {
VLog.d("VA-", "开始 hook 丁丁打卡", new Object[0]);
DingTalk.hook(VClient.get().getClassLoader());
}
}
private XC_LoadPackage.LoadPackageParam getLoadPackageParam(Application application) {
XC_LoadPackage.LoadPackageParam packageParam = new XC_LoadPackage.LoadPackageParam(XposedBridge.sLoadedPackageCallbacks);
if (application != null) {
if (packageParam.packageName == null) {
packageParam.packageName = application.getPackageName();
}
if (packageParam.processName == null) {
packageParam.processName = ProcessUtils.getProcessName(application);
}
if (packageParam.classLoader == null) {
packageParam.classLoader = application.getClassLoader();
}
if (packageParam.appInfo == null) {
packageParam.appInfo = application.getApplicationInfo();
}
}
return packageParam;
}
}
3.4 最后确认主 Activity 的 AppComponentDelegate 的是否指向的是我们重写的,如果不是删除原对应的 import
3.5 配置自定义 gadget 属性
{
"interaction": {
"type": "listen",
"address": "127.0.0.1",
"port": 26000,
"on_port_conflict": "fail",
"on_load": "resume"
}
}
4. riru + gadget
利用 Magisk 的 riru 模块,在 APP Fork 时注入 frida-gadget,具体实现可看我 github。
github: https://github.com/jussi-sky/Riru-FridaGadget