抓包protobuf反解析

在抓一个app的包的时候发现http的Content-type竟然是application/x-protobuf,第一次遇到这种。网上也有不少问关于这方面的,或许有人已经研究出来了,但是不肯放干货啊。只能自己探索了。

首先我用的抓包工具是Charles,抓包是能看到内容的。Charles本身是用java写的,所以很容易看到源代码。在com.xk72.charles.gui.transaction.viewers.protobuf包下面确实有一个ProtocolBuffersTreeBodyViewer$1的视图,因为jd-gui搜索代码功能有缺陷,导出jar也一直卡着,哪里开始解析的没有找到。只能从protobuf编码开始研究了。然后发现有个命令‘protoc.exe  --decode_raw ’直接可以解析任意字节流了。

能看到包的内容算是解决了,但是怎么伪造protobuf包呢?答案就是保持字节流的长度不变,直接替换byte的内容。然后直接发包就可以了。

比如我在分析一个protobuf字节流的时候,拿到的二进制保存到文件里查看是这样的:

86177897654321267"006006* b8e6683bd8cf4f5997f9ff55d04da8910ÿÿÿB`
$ffffffff-c978-5f17-ffff-ffffc2e834d93.8.5.1*$手机型å·ï¼šMuMu版本å·ï¼š6.0.1BaJ渠é“

然后另外一个protobuf字节流拿到的二进制保存到文件里查看是这样的:

kOKc182****1121 b8e6683bd8cf4f5997f9ff55d04da891 ¤ç‹®¼©ÎÐ×Ìë2019/9/6 11:26:19

在使用‘protoc.exe  --decode_raw ’查看包内容的时候,有一个int的关键字他的值是2290596,这个关键字之前的字符串是

b8e6683bd8cf4f5997f9ff55d04da891

然后分解这两个字节流的byte数组发现,b8e6683bd8cf4f5997f9ff55d04da891后面有几个一模一样的值

-92 -25 -117 1

是不是这四个字节或者其中的一部分就代表2290596呢?

protobuf采用的是Varints编码

比如数字149通过Varints编码后变成了

10010101 00000001

这里面有2个字节,在Varints中每个字节的第一个bit都是代表后面还有没有更多的字节,从上面的例子能看出,第一个字节首bit是1,代表后面还有字节,需要继续处理,第二个的首bit是0,代表到此为止后面没有字节了。

还有一个需要注意的是,Varints采用的是 least significant group first, 网上没有找到合适的翻译,其实就是它在表示整型变量时将字节顺序反过来存储,比如上面这个例子:

10010101 00000001  -> 0010101 0000001  //去掉首bit

0010101 0000001 ->00000010010101  //反转顺序

00000010010101换算成10进制就是149
————————————————
该部分引用:https://blog.csdn.net/toxie6415176/article/details/80258513

因为2^21次方是2097152小于2290596所以,需要四个字节来表示,因此上面四个字节都是用来表示2290596。

2290596的二进制是:10 0010 1111 0011 1010 0100按照上面规则它的Varints编码就是:

11011100 1001101 11110101 00000001

-92 -25 -117 1的补码:
11011100 1001101 11110101 00000001

就能验证结果了,所以发包的时候直接替换对应byte索引里面的内容就可以了。

关于protoc.exe  --decode_raw 这个命令网上很少有介绍。

protoc.exe  --decode_raw < input_raw.bin > out_put.txt

input_raw.bin就是protob的二进制文件,out_put.txt就是输入结构到制定文件,如果不使用就直接显示在命令行上了。

猜你喜欢

转载自blog.csdn.net/skillart/article/details/100578069
今日推荐