• 某优鲜APP协议参数paramsMD5 逆向分析


    app版本1.4.0
    app使用360壳且混淆

    一、抓包分析

    app登录入口

    二、先脱壳

    因为有360加固,所以先脱壳

    三、用jadx-gui打开

    打开0x9e4e7f34.dex
    搜索关键字paramsMD5

    1.打开之后搜索关键字符串paramMd5

    2.继续跟进

    3.java代码

    //这几个是头部定义的字符串
        //private static final String d = "isSimulator";
        //private static final String e = "networkType";
        //private static final String f = "viewSize";
        //private static final String g = "time";
    
        public static String b(String str) {
            try {
                JSONObject jSONObject = new JSONObject(str);
                boolean z = false;
                if (jSONObject.has(d)) {
                    z = jSONObject.getBoolean(d);
                }
                String str2 = "";
                if (jSONObject.has(f)) {
                    str2 = jSONObject.getString(f);
                }
                String str3 = "";
                if (jSONObject.has(e)) {
                    str3 = jSONObject.getString(e);
                }
                String str4 = "";
                if (jSONObject.has(g)) {
                    str4 = jSONObject.getString(g);
                }
                //注意这里,这里是加密的核心函数b.a 跳过去看一下
                return b.a(str + (z + str2 + str3 + str4));
            } catch (JSONException e2) {
                e2.printStackTrace();
                return b.a(str);
            }
        }
    

    4.继续跟进去看一下,算法核心代码,用的是散列算法HASH256(以为加个壳就安全了...都没有用ndk写算法),代码如下

    5.java代码

    /* compiled from: FMRequest */
        public static final class b {
            private b() {
            }
    
            public static String a(String str) {
                String str2 = "@456yx#*^&HrUU99";
                if (e.e.equals(e.a().b()) || e.f.equals(e.a().b())) {
                    str2 = "@yx123*&^DKJ##CC";
                }
                try {
                    SecretKeySpec secretKeySpec = new SecretKeySpec(str2.getBytes(), "HmacSHA256");
                    Mac instance = Mac.getInstance(secretKeySpec.getAlgorithm());
                    instance.init(secretKeySpec);
                    return Base64.encodeToString(instance.doFinal(str.getBytes()), 2);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }
    

    6.接下来还原python算法



    7.python实现

    import hashlib
    import json, base64, hmac
    
    data = {"addrId": "", "apiVersion": "a1.32", "appVersion": "1.4.0", "body": {}, "channel": "WanDouJia",
            "deviceId": "1265c71021c00905-c710-1265-0905-21c0", "httpsEnable": 1, "isSimulator": True,
            "networkType": "WIFI", "osType": 1, "reRule": "2", "scopeType": 1, "source": "yx", "time": "20200814163056",
            "token": "c45e0ae9c85e4a7f09f019df1767b3c6", "viewSize": "810x1440"}
    dataStr = json.dumps(data, ensure_ascii=False)
    isSimulator = data['isSimulator']
    viewSize = data['viewSize']
    networkType = data['networkType']
    time = data['time']
    #isSimulator 是否是模拟器 布尔值,Java中的值是小写,所以这里要转换为小写
    dataStr = dataStr + (str(isSimulator).lower() + viewSize + networkType + time)
    
    """
    String str2 = "@456yx#*^&HrUU99";
    if (e.e.equals(e.a().b()) || e.f.equals(e.a().b())) {
    str2 = "@yx123*&^DKJ##CC";
    }
    """
    data = dataStr.replace(" ","").encode('utf-8')  # 加密数据
    appsecret = "@456yx#*^&HrUU99".encode('utf-8')  # 秘钥
    signature = base64.b64encode(hmac.new(appsecret, data, digestmod=hashlib.sha256).digest())
    print("秘钥为:" + signature.decode())
    

    四、hook方法

    上frida,hook a
    frida脚本如下

    1.hook.js

    Java.perform(function () {
        console.log('HOOK Start!!!');
        var Des3Encrypt = Java.use("com.rt.market.fresh.application.g$b");
        console.log(Des3Encrypt);
        // // 加密
        Des3Encrypt.a.overload('java.lang.String').implementation = function (args1) {
            console.log("Encrypt args1:",args1);
            // console.log("Encrypt args2:",args2);
            // console.log("Encrypt args3:",args3);
            //console.log("Encrypt args4:",args4);
            var result1 = this.a(args1);
            console.log("Des3Encrypt.encode result1==:", result1);
            return result1;
        };
    });
    

    2.python 脚本

    # -*- coding: utf-8 -*-
    # @Time    : 2021/2/23
    # @Author  : 
    
    
    import logging
    import frida
    import sys
    
    logging.basicConfig(level=logging.DEBUG)
    
    def on_message(message, data):
        print(message)
    
    
    with open('hook.js', 'r', encoding='utf-8') as f:
        sta = ''.join(f.readlines())
    
    rdev = frida.get_remote_device()
    processes = rdev.enumerate_processes()  # 安卓手机中的所有进程
    # print(processes)
    session = rdev.attach("com.rt.market.fresh")
    # print(session)
    script = session.create_script(sta)
    script.on("message", on_message)
    script.load()
    sys.stdin.read()
    

    五、请求测试

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # @Time : 2021/2/23 14:15
    # @Author :
    # @Platform:
    
    import time
    import json
    import hashlib
    import base64,hmac
    import requests
    import warnings
    warnings.filterwarnings("ignore")
    
    T = time.strftime("%Y%m%d%H%M%S", time.localtime())
    print(T)
    
    def login_info(phone):
    
        url = 'https://membase-yxapp.feiniu.com/loginController/login/a132'
        headers = {
            "Content-Type":"application/x-www-form-urlencoded",
            "Content-Length":"761",
            "Host":"membase-yxapp.feiniu.com",
            "Connection":"Keep-Alive",
            "Accept-Encoding": "gzip",
            "User-Agent":"okhttp/3.12.0"
        }
        data_json =	{"addrId":"","apiVersion":"a1.32","appVersion":"1.4.0","body":{"cid":"af7a589f425a387519c56b2224fa22a3","isFromReg":"0","password":"123456qerrt","storeCode":"","username":phone},"channel":"WanDouJia","deviceId":"2ce10d59284c091b-0d59-2ce1-091b-284c","httpsEnable":1,"isSimulator":False,"networkType":"WIFI","osType":1,"reRule":"4","scopeType":0,"source":"yx","time":T,"token":"f062fb5d76032dd31df051216a3738a3","viewSize":"1440x2392"}
    
        dataStr = json.dumps(data_json, ensure_ascii=False)
        isSimulator = data_json['isSimulator']
        viewSize = data_json['viewSize']
        networkType = data_json['networkType']
        time = data_json['time']
    
        # isSimulator 是否是模拟器 布尔值,Java中的值是小写,所以这里要转换为小写
        dataStr = dataStr + (str(isSimulator).lower() + viewSize + networkType + time)
        print(dataStr)
    
        """
        String str2 = "@456yx#*^&HrUU99";
        if (e.e.equals(e.a().b()) || e.f.equals(e.a().b())) {
        str2 = "@yx123*&^DKJ##CC";
        }
        """
        data = dataStr.replace(" ", "").encode('utf-8')  # 加密数据
        appsecret = "@456yx#*^&HrUU99".encode('utf-8')  # 秘钥
        signature = base64.b64encode(hmac.new(appsecret, data, digestmod=hashlib.sha256).digest())
        # print(signature)
        paramsMD5= signature.decode()
        # print(paramsMD5)
        dicts = {"addrId":"","apiVersion":"a1.32","appVersion":"1.4.0","body":{"cid":"af7a589f425a387519c56b2224fa22a3","isFromReg":"0","password":"123456qerrt","storeCode":"","username":phone},"channel":"WanDouJia","deviceId":"2ce10d59284c091b-0d59-2ce1-091b-284c","httpsEnable":1,"isSimulator":False,"networkType":"WIFI","osType":1,"reRule":"4","scopeType":0,"source":"yx","time":T,"token":"f062fb5d76032dd31df051216a3738a3","viewSize":"1440x2392"}
        dict_str = json.dumps(dicts, ensure_ascii=False).replace(" ", "")
        data = {
             'data':dict_str,
             'paramsMD5':paramsMD5,
        }
        # print("data=",data)
        response = requests.post(url, data=data, headers=headers, verify=False, timeout=5)
        # print(response.text)
        content = response.json()
        print(content)
    
    if __name__ == '__main__':
        print(login_info('13665412404'))
    

    样本

    链接:https://pan.baidu.com/s/1qzpaV5sbVkG6fM3sDmkpgg
    提取码:9ymh

  • 相关阅读:
    HTTP代理浅说
    基于互联网内容的中文分词小实验
    spring、spring mvc、mybatis框架整合基本知识
    数据结构中缀表达式转后缀表达式以及后缀转中缀表达式
    后缀表达式与中缀表达式互转的理论知识【转】
    jquery的ajax与spring mvc对接注意事项
    Linux centos7下安装配置redis及Redis desktop Manager工具连接注意事项
    Spring事务异常回滚,捕获异常不抛出就不会回滚
    webapp 慎用setInterval、setTimeout
    javascript中String 对象slice 和substring 区别
  • 原文地址:https://www.cnblogs.com/gqv2009/p/14435296.html
Copyright © 2020-2023  润新知