예제 #1
0
 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
예제 #2
0
 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
예제 #3
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
예제 #4
0
 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
예제 #5
0
 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)
예제 #6
0
 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
예제 #7
0
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
예제 #8
0
    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
예제 #9
0
 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
예제 #10
0
 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
예제 #11
0
 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
예제 #12
0
 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
예제 #13
0
 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
예제 #14
0
    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))