js逆向实战之某书protobuf反序列化
什么是Protobuf?
\qquad Protobuf(Protocol Buffer)是 Google 开发的一套数据存储传输协议,作用就是将数据进行序列化后再传输,Protobuf 编码是二进制的,它不是可读的,也不容易手动修改,因此它增加了分析或修改数据的难度。同时Protobuf 能够把数据压缩得很小,从而提高传输效率。通俗的理解就是Protobuf跟json序列化是类似的,只不过实现的方法不同而已。
安装Protobuf
\qquad 点击下载对应的版本,然后解压,并加入环境变量。

序列化与反序列化
\qquad Protobuf序列化需要开发人员在 .proto 文件中自定义消息格式,使用protobuf 编译器(protoc)选择需要的语言生成消息处理文件,也可以在 官网一键生成,用生成的文件就能进行序列化与反序列化。
\qquad 下面将举例说明如何通过js逆向来进行反序列化,目标网址:aHR0cHM6Ly93d3cueGlhb2hvbmdzaHUuY29tL2V4cGxvcmUvNjRkYzg2OGEwMDAwMDAwMDBhMDFiZDgz。
\qquad 打开目标网址,F12抓包,collect接口的请求参数是base64编码的,
解码后的数据是这样的,
춐]
6discovery-undefined0.0.00:
xhs-pc-webB3.5.2pm5bc331f43e6e73244d2b51c2999b1e02HyYjdqDYqjyF8yYjdqDYq2I24qyKAfI4WlxWh7idWx1y1vK28SqduD0888yW2yWj8DDiqd0qy"
61c3e3e9000000001000d0df*264dc868a000000000a01bd83p:B
$2cd55f67-ae5a-446a-9571-cb81e171d8360J167Xຊִx˅1BJ
$9bab7cd2-3eae-4469-9553-06cc2e5c8492oMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36<https://www.xiaohongshu.com/explore/64dc868a000000000a01bd83"/explore/:noteId*Lhttps://www.xiaohongshu.com/explore/64e19dc2000000000103c666?m_source=pinpaiZ"
64dc868a000000000a01bd83rlink
可以看出有一些乱码在里面,这个时候其实还无法判断是否用了protobuf序列化,一些网站可以查看协议头的content-type,如下图所示就是使用protobuf。
但是目标网站对序列化结果进行了base64编码,所以协议头的content-type跟正常的请求是一样的。
这种情况就得通过动态调试来看看这到底是什么玩意,查看调用堆栈,定位到可疑代码,在此处打上断点。
单步跟进去,图示位置打上断点。
单步跟进,来到关键位置,到这里特征就很明显了,”proto“、”serializeBinary“等关键字就是protobuf的显著特征。
接下来就可以根据源码中的规律来自定义proto文件,在此之前需要了解一下proto文件的语法格式以及数据类型,篇幅有限大佬们可以查看别的教程,本文只侧重逆向部分。
编写.proto文件
\qquad 如下图所示,目标网站的消息格式是一个Tracker消息里有很多的子消息,有APP、Mobile、Device等。

我们可以根据这个写出最外层的proto,
syntax = "proto3";
package xhs;
message Tracker {repeated APP app = 1;repeated Mobile mobile = 2;repeated Device device = 3;repeated User user = 4;repeated Network network = 5;repeated Page page = 6;repeated Event event = 7;repeated Browser browser = 9;repeated NoteTarget noteTarget = 11;repeated NoteCommentTarget noteCommentTarget = 12;repeated TagTarget tagTarget = 13;repeated UserTarget userTarget = 14;repeated MallBannerTarget mallBannerTarget = 15;repeated MallGoodsTarget mallGoodsTarget = 16;repeated MallVendorTarget mallVendorTarget = 17;repeated MallCouponTarget mallCouponTarget = 18;repeated SearchTarget searchTarget = 30;repeated BrandingUserTarget brandingUserTarget = 40;repeated BrowserTarget browserTarget = 51;repeated ChannelTabTarget channelTabTarget = 100;repeated MessageTarget messageTarget = 151;repeated AdsTarget adsTarget = 152;repeated HeyTarget heyTarget = 153;repeated DebugTarget debugTarget = 154;repeated ActivityTarget activityTarget = 157;repeated LiveTarget liveTarget = 164;repeated CircleTarget circleTarget = 167;repeated GrowthPetTaskTarget growthPetTaskTarget = 195;repeated HideType hideType = 197;repeated WebTarget webTarget = 219;}
然后单步进入proto.App.serializeBinaryToWriter,写出App的proto。
message APP {enum NameTracker {DEFAULT_1 = 0;IOST = 1;ANDRT = 2;RNT = 3;MPT = 4;WAPT = 5;WXMPT = 6;BDMPT = 7;TTMPT = 8;QQMPT = 9;APMPT = 10;MINI_ANDRT = 11;}NameTracker nameTracker = 1;string AppVersion = 2;string TrackerVersion = 3;string SessionId = 4;string AppMarket = 5;enum Platform {DEFAULT_13 = 0;IOS = 1;ANDROID = 2;REACTNATIVE = 3;MOBILEBROWSER = 4;WECHATBROWSER = 5;WECHATMINIPROGRAM = 6;PC = 7;IOSBROWSER = 8;ANDROIDBROWSER = 9;FLUTTER = 10;};Platform platform = 6;string ArtifactName = 7;string ArtifactVersion = 8;enum AppMode {app_mode = 0;};AppMode appMode = 9;string LaunchId = 10;string MpScene = 11;string AppStartMode = 12;string BuildVersion = 13;int32 EventSeqIdInSession = 14;bool DarkMode = 15;string StartupId = 16;enum Orientation {DEFAULT_60 = 0;PORTRAIT = 1;LANDSCAPE = 2;LANDSCAPE_SPLIT = 3;PORTRAIT_SPLIT = 4;PORTRAIT_SPLIT_MAGIC = 5;LANDSCAPE_SPLIT_MAGIC = 6;LANDSCAPE_MAGIC = 7;PORTRAIT_MAGIC = 8;};Orientation orientation = 17;string BuildId = 1001;string Package = 1002;string AppName = 1003;string SdkName = 1004;string SdkVersion = 1005;enum Environment {DEFAULT_64 = 0;ENVIRONMENT_DEVELOP = 1;ENVIRONMENT_RELEASE = 2;};Environment environment = 1006;int64 ColdStartId = 1007;bool IsTeenagerMode = 1008;string DeviceType = 1009;}
enum 数据类型就是提前为字段预设定一些值,可以通过关键字搜索在源码中找到预设的值。
依葫芦画瓢就能写出完整的.proto文件,这个时候我们就可以生成任何语言的消息处理文件,以python为例,写好之后执行命令”protoc --python_out=. ./collect.proto“就会生成一个py文件,测试一下反序列化,
import base64
from utils import collect_pb2
a = 'jgXsthBdCjYIBRITZGlzY292ZXJ5LXVuZGVmaW5lZBoFMC4wLjAwBzoKeGhzLXBjLXdlYkIFMy41LjJwgwESABptCiA1YmMzMzFmNDNlNmU3MzI0NGQyYjUxYzI5OTliMWUwMooBSHlZamRxRFlxanlGOHlZamRxRFlxMkkyNHF5S0FmSTRXbHhXaDdpZFd4MXkxdksyOFNxZHVEMDg4OHlXMnlXajhERGlxZDBxeSIaChg2MWMzZTNlOTAwMDAwMDAwMTAwMGQwZGYqAggEMh0I+xcSGDY0ZGM4NjhhMDAwMDAwMDAwYTAxYmQ4MzpECiRjMThhYzliYS1mY2JiLTQ3YTYtOTMwOC1hMTM4MGVmZTQ1YzIgATAfSgMxMzFY4NOG49T0gAN4z8UBiALs1eGxojFKtQIKJDliYWI3Y2QyLTNlYWUtNDQ2OS05NTUzLTA2Y2MyZTVjODQ5MhJvTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNS4wLjAuMCBTYWZhcmkvNTM3LjM2GjxodHRwczovL3d3dy54aWFvaG9uZ3NodS5jb20vZXhwbG9yZS82NGRjODY4YTAwMDAwMDAwMGEwMWJkODMiEC9leHBsb3JlLzpub3RlSWQqTGh0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbS9leHBsb3JlLzY0ZTE5ZGMyMDAwMDAwMDAwMTAzYzY2Nj9tX3NvdXJjZT1waW5wYWlaIgoYNjRkYzg2OGEwMDAwMDAwMDBhMDFiZDgzEAFyBGxpbms='
b = base64.urlsafe_b64decode(a)
tracker = collect_pb2.Tracker()
tracker.ParseFromString(b[4::])
print(tracker)
此时已经可以成功的反序列化了,需要特殊说明的是base解码的时候必须要用urlsafe_b64decode方法,因为原始数据里面有url,解码后的字节数据去掉了前面4个字节,因为在编码的时候在前面加了四个无用字节。
很多教程会说用fd抓包下载bin,然后命令行 protoc --decode_raw < 1.bin执行,解析protobuf数据结构,根据这个结构写proto,这种方法只适合大佬用,对于刚接触protobuf的人来说如果看到这种教程就会掉入无底深坑。
本文只用来交流学习,关键信息均已脱敏,如有侵权请联系删除。
欢迎大家进扣群交流学习:OTQwNDQ3ODg5
相关文章:

js逆向实战之某书protobuf反序列化
什么是Protobuf? \qquad Protobuf(Protocol Buffer)是 Google 开发的一套数据存储传输协议,作用就是将数据进行序列化后再传输,Protobuf 编码是二进制的,它不是可读的,也不容易手动修改…...

cpolar+JuiceSSH实现手机端远程连接Linux服务器
文章目录 1. Linux安装cpolar2. 创建公网SSH连接地址3. JuiceSSH公网远程连接4. 固定连接SSH公网地址5. SSH固定地址连接测试 处于内网的虚拟机如何被外网访问呢?如何手机就能访问虚拟机呢? cpolarJuiceSSH 实现手机端远程连接Linux虚拟机(内网穿透,手机端连接Linux虚拟机) …...

[MyBatis系列②]Dao层开发的两种方式
目录 1、传统开发 1.1、代码 1.2、存在的问题 2、代理开发 2.1、开发规范 2.2、代码 ⭐mybatis系列①:增删改查 1、传统开发 传统的mybatis开发中,是在数据访问层实现相应的接口,在实现类中用"命名空间.id"的形式找到对应的映…...

言语理解-中心理解之主题词及行文脉络
例题 例题 例题 例题 例题 例题...
LeetCode 面试题 01.05. 一次编辑
文章目录 一、题目二、C# 题解法一:从第一个不同位置处判断后续相同子串法二:前后序遍历判断第一个不同字符的位置关系 优化法一法二 一、题目 字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。 给定两个字符串ÿ…...
Mybatis查询in的字段过多不走索引
mybatis查询in的字段有索引,比如说是主键查询, 但是in的字段过多导致索引失效, 这个时候可以考虑将in的数量变少, 200以内都可以, 在数据库方面采用 foreach unionall 的方式将数据集合查询出来 Service层: List<…...

封装公共el-form表单(记录)
1.公共表单组件 //commonForm.vue <script> import {TEXT,SELECT,PASSWORD,TEXTAREA,RADIO,DATE_PICKER } from /conf/uiTypes import { deepClone } from /utils export default {name: GFormCreator,props: {config: { // title/itemstype: Object,required: true}}…...
List 分批处理
1.Google Guava <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.0.1-jre</version></dependency>List<String> tempList Arrays.asList("水星","金星&qu…...

SpringSession
Spring Session 是 Spring 的项目之一。Spring Session 提供了一套创建和管理 Servlet HttpSession 的方案,默认采用外置的 Redis 来存储 Session 数据,以此来解决 Session 共享的 问题。(springsession储存session数据的方式有很多,我们常…...
Python Web 开发之 JWT 简介
在之前的课程中,介绍过 Flask-Login 框架,它是基于 Session 和 Cookie 技术来实现用户授权和验证的,不过 Session 有很多的局限性,这一节介绍一种基于 token 的验证方式 —— JWT (JSON Web Token),除了对 JWT 的概念讲解之外&…...

科技资讯|荷兰电动自行车丢失将被拒保,苹果Find My可以减少丢失
荷兰最大的自行车协会荷兰皇家旅游俱乐部宣布,将不再为胖胎电动自行车提供保险,因为这种自行车的被盗风险极高。 随着电动自行车的销量飙升,胖胎也变得更受欢迎。但问题是,胖胎电动自行车也成为了自行车盗窃者的首选目标。ANWB …...
debian rules语法
当创建Debian软件包时,debian/rules 文件是非常重要的,它定义了软件包的构建规则。这个文件使用Makefile语法,指导构建、编译和安装软件包。下面将详细地介绍debian/rules文件的语法和常见用法。 基本结构: 一个简单的debian/rul…...
网易2023年Q2财报:营收240亿元,游戏技术跨产业创造数字就业
8月24日,网易发布2023年Q2财报。二季度,网易继续聚焦主营业务,业绩表现稳健;净收入240亿元,非公认会计准则下归属于公司股东的持续经营净利润90亿元,研发投入39亿元,相当于拿出近一半利润投入研…...
Python的Flask框架创建、运行与访问
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

Java课题笔记~ 综合案例
3.综合案例 3.1 功能介绍 以上是我们在综合案例要实现的功能。除了对数据的增删改查功能外,还有一些复杂的功能,如 批量删除、分页查询、条件查询 等功能 批量删除 功能:每条数据前都有复选框,当我选中多条数据并点击 批量删除 按…...

Seaborn数据可视化(二)
目录 1.Seaborn风格设置 1.1 主题设置 1.2 轴线设置 1.3 移除轴线 1.4 使用字典传递函数 2.设置绘图元素比例 2.1 设置绘图元素比例paper 2.2 设置绘图元素比例poster 2.3 设置绘图元素比例notebook Seaborn将Matplotlib的参数划分为两个独立的组合,第一组用于…...
HDLBits-Verilog学习记录 | Verilog Language-Basics(1)
文章目录 3.Simple wire4.Four wires5.inverter | Notgate6. And gate7.Nor gate8.Xnorgate 3.Simple wire problem:Create a module with one input and one output that behaves like a wire. module top_module( input in, output out );assign out in;endmodule4.Four w…...

elementui表格嵌套上传文件直传到oss服务器(表单上传)
提示:记录项目中遇到的问题,仅供参考 文章目录 前言一、vue代码二、js接口请求代码 前言 项目需求是在表格中嵌套一个上传图片的功能,并且回显选择的图片和已上传的图片,再通过点击操作列中上传按钮才开始上传,使用的…...
使用navicat来访问doris
访问Doris的UI http:// dorisfe_ip:8030 由于doris是使用mysql协议,因此可以不用任何额外配置就可以使用navicat访问doris。 可以使用MySql客户端来连接Doris FE,也可以使用mysql命令工具连接,因为他是Mysql协议,所以在使用上跟M…...

2023国赛数学建模思路 - 案例:异常检测
文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

Qt的学习(二)
1. 创建Hello Word 两种方式,实现helloworld: 1.通过图形化的方式,在界面上创建出一个控件,显示helloworld 2.通过纯代码的方式,通过编写代码,在界面上创建控件, 显示hello world; …...

Axure零基础跟我学:展开与收回
亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...
python读取SQLite表个并生成pdf文件
代码用于创建含50列的SQLite数据库并插入500行随机浮点数据,随后读取数据,通过ReportLab生成横向PDF表格,包含格式化(两位小数)及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...

生产管理系统开发:专业软件开发公司的实践与思考
生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下,生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中,面临的挑战存在显著差异。本文结合具体实践案例,分析…...