-
-
[原创]某设备登记APP趣味破解
-
发表于: 2023-3-12 18:07 28129
-
恰逢周末降温,独自一人在家闲来无事逛会儿论坛打发下时间,才发现自己最近一次发文竟然可以追溯到2021年。其实这两年个人一直在尝试利用所掌握的技术、积累的知识技能来解决生活、工作中遇到的一些琐事,正好最近就遇到一件琐事。事情是这样的,公司强推一款设备登记APP,要求每个人进行安装并每日使用APP进行登记。如果名下只有一两台设备操作起来不算麻烦,但对于测试相关工作而言,无论是考虑系统版本的兼容性测试,还是需要依赖各种系统环境的安全测试,相关测试人员名下都有多台测试设备,这就需要我们每天手动对所有设备进行开机、启动APP、登记、关机等一系列的操作。苦不堪言,所以我只能选择搞TA。
首先对这款设备登记APP进行简单的介绍,这款APP比较简单主要包含三部分功能:扫码登陆、设备登记和记录查询。其中,扫码登陆主要是采集与用户身份相关的信息,比如用户名、用户ID及所在部室等信息;设备登记则是将用户信息、设备信息(资源编号、设备IMEI、设备ID等)、地理位置信息等组装成报文后解密上传至服务器;记录查询则是查询当前用户所有设备的登记记录。
根据上图设备登记APP的首页,大致可确定设备登记网络请求报文所涉及的字段内容,看到首页我的脑海中也立马想到了3种实现方案:
1、遍历设备列表依次修改对应EditText组件的文本内容,主动触发“提交”按钮的点击事件;
2、二次打包设备登记APP,添加设备列表维护、批量设备登记等功能相关代码;
3、逆向分析设备登记APP,将核心逻辑抽取后自实现一个新的APP用于批量自动化设备登记。
简单分析下上述3种实现方案的利弊:对于方案一而言,实现起来相对比较简单,甚至无需逆向分析目标APP,对类似需求的通用性也比较高,但是比较难管理,一方面涉及UI组件较多,另一方面也很难确定某一具体设备是否登记成功(至于如何快速定位界面重的UI组件以及主动触发组件的点击、长按等事件,后续可能会通过其他文章介绍一个好玩的案例);对于方案二而言,无需解释,理论可行但是限制性因素太多,比如目标APP可能会存在签名校验等防篡改策略,当然本人倒不是因为这个,由于太久没接触smali,实现成本就变得比较高了;对于方案三而言,可能唯一的弊端就是需要实现一个新的APP,但是这种实现所带来的收益也是巨大的,比如高度定制化,我们可以有更多、更灵活的玩法,本文后面也会介绍两种趣味破解方式。
抓包是移动APP逆向的常规手段,与大家一样我也是先尝试抓包分析一下报文,但让我感到“惊喜”的是这种内部使用的APP竟然还用上了证书钢钉。目前已经公开的破解证书钢钉的方案有很多,所以呢也不慌,甚至我还悠闲的打开了Android Studio,没想到却发现一个新的惊喜。
客户端日志泄露是一个很常见但极容易被忽视的安全问题,对于这种内部使用,又在“赶鸭子上架”的情况下开发的APP,极容易因为开发者的大意而出现,而对于泄露的日志只要静下心来分析,总会找到一些有用的信息。
从日志信息基本可确定目标APP会将用户ID、用户名及设备相关信息等组装成JSON字符串并加密后进行网络请求,因此也没太大必要破解证书钢钉进行抓包分析了。需要注意的是该APP分别用原生开发和flutter进行Android和IOS端的开发,逆向flutter的成本无疑要比Android逆向麻烦一下,所以本人选择从Android端下手。
后续的逆向分析过程大致包含6步:
1、导出应用安装包
使用“adb shell pm path 包名”定位apk所在路径后,直接用“adb pull”命令将apk文件导出到电脑本地。
2、应用脱壳及反编译
拿到apk文件后一股脑安装到脱壳机进行脱壳,之后使用jadx进行反编译。
3、定位当前Activity
使用“adb shell dumpsys activity top”可查询当前界面对应的Activity类,可确定首页对应“MainActivity”,使用jadx搜索类名定位并双击跳转。
4、点击事件逻辑分析
分析点击事件,需要先定位对应的组件。这里简单分享几种定位思路:一种思路是从当前Activity对应的布局文件xml中进行定位后,根据组件的id,根据View的findViewById函数定位;第二种思路是根据setOnClickListener函数搜索,然后判断处理逻辑是否符合预期进行定位;第三种思路就是肉眼观察当前Activity类定义的属性,根据字段名进行判断,但是这种思路可能因为混淆而失效。很幸运目标APP在MainActivity中定义了一个“btnConmit”属性,从名字看应该就是对应的“提交”按钮,后面就可以快速找到对应的事件处理逻辑相关代码,部分核心逻辑如下图所示:
5、加密逻辑分析
目标APP的加密逻辑还是比较简单的,与加密相关的代码就三张,如下图所示:
其中涉及的密码算法包括AES和RSA两种,其实有经验的朋友看到这俩密码算法,大致就可以猜出加密逻辑了。AES是一种对称密钥加密算法,而RSA是一种非对称密钥加密算法,对称密钥加密算法最大的优势是加密速度快,适合对大数据进行加密,但是密钥管理困难,而非对称密钥使用成对的密钥进行加解密,安全性较高一些,但是加解密速度要比对称密钥算法慢得多,因此二者经常被组合起来使用。
现在再分析目标APP的加密逻辑就比较简单了,大致就是如下三步:
第一步,调用AesUtils类的getAESSecureKey函数,动态生成一个AES密钥aESSecureKey。
第二步,使用AES密钥对网络请求内容(日志泄露中的JSON串)进行加密,生成密文encrypt。
第三步,使用RSA的公钥对AES密钥进行加密保护,生成加密后的ASE密钥encryptByPublicKey。
6、网络请求分析
继续分析代码可确定目标APP使用了OkHttp框架实现网络通信,并且封装了一个请求函数如下图所示:
其中三个参数分别对应网络请求的url、使用AES密钥加密后的密文、使用RSA公钥加密后的AES密钥,继续跟踪相关参数是如何被使用的。
从上图可看出最终是生成一个FormBody,而message和key则分别对应使用AES密钥加密后的密文和使用RSA公钥加密后的AES密钥。当服务端接收到网络请求后,只需要取出key并使用RSA的私钥进行解密获取到明文的AES密钥,然后使用AES密钥对message进行解密即可获取到明文的请求内容。
现在目标APP网络请求所包含的信息(用户信息、设备信息、地理位置信息等)、加密算法、网络请求等核心逻辑均已分析完成,我们便可以通过伪造网络请求数据来实现设备登记了,接下来分享两种好玩的破解方式。
赞赏
- [分享]分享一种针对uni-app相对通用的抓包方案 14276
- [原创]某设备登记APP趣味破解 28130
- [原创]DouYu弹幕投票助手 25307
- [原创]新姿势绕过应用的ROOT检测 48597
- [分享]基于虚拟机的类加载机制实现热修复 12510