Protobuf网络无法识别的流前缀



我正在尝试对Quasar RAT protobuf协议结构进行逆向工程。Quasar是一个用C#编写的远程管理工具,它是开源的,可以在这里在线找到。https://github.com/quasar/QuasarRAT

我已经成功地扭转了大部分,现在我可以从python脚本连接到Quasar服务器客户端。如果有一个问题仍然悬而未决,那么从客户端发送到服务器的每个字节流似乎都以一个3字节字段开头,该字段未在Quasar的protobuf类中注册。该字段似乎提供了不包括前缀字节的消息长度。在这个块中可以看到,例如,为大小为0x2d2的数组生成的带前缀的字节流,这些是附加到消息中的带前缀字节。

0x0A, 0xCF, 0x05

如果我决定在序列化消息之前更改消息字段,那么除了第一个0x0A字节之外,此字节流都会发生更改。看起来,如果我继续在消息字段中添加字节,第二个字节就会增长,如果我溢出第二个字符(使其达到0xff以上(,它会增加第三个字节,并将第二个字节重置为0x80。但数学对我来说根本没有意义,因为这个字段应该返回数组的大小,但在我可以计算的任何合理公式下都没有。我知道protobuf-net可以生成PreLengthPrefix字节,以消息的长度作为前缀,但这里的情况并非如此。

如有任何帮助,我们将不胜感激。

编码规则如下:https://developers.google.com/protocol-buffers/docs/encoding

基本上,每个字段都被编码为字段头(也称为"标签"(,后面跟着一个有效载荷。字段标题是一个"variant"(请参阅编码指南(,其值是一个由字段号和导线类型组成的整数。导线类型是3个最低有效位,字段号是其余的(偏移3位(。在0x0A(二进制1010(的情况下,导线类型为2(二进制010(,字段编号为1。

如何处理有效载荷取决于导线类型。对于导线类型2(前缀长度(,您应该期待下一个:

  • 一个变量,它是以字节为单位的有效负载的长度,然后
  • 实际有效载荷的多少字节

不幸的是,protobuf在没有架构的情况下是模糊的,所以知道你有前缀为长度的数据并不能告诉你是什么;以长度为前缀的有效载荷可以是:

  • UTF-8字符串
  • 原始BLOB(bytes(
  • 子消息
  • 一些基元类型(整数/浮点数等(的"压缩"数组-记住长度前缀是字节的数量,而不是元素的数量;这些元素甚至不一定是固定大小的(它们本身可能是变体

在许多方面,导线类型的目的不是告诉您如何解释数据;它是告诉你如何跳过(或者只是逐字存储(字段,如果它不是你所知道的字段。例如,其他人正在使用API的V3,而您只将您的模式更新为V2;它们向您的V2 API发送V3消息;V3有额外的字段你不关心-反序列化程序在遇到它们时不需要中断,因此连线类型告诉它如何忽略字段(即查找下一个字段的规则是什么(。否则,我们可以只使用模式信息,而根本不将连线类型存储在有效负载(尽管它也通过"打包"数组用于对重复的基元数据进行优化-这取决于序列化程序是否对长度前缀与大量字段头/值对进行编码(。

最新更新