A-A+

分析“微信小程序游戏”并用python脚本自动登录领取所有默认奖励

2024年05月07日 10:30 学习笔记 暂无评论 共3270字 (阅读82 views次)

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】

wireshark 抓包https \ wss

在开始之前,首先你需要明白如何通过wireshark 抓包 https \ wss 并解析其明文方法,因为文中使用的就是wireshark方法。

 

wss websocket数据包分析

这里直接从头到尾进行抓包登录,因为已经详细梳理过,所以很多步骤可以直接略过的。例如游戏选区什么的。

所以直接可以从开始界面进行真正的逐步分析。

images

如图所示,第一步建立了一个websocket连接,地址是:https://wss-bxxxo-yxxs.fxxxxngame.net:31052/

 

然后紧接着就进行了登录,但是并非websocket登录,而是一个post的网页登录请求。请求是 https://bxxxo-yxx.fxxxxgame.net/game/login.php?ac=212342&sid=8123457&appid=wx0123456789f

通过分析发现sid=8123457应该是游戏的服务区,ac=212342疑似是角色ID,appid=wx0123456789f它是微信的openid,具备唯一属性,估计在这个游戏里应该起到身份校验的密码作用。

 

不过这些都不是重点,在这个请求之后就出现了大量的websocket数据包,具体如下:

images

具体To server的代码如下:

 

\x00\xe6\x009\x00\r812347-212342\x00\x00\x00\x00\x00\x00\x00\x02cn\x00\x02CN\x00\r101.201.214.131\x00\xb8{"appid":"wx0123456789f","pf":"wx","pfkey":"","zoneid":0,"serverid":812347,"openid":212342,"openkey":"","phpChanelID":"","platform":2,"gdt_vid":"","weixinadinfo":"","embedgame":0}

虽然里面有部分数据,如\x00\xe6\x009\x00\r 这个不好分析,但是还是能明显看出一些格式。如812347-212342代表游戏服务区-角色ID,后门接着cnCN,然后是IP:101.201.214.131,在然后是一个json数据{"appid":"wx0123456789f","pf":"wx","pfkey":"","zoneid":0,"serverid":812347,"openid":212342,"openkey":"","phpChanelID":"","platform":2,"gdt_vid":"","weixinadinfo":"","embedgame":0}

这个是第一个To server的数据包,紧接着有一次发送到服务端一个数据包,具体如下000000db,如图:

images

然后剩下就是服务端返回,返回了很多很多数据,To client如下图:

images

下一步就是点游戏里的每个功能,然后发送对应的数据包,然后服务端回包。

 

整体看下来数据属于未加密(或半加密)状态,因为里面很多空字符并不好理解在服务端如何去转换这些数据。也只能通过表面做大致猜测。

 

python 复写发送wss websocket数据包

下一步可以尝试用python写一下自动登录脚本,然后根据点击功能提交的数据包然后写出对应的操作。

写python脚本前需要先看一下此游戏websocket数据传输具体的数据包,如图:

images

这里其实有一个重点,就是Opcode它对应的值是0010(二进制),对应十六进制就是%x2,其实也有提示Binary也就是说,传输的所有数据包都是以十六进制字节形式传输。

这里针对WebSocket 协议中的操作码(Opcode)的含义做一下解读:

操作码占据了 WebSocket 消息头中的 4 个比特位,用来定义“负载数据”(Payload data)的解释方式。如果接收到未知的操作码,接收端必须关闭 WebSocket 连接。以下是已定义的操作码:

  • %x0:表示一个继续帧(Continuation frame)
  • %x1:表示一个文本帧(Text frame)
  • %x2:表示一个二进制帧(Binary frame)
  • %x3-7:保留给未来的非控制帧
  • %x8:表示一个连接关闭帧(Connection close frame)
  • %x9:表示一个 Ping 帧(Ping frame)
  • %xA:表示一个 Pong 帧(Pong frame)
  • %xB-F:保留给未来的控制帧

换句话说,操作码告诉接收端如何解释传输的数据。例如,如果操作码为 %x1,那么接收端会将负载数据解释为文本数据。如果操作码为 %x8,那么接收端会将其视为关闭连接的指令。

 

下一步就是开始正式写脚本,首先通过wirshark获取到的数据包如下:

E7 81 B5 E5 85 94 E7 AC A6 02 00 28 E4 BB 8E E4 BB A5 E4 B8 
8A E5 9F BA E7 A1 80 E5 B1 9E E6 80 A7 E4 B8 AD E9 9A 8F E6 
9C BA E8 8E B7 E5 BE 97 31 E6 9D A1 00 25 3C 62 72 2F 3E 3C 
62 72 2F 3E E8 AF A5 E5 93 81 E8 B4 A8 E6 97 A0 E6 B3 95 E6 
90 BA E5 B8 A6 E6 8A 80 E8 83 BD 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 01 00 01 38 81 00 00 00 01 00 01 00 00 
E7 AC A6 02 00 28 E4 BB 8E E4 BB A5 E4 B8 8A E5 9F BA E7 A1 
80 E5 B1 9E E6 80 A7 E4 B8 AD E9 9A 8F E6 9C BA E8 8E B7 E5 
BE 97 31 E6 9D A1 00 25 3C 62 72 2F 3E 3C 62 72 2F 3E E8 AF 
A5 E5 93 81 E8 B4 A8 E6 97 A0 E6 B3 95 E6

 

首先要把这个数据中的空格进行替换hex_data.replace(" ", "")替换之后还需要进行一下字节转换,这里推荐使用bytes.fromhex()具体原因查看“bytes.fromhex() 与 binascii.unhexlify() 的区别”。数据已经转换完剩下就是提交了,在使用ws.send()一定需要注意,加入opcode参数,根据上面所说,它的值对应的就是websocket.ABNF.OPCODE_BINARY,所以整体就是ws.send(date, opcode=websocket.ABNF.OPCODE_BINARY)

到此基本也就完结了。

下面给出部分代码如下:

import asyncio
import websockets

async def send_data(data, uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send(data, opcode=websocket.ABNF.OPCODE_BINARY)
        print(f"Data sent: {data}")

async def main():
    uri = "ws://example.com/ws"  # 替换成实际的 WebSocket 地址
    hex_data = "E7 81 B5 E5 85 94 E7 AC A6 02 00 28 E4 BB 8E E4 BB A5 E4 B8 8A E5 9F BA E7 A1 80 E5 B1 9E E6 80 A7 E4 B8 AD E9 9A 8F E6 9C BA E8 8E B7 E5 BE 97 31 E6 9D A1 00 25 3C 62 72 2F 3E 3C 62 72 2F 3E E8 AF A5 E5 93 81 E8 B4 A8 E6 97 A0 "
    hex_data = hex_data.replace(" ", "")  # 去除空格
    data = bytes.fromhex(hex_data)
    await send_data(data, uri)

asyncio.run(main())

其实下一步可以比较多的方式来研究研究这个游戏的漏洞。

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×

给我留言