GPT Plus 订阅漏洞深度分析 - Google Play Billing 鉴权缺失导致 0 元订阅
ChatGPT Android 订阅逻辑漏洞深度分析
基于 RevenueCat 集成缺陷的业务逻辑绕过研究
⚠️ 免责声明
本文内容仅用于安全研究与技术交流,请勿将相关技术用于非法用途。任何未经授权的商业利用或攻击行为均可能违反《网络安全法》等相关法律法规。
🔍 核心摘要
本文深入剖析 ChatGPT Android 客户端在集成 Google Play Billing 与 RevenueCat 服务时存在的一处业务逻辑缺陷。由于服务端对客户端提交的订阅凭证缺乏二次校验机制,攻击者可通过两种技术路径实现订阅权益的异常获取。
💡 关键认知:这并非传统"破解",而是典型的服务端信任边界设计缺陷——过度依赖客户端传递的业务参数,未建立完整的凭证校验闭环。
📊 攻击方案对比总览
| 方案 | 攻击层面 | 技术门槛 | 设备要求 | 稳定性 |
|---|---|---|---|---|
| 方案 A:HTTP 响应篡改 | 网络层(MITM) | ⭐⭐ 中等 | 无需 Root | 依赖服务端策略 |
| 方案 B:内存令牌替换 | 运行时层(Frida Hook) | ⭐⭐⭐⭐ 较高 | 需 Root + Magisk | 相对更稳定 |
🛠️ 方案一:中间人劫持响应数据(免 Root 方案)
原理拆解
ChatGPT Android 应用在初始化时会请求用户账户状态接口:
1 | GET https://android.chat.openai.com/backend-api/accounts/check/v4-2023-04-27 |
返回的 JSON 中包含 eligible_promo_campaigns 字段,用于标识当前账号可享受的促销权益。正常情况下,该字段应由服务端基于账号画像动态生成。
漏洞点:客户端未对响应数据进行完整性校验,攻击者可通过中间人代理工具修改响应包,注入非授权的优惠标识。
前置条件
✅ 基础环境:
- 任意区域 Google 账号(建议美区)
- 已绑定有效支付方式的账号(用于通过风控,实际不扣费)
- Android 测试设备(模拟器或真机均可)
✅ 工具准备:
- 抓包代理工具:HttpCanary / Charles / mitmproxy
- Root 管理框架:Magisk(用于安装用户证书)
- 目标应用:ChatGPT Android 官方客户端
可用促销标识参考
🔹 通用型优惠码(长期有效):
| 标识符 | 权益内容 | 备注 |
|---|---|---|
3-day-free-trial |
3 天 Plus 试用 | 基础试用档位 |
plus-1-month-free-trial |
1 个月 Plus 免费 | 核心利用点 |
1-month-10-dollars |
首月半价($5) | 折扣型优惠 |
pro-winback-1-month-free |
Pro 挽回试用 | 需特定账号状态 |
🔹 限时/定向优惠码(时效性较强):
| 标识符 | 权益内容 | 说明 |
|---|---|---|
2wqkodfx51z2x |
6 个月免费试用 | 活动期可用 |
2ispxs5mtgz35 |
12 个月免费试用 | 高价值目标 |
📌 这些固定标识符的"可复用性",是外部平台持续提供低价订阅服务的底层原因。
响应包构造示例
以下为注入"1 个月免费试用"权益的典型响应结构:
1 | { |
🔑 关键字段解析:
discount.percentage: 100→ 表示 100% 折扣(即 0 元支付)duration.num_periods→ 优惠生效周期数no_auto_renewal_at_discount_end→ 优惠到期后是否自动续费
完成订阅与凭证提取
- 修改响应后重启应用,进入订阅页面即可看到"免费试用"选项
- 由于交易金额为 0,Google Play 风控策略相对宽松,仅需完成基础支付验证
- 订阅成功后,应用会向 RevenueCat 上报订阅凭证:
1 | POST https://api.revenuecat.com/v1/receipts |
- 拦截该请求,提取响应中的
fetch_token字段:
1 | { |
✨ 该
fetch_token即为订阅凭证,可用于其他账号的权益激活(注:该行为可能违反服务条款)
🧪 方案二:运行时内存令牌替换(Root + Frida 方案)
技术原理
ChatGPT Android 在调用 Google Play Billing 时,会将当前商品档位的 offerToken 传递给支付组件。攻击者可通过 Frida 框架 Hook 相关内存对象,将付费档位的 token 动态替换为免费试用档位的 token,从而诱导支付系统按"0 元"处理交易。
🔐 本质:在客户端本地篡改计费参数,而非直接攻击服务端接口
环境搭建清单
| 组件 | 作用 | 版本建议 |
|---|---|---|
| Root Android 设备 | 执行底层 Hook | Magisk 26+ |
| Windows/macOS 主机 | 运行 Frida 客户端 | Python 3.8+ |
| HLUDA Server | 绕过 Frida 检测 | 最新版 |
| ChatGPT APK | 目标应用 | 官方最新版 |
四步攻击流程
① 枚举计费类实例
通过 Java.choose('c3q') 遍历内存中混淆后的计费类对象,利用反射访问私有字段 b(offerId)与 c(offerToken)。
② 捕获目标 Token
持续监控,当发现 offerId 匹配免费试用档位且 offerToken 以 Adumm 为前缀时,缓存该 token 备用。
③ Hook 系统级参数传递
对以下三个 Android 框架方法进行插桩:
Intent.putExtra(String, String)Bundle.putString(String, String)Bundle.putStringArrayList(String, ArrayList)
在应用发起购买请求时,识别并替换原始付费 token 为缓存的免费 token。
④ 完成"0 元"支付
篡改后的请求被 Google Play 接受,返回成功回执,应用层据此开通相应权益。
核心脚本
1 | Java.perform(function () { |
操作指引
- 设备刷入 Magisk 并启用 Root
- 推送
frida-server(HLUDA 版)至设备并后台运行 - 启动 ChatGPT,进入"升级 Plus"页面(先不要点击购买)
- 主机执行:
frida -U -f com.openai.chatgpt -l exploit.js - 观察控制台输出
Token swapped提示后,再点击购买 - Google Play 弹窗显示金额为 $0,完成验证即可
⚠️ 风险提示:
- 脚本兼容性依赖具体应用版本,可能触发闪退
- 建议在订阅页面加载完成后再注入脚本
- HLUDA 可绕过部分检测,但无法保证 100% 隐蔽
🧩 漏洞根因深度剖析
🔸 方案一:响应注入类缺陷
根本原因:服务端仅校验优惠码格式有效性,未验证其获取路径与账号资格的匹配性。
修复进展:部分优惠码已绑定账号画像,但通用型标识符仍存在利用空间。
🔸 方案二:Billing 令牌信任问题
根本原因:Google Play Billing 接口设计默认信任客户端传递的 offerToken,缺乏服务端侧的二次资格校验。
修复进展:属平台级设计约束,需谷歌官方推进改进。
🔸 历史方案:凭证批量复用(已修复)
曾存在一种通过 RevenueCat 回调接口批量生成 fetch_token 的方案:
- 正价开通 1 个 Pro 账号
- 客户端触发"降级"操作,请求新凭证
- 未消费的
fetch_token可重复用于其他账号
修复措施:当前凭证已绑定设备指纹 + 账号 ID + 时间戳,实现"一证一用"。
🛡️ 安全加固建议
面向开发者的防御策略
| 层面 | 建议措施 |
|---|---|
| 服务端校验 | 所有订阅状态变更必须与 Google Play / RevenueCat 进行双向确认 |
| 凭证管理 | fetch_token/offerToken 应绑定设备指纹、用户 ID、时间窗口 |
| 优惠逻辑 | 建立优惠码使用审计日志,检测异常高频/跨账号使用行为 |
| 通信安全 | 移动端强制启用 SSL Pinning,防止中间人劫持 |
| 运行时防护 | 集成 Root 检测、Hook 框架识别、调试器感知等反篡改机制 |
面向普通用户的风险提示
- 🔒 利用此类漏洞可能导致账号被永久封禁
- 💳 绑定的支付方式存在信息泄露风险,建议使用虚拟卡/一次性卡
- 🔄 漏洞修复具有时效性,不建议作为长期方案依赖
⚖️ 法律与伦理声明
本文内容仅限于安全研究、学术交流与技术防御目的。任何未经授权的商业利用、批量攻击或恶意牟利行为,均可能触犯:
- 🇨🇳 《中华人民共和国网络安全法》第 27 条
- 🇨🇳 《计算机信息网络国际联网安全保护管理办法》
- 🇺🇸 Computer Fraud and Abuse Act (CFAA)
🙏 请遵守"负责任披露"原则,发现漏洞请优先联系厂商修复。
