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 一、简介 – 关于异常…...
redis实战-缓存三剑客穿透击穿雪崩解决方案
缓存穿透 定义 缓存穿透 :缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,造成数据库压力,也让缓存没有发挥出应有的作用 解决方案 缓存空对象 当我们客户端…...
Tomcat10安装及配置教程win11
Tomcat10安装及配置教程win11 Tomcat下载链接 Tomcat官网 Tomcat官网地址 https://tomcat.apache.org/ Tomcat的版本列表 点击上图中左侧红框内**Which version?**即可得下图 下载Tomcat 点击上图中左侧红框内红框内tomcat版本即可得下图,下载zip包 解压zip包…...
遗传算法解决TSP问题
一、求解问题概述 1.1 TSP问题 TSP问题是指旅行商问题(Traveling Salesman Problem)。在TSP问题中,假设有一名旅行商要在给定的一组城市之间进行旅行,每个城市只能被访问一次,并且旅行商必须最终返回出发城市。问题的…...
设计模式-工厂设计模式
核心思想 在简单工厂模式的基础上进一步的抽象化具备更多的可扩展和复用性,增强代码的可读性使添加产品不需要修改原来的代码,满足开闭原则 优缺点 优点 符合单一职责,每个工厂只负责生产对应的产品符合开闭原则,添加产品只需添…...
TM4C123库函数学习(3)---串口中断
前言 (1)学习本文之前,需要先学习前两篇文章。 (2)学习本文需要准备好TTL转USB模块。 函数介绍 ROM_GPIOPinConfigure() 配置GPIO引脚的复用功能。因为引脚不可能只有一个输出输入作用…...
opencv 进阶13-Fisherfaces 人脸识别-函数cv2.face.FisherFaceRecognizer_create()
Fisherfaces 人脸识别 PCA 方法是 EigenFaces 方法的核心,它找到了最大化数据总方差特征的线性组合。不可否认,EigenFaces 是一种非常有效的方法,但是它的缺点在于在操作过程中会损失许多特征信息。 因此,在一些情况下,…...
基于mysql5.7制作自定义的docker镜像,适用于xxl-job依赖的数据库,自动执行初始化脚本(ddl语句和dml语句)
一、背景 xxl-job-admin依赖mysql数据库,且需执行初始化脚本,包括ddl和dml语句。 具体的步骤总结如下: 1、新建数据库xxl_job2、创建mysql表table3、执行dml语句,包括新建admin用户及密码,创建执行器和任务。 毫无疑…...
LeetCodeHot100python版本:单调栈,栈,队列,堆
单调栈 739. 每日温度 42. 接雨水 双指针 单调栈(横向求解) 84. 柱状图中最大的矩形 栈和队列 队列:先入先出 栈:先入后出 两个栈 模拟 队列 一个队列 可以模拟 栈 20. 有效的括号 155. 最小栈 394. 字符串解码 堆 215. 数组中的第K个最大元素 3…...
JUC初识
JUC 是什么 java.util.concurrent 在并发编程中使用的工具包 从线程start 开始 package com.jhj.Thread;public class ThreadDemo {public static void main(String[] args) {Thread t1 new Thread(() -> {}, "t1");t1.start();} }start 方法调的是native sta…...
stm32之5.长按按键(使用时钟源)调整跑马灯速度
------------------------------ 源码 #include <stm32f4xx.h> #include "led.h" #include "delay.h" #include "my_str.h" #include "beep.h" #include "key.h" int main(void) { key_init(); Led_init();…...
全球做的最好的公司网站/b2b网站推广排名
最近心血来潮,打算打造一个自己声音音色的播客 主要有这么几个模块: 1.素材爬虫 素材爬虫主要有这么几个问题,一个是版权问题,不是说网上所有的东西都能爬,而且都能够被我拿去播放的,因此这里打算先从古代的…...
如何做企业介绍/云速seo百度点击
2019独角兽企业重金招聘Python工程师标准>>> Redis的事务 是什么Redis的事务 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞噢:&…...
新建网站如何公安备案/搜索最多的关键词的排名
尽管非常喜欢Windows,但微软的首席执行官史蒂夫鲍尔默表示,微软将使企业能够更简单地管理更多类型的计算机━━其中包括运行Linux 的计算机。 美国太平洋时区时间本周三,鲍尔默表示,微软已经听取了客户的请求:在Operat…...
自己做的网站不备案不能访问吗/长沙关键词优化公司电话
2,剪枝(pruning) 在训练结束后,可以将一些不重要的神经元连接 非结构化剪枝Pruning,结构化剪枝Filter Pruning,梯度Pruning等方法 (可用权重数值大小衡量配合损失函数中的稀疏约束)或整个滤波器去除, 之后进行若干轮微…...
网站建设费计入什么科目/灰色词网站seo
高中信息技术 知识7数据类型、常量和变量.pptx01 | 一段似曾相识的代码Dim x As IntegerDim y As IntegerDim z As IntegerDim max As IntegerxVal(Text1.Text)yVal(Text2.Text)zVal(Text3.Text)max0If x>y Then maxx Else maxyIf z>max Then maxzText4.textStr(max)对任…...
沧州地区做网站/外贸业务推广
一、字符串1.字符串的出现计算机发明初期,计算机主要用于做一些科学和工程的计算;而且刚开始计算机都是用来处理数值型的数据,后来引入了字符串的概念,计算机才开始进行非数值型数据的处理(其原理仍然是通过数值来模拟非数值&…...