网址:https://599.com/live/

解密流程

打开该网站,可以看到有些数据一直有发生变化,然后我们抓包看一下,虽然数据在变化,但是却没有新的包进来

有几个xhr响应的数据是经过加密的,这里加密的数据其实是当前网页显示的已加载的数据,但是经过了加密,网页刷新完成后,所有的数据都是通过websocket进行推送。而之前的,就是已经展示出来的数据就是在这几个xhr响应里面

image-20230616103856487

image-20230616103954912

打开ws请求栏,我们能很明显的看到有数据推送,而且返回的数据是经过加密的,发送的数据是 {"device":"pc","topic":"USER.topic.app.8"}

image-20230616104332341

我们用 AioWebSocket 模块来编写websocket请求,尝试获取一下数据,可以看到,数据可以正常获取,且没有需要携带其它认证参数,唯一需要解决的是将反回的数据进行解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
async def startup(uri):
# 异步执行websocket事件
async with AioWebSocket(uri) as aws:
converse = aws.manipulator
# 向服务器发送消息
await converse.send('{"device":"pc","topic":"USER.topic.app.8"}')
while True:
mes = await converse.receive()
logger.info(f"加密数据====>{mes}")
print("================*================")


if __name__ == '__main__':
remote = 'wss://api.599.com/scorepush/football'
try:
# 创建一个消息循环
loop = asyncio.new_event_loop()
# 设置消息循环
asyncio.set_event_loop(loop)
# 运行事件循环直到结束
loop.run_until_complete(startup(remote))
# asyncio.get_event_loop().run_until_complete(startup(remote))
except KeyboardInterrupt as exc:
logging.info('Quit.')

image-20230616104550483

返回的数据看上去有点像base64编码,我们通过发起程序,看一下他的加密流程,可以看到打上断点后进入到了这里,这里做了一个判断,数据请求成功后将返回的数据传给了t,然后在下面对t进行了处理,我们将下面的断点打上,看一下数据是否会进来

image-20230616104952692

可以看到返回的数据会进入这一段类似加密的方法中去,我们可以看下 h.decrypt 是什么

image-20230616105226612

这里有个 _ 方法,就在下面,这里进行数据分发,我们也打上断点看一下

image-20230616105445709

数据进来后,这里创建了一个 Promiss,异步执行加密方法,这里是AES加密,且iv和key都给出来了,我们可以拿一段我们前面获取到的加密数据去找个解密网站看一下,可以看到数据可以解密出来,那就好办了

image-20230616105813274

image-20230616110025060

用python或者js写一段aes解密函数即可,加上解密的函数,我们看下它实际返回的数据是啥,这里返回的数据正是网页中实时加载的指数数据,这样就数据获取成功了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 需要补位,str不是16的倍数那就补足为16的倍数
def add_to_16(value):
while len(value) % 16 != 0:
value += '\0'
return str.encode(value)


def aes_decrypt(text):
secret_key = '777db0c19edfaace' # 密钥
iv = "9876543210599311"
aes = AES.new(add_to_16(secret_key), AES.MODE_CBC, add_to_16(iv)) # 初始化加密器
base64_decrypted = base64.decodebytes(text) # 优先逆向解密 base64 成 bytes
decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '') # 执行解密密并转码返回str
return decrypted_text

image-20230616110230751