某优鲜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

原文地址:https://www.cnblogs.com/gqv2009/p/14435296.html