微信小游戏跳一跳,本质上时一个半离线游戏,它的与服务器的通信其实是在于或者在达到某些超越好友的时候回下载头像信息,或者是在最终游戏结束之后返回游戏结果给服务器,或者是获取现有的排行榜的时候才会向服务器要信息。所以说整个游戏并不是时时与服务器通信,也就是意味着双方沟通上下文关联不强,我们可以从中加入我们想要修改的数据,欺骗服务器,然后成功刷分。
那么这里就存在着这样一个漏洞,如果我知道它返回的数据的加密方式,获取到它原有的包的格式设置,那么我可以仿照这个包的格式,修改其返回内容(也就是最终我们记录刷新之后的数据包)
这里需要欺骗服务的一个关键就在于获取到这个session_id,也就是服务器判断用户身份的凭证,另一方面微信在公众号平台的第三方信息管理那边给出了它们的通信加密方式是AES,那么再将数据经过AES加密传给服务器,那就达到了欺骗服务器修改游戏记录数据的目的。
作者在原文中说是用fiddler来抓包的,这个需要手机和电脑在同一个网络下,比较麻烦,我这里用的是Packet Capture,这个app 可以针对一个应用进行抓包,比较方便。
然后抓包之后,找到我们想要的那个包,注意要用到的包是类似这样的:
其实上面的抓包有用的就最上面那两个,第一个是给了我们它的通信的结构体,另一个就给了我们它的session_id.
然后我们就可以把这些信息放回我们在最上面链接里给出的代码,然后就可以执行。
Python 3.5
requests
pycrypto
我实在Linux上跑的,应该windows也可以。
import requests import json import time from Crypto.Cipher import AES import base64 action_data = { "score": 10086, "times": 666, "game_data": "{}" } session_id = "5TrXoE7IXtM/Nr7vITnbU9bmR53VH0u8RkVnm6m/Fezg==" aes_key = session_id[0:16] aes_iv = aes_key cryptor = AES.new(aes_key, AES.MODE_CBC, aes_iv) str_action_data = json.dumps(action_data).encode("utf-8") print("json_str_action_data ", str_action_data) #Pkcs7 length = 16 - (len(str_action_data) % 16) str_action_data += bytes([length])*length cipher_action_data = base64.b64encode(cryptor.encrypt(str_action_data)).decode("utf-8") print("action_data ", cipher_action_data) post_data = { "base_req": { "session_id": session_id, "fast": 1, }, "action_data": cipher_action_data } headers = { "charset": "utf-8", "Accept-Encoding": "gzip", "referer": "https://servicewechat.com/wx7c8d593b2c3a7703/3/page-frame.html", "content-type": "application/json", "User-Agent": "MicroMessenger/6.6.1.1200(0x26060130) NetType/WIFI Language/zh_CN", "Content-Length": "0", "Host": "mp.weixin.qq.com", "Connection": "Keep-Alive" } url = "https://mp.weixin.qq.com/wxagame/wxagame_settlement" response = requests.post(url, json=post_data, headers=headers) print(json.loads(response.text))
注意上面的程序中是用在Wifi环境下的,它的User-Agent已经给了我们,如果你不是的话,可以根据抓来的包对headers这一个结构的内容进行修改。
另外注意分数超过一万已经被微信禁止了,过高的数据会因为异常而删除,一千以内现在还可以。