写在前面

啊哈哈,这次又是缘起手游进行的一次学习(等我第一个月工资下来配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上安装证书

image-20230520221308016

修改证书为始终信任

image-20230519215029114

Android配置Vmos和Drony

在真机上安装Drony

安装完成之后,往左划一下进入设置,选择不是无线网络

设置好上一步查到的Mac内网IP和mitmproxy监听端口(默认是8080)

接着修改过滤器成引导全部

img

然后点击规则,添加对应抓包的app

image-20230520221643289

设置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模块绕过本地证书强校验

然后就是前后端用统一的一套加解密逻辑进行数据混淆,隔段时间更新,只要保证不常见不泄漏,可以极大预防参数和接口暴力门槛。