抓取apk流量包分析字段

1
2
3
4
5
6
7
8
9
POST /v2_2/user/login HTTP/1.1
User-Agent: QianFan;quan0715;Android;Mozilla/5.0;AppleWebkit/533.1;redminote3xiaomi22;
Content-Type: application/x-www-form-urlencoded
Content-Length: 428
Host: cbrx.qianfanapi.com
Connection: close
Accept-Encoding: gzip, deflate

nonce=f8e161a7868740a69b5066d216e3f8c8&codeSign=A850D0F4EE17298CCD8D1B4D983DF829&timestamp=1650876507395&data={"params":{"password":"abc123456","username":"156234567890"}}&version=2.2.1&product_version=220&platform=redmi%20note%203&network=1&device=865166029891887&access_token=e86ace181f13eaa2c5f73ec4ea86b355&screen_width=900&screen_height=1600&bbsnopic=0&system=2&system_version=22&theme=4

登录抓包,得到以上情况。

分析发现找codesign就好

由于codesign于jeb的地方太多,所以下断点看是哪,就找到了下边这里

image-20220425165851364

静态分析代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected void a(String arg11, JSONObject arg12, d arg13) {
String v0 = UUID.randomUUID().toString().replaceAll("-", "");
long v2 = System.currentTimeMillis();
JSONObject v1 = this.a(arg12);
if(MyApplication.getInstance().isLogin()) {
g.a(arg11, new f[]{new f("user_id", "" + MyApplication.getInstance().getUserDataEntity().getUid()), new f("login_token", "" + MyApplication.getInstance().getUserDataEntity().getLogin_token()), new f("nonce", v0), new f("codeSign", v.a(v0, v1, MyApplication.getInstance().getUserDataEntity().getUid() + "", v2)), new f("timestamp", v2 + ""), new f("data", v1.toString()), new f("version", a.f + ""), new f("product_version", "220"), new f("platform", Build.PRODUCT + ""), new f("network", MyApplication.getNetworkType() + ""), new f("device", "" + MyApplication.getDeviceId()), new f("access_token", "" + a.h), new f("screen_width", "" + a.i), new f("screen_height", "" + a.j), new f("bbsnopic", MyApplication.isForumNoIMG() + ""), new f("system", "2"), new f("system_version", Build$VERSION.SDK_INT + ""), new f("theme", a.b + "")}, ((ResultCallback)arg13));
}
else {
g.a(arg11, new f[]{new f("nonce", v0), new f("codeSign", v.a(v0, v1, v2)), new f("timestamp", v2 + ""), new f("data", v1.toString()), new f("version", a.f + ""), new f("product_version", "220"), new f("platform", Build.PRODUCT + ""), new f("network", MyApplication.getNetworkType() + ""), new f("device", "" + MyApplication.getDeviceId()), new f("access_token", "" + a.h), new f("screen_width", "" + a.i), new f("screen_height", "" + a.j), new f("bbsnopic", MyApplication.isForumNoIMG() + ""), new f("system", "2"), new f("system_version", Build$VERSION.SDK_INT + ""), new f("theme", a.b + "")}, ((ResultCallback)arg13));
}
}

protected void a(String arg11, JSONObject arg12, String arg13, d arg14) {
q.a("BaseApi", arg11);
String v0 = UUID.randomUUID().toString().replaceAll("-", "");
JSONObject v1 = this.a(arg12);
long v2 = System.currentTimeMillis();
if(MyApplication.getInstance().isLogin()) {
g.a(arg11, new f[]{new f("user_id", "" + MyApplication.getInstance().getUserDataEntity().getUid()), new f("login_token", "" + MyApplication.getInstance().getUserDataEntity().getLogin_token()), new f("nonce", v0), new f("timestamp", v2 + ""), new f("codeSign", v.a(v0, v1, MyApplication.getInstance().getUserDataEntity().getUid() + "", v2)), new f("data", v1.toString()), new f("version", a.f + ""), new f("product_version", "220"), new f("platform", Build.PRODUCT + ""), new f("network", MyApplication.getNetworkType() + ""), new f("device", "" + MyApplication.getDeviceId()), new f("access_token", "" + a.h), new f("screen_width", "" + a.i), new f("screen_height", "" + a.j), new f("bbsnopic", MyApplication.isForumNoIMG() + ""), new f("system", "2"), new f("system_version", Build$VERSION.SDK_INT + ""), new f("theme", a.b + "")}, ((ResultCallback)arg14), arg13);
}
else {
g.a(arg11, new f[]{new f("nonce", v0), new f("codeSign", v.a(v0, v1, v2)), new f("timestamp", v2 + ""), new f("data", v1.toString()), new f("version", a.f + ""), new f("product_version", "220"), new f("platform", Build.PRODUCT + ""), new f("network", MyApplication.getNetworkType() + ""), new f("device", "" + MyApplication.getDeviceId()), new f("access_token", "" + a.h), new f("screen_width", "" + a.i), new f("screen_height", "" + a.j), new f("bbsnopic", MyApplication.isForumNoIMG() + ""), new f("system", "2"), new f("system_version", Build$VERSION.SDK_INT + ""), new f("theme", a.b + "")}, ((ResultCallback)arg14), arg13);
}
}

protected void a(String arg8, String arg9, String arg10, String arg11, String arg12, String arg13, String arg14, String arg15, String arg16, String arg17, d arg18) {
g.a(arg8, new f[]{new f("user_id", "" + arg9), new f("login_token", "" + arg10), new f("device", arg11 + ""), new f("system", "" + arg12), new f("screen_width", "" + arg13), new f("useragent", "" + arg14), new f("network", "" + arg15), new f("product_version", "" + arg16), new f("theme", "" + arg17)}, arg18);
}
codesign

new f("codeSign", v.a(v0, v1, v2))

**a():**这是一个重载

1
2
3
4
5
6
7
public static String a(String arg3, JSONObject arg4, String arg5, long arg6) {
return r.a(arg4.toString() + arg3 + v.a() + arg6 + arg5).toUpperCase();
}

public static String a(String arg4, JSONObject arg5, long arg6) {
return r.a(arg5.toString() + arg4 + v.a() + arg6).toUpperCase(); // toUpperCase() 方法将字符串小写字符转换为大写,这里外围的a()是md5加密
}

v1+v0+v.a()+v2

然后转化为全小写

里面得a():

1
2
3
private static String a() {
return v.a(af.b(0x7F08010E), ""); //十进制为2131230990,af.b(0x7F08010E)可以理解为读了一段参数
}

af.b(0x7F08010E)这里涉及到jeb中values目录下的public.xml和string.xml文件查看。

读取出94ac5cfb69e87bd7

里面的b():

1
2
3
4
5
6
7
8
9
10
11
12
public static String b(int arg1) {
String v0_1;
try {
v0_1 = MyApplication.getInstance().getResources().getString(arg1);
}
catch(Exception v0) {
v0.printStackTrace();
v0_1 = "";
}

return v0_1;
}

以字符串的返回数字

上边a()里面的a():

1
2
3
4
5
6
7
8
private static String a(String arg2, String arg3) {
return af.a(arg2 + arg3, af.b(0x7F080201)); //a()见下,读取出860f50db3569e448
}


public static String a(String arg2, String arg3) {
return new StringBuffer(arg2 + arg3).reverse().toString();
}

860f50db3569e448

要反转

总结:

data+nonce+反转(af.b()+af.a())+timestamp

字串拼接为

{“params”:{“password”:”abc123456”,”username”:”156234567890”}}f8e161a7868740a69b5066d216e3f8c8844e9653bd05f0687db78e96bfc5ca491650876507395

加密后:a850d0f4ee17298ccd8d1b4d983df829

A850D0F4EE17298CCD8D1B4D983DF829

image-20220425183435456

access_token

new f("access_token", "" + a.h)