Charles抓包查看

通过观察发现,这两个url的signature是变化的,要想获取数据,看来要解密signature了。

App查壳

将App的扩展名修改为 zip 并解压

查看 lib 文件夹

用 jadx 打开 classes.dex

App脱壳

我们利用 Xposed框架 —– Fdex2 模块进行脱壳

点击 Fdex2 – 引力播app – 重新启动引力播

一般界面启动之后,就脱成功了,查看目录:

1
/data/data/com.iCitySuzhou.001

这个目录需要拥有root权限的文件浏览器才能看到,推荐 Re文件浏览器

拉取到电脑

1、将 /data/data/com.iCitySuzhou.suzhou001/ 文件夹手动移到 /sdcard/ 目录下

2、电脑执行拉取命令

1
adb pull /sdcard/com.iCitySuzhou.suzhou001/  C:\Users\hyzsj\Desktop

3、拉取到桌面

开始找signature

是哪个dex,我们一开始也不清楚,需要一个一个看。

第一个、第二个简单看了一下,里面全是 tencent 开头的文件,感觉不像

第三个 dex 就靠谱多了

下面这条看着很像,但更像是apk的签名验证

继续往下看,这条就差不多了,因为 syssysVersionappVersion 这些都在请求头里

解密signature

1
2
String udid = MyApplication.getInstance().getUDID();
String valueOf = String.valueOf(System.currentTimeMillis() / 1000);

uuid 和 valueOf 已经给出了,我们只要找到 signature 生成逻辑代码就好了。

可以看到 signature 的值就是就去 绿色标记部分,我们直接 查找用例 看一下

发现 m12059a 这个方法就在下面,看这意思:将uuid、时间戳、固定字符串,和&&拼接成一个新的Str了

我们继续跳转,看一下方法m11218a的结构:

不难看出,传入参数是str,然后做了 md5、可能还有 位运算 等等,算了看不懂,我们还是直接封装成jar调用吧。

封装成jar包

java代码 做成 jar 包,可以使用 python 去调用

保存下面代码:Mysig.java 类名需要修改 C2387a ==> Mysig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.security.MessageDigest;

/* renamed from: com.hualong.framework.b.a */
public class C2387a {
/* renamed from: a */
public static String m11218a(String str) {
if (str == null) {
return null;
}
StringBuffer stringBuffer = new StringBuffer();
try {
MessageDigest instance = MessageDigest.getInstance("MD5");
instance.update(str.getBytes());
for (byte b : instance.digest()) {
stringBuffer.append(Integer.toString((b >>> 4) & 15, 16)).append(Integer.toString(b & 15, 16));
}
} catch (Exception e) {
}
return stringBuffer.toString();
}
}

编译成class文件 , 编译成jar文件 ,如果不行就拆开执行

1
javac .\MySig.java && jar cvf MySig.jar MySig.class

调用执行

接下来我们要调用 MySig.jar, python代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from jpype import *
import time

uuid = 'IMEI867979020568173-IMSI460NNNNNNNNNNNN'
stamp = str(int(time.time()))

sig_str = uuid + '&&' + stamp + '&&' + 'f1190aca-d08e-4041-8666-29931cd89dde'
jvmpath = getDefaultJVMPath()
jarpath = "c:/Users/hyzsj/Desktop/"
startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % (jarpath + 'MySig.jar'))
print('aa:', "-Djava.class.path=%s" % (jarpath + 'MySig.jar'))
JDClass = JClass('MySig')
jd = JDClass()
entry_sig = jd.m11218a(sig_str)
java.lang.System.out.println(entry_sig)
print(entry_sig)
shutdownJVM()

需要安装 jpype

Windows 在 https://www.lfd.uci.edu/~gohlke/pythonlibs/

找到包,下载到本地,执行pip安装即可:

1
pip install JPype1-1.0.2-cp37-cp37m-win_amd64.whl

最后发送请求测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
url = 'https://app.suzhou-news.cn/api/v1/appNews/getBannerNewsList7?page=2&bannerID=11'
headers = {
'path': '/api/v1/appNews/getBannerNewsList7?page=2&bannerID=11',
'sys': 'Android',
'sysversion': '6.0.1',
'appversion': '8.2',
'appversioncode': '54',
'udid': 'IMEI867979020568173-IMSI460NNNNNNNNNNNN',
'clienttype': 'android',
'timestamp': stamp,
'signature': str(entry_sig),
'user-agent': 'okhttp/3.9.0'
}
res = requests.get(url, headers=headers, verify=False)
with open('iCitySuzhou.json', 'w', encoding='utf-8')as f:
json.dump(res.json(), f, ensure_ascii=False, indent=2)

最终结果