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