ProtobufPwn

还原.proto文件

pbtk

1
./extractors/from_binary.py [-h] input_file [output_dir]

逆向

先找到字段字符串

然后通过交叉引用找到message字段的结构体,一般在.data.rel.ro

结构体各字段具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
struct ProtobufCFieldDescriptor {
/** Name of the field as given in the .proto file. */
const char *name;
/** Tag value of the field as given in the .proto file. */
uint32_t id;
/** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
ProtobufCLabel label;
/** The type of the field. */
ProtobufCType type;
/**
* The offset in bytes of the message's C structure's quantifier field
* (the `has_MEMBER` field for optional members or the `n_MEMBER` field
* for repeated members or the case enum for oneofs).
*/
unsigned quantifier_offset;
/**
* The offset in bytes into the message's C structure for the member
* itself.
*/
unsigned offset;
/**
* A type-specific descriptor.
*
* If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the
* corresponding `ProtobufCEnumDescriptor`.
*
* If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to
* the corresponding `ProtobufCMessageDescriptor`.
*
* Otherwise this field is NULL.
*/
const void *descriptor; /* for MESSAGE and ENUM types */
/** The default value for this field, if defined. May be NULL. */
const void *default_value;
/**
* A flag word. Zero or more of the bits defined in the
* `ProtobufCFieldFlag` enum may be set.
*/
uint32_t flags;
/** Reserved for future use. */
unsigned reserved_flags;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
};

label对应枚举如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef enum {
/** A well-formed message must have exactly one of this field. */
PROTOBUF_C_LABEL_REQUIRED,
/**
* A well-formed message can have zero or one of this field (but not
* more than one).
*/
PROTOBUF_C_LABEL_OPTIONAL,
/**
* This field can be repeated any number of times (including zero) in a
* well-formed message. The order of the repeated values will be
* preserved.
*/
PROTOBUF_C_LABEL_REPEATED,
/**
* This field has no label. This is valid only in proto3 and is
* equivalent to OPTIONAL but no "has" quantifier will be consulted.
*/
PROTOBUF_C_LABEL_NONE,
} ProtobufCLabel;

type对应枚举如下:

Protobuf C Type C Type Line Number Minus One (Hex)
PROTOBUF_C_TYPE_INT32 int32 0x0
PROTOBUF_C_TYPE_SINT32 signed int32 0x1
PROTOBUF_C_TYPE_SFIXED32 signed int32 (4 bytes) 0x2
PROTOBUF_C_TYPE_INT64 int64 0x3
PROTOBUF_C_TYPE_SINT64 signed int64 0x4
PROTOBUF_C_TYPE_SFIXED64 signed int64 (8 bytes) 0x5
PROTOBUF_C_TYPE_UINT32 unsigned int32 0x6
PROTOBUF_C_TYPE_FIXED32 unsigned int32 (4 bytes) 0x7
PROTOBUF_C_TYPE_UINT64 unsigned int64 0x8
PROTOBUF_C_TYPE_FIXED64 unsigned int64 (8 bytes) 0x9
PROTOBUF_C_TYPE_FLOAT float 0xA
PROTOBUF_C_TYPE_DOUBLE double 0xB
PROTOBUF_C_TYPE_BOOL boolean 0xC
PROTOBUF_C_TYPE_ENUM enumerated type 0xD
PROTOBUF_C_TYPE_STRING UTF-8 or ASCII string 0xE
PROTOBUF_C_TYPE_BYTES arbitrary byte sequence 0xF
PROTOBUF_C_TYPE_MESSAGE nested message 0x10

下图

对应的message为:

1
bytes whatcon = 1;

编译proto文件

1
protoc proto_file.proto --python_out ./

编译完成后生成一个proto_file_pb2.py文件,在脚本中通过import proto_file_pb2引用,通过cont = proto_file_pb2.devicemsg()创建message对象,其中devicemsg为.proto文件内的message结构体名称,通过cont.whatcon=b’aaaa’赋值,最后通过cont.SerializeToString()解析然后发送。


ProtobufPwn
https://www.w4y2sh3ll.top/2024/05/29/ProtobufPwn/
作者
W4y2Sh3ll
发布于
2024年5月29日
许可协议