From 391d45166330d4b159250fab30f9a36420c8faa9 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Wed, 15 Jul 2020 14:50:00 +0800 Subject: smb2: SMB_EXT_FILE_ATTR is misused to parse FileAttributes of SMB2. Bug: 16699 Change-Id: I9a53cd45d7d7f956f73610d767f19bfc86219d39 Reviewed-on: https://code.wireshark.org/review/37864 Reviewed-by: Zhenhua Hu Petri-Dish: Alexis La Goutte Tested-by: Petri Dish Buildbot Reviewed-by: Alexis La Goutte --- epan/dissectors/packet-smb2.c | 175 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 165 insertions(+), 10 deletions(-) (limited to 'epan/dissectors/packet-smb2.c') diff --git a/epan/dissectors/packet-smb2.c b/epan/dissectors/packet-smb2.c index 0b47a5c6f8..5ec708bab8 100644 --- a/epan/dissectors/packet-smb2.c +++ b/epan/dissectors/packet-smb2.c @@ -590,6 +590,22 @@ static int hf_smb2_symlink_print_name = -1; static int hf_smb2_symlink_flags = -1; static int hf_smb2_bad_signature = -1; static int hf_smb2_good_signature = -1; +static int hf_smb2_fscc_file_attr = -1; +static int hf_smb2_fscc_file_attr_archive = -1; +static int hf_smb2_fscc_file_attr_compressed = -1; +static int hf_smb2_fscc_file_attr_directory = -1; +static int hf_smb2_fscc_file_attr_encrypted = -1; +static int hf_smb2_fscc_file_attr_hidden = -1; +static int hf_smb2_fscc_file_attr_normal = -1; +static int hf_smb2_fscc_file_attr_not_content_indexed = -1; +static int hf_smb2_fscc_file_attr_offline = -1; +static int hf_smb2_fscc_file_attr_read_only = -1; +static int hf_smb2_fscc_file_attr_reparse_point = -1; +static int hf_smb2_fscc_file_attr_sparse_file = -1; +static int hf_smb2_fscc_file_attr_system = -1; +static int hf_smb2_fscc_file_attr_temporary = -1; +static int hf_smb2_fscc_file_attr_integrity_stream = -1; +static int hf_smb2_fscc_file_attr_no_scrub_data = -1; static gint ett_smb2 = -1; static gint ett_smb2_olb = -1; @@ -700,6 +716,7 @@ static gint ett_smb2_error_redir_ip_list = -1; static gint ett_smb2_read_flags = -1; static gint ett_smb2_signature = -1; static gint ett_smb2_transform_flags = -1; +static gint ett_smb2_fscc_file_attributes = -1; static expert_field ei_smb2_invalid_length = EI_INIT; static expert_field ei_smb2_bad_response = EI_INIT; @@ -2400,6 +2417,80 @@ dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset return offset; } +#define SMB2_FSCC_FILE_ATTRIBUTE_READ_ONLY 0x00000001 +#define SMB2_FSCC_FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define SMB2_FSCC_FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define SMB2_FSCC_FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define SMB2_FSCC_FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define SMB2_FSCC_FILE_ATTRIBUTE_NORMAL 0x00000080 +#define SMB2_FSCC_FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define SMB2_FSCC_FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define SMB2_FSCC_FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define SMB2_FSCC_FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define SMB2_FSCC_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define SMB2_FSCC_FILE_ATTRIBUTE_ENCRYPTED 0x00004000 +#define SMB2_FSCC_FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000 +#define SMB2_FSCC_FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000 + + +static const true_false_string tfs_fscc_file_attribute_reparse = { + "Has an associated REPARSE POINT", + "Does NOT have an associated reparse point" +}; +static const true_false_string tfs_fscc_file_attribute_compressed = { + "COMPRESSED", + "Uncompressed" +}; +static const true_false_string tfs_fscc_file_attribute_offline = { + "OFFLINE", + "Online" +}; +static const true_false_string tfs_fscc_file_attribute_not_content_indexed = { + "Is not indexed by the content indexing service", + "Is indexed by the content indexing service" +}; +static const true_false_string tfs_fscc_file_attribute_integrity_stream = { + "Has Integrity Support", + "Does NOT have Integrity Support" +}; +static const true_false_string tfs_fscc_file_attribute_no_scrub_data = { + "Is excluded from the data integrity scan", + "Is not excluded from the data integrity scan" +}; + +/* + * File Attributes, section 2.6 in the [MS-FSCC] spec + */ +static int +dissect_fscc_file_attr(tvbuff_t* tvb, proto_tree* parent_tree, int offset) +{ + guint32 mask = tvb_get_letohl(tvb, offset); + static int* const mask_fields[] = { + &hf_smb2_fscc_file_attr_read_only, + &hf_smb2_fscc_file_attr_hidden, + &hf_smb2_fscc_file_attr_system, + &hf_smb2_fscc_file_attr_directory, + &hf_smb2_fscc_file_attr_archive, + &hf_smb2_fscc_file_attr_normal, + &hf_smb2_fscc_file_attr_temporary, + &hf_smb2_fscc_file_attr_sparse_file, + &hf_smb2_fscc_file_attr_reparse_point, + &hf_smb2_fscc_file_attr_compressed, + &hf_smb2_fscc_file_attr_offline, + &hf_smb2_fscc_file_attr_not_content_indexed, + &hf_smb2_fscc_file_attr_encrypted, + &hf_smb2_fscc_file_attr_integrity_stream, + &hf_smb2_fscc_file_attr_no_scrub_data, + NULL + }; + + proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset, hf_smb2_fscc_file_attr, ett_smb2_fscc_file_attributes, mask_fields, mask, BMT_NO_APPEND); + + offset += 4; + + return offset; +} /* this info level is unique to SMB2 and differst from the corresponding * SMB_FILE_ALL_INFO in SMB @@ -2438,7 +2529,7 @@ dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *pa offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp); /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* some unknown bytes */ proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA); @@ -2606,7 +2697,7 @@ dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree * offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp); /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* some unknown bytes */ proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA); @@ -4259,7 +4350,7 @@ static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _ offset += 8; /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* file name length */ file_name_len = tvb_get_letohl(tvb, offset); @@ -4338,7 +4429,7 @@ static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _ offset += 8; /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* file name length */ file_name_len = tvb_get_letohl(tvb, offset); @@ -4422,7 +4513,7 @@ static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _ offset += 8; /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* file name length */ file_name_len = tvb_get_letohl(tvb, offset); @@ -4578,7 +4669,7 @@ static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinf offset += 8; /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* file name length */ file_name_len = tvb_get_letohl(tvb, offset); @@ -4686,7 +4777,7 @@ static void dissect_smb2_id_full_directory_info(tvbuff_t *tvb, packet_info *pinf offset += 8; /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* file name length */ file_name_len = tvb_get_letohl(tvb, offset); @@ -5726,7 +5817,7 @@ dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t offset += 8; /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); return offset; } @@ -8771,7 +8862,7 @@ dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, offset = dissect_smb_access_mask(tvb, tree, offset); /* File Attributes */ - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* share access */ offset = dissect_nt_share_access(tvb, tree, offset); @@ -8878,7 +8969,7 @@ dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree /* File Attributes */ attr_mask=tvb_get_letohl(tvb, offset); - offset = dissect_file_ext_attr(tvb, tree, offset); + offset = dissect_fscc_file_attr(tvb, tree, offset); /* reserved */ proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA); @@ -13114,6 +13205,69 @@ proto_register_smb2(void) { "Flags", "smb2.symlink.flags", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_smb2_fscc_file_attr, + { "File Attributes", "smb2.file_attribute", FT_UINT32, BASE_HEX, + NULL, 0x0, NULL, HFILL } + }, + { &hf_smb2_fscc_file_attr_read_only, + { "Read Only", "smb2.file_attribute.read_only", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL } }, + + { &hf_smb2_fscc_file_attr_hidden, + { "Hidden", "smb2.file_attribute.hidden", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL } }, + + { &hf_smb2_fscc_file_attr_system, + { "System", "smb2.file_attribute.system", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL } }, + + { &hf_smb2_fscc_file_attr_directory, + { "Directory", "smb2.file_attribute.directory", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL } }, + + { &hf_smb2_fscc_file_attr_archive, + { "Requires archived", "smb2.file_attribute.archive", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL } }, + + { &hf_smb2_fscc_file_attr_normal, + { "Normal", "smb2.file_attribute.normal", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL } }, + + { &hf_smb2_fscc_file_attr_temporary, + { "Temporary", "smb2.file_attribute.temporary", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL } }, + + { &hf_smb2_fscc_file_attr_sparse_file, + { "Sparse", "smb2.file_attribute.sparse", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_SPARSE_FILE, "Is this a sparse file?", HFILL } }, + + { &hf_smb2_fscc_file_attr_reparse_point, + { "Reparse Point", "smb2.file_attribute.reparse", FT_BOOLEAN, 32, + TFS(&tfs_fscc_file_attribute_reparse), SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT, "Does this file have an associated reparse point?", HFILL } }, + + { &hf_smb2_fscc_file_attr_compressed, + { "Compressed", "smb2.file_attribute.compressed", FT_BOOLEAN, 32, + TFS(&tfs_fscc_file_attribute_compressed), SMB2_FSCC_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL } }, + + { &hf_smb2_fscc_file_attr_offline, + { "Offline", "smb2.file_attribute.offline", FT_BOOLEAN, 32, + TFS(&tfs_fscc_file_attribute_offline), SMB2_FSCC_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL } }, + + { &hf_smb2_fscc_file_attr_not_content_indexed, + { "Not Content Indexed", "smb2.file_attribute.not_content_indexed", FT_BOOLEAN, 32, + TFS(&tfs_fscc_file_attribute_not_content_indexed), SMB2_FSCC_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL } }, + + { &hf_smb2_fscc_file_attr_encrypted, + { "Encrypted", "smb2.file_attribute.encrypted", FT_BOOLEAN, 32, + TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL } }, + + { &hf_smb2_fscc_file_attr_integrity_stream, + { "Integrity Stream", "smb2.file_attribute.integrity_stream", FT_BOOLEAN, 32, + TFS(&tfs_fscc_file_attribute_integrity_stream), SMB2_FSCC_FILE_ATTRIBUTE_INTEGRITY_STREAM, "Is this file configured with inegrity support?", HFILL } }, + + { &hf_smb2_fscc_file_attr_no_scrub_data, + { "No Scrub Data", "smb2.file_attribute.no_scrub_data", FT_BOOLEAN, 32, + TFS(&tfs_fscc_file_attribute_no_scrub_data), SMB2_FSCC_FILE_ATTRIBUTE_NO_SCRUB_DATA, "Is this file configured to be excluded from the data integrity scan?", HFILL } }, }; static gint *ett[] = { @@ -13226,6 +13380,7 @@ proto_register_smb2(void) &ett_smb2_read_flags, &ett_smb2_signature, &ett_smb2_transform_flags, + &ett_smb2_fscc_file_attributes, }; static ei_register_info ei[] = { -- cgit v1.2.3