App信息
包名:com.baicorv.yueyequan
抓包分析数据
进入全部话题,刷新进行抓包
1 | url: https://customer.yueyequan.cn/comu-core/v1.0/topic/appList |
这里面要逆向的参数是ice-auth-sign
逆向分析
反编译搜索ice-auth-sign
,并没有相关信息,尝试其他思路。
根据数据长度分析,ice-auth-sign
的长度是128个字节,这128字节应该是转为hex之后的长度,原长度是64字节,可能是sha512算法
hook RegisterNatives()
也是出于尝试的心理,猜测它是在so中生成的
恰好就找到了与sign有关的函数
对里面的签名算法进行hook
1 | function hook_sign(){ |
hook到的签名与抓到的数据包中的签名是一样的,那就说明找到了对应的位置
hook NewStringUTF()
还有一种方式也是出于猜测的方式,通过hook字符串,指定长度为128,打印相关信息及调用栈
1 | function hook_NewStringUTF(){ |
也可以打印出相关信息
1 | dataString: 1f28d7d65c10c3af2d5c53d46772064ae16bdcac33880f394a351edbe957701562e4fc47dd344a02657e15bdec3054bf40da3c50df79049467955f7075fc12da |
反编译分析
getEncryptSign()
查找用例是在getSign()
中被调用的,同时getEncryptSign
也是一个native
函数
getSign()
hook getSign()
1 | function hook_getsign(){ |
结果
1 | SignatureUtils.getSign is called: str=GET, str2=/comu-core/v1.0/topic/appList, str3=pagenum=1pagesize=20 |
发现ice-auth-sign
是从这个方法返回的
call_getEncryptSign()
在分析so之前,写一个主动调用getEncryptSign()
的函数,用于固定参数,后面分析的时候参数是固定的
1 | function call_getEncryptSign(){ |
so分析
使用IDA反编译找到getEncryptSign()进行分析
sub_9F368()
看到一个函数sub9F368
这里hook一下查看参数及返回值
1 | function hook_9f368() { |
hook结果
1 | 9f368 onEnter |
这里是在原来的参数里拼接了ice-auth-appkey
和ice-auth-timestamp
及e494454bb61acae31109befb58aa774386b646035af606e9314fab13b9adffe7
这里面的ice-auth-appkey
和e494454bb61acae31109befb58aa774386b646035af606e9314fab13b9adffe7
都是定值,但是ice-auth-timestamp
这个时间戳是会变动的,所以会导致后面输出的结果也会变动
通过打印内存可以查看ice-auth-appkey
和e494454bb61acae31109befb58aa774386b646035af606e9314fab13b9adffe7
1 | function temp_call(){ |
urlEncode()
进入到一个函数urlEncode()
hook一下
1 | function hook_urlcode(){ |
结果
1 | urlcode is called |
这里就是进行了url编码
BIO_set_fun_update()
url编码之后就来到了BIO_set_fun_update()
函数里
对它进行hook
可以根据符号名或地址进行hook
1 | function hook_updateout(){ |
hook 结果
1 | updateout is called |
这里返回值是签名的值
进入BIO_set_fun_update()
函数进行分析
又出现了两个BIO_set_fun_update()
不一样的是这里的符号名和地址与前面的不一样
这里在hook一下,我用out和inner把两个BIO_set_fun_update()
区分开了
1 | function hook_updateout(){ |
结果
1 | updateout is called |
updateinner
被调用了两次,它的第二个参数一个是0xb
,另一个是0x6
,好像是一种标识
根据它的源码进行分析,如下,它是用来做switch判断的
firstKeyIndex和secondKeyIndex
其实在传参的时候就可以看到这两个值
通过打印内存查看这两个变量的值
1 | function temp_call(){ |
结果如下
case 11
先调用EVP_sha3_256()
然后根据返回值判断是否跳转到LABEL_4
先来hook一下
1 | function hook_EVP_sha3_256(){ |
结果
1 | EVP_sha3_256 is called |
返回值是I
,那就回跳转到LABEL_4
这里会调用calculateHash
calculateHash()
这里就直接hook一下他
1 | function hook_calculatehash(){ |
结果
1 | calculatehash is called |
经过测试,这是一个sha3-256算法
如下验证
这里执行完之后会跳转到下一个BIO_set_fun_update()
里,然后到case 6
分支里
case 6
这里执行的是sha512
hook 一下
1 | function hook_sha512(){ |
结果
1 | sha512 is called |
验证是否为标准的sha512,如下可以确定是标准的sha512
把这些代码整合一下放一起进行hook
代码整合
1 | function hook_getEncryptSign(){ |
hook结果
1 | SignatureUtils.getEncryptSign is called: str=GET, str2=/comu-core/v1.0/topic/appList, str3=name=pagenum=1pagesize=10 |
python生成ice-auth-sign
1 | import time |
Python请求获取话题数据
1 | import requests |