首页
社区
课程
招聘
[原创]最右APPv4.9.9登录协议分析
发表于: 2026-6-29 19:42 3450

[原创]最右APPv4.9.9登录协议分析

2026-6-29 19:42
3450

本文仅限安全研究与学习交流,严禁将本文内容用于任何商业或非法用途,本文涉及的代码及资源版权归原权利人所有,侵删。

APK版本——4.9.9,由于APP还在运营中,这里选择一个较老的版本进行分析学习。

所用工具:DIE、Fiddler、jadx-gui、Frida、IDA Pro7.7、雷电模拟器9.1(64位)。

首先使用DIE查看程序是否存在加固。如下图,这是一个基于 B4A(Basic4Android) 开发的Android应用,采用 BasicJava 混合编码,运行环境为 Android 9(API 28),没有特征明显的加固。

配置Fiddler代理,在雷电模拟中抓取APP登录的包。具体操作为在模拟器中打开APP选择账号密码登录,点击登录按钮观察APP响应并在Fiddler中查看抓到包的数据。

APP响应为“手机号还没有注册”。


抓取到的登录数据包一共有两个。

第一个包是HTTPS代理隧道握手。客户端要求通过代理建立到目标服务器443端口的TCP隧道。

第一个包的响应为200表示代理已成功打通隧道,但是包中标注 Connection: close 且“failed to send any data”,说明这个隧道建立后立即被关闭了。这意味着APP并没有真正走HTTPS(TLS)加密,而是尝试建立隧道失败后,降级为HTTP请求

第二个包是真正的登录POST请求。一眼扫去有以下特征:在登录包的请求URL后面加上了sign,Body是无法解密的乱码。

详细分析登录包的参数。

接下来看第二个包的响应:

响应体(96字节乱码):同样是 application/xcp 加密。

xcserververify: 1:服务器验证标记,说明服务端校验了请求头中的签名和XCP加密数据,返回的 1 表示验证通过。

X-Xc-Proto-Res 中的 1- 前缀:代表状态码(1=成功),后续带上了服务端返回的加密Token(登录后的Session)密文。

推测服务端解密流程为:X-Xc-Proto-Req 中的密钥信息 → 解密Body → 校验Sign是否匹配 → 验证账号密码 → 返回加密的Token密文。

接下来就要根据搜索抓包时看到的关键词,找到引用这些字符串的代码,分析其调用关系。有以下几种搜索思路:

搜索Header名:如"ZYP", "X-Xc-Proto-Req", "Request-Type"

搜索参数名:如"sign", "v2-"

搜索URL路径:如"ef0K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3q4H3K9g2)9J5k6h3W2*7N6h3W2&6L8%4g2Q4x3X3g2U0L8$3#2Q4x3V1k6S2j5$3y4G2N6h3&6@1i4K6u0r3L8r3!0Y4K9h3^5`."

Jadx打开安装包进行全文搜索,这里把可能的每个参数都搜索一遍,发现搜索"X-Xc-Proto-Req"有且仅有一处使用,这就很方便了,直接追踪查看分析调用处代码。

代码总体是一个网络请求的核心拦截器(Interceptor),负责在POST请求发出前对请求体(Body) 进行加工和加密,并添加关键头部。

对这段反编译代码详细分析。

请求预处理。

取出原始请求的URL、协议、域名,用于后续判断是否强制HTTPS。

URL协议切换。

若原URL是https且域名满足mJ()条件,或全局开关euC.vO()为真,则强制使用https,否则降级为http

mJ(strYc):检查主机名是否在硬编码白名单 euB 中(api.weibo.com, api.weixin.qq.com, graph.qq.com),这些域名强制使用 HTTPS,对应了APP中其他三种登录方式。

this.euC.vO():全局开关,若为 true 则强制使用 HTTPS。

若以上条件均不满足,则降级为 HTTP(端口 80),这就是为什么抓包中使用 HTTP 的原因——域名不在白名单且 vO()false

添加设备ID头。

处理POST请求体。

euC.z(jSONObject)动态注入参数的地方,会加入timestamprandom等,这些是签名计算的基础

NetCrypto.j()NetCrypto.i():两个方法都接收URL字符串字节数组,返回值为签名(sign),并调用qJ()设置到请求中。抓包中看到的sign=v2-xxx就是由这两个方法生成的。

NetCrypto.encodeAES():负责AES加密Body。

NetCrypto.getProtocolKey():生成X-Xc-Proto-Req头的内容(抓包中的长串Base64)

追踪NetCrypto类分析,如下图,大部分方法都在so层中的libnet_crypto中实现,生成sign函数的i和j调用了native函数generateSign和sign函数。

在进入so层进一步分析之前,使用FridaHOOK得到加密前的明文JSON。

HOOK代码:

如下图,成功拿到登录包加密前的body。

再次HOOK Java 层的 i、j 和 getProtocolKey,获得加密后的密文ibArr 参数)、最终的 Sign 值X-Xc-Proto-ReqgetProtocolKey 的返回值)。HOOK出加密后的密文可以尝试跳过获取密钥和iv验证加密Body的算法是否为没有魔改的标准的AES,hooksign和XXPT头验抓到的包中的数据。

HOOK代码:

 HOOK结果:

使用IDA Pro7.7打开libnet_crypto.so文件分析,在导出函数表中找到JNI_OnLoad使用的是动态注册。

点击进入分析,jclass和RegisterNatives没有正常识别,且存在简单的ollvm混淆

这里使用插件或者手动去除都可以。


[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

最后于 2026-7-4 17:48 被ODcat编辑 ,原因:
收藏
免费 0
打赏
分享
最新回复 (4)
雪    币: 230
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
2026-6-29 20:07
0
雪    币: 666
活跃值: (95)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
C0rr7ct

别搞,你才是佬

最后于 2026-6-29 20:38 被ODcat编辑 ,原因:
2026-6-29 20:27
0
雪    币: 112
活跃值: (9015)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
tql
2026-6-30 17:26
0
雪    币: 2916
活跃值: (5275)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
tql
2026-7-1 17:32
0
游客
登录 | 注册 方可回帖
返回