def test_parse_message(self): actual = SMB2HeaderResponse() data = b"\xfe\x53\x4d\x42" \ b"\x40\x00" \ b"\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x01\x00" \ b"\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x01\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x0a\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x01\x02\x03\x04" actual.unpack(data) assert len(actual) == 68 assert actual['protocol_id'].get_value() == b"\xfeSMB" assert actual['structure_size'].get_value() == 64 assert actual['credit_charge'].get_value() == 0 assert actual['status'].get_value() == 0 assert actual['command'].get_value() == Commands.SMB2_SESSION_SETUP assert actual['credit_response'].get_value() == 0 assert actual['flags'].get_value() == 0 assert actual['next_command'].get_value() == 0 assert actual['message_id'].get_value() == 1 assert actual['reserved'].get_value() == 0 assert actual['tree_id'].get_value() == 0 assert actual['session_id'].get_value() == 10 assert actual['signature'].get_value() == b"\x00" * 16 assert actual['data'].get_value() == b"\x01\x02\x03\x04"
def test_verify_message_skip(self, smb_real): connection = Connection(uuid.uuid4(), smb_real[2], smb_real[3], True) connection.connect() try: header = SMB2HeaderResponse() header['message_id'] = 0xFFFFFFFFFFFFFFFF connection.verify_signature(header, 0) finally: connection.disconnect()
def test_verify_message_skip(self, smb_real): connection = Connection(uuid.uuid4(), smb_real[2], smb_real[3], True) connection.connect() try: header = SMB2HeaderResponse() header['message_id'] = 0xFFFFFFFFFFFFFFFF expected = header.pack() connection._verify(header, 0) actual = header.pack() assert actual == expected finally: connection.disconnect()
def test_verify_fail_no_session(self, smb_real): connection = Connection(uuid.uuid4(), smb_real[2], smb_real[3], True) connection.connect() try: header = SMB2HeaderResponse() header['message_id'] = 1 header['flags'].set_flag(Smb2Flags.SMB2_FLAGS_SIGNED) with pytest.raises(SMBException) as exc: connection._verify(header, 100) assert str(exc.value) == "Failed to find session 100 for " \ "message verification" finally: connection.disconnect()
def test_decrypt_invalid_session_id(self, smb_real): connection = Connection(uuid.uuid4(), smb_real[2], smb_real[3], True) session = Session(connection, smb_real[0], smb_real[1]) connection.connect() try: session.connect() # just get some random message b_header = connection.preauth_integrity_hash_value[-1] header = SMB2HeaderResponse() header.unpack(b_header) enc_header = connection._encrypt(header.pack(), session) assert isinstance(enc_header, SMB2TransformHeader) enc_header['session_id'] = 100 with pytest.raises(SMBException) as exc: connection._decrypt(enc_header) assert str(exc.value) == "Failed to find valid session 100 for " \ "message decryption" finally: connection.disconnect(True)
def test_decrypt_invalid_flag(self, smb_real): connection = Connection(uuid.uuid4(), smb_real[2], smb_real[3], True) session = Session(connection, smb_real[0], smb_real[1]) connection.connect() try: session.connect() # just get some random message b_header = connection.preauth_integrity_hash_value[-1] header = SMB2HeaderResponse() header.unpack(b_header) enc_header = connection._encrypt(header.pack(), session) assert isinstance(enc_header, SMB2TransformHeader) enc_header['flags'] = 5 with pytest.raises(SMBException) as exc: connection._decrypt(enc_header) assert str(exc.value) == "Expecting flag of 0x0001 but got 5 in " \ "the SMB Transform Header Response" finally: connection.disconnect(True)
def test_verify_mistmatch(self, smb_real): connection = Connection(uuid.uuid4(), smb_real[2], smb_real[3], True) session = Session(connection, smb_real[0], smb_real[1]) connection.connect() try: session.connect() b_header = connection.preauth_integrity_hash_value[-2] header = SMB2HeaderResponse() header.unpack(b_header) # just set some random values for verification failure header['flags'].set_flag(Smb2Flags.SMB2_FLAGS_SIGNED) header['signature'] = b"\xff" * 16 with pytest.raises(SMBException) as exc: connection.verify_signature( header, list(connection.session_table.keys())[0], force=True) assert "Server message signature could not be verified:" in str( exc.value) finally: connection.disconnect(True)
def test_create_message(self): header = SMB2HeaderResponse() header['command'] = Commands.SMB2_SESSION_SETUP header['message_id'] = 1 header['session_id'] = 10 expected = b"\xfe\x53\x4d\x42" \ b"\x40\x00" \ b"\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x01\x00" \ b"\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x01\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x0a\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" actual = header.pack() assert len(header) == 64 assert actual == expected
def _get_header(self, data, status=NtStatus.STATUS_INVALID_PARAMETER): header = SMB2HeaderResponse() header['status'] = status header['message_id'] = 10 header['data'] = data return header