开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 42603|回复: 19
收起左侧

[android教程] 酒仙网reservationToken算法解析

[复制链接]
结帖率:67% (2/3)
发表于 2021-3-2 14:10:19 | 显示全部楼层 |阅读模式   广西壮族自治区南宁市
0x00 前言:
    在调用下单接口(addorder.html),里面包含一个参数名称为reservationToken,它的值是一串类似md5的十六进制。这里分享下逆向追踪过程,目前已实现。

0x01 算法定位:
拖入APK到jadx,直接搜索关键字reservationToken,我们看到图中的代码





其中,orderPrepareParameter2.mReservationToken = MD5Util.encode("ANDROID" + W.e() + X.b());  是根据 3个字符串进行拼接在执行的操作,那么我们接下来就来查找这2个方法的字符串。

目前已知:md5("ANDROID" + ? + ?)  

0x02 W.e()算法扣出:
我们追入:W.e() 内进行查看


我们可以看到,它这里是直接把结果存入的f26606b进行返回的,由于该APP它都做了缓存判断,所以如果直接下frida的话,也没办法直接HOOK到它生成的过程,但是我们发现他是调用的static方法UTDevice.getUtdid 获得的,我们可以编写frida代码主动调用,然后看看它输出的结果,以下是frida代码:

编写好代码直接运行,因为是主动调用的,无需等待hook,   那么我们看到是一串字符串,感觉有点像base64编码。

这部操作的意义并不是很大,只是知道了 W.e() 的返回值,但我们需要知道它的生成过程,所以继续 UTDevice.getUtdid 跟进。

我们继续跟进去后,发现它是调用的 b.b(context) 获取的一个class类,然后在调用 f() 返回的结果:

那么我们继续跟如b.b()内的实现部分


这里我们看到,它先判断f13187a是不是null,如果是的话,继续调用a(context)创建,这些都是它的缓存机制判断,我们继续跟进a内



这里就是它创建class类的参数赋值代码了,我们知道,刚刚它是调用 b.b(context) 然后调用 f() 来得到的,我们现在去看看 f() 它返回的是对应哪个属性,这样就知道这里对应的是哪个值了。


我们发现,f是返回的f13186g,而f13186g是由e方法赋值的,那么上一张截图,我们看到,e方法就是传入的 value 这个值。aVar.e(value) 也就是上一张截图的这行代码了,那么我们就继续跟进value的方法,也就是 String value = c.a(context).getValue(); 里面的过程



我们这里可以看到,它调用的h()方法,继续跟进,事情逐渐变得好玩了。



这里代码比较多,我们先来一下,它是调用的 this.h = i(); ,如果不是空的,就直接返回,其实这里也是获取缓存的值,我们跟进 i() 里面,由于这个方法代码反编译失败,都是一片绿色,阅读比较吃力,但是经过详细的阅读得出就是读取的缓存,所以这行忽略,我们往下看:
byte[] c2 = m5c();

this.h = b.encodeToString(c2, 2);

得出2行关键代码,这里它通过调用m5c()获得一个byteArr数组,接着进行base64编码后返回,也就是m5c里面估计就是关键生成了。



这里基本大部分都是Android的SDK代码,我们可以直接新建一个java工程,直接复制他的代码,将报错地方纠正。



我们扣出代码,发现报错的地方就是 d.getBytes 、 e.a(this.mContext) 、 g.a 、b 四处地方,我们逐一进去查看,首先查看 d.getBytes()



它就是进行的一个位移操作,我还以为是什么复杂的类,我们直接复制出来就好了,重新命名下。


直接复制出来,我重新命名成了 DgetBytes,然后把 d.getBytes 改成这个方法名,就解决了,那么我们继续查看下一个方法  e.a(this.mContext) ,跟进



这个方法也很简单,就是获取手机的deviceId,下面的就是判断如果获取不到执行别的获取方案,就不跟进了。 我们直接写死deviceId,也就是IMEI码就行了,到时候在封装成一个传参的方式即可。
最后跟进g.a()里面查看



这也是一个相加操作,很简单,也直接跟刚刚的方式一样扣出来,我重新命名成了ga,然后修改下调用的代码即可。

还剩最后一个 b() 方法,这个也是可以直接扣的

我们重新命名成了be,那么看下完全扣完的代码,一点报错没有了


后面我们在进行BASE64编码就完成了第二个参数的生成过程了!! 如果要转成其它语言代码的话,就看你的代码阅读能力了,因为都是直接扣出来的~

目前已知:md5("ANDROID" + 算法A(IMEI) + ?)  


这里我就定义成它叫做算法A,他的调用过程就是 Base64.getEncoder().encodeToString(m5c()); 的返回,接下来我们解析第三个参数


0x03 X.b()算法扣出:



我们继续进行扣代码,继续跟进X.b()内查看


这个方法很简单,看着代码挺多,我们慢慢阅读解析。
首先它调用 String packageName = AppContext.getContext().getPackageName() 获取当前APP的包名,然后获取缓存,看看有没有记录device_id这个值,我们要知道他的生成过程。
如果没有,那么它继续调用Settings.Secure.getString(AppContext.getContext().getContentResolver(), "android_id"),这个就是获取系统参数的android_id
如果获取的值是一个它固定的值9774d56d682e549c它就拿来返回了。
最终我们肯定确定,它就是调用
String deviceId = ((TelephonyManager) AppContext.getContext().getSystemService("phone")).getDeviceId();
f8203a = (deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID()).toString();

获取手机的IMEI,然后在通过 nameUUIDFromBytes 进行格式化,自此就结束了~

其实我们用frida HOOK发现,它返回的值跟我们抓包看到的APPKEY是一样的值。

目前已知:md5("ANDROID" + 算法A(IMEI) + UUID格式化(IMEI))  

0x04 算法复原:


最后我们根据上面已知的生成过程,成功扣出算法。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

本帖被以下淘专辑推荐:

发表于 2021-11-6 21:10:20 | 显示全部楼层   江西省赣州市
谢谢分享
回复 支持 反对

使用道具 举报

发表于 2021-10-16 11:50:57 | 显示全部楼层   江西省赣州市
太厉害了,很实用,需要学习下这个破J过程
回复 支持 反对

使用道具 举报

发表于 2021-10-2 18:47:47 高大上手机用户 | 显示全部楼层   河北省石家庄市
求购 酒仙  安心,黄果树等软件  xiaozhuhupo
回复 支持 反对

使用道具 举报

头像被屏蔽
结帖率:0% (0/2)
发表于 2021-7-5 19:48:53 高大上手机用户 | 显示全部楼层   贵州省遵义市
提示: 该帖被管理员或版主屏蔽
回复 支持 反对

使用道具 举报

头像被屏蔽
结帖率:0% (0/1)
发表于 2021-7-4 08:31:38 | 显示全部楼层   广东省珠海市
提示: 该帖被管理员或版主屏蔽
回复 支持 反对

使用道具 举报

发表于 2021-3-31 15:40:12 | 显示全部楼层   山东省济南市
厉害厉害
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2021-3-31 15:24:17 高大上手机用户 | 显示全部楼层   湖南省常德市
提示: 该帖被管理员或版主屏蔽
回复 支持 反对

使用道具 举报

结帖率:80% (4/5)
发表于 2021-3-24 16:28:52 | 显示全部楼层   江苏省常州市
诺离 发表于 2021-3-23 18:20
那就得知道他在哪一步记录的utdid了

我也是这么想的,正常思路就是初始设备的时候,服务端保存了utdid和appKey的对应关系
回复 支持 反对

使用道具 举报

结帖率:67% (2/3)

签到天数: 1 天

 楼主| 发表于 2021-3-23 18:20:26 | 显示全部楼层   广西壮族自治区南宁市
lfly453 发表于 2021-3-22 18:16
服务端如果没法获取UTDevice.getUtdid的值,就没法校验,addorder接口中是没有该字段的 ...

那就得知道他在哪一步记录的utdid了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表