记一次使用 Xposed RPC 和 BurpGuard 应对金融APP参数签名及加密的详细过程
前言
在一次金融渗透测试项目中需要对 APP 进行渗透,发现 APP 对参数进行了签名以及加密,于是便逆向 APP 并通过 Xposed RPC 和 BurpGuard 解决了问题,从中学到了许多,因此记录过程并分享一下思路,代码和图片均做了脱敏处理,同时省略了代码调试的过程。
阅读完本文,你可以学习到:
- APP 请求逆向思路
- 如何查阅资料
- APP 请求签名和加密的原理
- 了解白盒 WbSM4
- Xposed RPC 的实现思路
- BurpGuard 如何使用
声明:本文不针对任何 APP,仅对加密及签名技术进行研究,如有侵权,请联系删除。
详细过程
测试环境:mumu 模拟器、Magisk
、Lsposed
初探签名及加密
APP 的 HTTPS 验证就不阐述了,常规方式均可绕过。
查看请求包,发现了 MsgId
、AppSign
以及密文 cTxt
:
修改 MsgId
,返回 401,很明显做了请求签名:
加密分析
这里 APP 采用了爱加密企业版加固,于是使用 算法助手Plus + frida 脚本脱壳,使用 Jadx
反编译,搜索关键词,发现没搜到:
随后翻了翻,发现代码都抽空了,到 native 层去了?似乎是没脱完整:
求助某大佬帮忙脱了个壳,继续搜索关键词,找到两处,看到 ECB,莫非是常见的 AES-ECB
加密(心中窃喜):
跟进去:
继续跟 encryptECB
:
跟进:
最终来到 xxx.WbSM4Util$Companion
类的 encryptDataECB
方法:
这是对应的解密函数:
接着看看加密函数中的关键部分 WbSm4().encode()
,这个函数传入的就是明文的字节对象和长度,并没有密钥相关,最后做了一层 Base64:
跟进 WbSm4
一探究竟,发现是 native 的:
网上搜寻一下看看是什么,似乎是 SM4
国密:
问一下 GPT
,白盒 SM4
是什么,看起来是很难复现的算法,密钥也很难提取,后续可能需要采用 RPC 远程调用 :
根据上面的代码分析简单画一个图:
签名分析
接下来看看签名,搜索签名关键词 appsign
:
跟进第一个的 WelfareTaskRequestService.APPSIGN
,是个常量:
搜索常量名,看看哪一处使用了它,这里发现第二个是添加请求头,比较可疑:
跟进代码如下:
分析上面代码可知,RemoteMessageConst.MSGID
是个字符串常量,值为”MsgId”,而签名是由静态方法 HeaderUtils.generateAppSign(url,uuid.requestBody)
生成的,其中三个参数分别为:完整 URL、UUID、完整请求 Body,可以看出请求 body 与 msgid
和 appsign
强相关,任何一个参数错误都可能导致请求不合法,以下是简单示意图:
Xposed RPC 实现
加密和签名都分析完毕,剩下的就是使用 RPC (远程过程调用)了,也就是注入代码,这里我用的是 Xposed
框架,没有检测,但 frida
有检测,过检测的方式参考下方公众号的文章(理论无脑过爱加密企业版),自己试了下确实可以:
https://mp.weixin.qq.com/s/34c5JVJzSCEfqlPanV1FtA
对 Xposed
的 RPC 不太熟悉,网上查阅资料,找到如下文章:
https://www.52pojie.cn/thread-1519322-1-1.html
发现使用 NanoHTTPD
在 APP 内部起一个 HTTP 服务器来与外部通信来实现 RPC 比较方便,写一个 demo,代码可以直接运行,会开启一个 50000 端口的 HTTP 服务器,开放 /encrypt
接口用于加密数据和生成签名,/decrypt
接口用于解密数据:
Xposed 模块使用的模板:https://github.com/yinsel/XposedProjectTemplate
完整 Xposed
代码实现如下(代码写的有点烂,勿喷):
连接 ADB 将模拟器端口转发出来:
adb forward tcp:50000 tcp:50000
测试 APP 内部的 HTTP 服务器是否启动,成功启动:
接口测试,这里使用的是 Reqable
,测试解密接口:
测试加密接口,获取加密数据和签名,可以看到加密的数据一致:
尝试替换获取的签名并发送测试,成功:
BurpGuard 实现
BurpGuard 项目地址:https://github.com/yinsel/BurpGuard
这里画一个示意图以便分析和理解:
完整代码如下:
ClientProxyHandler:
BurpProxyHandler:
最终效果
模拟器安装编写的 Xposed
模块,使用 Lsposed
激活并勾选 APP。
运行 BurpGuard
,并配置模拟器 WIFI 代理为 8081,也就是让 APP 首先走 ClientProxyHandler
,同时 Burp 配置上游代理为 8082:
python BurpGuard.py
在模拟器操作 APP,并使用 Burp 拦截,可以看到请求 body 已经解密:
发送至重发器,并尝试修改请求 body,这里加了个单引号,请求正常:
接下来就可以愉快的渗透啦!