网络抓包03 - 实践篇

声明: 本文中提及的APK及相关内容仅用于学习和交流目的,不涉及任何商业用途。本文不鼓励或支持任何形式的版权侵犯行为,同时也强调对软件的安全使用。我们尊重和维护开发者的权益,强烈建议读者在使用软件时遵守相关法律法规,并尊重软件的使用许可协议。对于因不当使用软件而导致的任何法律或安全问题,本文作者及发布平台不承担任何责任。如果软件开发者或权利人有任何版权或安全方面的疑虑,请及时与我们联系,我们将第一时间进行相应处理。

保存证书

此样本已经失效了,了解一下思路吧

对于VPN抓包失败的,先上一套降龙十八掌。

比如,先尝试Hook一下 KeyStore,看看情况:

function hook_KeyStore_load() {
    Java.perform(function () {
        var StringClass = Java.use("java.lang.String");
        var KeyStore = Java.use("java.security.KeyStore");

        KeyStore.load.overload('java.security.KeyStore$LoadStoreParameter').implementation = function (arg0) {
            console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            console.log("KeyStore.load1:", arg0);
            this.load(arg0);
        };

        KeyStore.load.overload('java.io.InputStream', '[C').implementation = function (arg0, arg1) {
            console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
            console.log("KeyStore.load2: ", arg0, arg1 ? "|" +  StringClass.$new(arg1) + "|": "password is null");
            if (arg0) {
                saveFile(arg0, "ncsearch");
            }
            this.load(arg0, arg1);
        };

        console.log("hook_KeyStore_load...");
    });
}

function saveFile(is, saveName) {
    var file = Java.use("java.io.File").$new("/sdcard/Download/" + saveName + ".p12");
    var out = Java.use("java.io.FileOutputStream").$new(file);

    var buffer = new Array(1024);
    buffer = buffer.fill(0)
    buffer = Java.array('byte', buffer);

    var len;
    while ((len = is.read(buffer)) > 0) {
        out.write(buffer, 0, len)
    }

    out.close()
    console.log("save file success!")
}

输出如下内容:

java.lang.Throwable
        at java.security.KeyStore.load(Native Method)
        at com.ninemax.ncsearchnew.utils.HttpClientSslHelper.getSSLContext(HttpClientSslHelper.java:152)
        at com.ninemax.ncsearchnew.utils.HttpUtils.loadData(HttpUtils.java:95)
        at com.ninemax.ncsearchnew.utils.HttpUtils.loadData(HttpUtils.java:52)
        at com.ninemax.ncsearchnew.ui.base.BaseActivity.loadData(BaseActivity.java:215)
        at com.ninemax.ncsearchnew.ui.SpalshActivity.getWebsiteData(SpalshActivity.java:232)
        at com.ninemax.ncsearchnew.ui.SpalshActivity.onApplyPrivacyFinish(SpalshActivity.java:183)
        at com.ninemax.ncsearchnew.ui.SpalshActivity.showPrivacyDialog(SpalshActivity.java:698)
        at com.ninemax.ncsearchnew.ui.SpalshActivity.initData(SpalshActivity.java:171)
        at com.ninemax.ncsearchnew.ui.base.BaseActivity.onCreate(BaseActivity.java:96)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

KeyStore.load2:  android.content.res.AssetManager$AssetInputStream@6498482 |cods.org.cn|

明显是从 asset 里面读取了一个文件,然后加载成 KeyStore,我们将这个文件直接写到 sdcard 上,使用 keystore explore 打开看看。

https://keystore-explorer.org/downloads.html

需要注意,上面我们保存文件的时候,使用的是 .p12,但是实际上不一定是 .p12 格式,具体还需要使用软件查看,使用 kse 打开证书:

输入上面打印出来的密码:

可以看到,它确实是一个 PKCS12 格式的文件,我们可以直接将它导入到charles里面去,为了简单,域名我选择了全匹配。

弄完之后,再去做请求,一般情况下会ok,如果还不行,就需要祭出 ssl pin 等hook代码了,objection 也可以一键处理,就不展开了。

SSL PIN 的处理

看另一个样本:

VPN抓包也是失败的,祭出 ssl pin 等 hook 的代码之后,发现还是走不通。这就让人比较头大了。

可以确定的是,网络请求肯定是触发了的,那么我们hook一下最底层的代码,看看调用堆栈。

比如,我们使用 objection hook  这个类 com.android.org.conscrypt.TrustManagerImpl 的所有方法,再次点击按钮,发送网络请求,就可以看到堆栈:

        at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(Native Method)
        at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:335)
        at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:113)
        at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:133)
        at java.lang.reflect.Method.invoke(Native Method)
        at android.net.http.X509TrustManagerExtensions.checkServerTrusted(X509TrustManagerExtensions.java:101)
        at java.lang.reflect.Method.invoke(Native Method)
        at ul.b$a.a(AndroidPlatform.java:2)
        at nl.f.a(CertificatePinner.java:13)
        at ql.d.f(RealConnection.java:52)
        at ql.d.c(RealConnection.java:22)
        at ql.g.d(StreamAllocation.java:95)
        at ql.g.e(StreamAllocation.java:1)
        at ql.a.a(ConnectInterceptor.java:13)
        at rl.f.b(RealInterceptorChain.java:11)
        at pl.b.a(CacheInterceptor.java:105)
        at rl.f.b(RealInterceptorChain.java:11)
        at rl.a.a(BridgeInterceptor.java:37)
        at rl.f.b(RealInterceptorChain.java:11)
        at rl.i.a(RetryAndFollowUpInterceptor.java:12)
        at rl.f.b(RealInterceptorChain.java:11)
        at rl.f.a(RealInterceptorChain.java:1)
        at yl.a.a(HttpLoggingInterceptor.java:4)
        at rl.f.b(RealInterceptorChain.java:11)
        at y8.b.a(HttpResponseInterceptor.kt:8)
        at rl.f.b(RealInterceptorChain.java:11)
        at y8.a.a(HttpRequestInterceptor.kt:37)
        at rl.f.b(RealInterceptorChain.java:11)
        at rl.f.a(RealInterceptorChain.java:1)
        at nl.y.c(RealCall.java:23)
        at nl.y.b(RealCall.java:16)
        at lm.p.execute(OkHttpCall.java:18)
        at x8.a.execute(EasyCall.kt:1)
        at x8.a.c(EasyCall.kt:1)
        at com.ticktick.task.helper.UserActivationHelper.sendUserActivation(UserActivationHelper.kt:2)
        at com.ticktick.task.helper.UserActivationHelper.trySendUserActivation(UserActivationHelper.kt:1)
        at com.ticktick.task.helper.UserActivationHelper.access$trySendUserActivation(UserActivationHelper.kt:1)
        at com.ticktick.task.helper.UserActivationHelper$trySendUserActivation$$inlined$timerTask$1.run(Timer.kt:1)
        at java.util.TimerThread.mainLoop(Timer.java:562)
        at java.util.TimerThread.run(Timer.java:512)

这个时候,就明白了,应用层的类都被混淆了,所以我们 hook 代码失效了,我们直接hook混淆后的类:

function hook_cp() {
    Java.perform(function () {
        var ClassName = "nl.f";
        var Platform = Java.use(ClassName);
        var targetMethod = "a";
        var len = Platform[targetMethod].overloads.length;
        console.log(len);
        for (var i = 0; i < len; ++i) {
            Platform[targetMethod].overloads[i].implementation = function () {
                console.log("class:", ClassName, "target:", targetMethod, " i:", i, arguments);
            }
        }
    });
}

这个时候,就可以正常抓到包了:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值