美文网首页
咪咕音乐sign协议分析

咪咕音乐sign协议分析

作者: ever_hu | 来源:发表于2021-12-28 14:22 被阅读0次

咪咕音乐sign协议分析

环境

app 7.7.0

第一个sign

抓包

image-20211226154036370

是个小写的16进制的32位字符,jadx搜索"sign"

image-20211226154457243

30多个结果,不过有挺多是调用其他sdk的,比如com.meizu.*com.unionpay.*,这些都不太需要关注。

看看com.migu.tsg.s.b

image-20211226154811831

com.migu.tsg.j.d

image-20211226154844207

直接调用MD5,frida hook看看就行了,后面就省略了。

第二个sign

image-20211226155157063

可以看到是个大写的16进制的32位字符,搜索了"sign",看了几个都不太像。然后看到header还有个字段signVersion,搜索这个字符串,发现也没结果。

尝试hook系统的java.security.MessageDigestjavax.crypto.Mac这两个库的函数,然后发现也没有结果。

再换另一种方法,猜测可能是在so里面生成的,于是尝试使用frida_hook_libarthook_art.js,注释其他的模块,只保留NewStringUTF,然后启动,发现还是没有。

再换另一种方法,使用Yang大佬的Frida实现okhttp3.Interceptor并打印堆栈

function hook_okhttp3() {
    // 1. frida Hook java层的代码必须包裹在Java.perform中,Java.perform会将Hook Java相关API准备就绪。
    Java.perform(function () {

        // 2. 准备相应类库,用于后续调用,前两个库是Android自带类库,后三个是使用Okhttp网络库的情况下才有的类
        var ByteString = Java.use("com.android.okhttp.okio.ByteString");
        var Buffer = Java.use("com.android.okhttp.okio.Buffer");
        var Interceptor = Java.use("okhttp3.Interceptor");
        var ArrayList = Java.use("java.util.ArrayList");
        var OkHttpClient = Java.use("okhttp3.OkHttpClient");

        //  注册一个Java类
        var MyInterceptor = Java.registerClass({
            name: "okhttp3.MyInterceptor",
            implements: [Interceptor],
            methods: {
                intercept: function (chain) {
                    console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
                    var request = chain.request();
                    try {
                        console.log("MyInterceptor.intercept onEnter:", request, "\nrequest headers:\n", request.headers());
                        var requestBody = request.body();
                        var contentLength = requestBody ? requestBody.contentLength() : 0;
                        if (contentLength > 0) {
                            var BufferObj = Buffer.$new();
                            requestBody.writeTo(BufferObj);
                            try {
                                console.log("\nrequest body String:\n", BufferObj.readString(), "\n");
                            } catch (error) {
                                try {
                                    console.log("\nrequest body ByteString:\n", ByteString.of(BufferObj.readByteArray()).hex(), "\n");
                                } catch (error) {
                                    console.log("error 1:", error);
                                }
                            }
                        }
                    } catch (error) {
                        console.log("error 2:", error);
                    }
                    var response = chain.proceed(request);
                    try {
                        console.log("MyInterceptor.intercept onLeave:", response, "\nresponse headers:\n", response.headers());
                        var responseBody = response.body();
                        var contentLength = responseBody ? responseBody.contentLength() : 0;
                        if (contentLength > 0) {
                            console.log("\nresponsecontentLength:", contentLength, "responseBody:", responseBody, "\n");

                            var ContentType = response.headers().get("Content-Type");
                            console.log("ContentType:", ContentType);
                            if (ContentType.indexOf("video") == -1) {
                                if (ContentType.indexOf("application") == 0) {
                                    var source = responseBody.source();
                                    if (ContentType.indexOf("application/zip") != 0) {
                                        try {
                                            console.log("\nresponse.body StringClass\n", source.readUtf8(), "\n");
                                        } catch (error) {
                                            try {
                                                console.log("\nresponse.body ByteString\n", source.readByteString().hex(), "\n");
                                            } catch (error) {
                                                console.log("error 4:", error);
                                            }
                                        }
                                    }
                                }

                            }

                        }

                    } catch (error) {
                        console.log("error 3:", error);
                    }
                    return response;
                }
            }
        });

        OkHttpClient.$init.overload('okhttp3.OkHttpClient$Builder').implementation = function (Builder) {
            console.log("OkHttpClient.$init:", this, Java.cast(Builder.interceptors(), ArrayList));
            this.$init(Builder);
        };

        var MyInterceptorObj = MyInterceptor.$new();
        var Builder = Java.use("okhttp3.OkHttpClient$Builder");
        console.log(Builder);
        Builder.build.implementation = function () {
            // this.interceptors().clear();
            this.interceptors().add(MyInterceptorObj);
            var result = this.build();
            return result;
        };

        Builder.addInterceptor.implementation = function (interceptor) {
            // this.interceptors().clear();
            this.interceptors().add(MyInterceptorObj);
            return this;
        };

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

hook_okhttp3();
image-20211226160722609

终于有结果了,可以看到调用堆栈,其中我们比较关注的是com.migu.bizz_v2.interceptor.BaseInterceptor.intercept,但是这个函数在jadx看不到啊。。

image-20211226164738920

找不到该怎么办,这时候应该搜索classLoader

function searchClassLoader(className) {
    Java.enumerateClassLoaders({
        onMatch: function (loader) {
            try {
                if (loader.findClass(className)) {
                    Java.classFactory.loader = loader;
                    console.log("find:", loader);
                }
            } catch (error) {
            }
        }, 
        onComplete: function () {
            console.log("finish search");
        }
    })
}

searchClassLoader("com.migu.bizz_v2.interceptor.BaseInterceptor");
image-20211226164642786

虽然有点多,不过我们还是一个找,最后发现是在base_runtime-master.apk这个文件里,

image-20211226161559593 image-20211226161656530

最后是调用这两个的其中一个,我们已经可以看到调用了SecuritySignUtils.sign,但是这个方法又不在这两个apk文件里面。

不过jadx无法查看signStreamBody方法,我们改用GDA打开

image-20211226162342763

可以看到也是调用了SecuritySignUtils这个类。

继续搜索这个类

searchClassLoader("com.migu.security.SecuritySignUtils");
image-20211226162514604

打开文件看看,发现是在libraries_feature-master.apk这个文件

image-20211226162618024

所以最终是调用了libmgsign.so文件,可以hook验证一下。

function hook_security() {
    var util = Java.use("com.migu.security.SecuritySignUtils");
    var String = Java.use("java.lang.String");
    util.signAppend.implementation = function(j, bArr, j2) {
        console.log("signAppend-j:", j);
        console.log("signAppend-bArr", String.$new(bArr));
        console.log("signAppend-j2:", j2);
        var ret = this.signAppend(j, bArr, j2);
        return ret;
    }
    util.signEnd.implementation = function(str){
        console.log("str:", str);
        var ret = this.signEnd(str);
        console.log("ret:", ret);
        return ret;
    }
}

function main() {
    Java.perform(function(){
        searchClassLoader("com.migu.security.SecuritySignUtils");
        hook_security();
    })
}

setTimeout(main, 5000);
image-20211226165139221

可惜的是,libmgsign.so不在上述三个apk文件里,那么怎么找到它呢?frida中执行下列命令

Process.findModuleByName("libmgsign.so")
image-20211226165217497

那就把这个文件pull下来,ida打开

image-20211226163455390 image-20211226163525541 image-20211226163553931 image-20211226163823727 image-20211226163855121

所以它最后也是个md5,至于输入是什么,是否经过魔改,hook一下md5的initupdatefinal就清楚了,之后再分析。

相关文章

  • 咪咕音乐sign协议分析

    咪咕音乐sign协议分析 环境 app 7.7.0 第一个sign 抓包 是个小写的16进制的32位字符,jadx...

  • 咪咕音乐

    import requestsimport osimport jsonimport time class migu...

  • 2017-08-14

    咪咕主播琵琶仙子秀歌艺,欲做“音乐主播第一咖” 咪咕主播琵琶仙子秀歌艺,欲做“音乐主播第一咖”咪咕主播琵琶仙子秀歌...

  • 咪咕sdk反调试分析

    layout: posttitle: 咪咕sdk反调试分析categories: Androiddescripti...

  • 第十一届音乐盛典咪咕汇即将开幕,跨界民生银行发行限量版信用卡

    据悉,2017年12月16日,第十一届音乐盛典咪咕汇将在上海梅赛德斯-奔驰文化中心闪耀举办。咪咕汇作为华语乐...

  • 2018-11-08

    纸数融媒大联动——半月谈与咪咕签订战略合作协议 11月7日,半月谈新媒体科技有限公司与咪咕数字传媒有限公司在京签署...

  • 玩偶游戏

    (一) “你叫什么名字来着?” “咪咕德拉米斯基” “咪咕什么基?” “德拉米斯基。” “什么米斯基?” “咪咕德...

  • 如何下载咪咕的高音质音乐

    打开 萤火虫咪咕音乐无损音乐的网站 https://bilibili.syyhc.com/mp3.html 这是一...

  • Listen1 2.8.0 中文版 (全网付费VIP音乐免费听)

    Listen 1 可以搜索和播放来自网易云音乐,虾米音乐,酷狗音乐,酷我音乐,哔哩哔哩,咪咕音乐,QQ音乐七个主流...

  • 咪咕阅读,最垃圾的阅读软件

    因为咪咕『天天爱阅读,0元享kindle』的活动,下载了咪咕阅读。 1/先说内容 咪咕阅读上面的书籍主要是网络文学...

网友评论

      本文标题:咪咕音乐sign协议分析

      本文链接:https://www.haomeiwen.com/subject/jxypqrtx.html