关于企业公开的信息数据,在工商各网站都可以公开爬取,某查查、大眼查的数据来源便是。但是我们直接研究某查查的数据,可不就是:黄雀在后!
没有关注的朋友,关注一波,我们开冲冲冲冲!
对于APP的逆向流程,之前在饿了么那边已经讲过了,就不再多讲。不记得的话,翻一下上次的笔记。^^
基本流程大致就是:
抓包->模拟报文->逆向加密参数->还原算法->成功
我用的版本是:某查查12.6.0
某查查的抓包结果:
这个是附近的企业的报文,目前看来,需要我们逆向得出的参数分别有:Authorization(这个应该是登陆帐户相关的)、sign这么俩。
为了得到Authorization,我们还得分析登陆的报文。
再次抓包分析登陆报文,发现在登陆成功后,服务器返回了Authorization的值,但是,这个报文的请求参数里依然带了Authorization参数,那这个参数又是哪里来的呢?(登录报文是/app/v1/admin/login,自己抓一下)
再次重新对整个流程抓包分析可知。
注意:这里的Authorization与你上传的设备信息(即deviceid,后面会说)息息相关,如果不匹配是不被认可的。
在/app/v1/admin/getAccessToken这个报文里,我们发现了deviceId这个参数,很不幸,不是IMEI,所以我们又多了一个需要逆向的参数。
对整个流程总结一下:
至此,思路理清楚了,我们需要逆向的也就剩下:deviceId和每个包都有的sign。这下总结的明明白白,开始逆向。
分析流程直接上图。
终于找到了。
得到com.ta.utdid2.device.c类的h函数即为生成函数,通过阅读逻辑,找到下述才是真正的逻辑。
至此,我们得到了deviceid的生成算法,下来我们通过还原一下。
直接上代码。
def gen_device_id(self):
timestamp = self.get_bytes(int(time.time()))
random_num = self.get_bytes(random.randint(0, 0x7FFFFFFF))
imei = self.get_bytes(self.str_to_int(self.gen_imei()))
bytes_src = timestamp + random_num + b'\x03\x00' + imei
sign = self.get_bytes(self.str_to_int(tool.base64_encode(tool.hmac_sha1(bytes_src, 'd6fc3a4a06adbde89223bvefedc24fecde188aaa9161'))))
bytes_src += sign
return tool.base64_encode(bytes_src)def gen_device_id(self):
至此生成deviceid完成。
我们直接在刚才找到的请求列表里找到sign参数。
@FormUrlEncoded
@POST("v1/admin/getAccessToken")
g<ApiResponse<TokenVO>> a(@Field("appId") String str, @Field("deviceId") String str2, @Field("version") String str3, @Field("deviceType") String str4, @Field("os") String str5, @Field("timestamp") long j, @Field("sign") String str6);
如上,sign是时间戳后面的参数。
可看出,sign由时间戳和aXY组合后进去axq.n函数计算得出,这个aXY找到如下:
既然是固定字符串的解密结果,那他肯定也是固定的,我们就没必要每次生成了,通过hook的方式,将这个值拿到直接用就好了。
可能各个版本会不同的。
接下来继续看axq.n函数。
函数太长,截图放不下了。
经过研究你会发现,这里无论是md5算法或者是阿里聚安全的算法都是在so里面了,这就有两个思路,一个办法是逆向so找到生成算法,一个是hook这个n函数,强制调用即可。
下面给个frida hook的代码,仅供参考,或者用xposed来hook都是可以的。
rpc.exports = {
sign: function(deviceid, timestamp, param3){
var result = "";
Java.perform(function () {
try{
var input_params = [deviceid, timestamp, param3]
var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
var class_EncryptImpl = Java.use("com.android.icredit.utils.EncryptImpl");
var context = currentApplication.getApplicationContext();
var inst = class_EncryptImpl.$new(context);
result = inst.n(input_params);
}catch(e){
console.log(e)
}
});
return result;
}
}
至此,所有的参数都有了。不论是登陆包、密钥置换包、数据抓取的包,都能完全仿真了。
以上。
欢迎阅读转发~想要转载的朋友请告知我之后转载,并注明原帖来源。
如有问题,请与我联系。
2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!
最后于 18小时前 被帅逼李三郎编辑 ,原因: