Js逆向--新版Steam登录之Protobuf协议数据解析

前言

Steam游戏平台在今年三四月份更新了登录协议,放弃了原有的简单RSA加密,数据传输格式改成了Protobuf协议,难度相比之前大了许多,主要还是对于Protobuf协议不熟悉,最近看了之前RSA加密相关视频,怀着热血想小试牛刀一下,结果当看到返回的数据格式时,一下子就傻眼了,经过了5天的研究调试,期间差点放弃,好在最后还是被我逆向出来了

目标

看过新版steam请求的都知道,来到登录界面,输入账号密码后点击登录,会出现一个get请求,查看这个请求的负载发现有两个参数,origin自不用说是个固定的,可以看出来input_protobuf_encoded是个被加密过的


image.png

image.png

同时查看响应的数据,掐指一算,是一串有乱码的字符串,看来这个响应数据也是被加密过的(准确的说是利用protobuf协议序列化过)


image.png

所以本节主要内容就是对请求参数中加密的input_protobuf_encoded进行解析,以及对响应的数据进行解析。

protobuf数据格式

引入正题,protobuf是什么,具体百度一下你就知道,简单来说protobuf是一种Google提供的高效的协议数据交换格式,就像JSON一样,有固定的格式,正向开发中需要编写。proto 文件来秒数这个数据具体都有什么信息,逆向没有这个文件,就只能根据值盲猜了,我为什么知道这个是protobuf数据格式,没人天生知道,经过这几天的研究才知道大概是什么数据

那如何使用protocol buffers?

开发者需要先编写proto文件,在proto文件中编写预期的数据类型、数据字段、默认值等
然后,通过编译器生成,编程语言对应的开发包!开发时调开发包中的对应方法进行序列化和反序列化。


image.png
Protobuf 实现基本过程

1、编写 .proto 文件
2、将 .proto 文件编译成对应编程语言的包
3、将包导入,通过代码实现 .proto 文件的序列化,并将序列化后的内容保存到 .bin 文件中,序列化后的数据可读性极差
Protobuf 序列化完成,此时就可以在网络间进行传输,接收端若想还原为可读数据,则需进行反序列化操作。
既然如此,我们可以简单的实现以上过程
1、创建.proto文件,编写简单的数据

image.png

2、将.proto编译成.js文件,至于编译器网上很多教程,我这里提供一个编译器下载地址:https://github.com/protocolbuffers/protobuf/releases/
安装完后,对.proto进行编译,定位到文件所在目录,执行如下命令,生产对应_pb.js文件

protoc --proto_path=.\ [目标文件名].proto --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:.
image.png

大致查看了解一下结构

image.png

image.png

image.png

大概的操作就是以我们自己编写的.proto文件中的数据格式为准,将对应格式的数据进行二进制序列化或者反序列protobuf格式的二进制数据为.proto文件定义的对象的格式。
(这里可以多注意一下serializeBinary这个方法名,方法体的代码写法,后面会用到)

3、使用生成的xx_pb.js文件可以用来干嘛?

  1. 将对象数据序列化成二进制protobuf格式的乱码数据
    生成的xx_pb.js中有一个初始化代码,先进行初始化,传入的参数是个数组,每个数组的索引位置对应.proto中一个唯一的序号


    image.png

    image.png

    上面生成的e 就是二进制protobuf格式的乱码数据

  2. 解析二进制protobuf格式的乱码数据
    (这里我不使用生成的.js文件来解析,因为我最终目的是用python爬虫,所以我打算使用.proto生成对应的.py文件来进行解析)
    执行类似上面的命令,生成对应的_pb2.py文件


    image.png

    image.png

这代码我是看不懂的,但是用还是会用的。。
现在我们可以使用hhh_pb2.py中的代码来解析proto_buf了。首先,我们需要导入生成的代码:

import hhh_pb2

然后,创建一个Body实例,并使用ParseFormString()方法解析:

body = hhh_pb2.Body()
body.ParseFromString(proto_buf_data)

在上面的代码中,proto_buf_data是一个包含了proto_buf数组的字节流。
一旦我们成功地解析了proto_buf数据,我们就可以通过访问Body实例的字段来获取数据了。例如,我们可以获取name字段的值

name = body.name

此外,对于repeated类型的字段,我们可以使用类似于列表的方法来访问他们的值:

for hobby in body.hobbies:
  print(hobby)

这样就完成了对proto_buf数据的解析

逆向解密请求参数input_protobuf_encoded

第一步根据input_protobuf_encoded名字找到对应加密的js文件,并且定位到input_protobuf_encoded赋值的地方,这里就不一一调试,网上有很多教学,我这里直接定位到关键代码


image.png

可以看到执行完a = r.JQ(o)后生成的a值和请求参数对比一下发现就是加密后的数据,后面d.params.input_protobuf_encoded = a 这样的代码也证明了这里就是需要逆向的关键代码,鼠标移到s,发现这个值是请求的基础url,在这里并没有什么用处可以忽略。

第二步,创建js文件,将关键代码复制进去


image.png

运行报错 n is not defined,鼠标移动到n.SerializeBody,定位到主要方法


image.png

image.png

将代码拷贝到js,改写一下代码,在运行出现报错,提示没有serializeBinary这个方法,
image.png

老规矩,进入serializeBinary对应的方法


image.png

image.png

将代码再拷贝到js运行,发现还是继续报错,根据我们一步一步补环境,发现非常麻烦,可能到最后还是毫无头绪。
这时候我们不妨换个思路,通过请求的响应数据可以看出,该请求是使用protobuf协议来传输数据的,那么只有在响应返回的数据中才进行处理吗?会不会在请求的参数中也进行了protobuf处理?
有了这个思路,我们观察一下补写js代码时出现的代码
image.png

这个代码中的方法serializeBinary以及里面的实现是不是跟上面我们在讲protobuf协议的时候生成的_pb.js代码中的serializeBinary很相似?
在观察有一个这样的代码,可以大概知道这个c类主要就是对account_name这个字段进行处理
image.png

看到这些代码,我脑海里有个想法,这个请求对请求参数的处理是不是将用户名先通过protobuf协议处理了一下,然后再用base64加密呢??
有了这个思路,我们试着根据上面的代码编写一下用户名对应的accountName.proto文件并编译成js


image.png

image.png

结合上面我们拷贝到js中的SerializeBody方法,进行改写
先初始化将用户名数组传入,然后调用编译生成的serializeBinary方法
image.png

运行发现e有结果了!之后就是普通的代码改写运行发现生成了一串数据,对比一下就是我们想要的数据
image.png

protobuf协议反序列化字节流数据

首先,根据上面生成的参数发起请求,得到返回的序列化过的protobuf字节流数据。
因为逆向没有proto这个文件,就只能根据值盲猜了,那怎么获取值呢,查资料我找到了两种比较好的方法

  1. 到github搜索blackboxprotobuf
    下载blackboxprotobuf-master.zip,解压将blackboxprotobuf拖入到python库中
    image.png

导入blackboxprotobuf,调用decode_message方法解析


image.png

打印出这样的数据


image.png

根据这样的数据结构找找有没有相关的代码,果然被我找到了,可以根据这里定义的类型更加容易编写.proto文件
image.png

image.png

编译成_pb2.py


image.png

导入RSAPublicKey_pb2调用解析数据
image.png

image.png

这样一来就成功反序列化得到我们需要的数据啦~~
2)除了上面查看字节流数据的方法外,还可以通过将字节流数据保存成.bin文件,在使用protoc --decode_raw < v1.bin命令来生成
image.png

image.png

小结

到此,这个请求该解析的都解析了,其实思路并不难,最大难点是对protobuf协议的不熟悉,我们了解了协议后,就能知道该网站的处理方法是先对数据进行protobuf协议序列化,之后可能是在对序列化数据在加密或者甚至就没加密直接返回。
到这里本节结束,算是给自己这几天研究的结果做一个总结记录!
(可能讲的有点乱,需要相关的代码可以联系我哦)

这里先对a = r.JQ(o)这行进行改写,鼠标移动到r.JQ,定位到对应的方法


image.png

image.png

复制到js,改写一下代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,888评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,677评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,386评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,726评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,729评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,337评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,902评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,807评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,349评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,439评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,567评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,242评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,933评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,420评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,531评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,995评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,585评论 2 359

推荐阅读更多精彩内容