某社区登录协议分析
1.首先对该APP抓包 获取请求字段:params =Jv4t3j/jzbV2ISssFo/Kvqtk6FCp271qkQSZEMXbAS0EThLEPpptyEwcl4wtj0QpnN5LWOtEeLaFofhV9xs0S0Rfdl4kOQX0vsEKJg==2.根据观察不难看出此为base64编码,是否为变种未知,字段为 params
3.对App进行反编译,定位 “params" 位置 共有两处,并且观察方法名,确定为该位置
https://img-blog.csdnimg.cn/57d8025948694d08b9abf02f83b024e1.png?data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
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;
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 + MX(i5, iArr, i7, i8, i6, iArr2);
iArr = i7;
i8 = i9;
}
i2 = iArr + MX(i5, iArr, i7, i8, i6, iArr2);
iArr = i2;
i3 = i5;
i = i4;
}
}
private static byte[] toByteArray(int[] iArr, boolean z) {
int i;
int length = iArr.length << 2;
if (z) {
i = iArr;
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 = (byte) (iArr >>> ((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 = bArr.length;
} else {
iArr = new int;
}
int length2 = bArr.length;
for (int i = 0; i < length2; i++) {
int i2 = i >>> 2;
iArr = iArr | ((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;
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)
https://img-blog.csdnimg.cn/8360a440e62347a7bff6e6b5a0e53aad.png?data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
13.提交后返回正常,该App并未将关键算法放于so层,导致轻易暴漏。由于没有使用ida,不涉及汇编调试,大家可以轻松解决。
推荐使用md(MarkDown)书写,会更易于阅读和排版
此外建议使用代码块包裹代码部分,
另有图片加载异常,请直接上传图片到吾爱然后作为附件插入,
csdn的图片容易盗链。 谢谢分享! CSDN的资源要不到两天就会被防盗链 amscracker 发表于 2021-10-21 17:09
CSDN的资源要不到两天就会被防盗链
csdn就是我写的 图片懒的截图了哈哈 这个教程内容真不错,不过我水平不够,不是很懂,还需要继续学习,谢谢分享了 其实,很多代码或者app都没深入考虑加密。找到源码后,直接就破解掉了。 感谢楼主的教程,很实用。最近也在学习安卓逆向相关内容,一起进步 懂了漂亮,感谢 学习了 学习了 感谢分享
页:
[1]