js逆向实战之某书protobuf反序列化

news2024/11/25 10:49:30

什么是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.2pm
 5bc331f43e6e73244d2b51c2999b1e02HyYjdqDYqjyF8yYjdqDYq2I24qyKAfI4WlxWh7idWx1y1vK28SqduD0888yW2yWj8DDiqd0qy"
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/922883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

抓包工具Charles的安装及代理设置(Windows浏览器代理、安卓代理)

1、下载Charles 官网地址&#xff1a;https://www.charlesproxy.com/download/&#xff0c;下载对应的安装包。安装完成后按照以下步骤进行代理配置。 2、配置Charles证书 按照以下截图步骤进行配置即可。 3、Charles代理设置 这里的端口号根据自己情况设置&#xff0c;这里…

17.4 【Linux】systemctl 针对 timer 的配置文件

有时候&#xff0c;某些服务你想要定期执行&#xff0c;或者是开机后执行&#xff0c;或者是什么服务启动多久后执行等等的。在过去&#xff0c;我们大概都是使用 crond 这个服务来定期处理&#xff0c; 不过&#xff0c;既然现在有一直常驻在内存当中的 systemd 这个好用的东西…

visio三维格式、三维旋转导出图模糊解决方案

问题描述 visio中元素经过三维格式或三维旋转&#xff08;也可能包括其他的特殊操作&#xff09;后&#xff0c;导出.emf格式的图会模糊&#xff0c;如下图所示。 解决方案 借助其他软件 在ppt中将对应的元素旋转后再导入visio&#xff0c;此时对于visio来说该元素相当于一…

RunnerGo:一款高效且易用的性能测试工具

在软件开发过程中&#xff0c;性能测试是确保应用程序能够高效运行的关键步骤。为了提供高质量的测试服务&#xff0c;许多企业正在寻求功能强大且易用的性能测试工具。RunnerGo是一个基于Go语言开发的性能测试平台&#xff0c;具有简单易用、高效稳定等特性&#xff0c;适用于…

Dubbo重启服务提供者或先启动服务消费者后启动服务提供者,消费者有时候会出现找不到服务的问题及解决

文章目录 [toc] 1.环境2.版本3.pom依赖3.1父工程的pom3.2子模块的pom 4.问题5.根本原因5.1根本原因说明5.2总入口5.3servletWeb容器初始化5.4 nacos服务注册监听点5.5 dubbo启动服务注册监听点 6.解决办法6.1降低springBoot版本为2.2.x6.2 修改源码6.2.1修改源码方式一6.2.2修改…

【RPC框架】RPC与Dubbo(让你一文搞懂,超级详细好理解!)

目录 什么是RPC框架&#xff0c;Dubbo又是什么&#xff0c;二者之间有什么联系 是不是说的有些抽象&#xff0c;那我们来说的通俗易懂点吧&#xff0c;这次你一定能听懂 简单举例 实际例子 真实场景demo&#xff08;说了这么多&#xff0c;实际体会一下代码吧&…

(6)(6.3) 自动任务中的相机控制

文章目录 前言 6.3.1 概述 6.3.2 自动任务类型 6.3.3 创建合成图像 前言 本文介绍 ArduPilot 的相机和云台命令&#xff0c;并说明如何在 Mission Planner 中使用这些命令来定义相机勘测任务。这些说明假定已经连接并配置了相机触发器和云台(camera trigger and gimbal ha…

iis服务web页面 localhost可以访问 ip不能访问

1、修改C:\Windows\System32\drivers\etc\下面hosts文件&#xff1b;需要重启电脑查看效果&#xff1b; 2、通过internet选项-》安全-》站点-》添加对应http://127.0.0.1和对应电能IP&#xff1b;

Android SDK 上手指南||第六章 用户交互

第六章 用户交互 在这篇教程中&#xff0c;我们将对之前所添加的Button元素进行设置以实现对用户点击的检测与响应。为了达成这一目标&#xff0c;我们需要在应用程序的主 Activity类中略微涉及Java编程内容。如果大家在Java开发方面的经验不太丰富也没必要担心&#xff0c;只…

Module not found: Error: Can‘t resolve ‘vue-pdf‘ in ‘xxx‘

使用命令npm run serve时vue项目报错&#xff1a; Module not found: Error: Cant resolve vue-pdf in xxx 解决方案&#xff1a; 运行命令&#xff1a; npm install vue-pdf --save --legacy-peer-deps 即可解决。 再次顺利执行npm run serve

032 - 位值类型-BIT

数据BIT类型用于存储位值。一种类型 允许存储-位值。 范围从 1 到 64。 BIT(M)MM 为了指定位值&#xff0c; 可以使用符号。是使用零和一编写的二进制值。例如&#xff0c; 和 分别代表7和128。请参见 第 9.1.5 节“位值文字”。 bvaluevalueb111b10000000 如果将值分配给 长…

ChatGPT提示与技巧分享:如何作出更好的提示2023年8月

​对ChatGPT的一些酷炫技巧感兴趣吗?这里提供了一些可以帮助你充分利用ChatGPT&#xff0c;成为AI工具专家的技巧。 毫无疑问&#xff0c;ChatGPT是目前最广泛使用的人工智能工具之一。它不仅毫不留情地取代了一些特定领域常用的软件小工具&#xff08;如智能对联、经典语录生…

2023.8 - java - Java 异常处理

异常是程序中的一些错误&#xff0c;但并不是所有的错误都是异常&#xff0c;并且错误有时候是可以避免的。 比如说&#xff0c;你的代码少了一个分号&#xff0c;那么运行出来结果是提示是错误 java.lang.Error&#xff1b;如果你用System.out.println(11/0)&#xff0c;那么…

2023年高教社杯数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

缓存穿透、缓存击穿和缓存雪崩

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱发博客的嗯哼&#xff0c;爱好Java的小菜鸟 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;社区论坛&#xff1a;希望大家能加入社区共同进步…

Linux:LAMP架构与论坛搭建

目录 一、动态资源与语言 二、LAMP 架构的组成 三、CGI和astcgi 3.1CGI​​​​​​ 3.2fastcgi 3.3CGI和fastcgi比较 3.4 PHP 配置 3.5 Opcode语言 四、编译安装Apache http 服务 五、安装论坛 一、动态资源与语言 WEB 资源类型&#xff1a; 静态资源&#xff1a;原…

idea的debug断点的使用

添加断点&#xff08;目前不知道如何添加断点&#xff0c;就给AutoConfigurationImportSelector的每个方法都加上断点&#xff09;&#xff1a; 然后将StockApplication启动类以debug方式运行&#xff0c;然后程序就会停在119行 点击上边的step over让程序往下运行一行&#x…

如何利用IPIDEA代理IP提高运营效率和安全性

Tiktok印尼用户的每月访问时间长达28.7小时&#xff0c;访问时间远远超过其他社交媒体&#xff08;FB15.5小时&#xff0c;INS7.8小时&#xff09;。TikTok Shop在印尼的市场份额跃升&#xff0c;赶超Tokopedia和Lazada。在Tiktok运营中&#xff0c;代理IP可以发挥哪些作用呢&a…

Java“牵手”天猫商品列表数据,关键词搜索天猫商品数据接口,天猫API申请指南

天猫商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取天猫商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问天猫商城的网页来获取商品详情信息。以下是两种常用方法的介绍&…

基于风险的漏洞管理

基于风险的漏洞管理涉及对即将被利用的漏洞的分类响应&#xff0c;如果被利用&#xff0c;可能会导致严重后果。本文详细介绍了确定漏洞优先级时要考虑的关键风险因素&#xff0c;以及确保基于风险的漏洞管理成功的其他注意事项。 什么是基于风险的漏洞管理对基于风险的漏洞管…