Exemplo n.º 1
0
    def _verify_dialect_negotiate(self):
        log_header = "Session: %s, Tree: %s" \
                     % (self.session.username, self.share_name)
        log.info("%s - Running secure negotiate process" % log_header)
        ioctl_request = SMB2IOCTLRequest()
        ioctl_request['ctl_code'] = \
            CtlCode.FSCTL_VALIDATE_NEGOTIATE_INFO
        ioctl_request['file_id'] = b"\xff" * 16

        val_neg = SMB2ValidateNegotiateInfoRequest()
        val_neg['capabilities'] = \
            self.session.connection.client_capabilities
        val_neg['guid'] = self.session.connection.client_guid
        val_neg['security_mode'] = \
            self.session.connection.client_security_mode
        val_neg['dialects'] = \
            self.session.connection.negotiated_dialects

        ioctl_request['buffer'] = val_neg
        ioctl_request['max_output_response'] = len(val_neg)
        ioctl_request['flags'] = IOCTLFlags.SMB2_0_IOCTL_IS_FSCTL
        log.info("%s - Sending Secure Negotiate Validation message"
                 % log_header)
        log.debug(ioctl_request)
        request = self.session.connection.send(ioctl_request,
                                               sid=self.session.session_id,
                                               tid=self.tree_connect_id)

        log.info("%s - Receiving secure negotiation response" % log_header)
        response = self.session.connection.receive(request)
        ioctl_resp = SMB2IOCTLResponse()
        ioctl_resp.unpack(response['data'].get_value())
        log.debug(ioctl_resp)

        log.info("%s - Unpacking secure negotiate response info" % log_header)
        val_resp = SMB2ValidateNegotiateInfoResponse()
        val_resp.unpack(ioctl_resp['buffer'].get_value())
        log.debug(val_resp)

        self._verify("server capabilities",
                     val_resp['capabilities'].get_value(),
                     self.session.connection.server_capabilities.get_value())
        self._verify("server guid",
                     val_resp['guid'].get_value(),
                     self.session.connection.server_guid)
        self._verify("server security mode",
                     val_resp['security_mode'].get_value(),
                     self.session.connection.server_security_mode)
        self._verify("server dialect",
                     val_resp['dialect'].get_value(),
                     self.session.connection.dialect)
        log.info("Session: %d, Tree: %d - Secure negotiate complete"
                 % (self.session.session_id, self.tree_connect_id))
Exemplo n.º 2
0
 def test_create_message(self):
     message = SMB2ValidateNegotiateInfoRequest()
     message['capabilities'] = 8
     message['guid'] = b"\x11" * 16
     message['security_mode'] = 1
     message['dialect_count'] = 2
     message['dialects'] = [Dialects.SMB_2_0_2, Dialects.SMB_2_1_0]
     expected = b"\x08\x00\x00\x00" \
                b"\x11\x11\x11\x11\x11\x11\x11\x11" \
                b"\x11\x11\x11\x11\x11\x11\x11\x11" \
                b"\x01\x00" \
                b"\x02\x00" \
                b"\x02\x02\x10\x02"
     actual = message.pack()
     assert len(message) == 28
     assert actual == expected
Exemplo n.º 3
0
 def test_parse_message(self):
     actual = SMB2ValidateNegotiateInfoRequest()
     data = b"\x08\x00\x00\x00" \
            b"\x11\x11\x11\x11\x11\x11\x11\x11" \
            b"\x11\x11\x11\x11\x11\x11\x11\x11" \
            b"\x01\x00" \
            b"\x02\x00" \
            b"\x02\x02\x10\x02"
     actual.unpack(data)
     assert len(actual) == 28
     assert actual['capabilities'].get_value() == 8
     assert actual['guid'].get_value() == uuid.UUID(bytes=b"\x11" * 16)
     assert actual['security_mode'].get_value() == 1
     assert actual['dialect_count'].get_value() == 2
     assert actual['dialects'][0] == 514
     assert actual['dialects'][1] == 528
     assert len(actual['dialects'].get_value()) == 2
Exemplo n.º 4
0
    def _verify_dialect_negotiate(self):
        log_header = "Session: %s, Tree: %s" \
                     % (self.session.username, self.share_name)
        log.info("%s - Running secure negotiate process" % log_header)

        if not self.session.signing_key:
            # This will only happen if we authenticated with the guest or anonymous user.
            raise SMBException(
                'Cannot verify negotiate information without a session signing key. Authenticate with '
                'a non-guest or anonymous account or set require_secure_negotiate=False to disable the '
                'negotiation info verification checks.')

        dialect = self.session.connection.dialect
        if dialect >= Dialects.SMB_3_1_1:
            # SMB 3.1.1+ uses the negotiation info to generate the signing key so doesn't need this extra exchange.
            return

        ioctl_request = SMB2IOCTLRequest()
        ioctl_request['ctl_code'] = \
            CtlCode.FSCTL_VALIDATE_NEGOTIATE_INFO
        ioctl_request['file_id'] = b"\xff" * 16

        val_neg = SMB2ValidateNegotiateInfoRequest()
        val_neg['capabilities'] = \
            self.session.connection.client_capabilities
        val_neg['guid'] = self.session.connection.client_guid
        val_neg['security_mode'] = \
            self.session.connection.client_security_mode
        val_neg['dialects'] = \
            self.session.connection.negotiated_dialects

        ioctl_request['buffer'] = val_neg
        ioctl_request['max_output_response'] = len(val_neg)
        ioctl_request['flags'] = IOCTLFlags.SMB2_0_IOCTL_IS_FSCTL
        log.info("%s - Sending Secure Negotiate Validation message" %
                 log_header)
        log.debug(ioctl_request)
        request = self.session.connection.send(ioctl_request,
                                               sid=self.session.session_id,
                                               tid=self.tree_connect_id,
                                               force_signature=True)

        log.info("%s - Receiving secure negotiation response" % log_header)
        try:
            response = self.session.connection.receive(request)

        except (FileClosed, InvalidDeviceRequest, NotSupported) as e:
            # https://docs.microsoft.com/en-us/archive/blogs/openspecification/smb3-secure-dialect-negotiation
            # Older dialects may respond with these exceptions, this is expected and we only want to fail if
            # they are not signed. Check that header signature was signed, fail if it wasn't. The signature, if
            # present, would have been verified when the connection received the data.
            if e.header['signature'].get_value() == b'\x00' * 16:
                raise

            return

        # If we received an actual response we want to validate the info provided matches with what was negotiated.
        ioctl_resp = SMB2IOCTLResponse()
        ioctl_resp.unpack(response['data'].get_value())
        log.debug(ioctl_resp)

        log.info("%s - Unpacking secure negotiate response info" % log_header)
        val_resp = SMB2ValidateNegotiateInfoResponse()
        val_resp.unpack(ioctl_resp['buffer'].get_value())
        log.debug(val_resp)

        self._verify("server capabilities",
                     val_resp['capabilities'].get_value(),
                     self.session.connection.server_capabilities.get_value())
        self._verify("server guid", val_resp['guid'].get_value(),
                     self.session.connection.server_guid)
        self._verify("server security mode",
                     val_resp['security_mode'].get_value(),
                     self.session.connection.server_security_mode)
        self._verify("server dialect", val_resp['dialect'].get_value(),
                     self.session.connection.dialect)
        log.info("Session: %d, Tree: %d - Secure negotiate complete" %
                 (self.session.session_id, self.tree_connect_id))