安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid

本文仅供学习交流,只提供关键思路不会给出完整代码,严禁用于非法用途,若有侵权请联系我删除!

目标app: 5aSn6bqm572ROC41LjQ=

目标接口:aHR0cHM6Ly9hY3MubS50YW9iYW8uY29tL2d3L210b3AuZGFtYWkud2lyZWxlc3MuZGlzY292ZXJ5LmRldGFpbC5nZXQvMS40Lw==

一、引言

接上一篇 安卓逆向 - Frida Hook(抓包实践)_小馒头yy的博客-CSDN博客​​​​​​

我们抓到了某麦网帖子详情的包,发现其中存在  x-mini-wua x-sgext x-sign x-umt x-utdid等加密参数,今天来分析其签名生成(al系app通用签名套路),并搭建RPC实现主动调用。

安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第1张图片

二、搜索大法,定位关键代码

1、打开 jadx,点击文本搜索 - 选择代码 -  输入x-sign字段,发现如下多个关键位置。我们依次点开分析。并使用Frida hook主要方法,判断是否有走这一段代码。

安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第2张图片

定位到如下关键代码:

String str9 = unifiedSign.get("x-sign");

关注这段代码的上下文,我们发现 x-mini-wua x-sgext x-sign x-umt x-utdid等参数都是由 iSign.getUnifiedSig() 生成。

 HashMap unifiedSign = iSign.getUnifiedSign(hashMap3, hashMap4, str5, str6, z2);

安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第3张图片

 

三、动态调试

我们跟进去,发现这是一个接口,继续找该接口的实现类。

    HashMap getUnifiedSign(HashMap hashMap, HashMap hashMap2, String str, String str2, boolean z);

选中接口 ISign,右键查找用例,寻找该接口的实现类。

安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第4张图片

安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第5张图片

 最终我们定位到 mtopsdk.security.InnerSignImpl类的 getUnifiedSign() 安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第6张图片

 hook 之:

// mtopsdk.security.InnerSignImpl
function hook5() {
    console.log("hook5 start..")
    var Build = Java.use('mtopsdk.security.InnerSignImpl');
    var JSONObject = Java.use("com.alibaba.fastjson.JSONObject");
    Build.getUnifiedSign.overload('java.util.HashMap', 'java.util.HashMap', 'java.lang.String', 'java.lang.String', 'boolean').implementation = function (a, b, c, d, e) {
        console.log('参数 a: ' + a)
        console.log('参数 b: ' + b)
        console.log('参数 c: ' + c)
        console.log('参数 d: ' + d)
        console.log('参数 e: ' + e)

        //     showStacks()
        var res = this.getUnifiedSign(a, b, c, d, e)
        console.log("res: " + res)
        return res;
    }
}

 console.log("res: " + res) 语句输出的内容和我们抓包得到的数据一致。观察其入参都是明文,我们可以以此搭建RPC环境, 实现主动调用。

安卓逆向 - 某麦网 x-mini-wua x-sgext x-sign x-umt x-utdid_第7张图片

四、搭建 RPC,实现主动调用

1、获取内存中的 InnerSignImpl类对象

getMemoryObj: function (result) {
        if (result == null || result === '' || result === undefined) {
            Java.perform(function () {
                console.log("begin");
                Java.choose("mtopsdk.security.InnerSignImpl", {
                    onMatch: function (x) {
                        console.log("choose" + x);
                        result = x;
                    },
                    onComplete: function () {
                        console.log("end");
                    }
                })
            })
        }
        return result;
    }

2、封装参数:主要是 hashMap, hashMap2这两个参数,其他三个写死即可。特别注意data参数传的是一个json字符串,需要转义

            var HashMap1 = Java.use('java.util.HashMap').$new();
            HashMap1.put("deviceId", null);
            HashMap1.put("appKey", "23781390");
            HashMap1.put("utdid", "ZL4dqtfxPh0DALSURGw7eDIY");
            HashMap1.put("x-features", "27");
            HashMap1.put("ttid", "10005884@damai_android_8.5.4");
            HashMap1.put("v", "1.4");
            HashMap1.put("sid", null);
            HashMap1.put("t", "1691142277");
            HashMap1.put("api", "mtop.damai.wireless.discovery.detail.get");
            HashMap1.put("data", "{\"contentId\":\"10726085\",\"appType\":\"1\",\"source\":\"10101\",\"osType\":\"2\",\"pageSize\":\"30\",\"pageIndex\":\"1\",\"version\":\"6000168\",\"channel_from\":\"damai_market\"}");
            HashMap1.put("uid", null);

            var HashMap2 = Java.use('java.util.HashMap').$new();
            HashMap2.put("pageName", "");
            HashMap2.put("pageId", "");

3、调用

 res = rpc.exports.remoteObj.getUnifiedSign(HashMap1, HashMap2, "23781390", "", false);

4、搭建Python服务,加载 dm_rpc.js 代码

def begin():
    global script
    # 加载 js
    while True:
        try:
            process = frida.get_device_manager().get_device(ip + ":" + port).attach(package)
            break
        except BaseException as e:
            print('获取。。。')
    with open("dm_rpc.js", 'r', encoding='utf-8') as js:
        jscode = js.read()
    script = process.create_script(jscode)
    script.load()
    # 启动服务
    app.run(debug=True, port=8006)

if __name__ == "__main__":
    ip = '127.0.0.1'
    port = '21563'
    package = 'cn.damai'
    begin()

5、开放接口给外部访问:

@app.route('/sign', methods=['get'])
def sign():
    par = request.args.get("key")
    params = str(par)
    res = script.exports.signature(params)
    return res

完结!

你可能感兴趣的:(爬虫,android,python,爬虫,网络爬虫,rpc,安卓逆向)