Search code examples
encryptioncompressionprotocol-buffersgrpcpacking

how to unpack/decompress raw grpc data?


i intercepted grpc http2 request yet i cant make much sense of the data mitmproxy is printing it as hex this is some of the headers

te: trailers
content-type: application/grpc
grpc-accept-encoding: identity,deflate,gzip
accept-encoding: identity,gzip

yet the data doesn't make any sense I tried gunzip on cyberchef and it keep saying "Gunzip - invalid file signature:" I tried protobuf decoder and it says "Error: Exhausted Buffer" any ideas how should I approach this?

edit: this is the data im trying to decompress

\x12
\x10\xb8z =P\xdeCw\x89\x1e}\xbb\x8c*\x1f\x11\x10\xff\xc7\xa0\xad\xaa\xd9\xbe\xcf\xb6\x01\x1a\x16
\x14
\x12
\x10>D_.\x9bd\\\x7f\x88\xbc\xd0\x00}\xab')"\x0b\x10\x01"\x05\x12\x03
\x01E8\x02"

and this is the other protobuf message who mitmproxy managed to decompress

(
&\x12$3e445f2e-9b64-5c7f-88bc-**

and this is the 2 decompressed data

1 {
  1 {
    2: 3e445f2e-9b64-5c7f-88bc-**
  }
}

Solution

  • The gRPC protocol is defined in this document. In particular, the section about "Length-Prefixed-Message" describes how the data is encoded:

    The repeated sequence of Length-Prefixed-Message items is delivered in DATA frames

    • Length-Prefixed-Message → Compressed-Flag Message-Length Message
    • Compressed-Flag → 0 / 1 # encoded as 1 byte unsigned integer
    • Message-Length → {length of Message} # encoded as 4 byte unsigned integer (big endian)
    • Message → *{binary octet}

    In other words, to read messages, read 1 byte for the compressed bit, then read 4 bytes for the length, then read that many bytes for the message. If he compressed bit is set, you will need to decompress the message using the format described in the "grpc-encoding" header. Then the format of the message is application-specific. Protobuf is common.