def test_create_message(self): message = DataRepresentationFormat() message['floating_point'] = FloatingPointRepresentation.IEEE expected = b"\x10" \ b"\x00" \ b"\x00" \ b"\x00" actual = message.pack() assert len(message) == 4 assert actual == expected
def test_parse_message(self): actual = DataRepresentationFormat() data = b"\x10" \ b"\x00" \ b"\x00" \ b"\x00" data = actual.unpack(data) assert len(actual) == 4 assert data == b"" assert actual['integer_character'].get_value() == \ IntegerCharacterRepresentation.ASCII_LITTLE_ENDIAN assert actual['floating_point'].get_value() == \ FloatingPointRepresentation.IEEE assert actual['reserved1'].get_value() == 0 assert actual['reserved2'].get_value() == 0
def _invoke(self, function_name, opnum, data): req = RequestPDU() req['pfx_flags'].set_flag(PFlags.PFC_FIRST_FRAG) req['pfx_flags'].set_flag(PFlags.PFC_LAST_FRAG) req['packed_drep'] = DataRepresentationFormat() req['call_id'] = self.call_id self.call_id += 1 req['opnum'] = opnum req['stub_data'] = data ioctl_request = SMB2IOCTLRequest() ioctl_request['ctl_code'] = CtlCode.FSCTL_PIPE_TRANSCEIVE ioctl_request['file_id'] = self.handle.file_id ioctl_request['max_output_response'] = 1024 ioctl_request['flags'] = IOCTLFlags.SMB2_0_IOCTL_IS_FSCTL ioctl_request['buffer'] = req session_id = self.tree.session.session_id tree_id = self.tree.tree_connect_id log.info("Sending svcctl RPC request for %s" % function_name) log.debug(str(req)) request = self.tree.session.connection.send(ioctl_request, sid=session_id, tid=tree_id) log.info("Receiving svcctl RPC response for %s" % function_name) resp = self.tree.session.connection.receive(request) ioctl_resp = SMB2IOCTLResponse() ioctl_resp.unpack(resp['data'].get_value()) log.debug(str(ioctl_resp)) pdu_resp = self._parse_pdu(ioctl_resp['buffer'].get_value(), opnum) return pdu_resp
def test_create_message_with_object(self): message = RequestPDU() message['pfx_flags'].set_flag(PFlags.PFC_OBJECT_UUID) message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 4 message['cont_id'] = 1 message['opnum'] = 10 message['object'] = b"\xff" * 16 message['stub_data'] = b"\x01\x02\x03\x04" expected = b"\x05" \ b"\x00" \ b"\x00" \ b"\x80" \ b"\x10\x00\x00\x00" \ b"\x2c\x00" \ b"\x00\x00" \ b"\x04\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x01\x00" \ b"\x0a\x00" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\x01\x02\x03\x04" actual = message.pack() assert len(message) == 44 assert actual == expected
def test_parse_pdu_failure(self): connection = Connection(uuid.uuid4(), "server", 445) session = Session(connection, "user", "password") api = SCMRApi(session) fault_pdu = FaultPDU() fault_pdu['packed_drep'] = DataRepresentationFormat() with pytest.raises(PDUException) as exc: api._parse_pdu(fault_pdu.pack(), 10) assert "Expecting ResponsePDU for opnum 10 response but got: " \ "FaultPDU" in str(exc.value)
def test_parse_pdu_fine(self): connection = Connection(uuid.uuid4(), "server", 445) session = Session(connection, "user", "password") api = SCMRApi(session) response_pdu = ResponsePDU() response_pdu['packed_drep'] = DataRepresentationFormat() response_pdu['stub_data'] = b"\x01\x02\x03\x04" expected = b"\x01\x02\x03\x04" actual = api._parse_pdu(response_pdu.pack(), 10) assert actual == expected
def test_parse_pdu_known(): message = BindNakPDU() message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 4 message['provider_reject_reason'] = BindNakReason.LOCAL_LIMIT_EXCEEDED message['p_protocols'] = [5] data = message.pack() actual = parse_pdu(data) assert isinstance(actual, BindNakPDU) assert len(actual) == 21
def test_create_message(self): message = BindAckPDU() message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 4 message['max_xmit_frag'] = 4280 message['max_recv_frag'] = 4280 message['assoc_group_id'] = 2 message['sec_addr'] = b"\x5C\x70\x69\x70\x65\x5C\x6E\x74" \ b"\x73\x76\x63\x73\x00" syntax = SyntaxIdElement() syntax['uuid'] = uuid.UUID(bytes=b"\xff" * 16) syntax['version'] = 2 res1 = Result() res1['result'] = ContextResult.ACCEPTANCE res1['reason'] = ResultReason.REASON_NOT_SPECIFIED res1['transfer_syntax'] = syntax res2 = Result() res2['result'] = ContextResult.NEGOTIATE_ACK res2['reason'] = ResultReason.LOCAL_LIMIT_EXCEEDED res2['transfer_syntax'] = syntax message['results'] = [res1, res2] expected = b"\x05" \ b"\x00" \ b"\x0c" \ b"\x00" \ b"\x10\x00\x00\x00" \ b"\x5c\x00" \ b"\x00\x00" \ b"\x04\x00\x00\x00" \ b"\xb8\x10" \ b"\xb8\x10" \ b"\x02\x00\x00\x00" \ b"\x0d\x00" \ b"\x5c\x70\x69\x70\x65\x5C\x6e\x74" \ b"\x73\x76\x63\x73\x00" \ b"\x00" \ b"\x02" \ b"\x00" \ b"\x00\x00" \ b"\x00\x00" \ b"\x00\x00" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\x02\x00\x00\x00" \ b"\x03\x00" \ b"\x03\x00" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\x02\x00\x00\x00" actual = message.pack() assert len(message) == 92 assert actual == expected
def test_create_message(self): message = BindPDU() message['pfx_flags'].set_flag(PFlags.PFC_MAYBE) packed_drep = DataRepresentationFormat() packed_drep['integer_character'] = \ IntegerCharacterRepresentation.ASCII_LITTLE_ENDIAN packed_drep['floating_point'] = FloatingPointRepresentation.IEEE message['packed_drep'] = packed_drep message['call_id'] = 4 message['assoc_group_id'] = 2 con_elem = ContextElement() con_elem['context_id'] = 1 syntax = SyntaxIdElement() syntax['uuid'] = uuid.UUID(bytes=b"\xff" * 16) con_elem['abstract_syntax'] = syntax con_elem['transfer_syntaxes'] = [syntax] message['context_elems'] = [con_elem] expected = b"\x05" \ b"\x00" \ b"\x0b" \ b"\x40" \ b"\x10" \ b"\x00" \ b"\x00" \ b"\x00" \ b"\x48\x00" \ b"\x00\x00" \ b"\x04\x00\x00\x00" \ b"\xb8\x10" \ b"\xb8\x10" \ b"\x02\x00\x00\x00" \ b"\x01" \ b"\x00" \ b"\x00\x00" \ b"\x01" \ b"\x00" \ b"\x01" \ b"\x00" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\x00\x00\x00\x00" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\x00\x00\x00\x00" actual = message.pack() assert len(message) == 72 assert actual == expected
def test_create_message(self): message = BindNakPDU() message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 4 message['provider_reject_reason'] = BindNakReason.LOCAL_LIMIT_EXCEEDED message['p_protocols'] = [5] expected = b"\x05" \ b"\x00" \ b"\x0d" \ b"\x00" \ b"\x10\x00\x00\x00" \ b"\x15\x00" \ b"\x00\x00" \ b"\x04\x00\x00\x00" \ b"\x02\x00" \ b"\x01" \ b"\x05\x00" actual = message.pack() assert len(actual) == 21 assert actual == expected
def test_create_message(self): message = RequestPDU() message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 4 message['cont_id'] = 1 message['opnum'] = 10 message['stub_data'] = b"\x01\x02\x03\x04" expected = b"\x05" \ b"\x00" \ b"\x00" \ b"\x00" \ b"\x10\x00\x00\x00" \ b"\x1c\x00" \ b"\x00\x00" \ b"\x04\x00\x00\x00" \ b"\x00\x00\x00\x00" \ b"\x01\x00" \ b"\x0a\x00" \ b"\x01\x02\x03\x04" actual = message.pack() assert len(message) == 28 assert actual == expected
def test_create_message(self): message = ResponsePDU() message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 4 message['alloc_hint'] = 8 message['cont_id'] = 12 message['cancel_count'] = 1 message['stub_data'] = b"\x01\x02\x03\x04" expected = b"\x05" \ b"\x00" \ b"\x02" \ b"\x00" \ b"\x10\x00\x00\x00" \ b"\x1c\x00" \ b"\x00\x00" \ b"\x04\x00\x00\x00" \ b"\x08\x00\x00\x00" \ b"\x0c\x00" \ b"\x01" \ b"\x00" \ b"\x01\x02\x03\x04" actual = message.pack() assert len(message) == 28 assert actual == expected
def test_create_message(self): message = FaultPDU() message['pfx_flags'].set_flag(PFlags.PFC_DID_NOT_EXECUTE) message['pfx_flags'].set_flag(PFlags.PFC_LAST_FRAG) message['packed_drep'] = DataRepresentationFormat() message['call_id'] = 1 message['alloc_hint'] = 32 message['status'] = FaultStatus.NCA_S_FAULT_ADDR_ERROR expected = b"\x05" \ b"\x00" \ b"\x03" \ b"\x22" \ b"\x10\x00\x00\x00" \ b"\x1c\x00" \ b"\x00\x00" \ b"\x01\x00\x00\x00" \ b"\x20\x00\x00\x00" \ b"\x00\x00" \ b"\x00" \ b"\x00" \ b"\x02\x00\x00\x1c" actual = message.pack() assert len(message) == 28 assert actual == expected
def open(self): log.debug("Connecting to SMB Tree %s for SCMR" % self.tree.share_name) self.tree.connect() log.debug("Opening handle to svcctl pipe") self.handle.create( ImpersonationLevel.Impersonation, FilePipePrinterAccessMask.GENERIC_READ | FilePipePrinterAccessMask.GENERIC_WRITE, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE | ShareAccess.FILE_SHARE_DELETE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_NON_DIRECTORY_FILE) # we need to bind svcctl to SCManagerW over DCE/RPC bind = BindPDU() bind['pfx_flags'].set_flag(PFlags.PFC_FIRST_FRAG) bind['pfx_flags'].set_flag(PFlags.PFC_LAST_FRAG) bind['packed_drep'] = DataRepresentationFormat() bind['call_id'] = self.call_id self.call_id += 1 context_ndr = ContextElement() context_ndr['context_id'] = 0 context_ndr['abstract_syntax'] = SyntaxIdElement() context_ndr['abstract_syntax']['uuid'] = \ uuid.UUID("367ABB81-9844-35F1-AD32-98F038001003") context_ndr['abstract_syntax']['version'] = 2 # https://msdn.microsoft.com/en-us/library/cc243843.aspx ndr_syntax = SyntaxIdElement() ndr_syntax['uuid'] = uuid.UUID("8a885d04-1ceb-11c9-9fe8-08002b104860") ndr_syntax['version'] = 2 context_ndr['transfer_syntaxes'] = [ndr_syntax] context_bind = ContextElement() context_bind['context_id'] = 1 context_bind['abstract_syntax'] = SyntaxIdElement() context_bind['abstract_syntax']['uuid'] = \ uuid.UUID("367ABB81-9844-35F1-AD32-98F038001003") context_bind['abstract_syntax']['version'] = 2 # https://msdn.microsoft.com/en-us/library/cc243715.aspx # uuid prefix = 6CB71C2C-9812-4540 # uuid prefix bytes = b'\x2c\x1c\xb7\x6c\x12\x98\x40\x45' # BindTimeFeatureNegotiateBitmask # https://msdn.microsoft.com/en-us/library/cc243884.aspx # SecurityContextMultiplexingSupported = 0x01 # KeepConnectionOnOrphanSupported = 0x02 # version number is 1 bind_syntax = SyntaxIdElement() bind_syntax['uuid'] = b'\x2c\x1c\xb7\x6c\x12\x98\x40\x45' \ b'\x03\x00\x00\x00\x00\x00\x00\x00' bind_syntax['version'] = 1 context_bind['transfer_syntaxes'] = [bind_syntax] bind['context_elems'] = [context_ndr, context_bind] bind_data = bind.pack() log.info("Sending bind request to svcctl") log.debug(str(bind)) self.handle.write(bind_data) log.info("Receiving bind result for svcctl") bind_data = self.handle.read(0, 1024) bind_result = parse_pdu(bind_data) log.debug(str(bind_result)) if not isinstance(bind_result, BindAckPDU): raise PDUException("Expecting BindAckPDU for initial bind result " "but got: %s" % str(bind_result))