【Web逆向】万方数据平台正文的逆向分析(上篇--加密发送请求)—— 逆向protobuf

news2024/11/20 14:23:04

【Web逆向】万方数据平台正文的逆向分析(上篇--加密发送请求)—— 逆向protobuf

  • 声明
  • 一、了解protobuf协议:
  • 二、前期准备:
  • 二、目标网站:
  • 三、开始分析:
    • 我们一句句分析:
      • 先for循环部分:
      • 后面就是给a赋值了:
  • 四、写proto文件(核心)

声明

本文章中所有内容仅供学习交流,相关链接做了脱敏处理,若有侵权,请联系我立即删除!

一、了解protobuf协议:

Protobuf(Protocol Buffer)是 Google 开发的一套数据存储传输协议,为二进制序列化格式,可用作 JSON 或 XML 等格式的更有效替代方案。开发人员可以在 .proto 文件中定义消息格式,并使用 protobuf 编译器(protoc)按他们选择的语言生成消息处理程序。Protobuf 编码是二进制的,与 json、xml 不同,它不是可读的,也不容易手动修改。Protobuf 能够把数据压缩得很小,所以传输数据就比 xml 和 json 快几倍,使用其有利于提高效率,但同时增加了分析或修改数据的难度。

序列化 (Serialization) 是指将对象转换为字节序列的过程,在序列化期间,对象将其当前状态写入到临时或持久性存储区,以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

二、前期准备:

下载protoc文件:找对应版本下载
在这里插入图片描述
然后添加到环境变量,便于之后使用。

在这里插入图片描述

二、目标网站:

基于矢量光场空间调制的光波偏振方向解算方法研究

打开网站,找到我们这次需要分析的包。

返回数据也是乱码:

在这里插入图片描述

经过查资料,观察返回的content-type为application/grpc-web+proto 是以protobuf数据结构传输的。

在这里插入图片描述

我们用fiddler抓包,过滤掉png和js,只显示主机是d.wanfangdata.com.cn;的

在这里插入图片描述

可以看到getDetailInFormation发送的十六进制数据,黑色16进制数据是发送的数据,蓝色是请求头数据:

在这里插入图片描述

在这里插入图片描述

我们把黑色部分从第六位起(也就是0A)保存为bin文件,如下图:

在这里插入图片描述

三、开始分析:

我们下个xhr断点看看,看看数据是怎么来的。

可以看到数据是以字节集的形式发出的,与上面fd抓包的16进制数据是一一对应的。

在这里插入图片描述

接下来,我们看看数据是怎么来的?跟e来到上一个栈,可以发现是a赋值给e的。

在这里插入图片描述

我们在e赋值的地方下断点,看看a怎么来的,重新调试一次,主要看a怎么构成的。

发现其实核心就是10406行到10415行赋值这一段。

for (n = (e = (0,n.a)(e.getRequestMessage())).length,
    l = [0, 0, 0, 0],
    a = new Uint8Array(5 + n),
    s = 3; 0 <= s; s--)
    l[s] = n % 256,
    n >>>= 8;
if (a.set(new Uint8Array(l), 1),
    a.set(e, 5),
    e = a,

我们一句句分析:

先for循环部分:

e = (0,n.a) (e.getRequestMessage())

在这里插入图片描述

得到的是一个unit8Array数组,刚刚好就是我们刚才排查出发包的数据从5开始往后数。

n = (e = (0,n.a)(e.getRequestMessage())).length

在这里插入图片描述

这里得到这个数组长度是27。

f = [0, 0, 0, 0]

这里类似设置了一个头,4位空数组

a = new Uint8Array(5 + n)

这里a的初始化,因为我们知道最后a是一个Uint8Array的数组,他的长度是5+n。

s = 3; 0 <= s; s--

这里可以确定整个循环的次数,4次。

因为js是以;为结束的,所以相当于下列语句循环了4次,那这步操作是干嘛的呢?

f[s] = n % 256,
n >>>= 8;

给f数组各位赋值的,刚刚好f数组就是4位。所以说先给f的第四位赋值相当于f[3], 再 n进行>>>=移位操作,得到:

f[3] =27%256=27    27 >>>8=0 =>n=0
f[2] = 0%256 =0    0  >>>8=0 =>n=0
f[1] = 0%256 =0    0  >>>8=0 =>n=0
f[0] = 0%256 =0    0  >>>8=0 =>n=0
f=[0, 0, 0, 27]

在这里插入图片描述

后面就是给a赋值了:

a.set(new Uint8Array(f), 1)

a是数组,然后查mdn文档,可知set方法的作用:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set

set() 方法用于从指定数组中读取值,并将其存储在类型化数组中。

有两个参数,typedarray,offset(可选,默认为 0)

typedarray对应 new Uint8Array(f)

offset 对应 1

相当于从下标1开始,给a数组插入值f。

所以得到

在这里插入图片描述

这里核心就是这个set方法,不懂查一下就理解了。

a.set(e, 5)

相当于从数组下标5开始把e的值赋值给a

ok,我们到这里已经把a怎么来的理解清楚了,也明白了前面5位是怎么来的。

但是,我们还是没接触到protobuf啊,只是知道了数据得到的大概过程。核心就在(0,n.a)(e.getRequestMessage())里面。

四、写proto文件(核心)

跟进n.a方法

在这里插入图片描述

发现了写protobuf数据格式的关键函数:serializeBinary

在这里插入图片描述

关键点:

根据serializeBinaryToWriter关键函数,可以得到此结构分层,跟进去可以得到包含几个信息

在这里插入图片描述

write + (信息类型)函数,第一个参数代表是第几个。(如下图圈主部分)
在这里插入图片描述

看到writeMessage,后面有serializeBinaryToWriter关键函数,跟进去,就能再次得到此message的结构层次,一样分析,就能得出完整结构。

一个个分析按顺序写proto文件

syntax = "proto3";

message SearchService {
  string getResourcetype = 1;
  string getId = 2;
  string getReferer = 3;
  string getMd5id = 4;
  string getTransaction = 5;
}

命令行生成可python操作的protobuf文件

在这里插入图片描述
在这里插入图片描述

数据分析:fd抓包下载bin,然后命令行 protoc --decode_raw < test.bin执行,解析protobuf数据结构

在这里插入图片描述

然后对应上面的结构找到对应变量,用python赋值运行:

import test_pb2 as pb

SearchRequest = pb.SearchService()
SearchRequest.getResourcetype = 'Periodical'
SearchRequest.getId = 'wlxb202301001'
SearchRequest.getReferer = ''
SearchRequest.getMd5id = ''
SearchRequest.getTransaction = ''
form_data = SearchRequest.SerializeToString()
print(form_data)

在这里插入图片描述

我们验证一下上面输出是否正确,用blackboxprotobuf模块解析,即可看到原始数据(这里用到上面解析出来的bin文件):

import blackboxprotobuf

# 1、得到消息类型message_type
with open(r"test.bin", "rb") as fp:
    data = fp.read()
    deserialize_data, message_type = blackboxprotobuf.protobuf_to_json(data)
    print(f"原始数据: {deserialize_data}")
    print(f"消息类型: {message_type}")

    # str 转 dict
    deserialize_data = eval(deserialize_data)

    form_data = bytes(blackboxprotobuf.encode_message(deserialize_data, message_type))
    print(form_data)

在这里插入图片描述

和咱们用proto文件编译出来protobuf文件去解析的输出一样,所以咱们编译没问题!

用python发包,根据上面的分析,发现需要补头5位

bytes_head = bytes([0, 0, 0, 0, len(form_data)])

完整代码(获得数据):

import test_pb2 as pb

SearchRequest = pb.SearchService()
SearchRequest.getResourcetype = 'Periodical'
SearchRequest.getId = 'wlxb202301001'
SearchRequest.getReferer = ''
SearchRequest.getMd5id = ''
SearchRequest.getTransaction = ''
form_data = SearchRequest.SerializeToString()
print(form_data)
print(len(form_data))
bytes_head = bytes([0, 0, 0, 0, len(form_data)])
print(bytes_head + form_data)
header = {
    "Accept": "*/*",
    "Accept-Language": "zh-CN,zh;q=0.9,zh-TW;q=0.8",
    "Content-Type": "application/grpc-web+proto",
    "Origin": "https://s.wanfangdata.com.cn",
    "Referer": "https://d.wanfangdata.com.cn/periodical/wlxb202301001",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
}

url = 'https://d.wanfangdata.com.cn/Detail.DetailService/getDetailInFormation'
res = requests.post(url, data=bytes_head + form_data, headers=header)
print(res.content)

发送请求后返回的数据:

在这里插入图片描述

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

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

相关文章

Servlet笔记(11):Servletcontext对象

1、什么是ServletContext ServletContext是一个全局储存空间&#xff0c;随服务器的生命周期变化&#xff0c; Cookie&#xff0c;Session&#xff0c;ServletContext的区别 Cookie&#xff1a; 存在于客户端的本地文本文件 Session&#xff1a; 存在于服务器的文本文件&#…

今天我在朋友圈看到的新京报公众号一段文章&#xff1a;十三届全国人大&#xff08;过几天就任期结束&#xff09;在第五次会议&#xff08;2022年3月5日&#xff09;对证监会提了一条第6178号建议《关于严厉打击风水盲测股市动向的建议》。今天&#xff0c;证监会进行了收称答…

业务代码编写过程中如何「优雅的」配置隔离

思考 不同的处理方式 1.常规的处理方式&#xff0c;通过某种规则判断区分代码环境 // 获取环境标识 const env getCurrentEnv();if (env dev) {// do something } else if (env test) {// do something } else if (env prod) {// do something } 分析&#xff1a; 1.此种…

Linux 操作系统——查看/修改系统时区、时间、本地时间修改为UTC

文章目录1.背景描述2.知识储备3.解决步骤1. 查看当前时区2.修改设置Linux服务器时区3.复制相应的时区文件&#xff0c;替换系统时区文件&#xff1b;或者创建链接文件4. 查看和修改Linux的时间5. 硬件时间和系统时间的 相互同步1.背景描述 最近一个项目日期采用java8的LocalDa…

你在公司混的差,可能和组织架构有关!

原创&#xff1a;小姐姐味道&#xff08;微信公众号ID&#xff1a;xjjdog&#xff09;&#xff0c;欢迎分享&#xff0c;非公众号转载保留此声明。如果你接触过公司的面试工作&#xff0c;一定见过很多来自大公司的渣渣。这些人的薪资和职位&#xff0c;比你高出很多&#xff0…

Delphi RSA加解密(二)

dll开发环境: Delphi XE 10.1 Berlin exe开发环境: Delphi 6 前提文章: Delphi RSA加解密(一) 目录 1. 概述 2. 准备工作 2.1 下载DEMO程序 2.2 字符编码说明 3. Cryption.dll封装 3.1 接口概况 3.2 uPub.pas单元代码 3.3 uInterface.pas单元代码 3.4 特别注意 4. 主程序…

如何选择合适的数字隔离器

随着数字隔离器在工业和汽车应用中的日益普及&#xff0c;从众多可用选项中选择最适合您系统的器件可能会让人不知所措。除了这一挑战之外&#xff0c;大多数数字隔离器在设计时都考虑了特定的系统要求和应用&#xff0c;让您需要对无穷无尽的规格和功能进行分类&#xff0c;以…

C++ sting类(一)各类操作

1、 C语言中的字符串C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合程序设计的思想&#xff0c;而且底层空间需要用户自己管…

NEXUS 6P刷机安装Edxposed

刷机 abd等工具下载&#xff1a; https://developer.android.com/studio/releases/platform-tools?hlzh-cn 下载后配置环境变量 镜像下载&#xff1a; https://developers.google.com/android/images?hlzh-cn#angler Magisk下载 GitHub - topjohnwu/Magisk: The Magic M…

基于BP神经网络的衣服识别,BP神经网络详细原理,BP神经网络图像识别神经网络案例之19

目标 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数&#xff0c; BP神经网络的传递函数 数据 神经网络参数 基于BP神经网络 性别识别的MATLAB代码 效果图 结果分析 展望 背影 人靠衣服马靠鞍&#xff0c;通过穿衣可…

Matlab字符串相关操作-拼接、格式化

常见的有三种方法&#xff1a;向量拼接、strcat函数和sprintf函数1、向量拼接在matlab中字符串本质上也是一个向量&#xff0c;可以通过矩阵运算来实现字符串的拼接&#xff0c;这里随便输入两个字符串a1和b1&#xff0c;用矩阵形式进行拼接&#xff1a;a1 I love;b1 Matlab…

Web项目部署环境搭建:JDK + Tomcat + IDEA

Web项目部署环境搭建&#xff1a;JDK Tomcat IDEA1.java JDK1.1 下载安装1.2 配置环境变量1.3 检查安装成功2. TomCat2.1 下载安装2.2 配置环境变量2.3 检查安装成功3.IDEA3.1 下载安装3.2 永久可得3.3 IDEA部署Tomcat出来混总是要还的&#xff0c;记得大学本科四年&#xff…

Protobuf 逆向解析两种方法

Protobuf 逆向解析两种方法一、Protobuf 的特征二、解析.bin文件显示原始数据法一&#xff1a;用 blackboxprotobuf 模块解析法二&#xff1a;使用 protoc 解析工具一、Protobuf 的特征 案例网址 Protocol buffers是一种语言无关、平台无关、可扩展的序列化结构数据的方法&…

计算机网络 — UDP协议(看这一篇就可以

UDP协议UDP是传输层的重要协议之一&#xff0c;另一重要协议为TCP协议。两者对比&#xff1a;TCP协议复杂&#xff0c;但传输可靠。UDP协议简单&#xff0c;但传输不可靠。UDP协议全称为&#xff1a;User Datagram Protocol&#xff08;用户数据报协议&#xff09;。它是一个简…

嵌入式 STM32 使用C语言打开读取歌曲目录

目录 一、C语言目录库函数 1、打开一个目录文件opendir() 2、readdir&#xff08;);读取目录下文件 3、建立链表保存读到的文件名 一、C语言目录库函数 目录库函数链接&#xff1a;http://wjhsh.net/qiny1012-p-8405394.html 1、打开一个目录文件opendir() opendir()函数…

JavaScript BOM操作

目录 前言 window 对象 location 对象 navigator 对象 screen 对象 history 对象 前言 BOM&#xff08;Browser Object Model&#xff09;指的是浏览器对象模型&#xff0c;它是 JavaScript 和浏览器之间的接口。通过 BOM&#xff0c;JavaScript 可以与浏览器窗口交互&…

【Linux】重定向原理dup2缓冲区

文章目录重定向原理输出重定向关于FILE解释输出重定向原理追加重定向输入重定向dup2缓冲区语言级别的缓冲区内核缓冲区重定向原理 重定向的本质就是修改文件描述符下标对应的struct file*的内容 输出重定向 输出重定向就是把本来应该输出到显示器的数据重定向输出到另一个文…

自己制作投票链接网上投票链接制作可以投票的链接制作

近些年来&#xff0c;第三方的微信投票制作平台如雨后春笋般络绎不绝。随着手机的互联网的发展及微信开放平台各项基于手机能力的开放&#xff0c;更多人选择微信投票小程序平台&#xff0c;因为它有非常大的优势。1.它比起微信公众号自带的投票系统、传统的H5投票系统有可以图…

RK3568平台开发系列讲解(设备驱动篇)Pinctrl子系统详解

🚀返回专栏总目录 文章目录 一、pinctrl子系统结构描述二、重要的概念三、主要的数据结构和接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢我们知道在许多soc内部包含有多个pin控制器,通过pin控制器的寄存器,我们可以配置一个或者一组引脚的功能和特性。Linux…

K8S篇之pod及生命周期

文章目录Pod 概览pod使用方式Pod 中如何管理多个容器Pod 和控制器Pod 模板Pod 更新与替换静态 Pod容器探针pod的生命周期Pod 阶段容器状态容器重启策略Pod 状况pod readinessGates容器探针检查机制execgrpchttpGettcpSocket探测结果探测类型livenessProbe&#xff08;存活探针&…