好友
阅读权限 10
听众
最后登录 1970-1-1
俗里俗气
发表于 2021-10-20 19:03
1.首先对该APP抓包 获取请求字段:params =Jv4t3j/jzbV2ISssFo/Kvqtk6FCp271qkQSZEMXbAS0EThLEPpptyEwcl4wtj0QpnN5LWOtEeLaFofhV9xs0S0Rfdl4kOQX0vsEKJg==
2.根据观察不难看出此为base64编码,是否为变种未知,字段为 params
3.对App进行反编译,定位 “params" 位置 共有两处,并且观察方法名,确定为该位置
​ ​​
4.我们通过FrIDA Hook该方法参数,获取传参值,代码如下
"""
jscode =
Java.perform(function () {
var Utils = Java.use("com.asdfg2.daili.Common.HttpUtils");
Utils.post.implementation = function (a,map,c,d)
send(a);
var keyset = map.keySet();
var it = keyset.iterator();
while(it.hasNext()){
var keystr = it.next().toString();
var valuestr = map.get(keystr).toString();
send(keystr+" " +valuestr);
}
send("-----------");
}
});
"""
Map 参数如下: password 9d12c191dd8169de8515e174184f74bf mobile 15842731659
5. password 在传参前就已经加密,但是经验证为MD5加密,跟进 XXTEA.encryptToBase64String方法,str2参数:encryptKey = "weichats"
str1参数:{"password":"9d12c191dd8169de8515e174184f74bf","mobile":"15842731659"}
final String string = MyApplication.getPreferences().getString("access_token", "");
final String json = (map == null || map.size() == 0) ? null : new Gson().toJson(map);
if (!TextUtils.isEmpty(json)) {
json = XXTEA.encryptToBase64String(json, BuildConfig.encryptKey);
}
6. Hook参数返回值可以发现,该参数返回值为Post的请求体
public static final String encryptToBase64String(String str, String str2) {
byte[] encrypt = encrypt(str, str2);
if (encrypt == null) {
return null;
}
return Base64.encode(encrypt);
}
6. encrypt 是通过 encrypt方法返回,类型为byte[]
public static final byte[] encrypt(String str, String str2) {
try {
return encrypt(str.getBytes("UTF-8"), str2.getBytes("UTF-8"));
} catch (UnsupportedEncodingException unused) {
return null;
}
}
7. 该返回调用其重载方法代码如下
public static final byte[] encrypt(byte[] bArr, byte[] bArr2) {
if (bArr.length == 0) {
return bArr;
}
return toByteArray(encrypt(toIntArray(bArr, true), toIntArray(fixKey(bArr2), false)), false);
}
8.在重载方法encrptt中返回值参数调用 toIntArray方法,fixKey方法,toByteArray,encrypt方法 代码如下
private static int[] encrypt(int[] iArr, int[] iArr2) {
int length = iArr.length - 1;
if (length < 1) {
return iArr;
}
int i = (52 / (length + 1)) + 6;
int i2 = iArr[length];
int i3 = 0;
while (true) {
int i4 = i - 1;
if (i <= 0) {
return iArr;
}
int i5 = DELTA + i3;
int i6 = (i5 >>> 2) & 3;
int i7 = i2;
int i8 = 0;
while (i8 < length) {
int i9 = i8 + 1;
i7 = iArr[i8] + MX(i5, iArr[i9], i7, i8, i6, iArr2);
iArr[i8] = i7;
i8 = i9;
}
i2 = iArr[length] + MX(i5, iArr[0], i7, i8, i6, iArr2);
iArr[length] = i2;
i3 = i5;
i = i4;
}
}
private static byte[] toByteArray(int[] iArr, boolean z) {
int i;
int length = iArr.length << 2;
if (z) {
i = iArr[iArr.length - 1];
int i2 = length - 4;
if (i < i2 - 3 || i > i2) {
return null;
}
} else {
i = length;
}
byte[] bArr = new byte;
for (int i3 = 0; i3 < i; i3++) {
bArr[i3] = (byte) (iArr[i3 >>> 2] >>> ((i3 & 3) << 3));
}
return bArr;
}
}
private static int[] toIntArray(byte[] bArr, boolean z) {
int[] iArr;
int length = (bArr.length & 3) == 0 ? bArr.length >>> 2 : (bArr.length >>> 2) + 1;
if (z) {
iArr = new int[(length + 1)];
iArr[length] = bArr.length;
} else {
iArr = new int[length];
}
int length2 = bArr.length;
for (int i = 0; i < length2; i++) {
int i2 = i >>> 2;
iArr[i2] = iArr[i2] | ((bArr & UByte.MAX_VALUE) << ((i & 3) << 3));
}
return iArr;
}
private static byte[] fixKey(byte[] bArr) {
if (bArr.length == 16) {
return bArr;
}
byte[] bArr2 = new byte[16];
if (bArr.length < 16) {
System.arraycopy(bArr, 0, bArr2, 0, bArr.length);
} else {
System.arraycopy(bArr, 0, bArr2, 0, 16);
}
return bArr2;
}
9.字段 UByte.MAX_VALUE = -1 DELTA = -1640531527
private static int MX(int i, int i2, int i3, int i4, int i5, int[] iArr) {
return ((i ^ i2) + (iArr[(i4 & 3) ^ i5] ^ i3)) ^ (((i3 >>> 5) ^ (i2 << 2)) + ((i2 >>> 3) ^ (i3 << 4)));
}
10.至此 encrypt(str, str2) 返回的数组算法跟进完毕,代码内容均为基础算法
11. 最后调用 Base64.encode(encrypt) 很显然这是Base64的编码,我们可以利用Java自带的Base64包,替换为Base64.getEncoder().encodeToString(encrypt)
12.在Java层分析完毕,开始模拟进行Post提交。
import requests
proxies = {
'http': 'http://127.0.0.1:8899', 'https': 'http://127.0.0.1:8899'
}
loginl = {
"User-Agent": "okhttp-okgo/jeasonlzy",
"accessToken":"",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "ios.bz-cf.com",
"Connection": "Keep-Alive"
}
fdata ={
"params" : 'Jv4t3j/jzbV2ISssFo/Kvqtk6FCp271qkQSZEMXbAS0EThLEPpptyEwcl4wtj0QpnN5LWOtEeLaFofhV9xs0S0Rfdl4kOQX0vsEKJg==',
}
print(fdata)
r = requests.post("http://ios.bz-cf.com/index/user/login", data=fdata, headers=loginl, verify=False,proxies=proxies)
print(r.text)
​ ​​
13.提交后返回正常,该App并未将关键算法放于so层,导致轻易暴漏。由于没有使用ida,不涉及汇编调试,大家可以轻松解决。
免费评分
查看全部评分