写在前面
啊哈哈,这次又是缘起手游进行的一次学习(等我第一个月工资下来配PC逃脱垃圾手游=。=
对于一些手游淘宝有一些付费脚本售卖,不少还提供试用,结合之前破解外挂的经验,这种基本都是请求服务端来判断是否已激活和查询剩余时间的,只要返回体里的数据不加密混淆都很容易通过抓包分析API个底朝穿
所以学习白嫖思路很简单:先通过试用抓包后,分析接口,用中间人攻击拦截并篡改返回数据就能达到欺骗的效果
这里插一嘴,之前没想到直接篡改数据,用的是在NAS上搭建个Apache返回数据,然后改hosts实现偷天换日同样的效果。但这种方法很麻烦,主要还是hosts只能指定IP不能指定域名,也不能指定端口,增加了服务端设计复杂度,直接Man in the middle (MITM)中间人拦截篡改优雅的多
尝试
首先在真机中安装了个HttpCanary,直接抓取Vmos一切顺利,然后想着怎么让Vmos数据走Mitmproxy的监听端口
直接在真机里设置Wi-Fi代理,失败,直接没网
在Vmos中设置Wi-Fi代理,能抓到一些数据,但是抓不到脚本的数据,大概是脚本不走系统代理,这样就只能思考在真机中抓取Vmos的数据了,搜索一番发现了Drony完美解决问题
总结:虚拟机加Drony抓包转发,什么高版本CA证书不认,什么软件不走系统代理抓不到包这些都能解决
最终方案
用的是Android端Drony抓去Vmos虚拟机里的脚本数据并转发到Mitmproxy监听端口,Mac端用的是Python和Mitmproxy实现拦截和数据篡改
这里研究的脚本走的HTTP...直接省不少事情
如果要抓HTTPS的数据,在Android 7 以上系统已经不认用户的CA证书了,只能通过root转成系统CA证书哦或者虚拟机等方式抓,这里就不赘述了,提供几个关键词JustTrustMe,Xposed 和 Magisk或者Vmos
具体步骤
Mac端配置mitmproxy
# 安装mitmproxy
brew install mitmproxy
# 查看Mac的内网IP
ifconfig
# 启动mitmweb页面,默认8081端口
mitmweb
在Mac上安装证书
修改证书为始终信任
Android配置Vmos和Drony
在真机上安装Drony
安装完成之后,往左划一下进入设置,选择不是无线网络
设置好上一步查到的Mac内网IP和mitmproxy监听端口(默认是8080)
接着修改过滤器成引导全部
然后点击规则,添加对应抓包的app
设置Vmos的高玩设计,打开网络ADB,结束
编写Python拦截篡改脚本
mitmproxy高级的地方就是它不仅是个抓包分析工具,它还能借助Python实现自动化批量拦截篡改数据包
具体编写这里不细说,直接看官方文档快得多
这里贴一下我自己的供参考
pip3 install mitmproxy
import mitmproxy.http
class Main:
def __init__(self):
self.num = 0
def response(self, flow: mitmproxy.http.HTTPFlow):
# 检查是否为目标URL
if flow.request.pretty_host == "XXX.com":
# 获取查询参数
query_params = dict(flow.request.query or {})
# 根据不同的参数值,进行不同的修改
if "flag" in query_params and query_params["flag"] == "注册码登录":
# 修改Response body
flow.response.content = "登录成功|48|1818625994".encode('utf-8')
elif "flag" in query_params and query_params["flag"] == "获取项目键名称值":
# 修改Response body
flow.response.content = "OTY=@MQY8jM4@NTQ1@MjgQy@GUPMjfd3gfkd2MTUy@LPgekwq8sjfqMjM4".encode('utf-8')
elif "flag" in query_params and query_params["flag"] == "注册码设置备注":
# 修改Response body
flow.response.content = "设置成功".encode('utf-8')
elif "flag" in query_params and query_params["flag"] == "查询注册码时间":
# 修改Response body
flow.response.content = "59".encode('utf-8')X
elif "flag" in query_params and query_params["flag"] == "注册码验证":
# 修改Response body
flow.response.content = "2023-05-20 11:53:22|2024-05-20 12:53:22|2023-05-20 11:54:41|2023-05-20 11:54:41".encode('utf-8')
addons = [
Main(),
]
# 带上脚本启动
mitmweb -s main.py
预防思路
首先接口敏感数据一定要走HTTPS,借助SSL certificate pinning能极大提高门槛,但是仍然可以通过Xposed模块绕过本地证书强校验
然后就是前后端用统一的一套加解密逻辑进行数据混淆,隔段时间更新,只要保证不常见不泄漏,可以极大预防参数和接口暴力门槛。