问题:通过抓包调试我们可以发现,在每次请求时服务器会在请求头验证x-gorgon和x-khronos字段,如果验证不通过,服务器不会返回数据。
1、定位加密位置
首先下载apk文件,然后用jadx反编译(可能需要安装java环境),反编译成功后,我们需要定位到加密函数的位置。
2、分析加密函数
点击界面中的魔法棒,全局搜索x-gorgon可以发现加密部分在com.ss.sys.ces.gg.tt的init_gorgon函数中,通过分析java代码可以知道,x-gorgon是调用leviathan函数生成的,而该函数在native层的,其加密逻辑在libcms.so文件中,传入leviathan中的是当前时间的时间戳和一个bytes数组,而这个byte数组也是一个128位字符串调用算法生成的,这个时间戳也是x-khronos的值。
3、生成128位字符串
这个128位字符串是由a2,str3,str4,str5四个变量拼接成的,a2是整个url的md5,str3是提交的数据的md5,str4是cookie值的md5,str5是cookie中从sessionid=之后到结束的字符串的md5,事实上str4和str5可以用32个0来表示,str3只有在post请求时需要生成,其它如get请求时也可以用32个0表示。
4、生成传入so文件中加密函数内的byte数组
但是这个128位字符串是如何变成一个byte数组的呢,这里调用了com.ss.a.b下的a函数生成,其算法用python实现如下:1
2
3
4
5
6
7
8
9
10
11def generate(a):
w = []
for i in range(0, len(a), 2):
bin_str = bin(int(a[i], 16))[2:] + '0000'
if len(bin_str) < 8:
bin_str = '0'*(8-len(bin_str)) + bin_str
if bin_str.startswith('1'):
w.append(-(int(''.join(['0' if int(k) else '1' for k in bin_str]), 2) + 1) + int(a[i + 1], 16))
else:
w.append(int(bin_str, 2) + int(a[i + 1], 16))
return w
5、模拟运行环境加载so文件进行加密
接下来就是leviathan函数的实现,由于是在native层中实现加密,且有反调试措施,所以目前只能通过调用so文件来实现加密,这里我使用的是GitHub中的一个开源项目AndroidEmu来模拟运行环境并加载so文件,然后使用python调用leviathan函数,传入时间戳和byte数组得到加密结果,此结果即为x-gorgon的值。