reversing google protobuf protocol

25
THE CURIOUS CASE OF PROTOBUFS De-mystifying Google’s hottest binary protocol Prasanna Kanagasabai Jovin Lobo

Upload: nu-the-open-security-community

Post on 15-Jul-2015

536 views

Category:

Internet


0 download

TRANSCRIPT

Page 1: Reversing Google Protobuf protocol

THE CURIOUS CASE OF PROTOBUFS…

De-mystifying Google’s hottest binary protocol

Prasanna KanagasabaiJovin Lobo

Page 2: Reversing Google Protobuf protocol

Agenda

Introduction.

Anatomy of Protobufs Defining Message formats in .Proto files.

Protobuf compiler

Python API to read write messages.

Encoding Scheme

Problem Statement.

Decoding like-a-pro with IronWasp ‘ProtobufDecoder’.

Page 3: Reversing Google Protobuf protocol

About us

Prasanna Kanagasabai :

Information Security Pentester @ ThoughtWorks Pune.

Speaker @ Nullcon , Clubhack, IIT Guwahati, Etc ..

Moderator of null Pune.

Author of IronSAP @ Automated SAP Testing tool

Passionately love pen-testing web applications.

Jovin Lobo:

Associate Consultant @ Aujas (www.aujas.com)

Proud member of null- The Open Security Community (www.null.co.in)

Author of GameOver – Linux distro for learning web security.

Spoken at nullCon, GNUnify before.

Page 4: Reversing Google Protobuf protocol

Introduction:

Protocol Buffers a.k.a Protobufs :

Protobufs are Google's own way of serializing structured data .

Extensible, language-neutral and platform-neutral .

Smaller, faster and simpler to implement.

Java, C++ and Python

Page 5: Reversing Google Protobuf protocol

Anatomy:

Over view :

Page 6: Reversing Google Protobuf protocol

Defining a .Proto file.

#> less Example.protomessage Conference {

required string conf_name = 1 ;

required int32 no_of_days = 2 ;

optional string email = 3 ;

}

// * 1,2,3 are unique tags. These are used by the fields in binary encoding.* For optimization use tags from 1-15 as higher nos. will use one more byte to encode.

Page 7: Reversing Google Protobuf protocol

Compiling

Syntax:

protoc –I=$_input_Dir --python_out=$_out_Dir$_Path_ProtoFile

Eg:

protoc –I=. --python_out=. Example.proto

This will generate a Example_pb2.py file in the specified destination directory.

Page 8: Reversing Google Protobuf protocol

$ProtoFile_pb2.py

The Protobuf compiler generates special descriptors for all your messages, enums, and fields.

It also generates empty classes, one for each message type:

Eg:

Page 9: Reversing Google Protobuf protocol

Reading and writing messages using the Protobuf binary format :

SerializeToString() serializes the message and returns it as a string.

ParseFromString(data)

parses a message from the given string.

Page 10: Reversing Google Protobuf protocol

Why Does one Reverse Protobuf It is needed to see the content of payload in

transit.

Any Modifications to payload by changing the stream could break the payload.

Page 11: Reversing Google Protobuf protocol

Demo: Protobuf… how it wrks

Page 12: Reversing Google Protobuf protocol

Encoding.

example2.proto

message Ex1 {

required int32 num = 1; // field tag

}

Code snippet:

obj = example2_pb2.Ex1();

obj.num = 290; // field value

obj.SerializeToString();

Output :

08 A2 02 #hex

000010001010001000000010 #binary

Page 13: Reversing Google Protobuf protocol

Problem statement.

Page 14: Reversing Google Protobuf protocol

This is what freaked him out

08 A2 02

Page 15: Reversing Google Protobuf protocol

Lets Decode it ..

Step 1 :

Find the wire type .

Step 2:

Find the field number.

Step 3: Find the field tag.

Page 16: Reversing Google Protobuf protocol

Step1: finding wire type.

Convert the payload to binary

0000 1000 1010 0010 0000 0010

To find wire type take the first byte: 0000 1000 1010 0010 0000 0010

[0]000 1000 Drop MSB from First byte.

0001 000 The last 3 bits give wire type.

Wire type is 000

type = 0 is Varint.

Page 17: Reversing Google Protobuf protocol

Wire types

Source : https://developers.google.com/protocol-buffers/docs/encoding

Page 18: Reversing Google Protobuf protocol

Step 2: Field tag.

What we already have is 0001000

Now we right shift value by 3 bits and the remaining bits will give us the field tag.

0001000

0001 000

‘0001 ‘ i.e. ‘ 1’

So we get the field tag = 1

Page 19: Reversing Google Protobuf protocol

Step 3: Find the field value

0000 1000 1010 0010 0000 0010

We drop the 1st byte

1010 0010 0000 0010

Drop the MSB’s from each of these bytes

1010 0010 0000 0010

010 0010 000 0010

Reverse these bytes to obtain the field value. 000 0010 010 0010

000 0010 010 0010 i.e 256 + 32 + 2 = 290

So we finally get the value of the field = 290.

Page 20: Reversing Google Protobuf protocol

So we successfully decoded

example2.proto

message Ex1 {

required int32 num = 1;

}

Code snippet:

obj = example2_pb2.Ex1();

obj.num = 290;

obj.SerializeToString();

Output :

08 A2 02 #hex

000010001010001000000010 #binary

We successfully Decoded Value : “290”

Page 21: Reversing Google Protobuf protocol

Demo : Lets do this live

Page 22: Reversing Google Protobuf protocol

Automating all this with IronWasp Protobuf Decoder:

About IronWasp : IronWasp is an open-source web security scanner.

It is designed to be customizable to the extent where users can create their own custom security scanners using it.

Website : www.ironwasp.org

Plugin : https://bitbucket.org/RandomSecurity/protobuf-decoder

Page 23: Reversing Google Protobuf protocol

Demo

Page 24: Reversing Google Protobuf protocol

RoadMap

Add additional Wire types