postern + charles无法抓包遇到问题

解决Android应用中的网络问题:代理设置、反调试检测与SSL验证技巧

一、设置问题

仅设置postern代理即可,不需要再设置系统wifi代理

二、vpn被反调试了

常见检测vpn代码,搜索“.getActiveNetwork()

    public final boolean isVpnConnected(Context context) {
        NetworkCapabilities networkCapabilities;
        Object systemService = context.getSystemService("connectivity");
        if (systemService != null) {
            ConnectivityManager connectivityManager = (ConnectivityManager) systemService;
            Network activeNetwork = connectivityManager.getActiveNetwork();
            if (activeNetwork == null || (networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)) == null) {
                return false;
            }
            return networkCapabilities.hasTransport(4);
         // 是否是VPN端口
        // return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);

        }
 

三、ssl校验没过

// okhttp3.CertificatePinner有可能被混淆了,导致ssl验证不过,查看混淆的类名并修改kill_ssl.js源码,尝试hook这些java.net.url、java.io.File.$init函数打印调用栈找突破口

hook代码寻找下蛛丝马迹

// kill_ssl_dbg.js
// Frida script: enumerate suspicious classes, inspect methods, hook URL and File ctors and print stack traces.
// 运行方式:frida -U -f <pkg> -l kill_ssl_dbg.js --no-pause

if (Java.available) {
    Java.perform(function () {
        var Thread = Java.use('java.lang.Thread');
        var ExceptionClass = Java.use('java.lang.Exception');

        // helper: print Java stack trace (current thread)
        function printStack(prefix) {
            try {
                var st = Thread.currentThread().getStackTrace();
                // st is Java array of StackTraceElement
                for (var i = 0; i < st.length; i++) {
                    var e = st[i];
                    // skip top frames from frida/java internals if you want; here we print all
                    console.log(prefix + '  at ' + e.toString());
                }
            } catch (err) {
                console.log('[printStack] error: ' + err);
            }
        }

        // 1) 枚举所有已加载类,筛选可疑类名(包含常见关键词)
        console.log('=== enumerateLoadedClasses (filter suspicious names) ===');
        var keywords = ['Certificate', 'certificate', 'Cert', 'cert', 'Pin', 'pin', 'Pinner', 'pinner', 'okhttp', 'tls', 'ssl', 'Trust', 'trust', 'X509', 'HostnameVerifier', 'TrustManager'];
        Java.enumerateLoadedClasses({
            onMatch: function (className) {
                // 简单关键词过滤
                var lower = className.toLowerCase();
                for (var k = 0; k < keywords.length; k++) {
                    if (lower.indexOf(keywords[k].toLowerCase()) !== -1) {
                        console.log('[CANDIDATE] ' + className);
                        break;
                    }
                }
            },
            onComplete: function () { console.log('=== enumeration complete ==='); }
        });

        // 2) 进一步尝试对可疑类进行反射式方法枚举(注意 try/catch)
        function inspectClassMethods(className) {
            try {
                var cls = Java.use(className); // may throw if class is not accessible
                // use reflection to get declared methods
                var jclass = cls.class; // java.lang.Class
                var methods = jclass.getDeclaredMethods(); // Java array of Method
                console.log('--- Methods of ' + className + ' ---');
                for (var i = 0; i < methods.length; i++) {
                    try {
                        var m = methods[i];
                        // method.toString() gives signature
                        console.log('  ' + m.toString());
                        // optionally, detect methods with "check" / "pin" / "verify"
                        var mname = m.getName();
                        if (mname.indexOf('check') !== -1 || mname.toLowerCase().indexOf('pin') !== -1 || mname.toLowerCase().indexOf('verify') !== -1) {
                            console.log('    >>> suspicious method name: ' + mname);
                        }
                    } catch (me) { /* ignore per-method errors */ }
                }
            } catch (e) {
                // some classes cannot be used directly due to hidden API / classloader issues
                // try to attempt via reflection Class.forName
                try {
                    var ClsForName = Java.use('java.lang.Class');
                    var jcn = ClsForName.forName(className);
                    var methods2 = jcn.getDeclaredMethods();
                    console.log('--- (via forName) Methods of ' + className + ' ---');
                    for (var j = 0; j < methods2.length; j++) {
                        try {
                            console.log('  ' + methods2[j].toString());
                        } catch (ee) {}
                    }
                } catch (ee) {
                    // final fallback: print cannot inspect
                    console.log('[inspectClassMethods] cannot inspect ' + className + ' : ' + e);
                }
            }
        }

        // 3) 提供一个函数:扫描并尝试 inspect 含某关键词的类(如果你已经知道混淆后可能的前缀/模式可直接调用)
        function scanAndInspect(keyword) {
            Java.enumerateLoadedClasses({
                onMatch: function (className) {
                    if (className.toLowerCase().indexOf(keyword.toLowerCase()) !== -1) {
                        console.log('[INSPECT] ' + className);
                        inspectClassMethods(className);
                    }
                },
                onComplete: function () { console.log('[scanAndInspect] complete for ' + keyword); }
            });
        }

        // 4) Hook java.net.URL constructors (常见的地方:网络请求构造 URL)
        try {
            var URL = Java.use('java.net.URL');
            // iterate overloads of $init and replace
            URL.$init.overloads.forEach(function (ov) {
                try {
                    ov.implementation = function () {
                        var args = [];
                        for (var i = 0; i < arguments.length; i++) args.push('' + arguments[i]);
                        console.log('[HOOK] java.net.URL.<init> called with args = ' + JSON.stringify(args));
                        printStack('URL ctor stack:');
                        // call original
                        return ov.apply(this, arguments);
                    };
                    console.log('[HOOKED] java.net.URL ctor overload: ' + ov);
                } catch (err) {
                    console.log('[Error hooking URL ctor overload] ' + err);
                }
            });
        } catch (err) {
            console.log('[Hook URL] failed: ' + err);
        }

        // 5) Hook java.io.File constructors
        try {
            var File = Java.use('java.io.File');
            File.$init.overloads.forEach(function (ov) {
                try {
                    ov.implementation = function () {
                        var args = [];
                        for (var i = 0; i < arguments.length; i++) args.push('' + arguments[i]);
                        console.log('[HOOK] java.io.File.<init> called with args = ' + JSON.stringify(args));
                        printStack('File ctor stack:');
                        return ov.apply(this, arguments);
                    };
                    console.log('[HOOKED] java.io.File ctor overload: ' + ov);
                } catch (err) {
                    console.log('[Error hooking File ctor overload] ' + err);
                }
            });
        } catch (err) {
            console.log('[Hook File] failed: ' + err);
        }

        // 6) Hook some common okhttp-ish entrypoints (只打印,不修改行为)
        //  - okhttp3.OkHttpClient.newCall or okhttp3.internal.* (如果类名存在)
        try {
            var maybeOkhttpClientName = 'okhttp3.OkHttpClient';
            if (Java.available) {
                try {
                    var OkHttpClient = Java.use(maybeOkhttpClientName);
                    // hook newCall
                    if (OkHttpClient.newCall) {
                        OkHttpClient.newCall.implementation = function (req) {
                            console.log('[HOOK] OkHttpClient.newCall called. req=' + req);
                            printStack('OkHttpClient.newCall stack:');
                            return this.newCall(req); // call original
                        };
                        console.log('[HOOKED] ' + maybeOkhttpClientName + '.newCall');
                    }
                } catch (e) {
                    // probably not present / obfuscated; that's expected
                }
            }
        } catch (e) {}

        // 7) Expose a small rpc to allow you to call scanAndInspect from frida REPL
        rpc.exports = {
            scan: function (kw) {
                return Java.perform(function () {
                    scanAndInspect(kw || 'Certificate');
                });
            },
            inspect: function (classname) {
                return Java.perform(function () {
                    inspectClassMethods(classname);
                });
            },
            dumpstack: function () {
                return Java.perform(function () {
                    printStack('manual dump:');
                });
            }
        };

        console.log('kill_ssl_dbg.js loaded. You can call rpc.scan("pinner") or rpc.inspect("<class>") from Frida python REPL.');
    });
} else {
    console.log('Java runtime is not available');
}

四、flutter应用

flutter应用需要在so层hook禁用证书,详细看:记录一次charles启用vpn+禁ssl都无法抓包app的情况竟因为是flutter应用

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云霄IT

感谢感谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值