def open_file(cls, tree, file): file = cls.normalize_filename(file) # ensure file is created, get maximal access, and set everybody read access max_req = SMB2CreateContextRequest() max_req[ "buffer_name"] = CreateContextName.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST max_req["buffer_data"] = SMB2CreateQueryMaximalAccessRequest() # create security buffer that sets the ACL for everyone to have read access everyone_sid = SIDPacket() everyone_sid.from_string("S-1-1-0") ace = AccessAllowedAce() ace["mask"] = AccessMask.GENERIC_ALL ace["sid"] = everyone_sid acl = AclPacket() acl["aces"] = [ace] sec_desc = SMB2CreateSDBuffer() sec_desc["control"].set_flag(SDControl.SELF_RELATIVE) sec_desc.set_dacl(acl) sd_buffer = SMB2CreateContextRequest() sd_buffer["buffer_name"] = CreateContextName.SMB2_CREATE_SD_BUFFER sd_buffer["buffer_data"] = sec_desc create_contexts = [max_req, sd_buffer] file_open = Open(tree, file) open_info = file_open.create( ImpersonationLevel.Impersonation, FilePipePrinterAccessMask.GENERIC_READ | FilePipePrinterAccessMask.GENERIC_WRITE, FileAttributes.FILE_ATTRIBUTE_NORMAL, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OVERWRITE_IF, CreateOptions.FILE_NON_DIRECTORY_FILE, ) return file_open
def test_get_context_data_unknown(self): message = SMB2CreateContextRequest() data = b"\x00\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x04\x00\x00\x00" \ b"\x45\x78\x74\x41" \ b"\x00\x00\x00\x00" \ b"\x20\x00\x00\x00" message.unpack(data) actual = message.get_context_data() assert actual == b"\x20\x00\x00\x00"
def test_pack_multiple_raw_context(self): alloc_size = SMB2CreateAllocationSize() alloc_size['allocation_size'] = 1024 expected = b"\x00\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x08\x00\x00\x00" \ b"\x41\x6c\x53\x69" \ b"\x00\x00\x00\x00" \ b"\x00\x04\x00\x00\x00\x00\x00\x00" actual = SMB2CreateContextRequest.pack_multiple([alloc_size]) assert actual == expected
def test_get_context_data_known(self): message = SMB2CreateContextRequest() data = b"\x00\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x20\x00\x00\x00" \ b"\x51\x46\x69\x64" \ b"\x00\x00\x00\x00" \ b"\xed\x5a\x00\x00\x00\x00\x99\x00" \ b"\x30\x50\xd7\xd8\x04\x82\xff\xff" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" message.unpack(data) actual = message.get_context_data() assert isinstance(actual, SMB2CreateQueryOnDiskIDResponse) assert actual['disk_file_id'].get_value() == 43065671436753645 assert actual['volume_id'].get_value() == 18446605556062310448 assert actual['reserved'].get_value() == b"\x00" * 16
def test_create_message(self): ea_buffer1 = SMB2CreateEABuffer() ea_buffer1['ea_name'] = "Authors\x00".encode('ascii') ea_buffer1['ea_value'] = "Jordan Borean".encode("utf-8") ea_buffer2 = SMB2CreateEABuffer() ea_buffer2['ea_name'] = "Title\x00".encode('ascii') ea_buffer2['ea_value'] = "Jordan Borean Title".encode('utf-8') ea_buffers = SMB2CreateContextRequest() ea_buffers['buffer_name'] = CreateContextName.SMB2_CREATE_EA_BUFFER ea_buffers['buffer_data'] = SMB2CreateEABuffer.pack_multiple( [ea_buffer1, ea_buffer2]) alloc_size = SMB2CreateAllocationSize() alloc_size['allocation_size'] = 1024 alloc_size_context = SMB2CreateContextRequest() alloc_size_context['buffer_name'] = \ CreateContextName.SMB2_CREATE_ALLOCATION_SIZE alloc_size_context['buffer_data'] = alloc_size query_disk = SMB2CreateContextRequest() query_disk['buffer_name'] = \ CreateContextName.SMB2_CREATE_QUERY_ON_DISK_ID expected = b"\x60\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x41\x00\x00\x00" \ b"\x45\x78\x74\x41" \ b"\x00\x00\x00\x00" \ b"\x20\x00\x00\x00" \ b"\x00" \ b"\x07" \ b"\x0d\x00" \ b"\x41\x75\x74\x68\x6f\x72\x73\x00" \ b"\x4a\x6f\x72\x64\x61\x6e\x20\x42" \ b"\x6f\x72\x65\x61\x6e" \ b"\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x00" \ b"\x05" \ b"\x13\x00" \ b"\x54\x69\x74\x6c\x65\x00" \ b"\x4a\x6f\x72\x64\x61\x6e\x20\x42" \ b"\x6f\x72\x65\x61\x6e\x20\x54\x69" \ b"\x74\x6c\x65" \ b"\x00\x00\x00\x00\x00\x00\x00" \ b"\x20\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x08\x00\x00\x00" \ b"\x41\x6c\x53\x69" \ b"\x00\x00\x00\x00" \ b"\x00\x04\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x51\x46\x69\x64" \ b"\x00\x00\x00\x00" actual = SMB2CreateContextRequest.pack_multiple( [ea_buffers, alloc_size_context, query_disk]) # now has padding on the end assert len(ea_buffers) == 96 assert len(alloc_size_context) == 32 assert len(query_disk) == 24 assert actual == expected
def test_parse_message(self): actual1 = SMB2CreateContextRequest() actual2 = SMB2CreateContextRequest() actual3 = SMB2CreateContextRequest() data = b"\x60\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x41\x00\x00\x00" \ b"\x45\x78\x74\x41" \ b"\x00\x00\x00\x00" \ b"\x20\x00\x00\x00" \ b"\x00" \ b"\x07" \ b"\x0d\x00" \ b"\x41\x75\x74\x68\x6f\x72\x73\x00" \ b"\x4a\x6f\x72\x64\x61\x6e\x20\x42" \ b"\x6f\x72\x65\x61\x6e" \ b"\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x00" \ b"\x05" \ b"\x13\x00" \ b"\x54\x69\x74\x6c\x65\x00" \ b"\x4a\x6f\x72\x64\x61\x6e\x20\x42" \ b"\x6f\x72\x65\x61\x6e\x20\x54\x69" \ b"\x74\x6c\x65" \ b"\x00\x00\x00\x00\x00\x00\x00" \ b"\x20\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x18\x00" \ b"\x08\x00\x00\x00" \ b"\x41\x6c\x53\x69" \ b"\x00\x00\x00\x00" \ b"\x00\x04\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x10\x00" \ b"\x04\x00" \ b"\x00\x00" \ b"\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x51\x46\x69\x64" \ b"\x00\x00\x00\x00" data = actual1.unpack(data) data = actual2.unpack(data) data = actual3.unpack(data) assert data == b"" assert len(actual1) == 96 assert actual1['next'].get_value() == 96 assert actual1['name_offset'].get_value() == 16 assert actual1['name_length'].get_value() == 4 assert actual1['reserved'].get_value() == 0 assert actual1['data_offset'].get_value() == 24 assert actual1['data_length'].get_value() == 65 assert actual1['buffer_name'].get_value() == b"\x45\x78\x74\x41" assert actual1['padding'].get_value() == b"\x00\x00\x00\x00" ea_buffer_data = actual1['buffer_data'].get_value() actual_ea_buffer1 = SMB2CreateEABuffer() actual_ea_buffer2 = SMB2CreateEABuffer() ea_buffer_data = actual_ea_buffer1.unpack(ea_buffer_data) ea_buffer_data = actual_ea_buffer2.unpack(ea_buffer_data) assert ea_buffer_data == b"" assert len(actual_ea_buffer1) == 32 assert actual_ea_buffer1['next_entry_offset'].get_value() == 32 assert actual_ea_buffer1['flags'].get_value() == 0 assert actual_ea_buffer1['ea_name_length'].get_value() == 7 assert actual_ea_buffer1['ea_value_length'].get_value() == 13 assert actual_ea_buffer1['ea_name'].get_value() == \ "Authors\x00".encode("ascii") assert actual_ea_buffer1['ea_value'].get_value() == b"Jordan Borean" assert actual_ea_buffer1['padding'].get_value() == b"\x00\x00\x00" assert len(actual_ea_buffer2) == 33 assert actual_ea_buffer2['next_entry_offset'].get_value() == 0 assert actual_ea_buffer2['flags'].get_value() == 0 assert actual_ea_buffer2['ea_name_length'].get_value() == 5 assert actual_ea_buffer2['ea_value_length'].get_value() == 19 assert actual_ea_buffer2['ea_name'].get_value() == \ "Title\x00".encode("ascii") assert actual_ea_buffer2['ea_value'].get_value() == \ b"Jordan Borean Title" assert actual_ea_buffer2['padding'].get_value() == b"" assert actual1['padding2'].get_value() == b"\x00" * 7 assert len(actual2) == 32 assert actual2['next'].get_value() == 32 assert actual2['name_offset'].get_value() == 16 assert actual2['name_length'].get_value() == 4 assert actual2['reserved'].get_value() == 0 assert actual2['data_offset'].get_value() == 24 assert actual2['data_length'].get_value() == 8 assert actual2['buffer_name'].get_value() == b"\x41\x6c\x53\x69" assert actual2['padding'].get_value() == b"\x00\x00\x00\x00" alloc_data = actual2['buffer_data'].get_value() alloc = SMB2CreateAllocationSize() alloc_data = alloc.unpack(alloc_data) assert alloc_data == b"" assert alloc['allocation_size'].get_value() == 1024 assert actual2['padding2'].get_value() == b"" assert len(actual3) == 24 assert actual3['next'].get_value() == 0 assert actual3['name_offset'].get_value() == 16 assert actual3['name_length'].get_value() == 4 assert actual3['reserved'].get_value() == 0 assert actual3['data_offset'].get_value() == 0 assert actual3['data_length'].get_value() == 0 assert actual3['buffer_name'].get_value() == b"\x51\x46\x69\x64" assert actual3['padding'].get_value() == b"" assert actual3['buffer_data'].get_value() == b"" assert actual3['padding2'].get_value() == b"\x00\x00\x00\x00"
def test_pack_multiple_bad_message(self): expected = "Invalid context message, must be either a SMB2CreateContextRequest or a predefined structure " \ "object with NAME defined." with pytest.raises(ValueError, match=re.escape(expected)): SMB2CreateContextRequest.pack_multiple([b"\x00"])
username = "******" password = "******" share = r"\\%s\share" % server file_name = "file-test.txt" connection = Connection(uuid.uuid4(), server, port) connection.connect() try: session = Session(connection, username, password) session.connect() tree = TreeConnect(session, share) tree.connect() # ensure file is created, get maximal access, and set everybody read access max_req = SMB2CreateContextRequest() max_req['buffer_name'] = \ CreateContextName.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST max_req['buffer_data'] = SMB2CreateQueryMaximalAccessRequest() # create security buffer that sets the ACL for everyone to have read access everyone_sid = SIDPacket() everyone_sid.from_string("S-1-1-0") ace = AccessAllowedAce() ace['mask'] = AccessMask.GENERIC_ALL ace['sid'] = everyone_sid acl = AclPacket() acl['aces'] = [ace]