文章总结: 本文记录了对采用SM2加密及零信任防护APP的渗透测试过程。作者利用PC端代理共享绕过深信服零信任网络限制,并通过ProxyPin建立SOCKS代理解决HTTP代理检测问题。逆向分析发现APP混淆命名,在AESInterceptor中实现了SM2加密逻辑。最终通过Jadx辅助生成Frida脚本,成功Hook加密函数获取请求明文与公钥,解决了加密流量无法分析的难题,为类似场景提供了完整的排查思路与操作示范。 综合评分: 85 文章分类: 移动安全,渗透测试,逆向分析,安全工具
针对SM2加密的APP测试
原创
Vlan911 Vlan911
我不懂安全
2026年2月27日 08:00 北京
本文知识点:
- app需要连接深信服零信任才能联网,如何抓包
- app存在代理检测,http代理无法直接抓包如何进行简单绕过
- app采用sm2加密,如何获取加密方法并进行hook
其实第一条与第二条本质上是一个问题,深信服零信任的解决方法也很简单,那就是PC端连接深信服零信任,同时保持pc端与移动端保持在同一个wifi环境,而后移动端不连接深信服的零信任,只将代理设置成pc端即可。
但是在本次测试的时候发现,app依然没有办法正常网络请求,而后发现app存在http代理检测,在使用了justTrustMe后问题也没解决,于是乎转换成socks代理,在使用proxypin后问题解决,成功拦截到数据包,这样就不需要单独写frida脚本进行绕过
可以看到,虽然成功拦截到正常请求了,但是请求包是加密的,返回包却是明文的
想知道加密方法是对称加密还是非对称加密其实很简单,那就是相同的请求重复请求两次,而后查看请求包的加密体,发现密文发生了明显的变化,所以由此可以判断此次加密为非对称加密
由于app客户端是在本地,并且一般情况下加密都是调用的标准库或者是自己写的,所以在代码里都能看到具体的加密方式,这里推荐使用jadx进行app逆向,因为jadx支持mcp可以方便我们利用大模型进行分析,同样jadx支持一键生成frida脚本,这样我们在找到点位后可以直接对这个请求进行hook,不需要我们自己绞尽脑汁写javascript脚本,能节省很多时间
我们使用jadx打开项目后,很快就能定位到请求的接口,可以看到首先LoginApi定义了登录相关的 API 方法,使用 Retrofit 注解标记 HTTP 方法和路径
接下来我在LoginApi2这个类里看到,这个类封装了实例创建的细节,并且通过NetWowkManager创建网络服务
通过定位NetWowkManager,发现他似乎是用来创建网络结构实例,然后调用最终调用 netWorkStructure.getApi(clazz) 获取 Retrofit 代理的 API 实例
跟进 NetWorkStructure类,发现这里面配置了网络请求的核心组件,包括拦截器、请求头、缓存等;并且里面创建了一个名为AESInterceptor的实例?但是这个实例里面实际上包装的是SM2加密方法,这就很迷,又被开发玩弄了这是?
继续跟踪AESInterceptor类,我们可以看到里面的关键encryptRequest加密请求方法,开头的位置定义了加密请求需要使用的硬编码公钥、以及解密返回使用的私钥
这也解释了,为什么请求加密了,但是返回解密了,这就很不赖
知道了加密的方法和位置,一开始我也侥幸的认为会不会请求加密的私钥和返回解密的私钥是一样的,但是我尝试拼接后,发现并不是
所以这里就演示一下简单的frida获取下加密前的请求体,主体内容是直接通过jadx生成的,就加了一个Java.perform包装了一下
Java.perform(function() { var SimpleSM2Util = Java.use("com.xxxx.intercepter.SimpleSM2Util"); SimpleSM2Util["encrypt"].implementation = function (str, str2, str3) { console.log(`SimpleSM2Util.encrypt is called: str=${str}, str2=${str2}, str3=${str3}`); let result = this["encrypt"](str, str2, str3); console.log(`SimpleSM2Util.encrypt result=${result}`); return result;};});
frida server是怎么使用的,怎么获取进程名字的这里不废话,让我们运行脚本然后点一下登录看看效果,可以看到,的确可以看到明文的请求了,但是看着别扭,小小优化一下
Java.perform(function() { var SimpleSM2Util = Java.use("com.xxx.intercepter.SimpleSM2Util");
SimpleSM2Util.encrypt.implementation = function(pubKey, param2, plaintext) { console.log("[加密前明文]:" + plaintext); console.log("[使用公钥]:" + pubKey);
var result = this.encrypt(pubKey, param2, plaintext); console.log("[加密后密文]:" + result); return result; };});
没问题,这就可以了
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:我不懂安全 Vlan911 Vlan911《针对SM2加密的APP测试》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论