Project SEKAI 逆向(3): pjsk API中间人攻击 POC
- 分析variant:世界計劃 2.6.1 (Google Play 台服)
这里和il2cpp关系貌似不大;主要记录一下api包劫持可以用的手段
1. 工具
host使用https://github.com/mitmproxy/mitmproxy,
victim上安装https://github.com/NVISOsecurity/MagiskTrustUserCerts后,导入mitmproxy的CA,重启就能把它变成根证书
最后,mitmproxy所用脚本:https://github.com/mos9527/sssekai/blob/main/sssekai/scripts/mitmproxy_sekai_api.py
2. 分析
上一篇猜测api的封包用了protobuf;并不然,这里是MessagePack
如此,数据schema和报文在一起;不用额外挖了
用mitmproxy做个poc实时解密转json
看看:
3. MITM
没错,搞这个只是想看看MASTER谱面长什么样…
锁MASTER的字段貌似在这里;尝试直接修改
def response(self, flow : http.HTTPFlow):
if self.filter(flow):
body = self.log_flow(flow.response.content, flow)
if body:
if 'userMusics' in body:
print('! Intercepted userMusics')
for music in body['userMusics']:
for stat in music['userMusicDifficultyStatuses']:
stat['musicDifficultyStatus'] = 'available'
flow.response.content = sekai_api_encrypt(packb(body))
选项可以点亮;但无果:貌似live会在服务端鉴权
不过live鉴权id貌似不会在开始live中使用;抓包中没有对id的二次引用
考虑可能谱面难度选择只在客户端进行,那么修改上报服务器的难度系数也许能够绕过
def request(self,flow: http.HTTPFlow):
print(flow.request.host_header, flow.request.url)
if self.filter(flow):
body = self.log_flow(flow.request.content, flow)
if body:
if 'musicDifficultyId' in body:
print('! Intercepted Live request')
body['musicDifficultyId'] = 4 # Expert
flow.request.content = sekai_api_encrypt(packb(body))
再次启动:
当然,分数上报只会按expert难度进行
意外较少,后续应该不会再玩 MITM 相关内容了
接下来…提取游戏asset?在此之前…
SEE YOU SPACE COWBOY…