jborean93 / smbprotocol

Python SMBv2 and v3 Client
MIT License
320 stars 74 forks source link

SpnegoError when connecting to impacket test server #261

Closed stefan6419846 closed 9 months ago

stefan6419846 commented 9 months ago

I am currently trying to use your package to connect to a SMB share. While it works with a real server, it seems like my testing setup breaks something (or I am using something wrong).

My testing setup involves https://github.com/fortra/impacket/blob/master/examples/smbserver.py, a dummy server. For my tests, I use two different commands: python smbserver.py testshare my_directory/ -debug -port 43793 -smb2support and python smbserver.py testshare my_directory/ -debug -port 43794 -smb2support -username abc -password def, id est a share on port 43793 without credentials and a share with credentials on port 43794.

Let's take the following script and try to run it:

import logging
import smbclient

logging.basicConfig(level=logging.DEBUG)

smbclient.register_session('127.0.0.1', port=43793)
smbclient.register_session('127.0.0.1', username='abc', password='def', port=43794)

I would expect this to run without issues, but it fails for both test shares.

When I try to connect to the share without the password, I get an NTLM error:

INFO:smbprotocol.connection:Initialising connection, guid: c8ca9e5c-43bf-4bed-aa6c-e8994836b1d5, require_signing: True, server_name: 127.0.0.1, port: 43793
INFO:smbprotocol.connection:Setting up transport connection
INFO:smbprotocol.transport:Connecting to DirectTcp socket
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.connection:Starting negotiation with SMB server
INFO:smbprotocol.connection:Negotiating with SMB2 protocol with highest client dialect of: SMB_3_1_1
DEBUG:smbprotocol.connection:Adding client guid c8ca9e5c-43bf-4bed-aa6c-e8994836b1d5 to negotiate request
DEBUG:smbprotocol.connection:Adding client capabilities 69 to negotiate request
DEBUG:smbprotocol.connection:Adding preauth integrity capabilities of hash SHA512 and salt b'\xd6\xef\x19Xdg`\xa1n\xd3\xd1\xff$\xf4\x88_^\xdf\xc4 \xb5*[\xfa\xa0\xbcC\x83K\xab/X' to negotiate request
DEBUG:smbprotocol.connection:Adding encryption capabilities of AES128|256 GCM and AES128|256 CCM to negotiate request
DEBUG:smbprotocol.connection:Adding netname context id of 127.0.0.1 to negotiate request
DEBUG:smbprotocol.connection:Adding signing algorithms AES_GMAC, AES_CMAC, and HMAC_SHA256 to negotiate request
INFO:smbprotocol.connection:Sending SMB2 Negotiate message
DEBUG:smbprotocol.connection:SMB3NegotiateRequest:
    structure_size = 36
    dialect_count = 5
    security_mode = (2) SMB2_NEGOTIATE_SIGNING_REQUIRED
    reserved = 0
    capabilities = (69) SMB2_GLOBAL_CAP_DFS, SMB2_GLOBAL_CAP_ENCRYPTION, SMB2_GLOBAL_CAP_LARGE_MTU
    client_guid = c8ca9e5c-43bf-4bed-aa6c-e8994836b1d5
    negotiate_context_offset = 112
    negotiate_context_count = 4
    reserved2 = 0
    dialects = [
        (514) SMB_2_0_2,
        (528) SMB_2_1_0,
        (768) SMB_3_0_0,
        (770) SMB_3_0_2,
        (785) SMB_3_1_1
    ]
    padding = 00 00
    negotiate_context_list = [
        SMB2NegotiateContextRequest:
            context_type = (1) SMB2_PREAUTH_INTEGRITY_CAPABILITIES
            data_length = 38
            reserved = 0
            data =
            SMB2PreauthIntegrityCapabilities:
                hash_algorithm_count = 1
                salt_length = 32
                hash_algorithms = [
                    (1) SHA_512
                ]
                salt = D6 EF 19 58 64 67 60 A1 6E D3 D1 FF 24 F4 88 5F 5E DF C4 20 B5 2A 5B FA A0 BC 43 83 4B AB 2F 58

                Raw Hex:
                    01 00 20 00 01 00 D6 EF
                    19 58 64 67 60 A1 6E D3
                    D1 FF 24 F4 88 5F 5E DF
                    C4 20 B5 2A 5B FA A0 BC
                    43 83 4B AB 2F 58
            padding = 00 00

            Raw Hex:
                01 00 26 00 00 00 00 00
                01 00 20 00 01 00 D6 EF
                19 58 64 67 60 A1 6E D3
                D1 FF 24 F4 88 5F 5E DF
                C4 20 B5 2A 5B FA A0 BC
                43 83 4B AB 2F 58 00 00,
        SMB2NegotiateContextRequest:
            context_type = (2) SMB2_ENCRYPTION_CAPABILITIES
            data_length = 10
            reserved = 0
            data =
            SMB2EncryptionCapabilities:
                cipher_count = 4
                ciphers = [
                    (2) AES_128_GCM,
                    (1) AES_128_CCM,
                    (4) AES_256_GCM,
                    (3) AES_256_CCM
                ]

                Raw Hex:
                    04 00 02 00 01 00 04 00
                    03 00
            padding = 00 00 00 00 00 00

            Raw Hex:
                02 00 0A 00 00 00 00 00
                04 00 02 00 01 00 04 00
                03 00 00 00 00 00 00 00,
        SMB2NegotiateContextRequest:
            context_type = (5) SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
            data_length = 18
            reserved = 0
            data =
            SMB2NetnameNegotiateContextId:
                net_name = 127.0.0.1

                Raw Hex:
                    31 00 32 00 37 00 2E 00
                    30 00 2E 00 30 00 2E 00
                    31 00
            padding = 00 00 00 00 00 00

            Raw Hex:
                05 00 12 00 00 00 00 00
                31 00 32 00 37 00 2E 00
                30 00 2E 00 30 00 2E 00
                31 00 00 00 00 00 00 00,
        SMB2NegotiateContextRequest:
            context_type = (8) SMB2_SIGNING_CAPABILITIES
            data_length = 8
            reserved = 0
            data =
            SMB2SigningCapabilities:
                signing_algorithm_count = 3
                signing_algorithms = [
                    (2) AES_GMAC,
                    (1) AES_CMAC,
                    (0) HMAC_SHA256
                ]

                Raw Hex:
                    03 00 02 00 01 00 00 00
            padding = 

            Raw Hex:
                08 00 08 00 00 00 00 00
                03 00 02 00 01 00 00 00
    ]

    Raw Hex:
        24 00 05 00 02 00 00 00
        45 00 00 00 C8 CA 9E 5C
        43 BF 4B ED AA 6C E8 99
        48 36 B1 D5 70 00 00 00
        04 00 00 00 02 02 10 02
        00 03 02 03 11 03 00 00
        01 00 26 00 00 00 00 00
        01 00 20 00 01 00 D6 EF
        19 58 64 67 60 A1 6E D3
        D1 FF 24 F4 88 5F 5E DF
        C4 20 B5 2A 5B FA A0 BC
        43 83 4B AB 2F 58 00 00
        02 00 0A 00 00 00 00 00
        04 00 02 00 01 00 04 00
        03 00 00 00 00 00 00 00
        05 00 12 00 00 00 00 00
        31 00 32 00 37 00 2E 00
        30 00 2E 00 30 00 2E 00
        31 00 00 00 00 00 00 00
        08 00 08 00 00 00 00 00
        03 00 02 00 01 00 00 00
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(158) (total 158)
DEBUG:smbprotocol.transport:Socket recv() returned 158 bytes (total 158)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.connection:Receiving SMB2 Negotiate response
DEBUG:smbprotocol.connection:SMB2HeaderResponse:
    protocol_id = FE 53 4D 42
    structure_size = 64
    credit_charge = 0
    status = (0) STATUS_SUCCESS
    command = (0) SMB2_NEGOTIATE
    credit_response = 1
    flags = (1) SMB2_FLAGS_SERVER_TO_REDIR
    next_command = 0
    message_id = 0
    reserved = 0
    tree_id = 0
    session_id = 0
    signature = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    data = 41 00 01 00 02 02 00 00 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 9B 7B 1B 42 50 DA 01 00 9B 7B 1B 42 50 DA 01 80 00 1E 00 00 00 00 00 60 1C 06 06 2B 06 01 05 05 02 A0 12 30 10 A0 0E 30 0C 06 0A 2B 06 01 04 01 82 37 02 02 0A

    Raw Hex:
        FE 53 4D 42 40 00 00 00
        00 00 00 00 00 00 01 00
        01 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        41 00 01 00 02 02 00 00
        41 41 41 41 41 41 41 41
        41 41 41 41 41 41 41 41
        00 00 00 00 00 00 01 00
        00 00 01 00 00 00 01 00
        00 9B 7B 1B 42 50 DA 01
        00 9B 7B 1B 42 50 DA 01
        80 00 1E 00 00 00 00 00
        60 1C 06 06 2B 06 01 05
        05 02 A0 12 30 10 A0 0E
        30 0C 06 0A 2B 06 01 04
        01 82 37 02 02 0A
INFO:smbprotocol.connection:Negotiated dialect: (514) SMB_2_0_2
INFO:smbprotocol.connection:Connection require signing: True
INFO:smbprotocol.session:Initialising session with username: None
DEBUG:smbprotocol.session:Decoding SPNEGO token containing supported auth mechanisms
DEBUG:spnego._negotiate:SPNEGO step input: YBwGBisGAQUFAqASMBCgDjAMBgorBgEEAYI3AgIK
DEBUG:spnego._negotiate:Attempting to create ntlm context when building SPNEGO mech list
DEBUG:spnego._negotiate:Failed to create context for SPNEGO protocol ntlm: SpnegoError (16): Operation not supported or available, Context: Retrieving NTLM store without NTLM_USER_FILE set to a filepath
Traceback (most recent call last):
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/session.py", line 282, in connect
    out_token = context.step(in_token)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_negotiate.py", line 148, in step
    mech_token_in, mech_list_mic, is_spnego = self._step_spnego_input(
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_negotiate.py", line 199, in _step_spnego_input
    mech_list = self._rebuild_context_list(
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_negotiate.py", line 475, in _rebuild_context_list
    raise BadMechanismError(context_msg="Unable to negotiate common mechanism", base_error=last_err)
spnego.exceptions.BadMechanismError: SpnegoError (1): SpnegoError (16): Operation not supported or available, Context: Retrieving NTLM store without NTLM_USER_FILE set to a filepath, Context: Unable to negotiate common mechanism

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/stefan/tmp/impacket/connect.py", line 6, in <module>
    smbclient.register_session('127.0.0.1', port=43793)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbclient/_pool.py", line 422, in register_session
    session.connect()
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/session.py", line 284, in connect
    raise SMBAuthenticationError(f"Failed to authenticate with server: {err}") from err
smbprotocol.exceptions.SMBAuthenticationError: Failed to authenticate with server: SpnegoError (1): SpnegoError (16): Operation not supported or available, Context: Retrieving NTLM store without NTLM_USER_FILE set to a filepath, Context: Unable to negotiate common mechanism
INFO:smbprotocol.connection:Disconnecting transport connection
INFO:smbprotocol.transport:Disconnecting DirectTcp socket
DEBUG:smbprotocol.transport:Socket recv() returned 0 bytes (total 4)

For the password-based share, something seems to be wrong about the signing:

INFO:smbprotocol.connection:Initialising connection, guid: 7635f960-10f8-4b63-baa6-42867d1c43de, require_signing: True, server_name: 127.0.0.1, port: 43794
INFO:smbprotocol.connection:Setting up transport connection
INFO:smbprotocol.transport:Connecting to DirectTcp socket
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.connection:Starting negotiation with SMB server
INFO:smbprotocol.connection:Negotiating with SMB2 protocol with highest client dialect of: SMB_3_1_1
DEBUG:smbprotocol.connection:Adding client guid 7635f960-10f8-4b63-baa6-42867d1c43de to negotiate request
DEBUG:smbprotocol.connection:Adding client capabilities 69 to negotiate request
DEBUG:smbprotocol.connection:Adding preauth integrity capabilities of hash SHA512 and salt b'o$\x18\xa6q\xec\xdd\xd5\xff\xb9Os\xbc\xba\x82\x01\xceD\t@+zA\xaf\xef\xecYD\x07\x9d\xef\x83' to negotiate request
DEBUG:smbprotocol.connection:Adding encryption capabilities of AES128|256 GCM and AES128|256 CCM to negotiate request
DEBUG:smbprotocol.connection:Adding netname context id of 127.0.0.1 to negotiate request
DEBUG:smbprotocol.connection:Adding signing algorithms AES_GMAC, AES_CMAC, and HMAC_SHA256 to negotiate request
INFO:smbprotocol.connection:Sending SMB2 Negotiate message
DEBUG:smbprotocol.connection:SMB3NegotiateRequest:
    structure_size = 36
    dialect_count = 5
    security_mode = (2) SMB2_NEGOTIATE_SIGNING_REQUIRED
    reserved = 0
    capabilities = (69) SMB2_GLOBAL_CAP_DFS, SMB2_GLOBAL_CAP_ENCRYPTION, SMB2_GLOBAL_CAP_LARGE_MTU
    client_guid = 7635f960-10f8-4b63-baa6-42867d1c43de
    negotiate_context_offset = 112
    negotiate_context_count = 4
    reserved2 = 0
    dialects = [
        (514) SMB_2_0_2,
        (528) SMB_2_1_0,
        (768) SMB_3_0_0,
        (770) SMB_3_0_2,
        (785) SMB_3_1_1
    ]
    padding = 00 00
    negotiate_context_list = [
        SMB2NegotiateContextRequest:
            context_type = (1) SMB2_PREAUTH_INTEGRITY_CAPABILITIES
            data_length = 38
            reserved = 0
            data =
            SMB2PreauthIntegrityCapabilities:
                hash_algorithm_count = 1
                salt_length = 32
                hash_algorithms = [
                    (1) SHA_512
                ]
                salt = 6F 24 18 A6 71 EC DD D5 FF B9 4F 73 BC BA 82 01 CE 44 09 40 2B 7A 41 AF EF EC 59 44 07 9D EF 83

                Raw Hex:
                    01 00 20 00 01 00 6F 24
                    18 A6 71 EC DD D5 FF B9
                    4F 73 BC BA 82 01 CE 44
                    09 40 2B 7A 41 AF EF EC
                    59 44 07 9D EF 83
            padding = 00 00

            Raw Hex:
                01 00 26 00 00 00 00 00
                01 00 20 00 01 00 6F 24
                18 A6 71 EC DD D5 FF B9
                4F 73 BC BA 82 01 CE 44
                09 40 2B 7A 41 AF EF EC
                59 44 07 9D EF 83 00 00,
        SMB2NegotiateContextRequest:
            context_type = (2) SMB2_ENCRYPTION_CAPABILITIES
            data_length = 10
            reserved = 0
            data =
            SMB2EncryptionCapabilities:
                cipher_count = 4
                ciphers = [
                    (2) AES_128_GCM,
                    (1) AES_128_CCM,
                    (4) AES_256_GCM,
                    (3) AES_256_CCM
                ]

                Raw Hex:
                    04 00 02 00 01 00 04 00
                    03 00
            padding = 00 00 00 00 00 00

            Raw Hex:
                02 00 0A 00 00 00 00 00
                04 00 02 00 01 00 04 00
                03 00 00 00 00 00 00 00,
        SMB2NegotiateContextRequest:
            context_type = (5) SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
            data_length = 18
            reserved = 0
            data =
            SMB2NetnameNegotiateContextId:
                net_name = 127.0.0.1

                Raw Hex:
                    31 00 32 00 37 00 2E 00
                    30 00 2E 00 30 00 2E 00
                    31 00
            padding = 00 00 00 00 00 00

            Raw Hex:
                05 00 12 00 00 00 00 00
                31 00 32 00 37 00 2E 00
                30 00 2E 00 30 00 2E 00
                31 00 00 00 00 00 00 00,
        SMB2NegotiateContextRequest:
            context_type = (8) SMB2_SIGNING_CAPABILITIES
            data_length = 8
            reserved = 0
            data =
            SMB2SigningCapabilities:
                signing_algorithm_count = 3
                signing_algorithms = [
                    (2) AES_GMAC,
                    (1) AES_CMAC,
                    (0) HMAC_SHA256
                ]

                Raw Hex:
                    03 00 02 00 01 00 00 00
            padding = 

            Raw Hex:
                08 00 08 00 00 00 00 00
                03 00 02 00 01 00 00 00
    ]

    Raw Hex:
        24 00 05 00 02 00 00 00
        45 00 00 00 76 35 F9 60
        10 F8 4B 63 BA A6 42 86
        7D 1C 43 DE 70 00 00 00
        04 00 00 00 02 02 10 02
        00 03 02 03 11 03 00 00
        01 00 26 00 00 00 00 00
        01 00 20 00 01 00 6F 24
        18 A6 71 EC DD D5 FF B9
        4F 73 BC BA 82 01 CE 44
        09 40 2B 7A 41 AF EF EC
        59 44 07 9D EF 83 00 00
        02 00 0A 00 00 00 00 00
        04 00 02 00 01 00 04 00
        03 00 00 00 00 00 00 00
        05 00 12 00 00 00 00 00
        31 00 32 00 37 00 2E 00
        30 00 2E 00 30 00 2E 00
        31 00 00 00 00 00 00 00
        08 00 08 00 00 00 00 00
        03 00 02 00 01 00 00 00
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(158) (total 158)
DEBUG:smbprotocol.transport:Socket recv() returned 158 bytes (total 158)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.connection:Receiving SMB2 Negotiate response
DEBUG:smbprotocol.connection:SMB2HeaderResponse:
    protocol_id = FE 53 4D 42
    structure_size = 64
    credit_charge = 0
    status = (0) STATUS_SUCCESS
    command = (0) SMB2_NEGOTIATE
    credit_response = 1
    flags = (1) SMB2_FLAGS_SERVER_TO_REDIR
    next_command = 0
    message_id = 0
    reserved = 0
    tree_id = 0
    session_id = 0
    signature = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    data = 41 00 01 00 02 02 00 00 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 0B B4 54 42 50 DA 01 00 0B B4 54 42 50 DA 01 80 00 1E 00 00 00 00 00 60 1C 06 06 2B 06 01 05 05 02 A0 12 30 10 A0 0E 30 0C 06 0A 2B 06 01 04 01 82 37 02 02 0A

    Raw Hex:
        FE 53 4D 42 40 00 00 00
        00 00 00 00 00 00 01 00
        01 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00
        41 00 01 00 02 02 00 00
        41 41 41 41 41 41 41 41
        41 41 41 41 41 41 41 41
        00 00 00 00 00 00 01 00
        00 00 01 00 00 00 01 00
        00 0B B4 54 42 50 DA 01
        00 0B B4 54 42 50 DA 01
        80 00 1E 00 00 00 00 00
        60 1C 06 06 2B 06 01 05
        05 02 A0 12 30 10 A0 0E
        30 0C 06 0A 2B 06 01 04
        01 82 37 02 02 0A
INFO:smbprotocol.connection:Negotiated dialect: (514) SMB_2_0_2
INFO:smbprotocol.connection:Connection require signing: True
INFO:smbprotocol.session:Initialising session with username: abc
DEBUG:smbprotocol.session:Decoding SPNEGO token containing supported auth mechanisms
DEBUG:spnego._negotiate:SPNEGO step input: YBwGBisGAQUFAqASMBCgDjAMBgorBgEEAYI3AgIK
DEBUG:spnego._negotiate:Attempting to create ntlm context when building SPNEGO mech list
DEBUG:spnego._negotiate:SPNEGO step output: YEgGBisGAQUFAqA+MDygDjAMBgorBgEEAYI3AgIKoioEKE5UTE1TU1AAAQAAADeCCOIAAAAAKAAAAAAAAAAoAAAAAAoCAAAAAA8=
INFO:smbprotocol.session:Sending SMB2_SESSION_SETUP request message
INFO:smbprotocol.session:Receiving SMB2_SESSION_SETUP response message
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(271) (total 271)
DEBUG:smbprotocol.transport:Socket recv() returned 271 bytes (total 271)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.session:More processing is required for SMB2_SESSION_SETUP
DEBUG:spnego._negotiate:SPNEGO step input: oYHEMIHBoAMKAQGhDAYKKwYBBAGCNwICCqKBqwSBqE5UTE1TU1AAAgAAABAAEAA4AAAABwKK4qqqqqqqqqqqAAAAAAAAAABgAGAASAAAAP//////////VwBBAFQAcQBnAGgAWgBiAAEAEABWAGoAegBuAHoAcwBFAE0AAwAQAFYAagB6AG4AegBzAEUATQACABAAVwBBAFQAcQBnAGgAWgBiAAQAEABXAEEAVABxAGcAaABaAGIABwAIAAALtFRCUNoBAAAAAA==
Traceback (most recent call last):
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/session.py", line 282, in connect
    out_token = context.step(in_token)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_negotiate.py", line 161, in step
    out_mic = self._step_spnego_mic(in_mic=mech_list_mic)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_negotiate.py", line 304, in _step_spnego_mic
    out_mic = self.sign(pack_mech_type_list(self._mech_list))
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_negotiate.py", line 389, in sign
    return self._context.sign(data, qop=qop)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_ntlm.py", line 841, in sign
    return sign(
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/spnego/_ntlm_raw/security.py", line 69, in sign
    raise OperationNotAvailableError(context_msg="Signing without integrity.")
spnego.exceptions.OperationNotAvailableError: SpnegoError (16): Operation not supported or available, Context: Signing without integrity.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/stefan/tmp/impacket/connect.py", line 7, in <module>
    smbclient.register_session('127.0.0.1', username='abc', password='def', port=43794)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbclient/_pool.py", line 422, in register_session
    session.connect()
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/session.py", line 284, in connect
    raise SMBAuthenticationError(f"Failed to authenticate with server: {err}") from err
smbprotocol.exceptions.SMBAuthenticationError: Failed to authenticate with server: SpnegoError (16): Operation not supported or available, Context: Signing without integrity.
INFO:smbprotocol.connection:Disconnecting transport connection
INFO:smbprotocol.transport:Disconnecting DirectTcp socket
DEBUG:smbprotocol.transport:Socket recv() returned 0 bytes (total 4)

Am I doing something wrong here or is this an issue with the server-side implementation of impacket? The same approach works correctly when using a "real" server, but I would like to avoid this for testing purposes if possible.

jborean93 commented 9 months ago

When I try to connect to the share without the password, I get an NTLM error:

This is expected, the error message is a result of trying to authenticate without any credentials specified. The last fallback attempt of the spnego library is to check for the precence of the NTLM_USER_FILE env var and the file it might be pointing to. While smbprotocol can theoretically work with guest authentication by providing any username and any password it's not exactly the same as anonymous auth without any password.

For the password-based share, something seems to be wrong about the signing:

This one is interesting, I'll have to try and set up a test environment to dig deeper. Looks like what is happening is the NTLM session negotiated with the Impacket server was not negotiated with signing support. Signing is mandatory with Negotiate auth with NTLM because it needs to use the signing context to generate the mechListMIC in the final authentication token. Signing, and confidentiality, is also required in SMB after authentication to perform the signing and encryption respectively used by NTLM. What I would try is:

Unfortunately I don't think there is much we can do to avoid this, the server seems to only offer basic security support (no signing or encryption) so you need to go out of your way to opt out of that from the client side as it is the insecure path.

stefan6419846 commented 9 months ago

Thanks for the explanations. Setting auth_protocol='ntlm' did not fail immediately any more, but gets stuck in an infinite loop in an attempt which looks like trying to setup the session:

[...]
INFO:smbprotocol.session:Sending SMB2_SESSION_SETUP request message
INFO:smbprotocol.session:Receiving SMB2_SESSION_SETUP response message
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(240) (total 240)
DEBUG:smbprotocol.transport:Socket recv() returned 240 bytes (total 240)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.session:More processing is required for SMB2_SESSION_SETUP
DEBUG:spnego._ntlm:NTLM step input: TlRMTVNTUAACAAAAEAAQADgAAAAHAoriqqqqqqqqqqoAAAAAAAAAAGAAYABIAAAA//////////94AEgATQBUAEQAQgBJAFYAAQAQAEEAVwB2AFAASQBJAEIAdwADABAAQQBXAHYAUABJAEkAQgB3AAIAEAB4AEgATQBUAEQAQgBJAFYABAAQAHgASABNAFQARABCAEkAVgAHAAgAANndrsZR2gEAAAAA
DEBUG:spnego._ntlm:NTLM step output: TlRMTVNTUAABAAAAN4II4gAAAAAoAAAAAAAAACgAAAAACgIAAAAADw==
INFO:smbprotocol.session:Sending SMB2_SESSION_SETUP request message
INFO:smbprotocol.session:Receiving SMB2_SESSION_SETUP response message
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(240) (total 240)
DEBUG:smbprotocol.transport:Socket recv() returned 240 bytes (total 240)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.session:More processing is required for SMB2_SESSION_SETUP
DEBUG:spnego._ntlm:NTLM step input: TlRMTVNTUAACAAAAEAAQADgAAAAHAoriqqqqqqqqqqoAAAAAAAAAAGAAYABIAAAA//////////94AEgATQBUAEQAQgBJAFYAAQAQAEEAVwB2AFAASQBJAEIAdwADABAAQQBXAHYAUABJAEkAQgB3AAIAEAB4AEgATQBUAEQAQgBJAFYABAAQAHgASABNAFQARABCAEkAVgAHAAgAANndrsZR2gEAAAAA
DEBUG:spnego._ntlm:NTLM step output: TlRMTVNTUAABAAAAN4II4gAAAAAoAAAAAAAAACgAAAAACgIAAAAADw==
INFO:smbprotocol.session:Sending SMB2_SESSION_SETUP request message
INFO:smbprotocol.session:Receiving SMB2_SESSION_SETUP response message
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(240) (total 240)
DEBUG:smbprotocol.transport:Socket recv() returned 240 bytes (total 240)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.session:More processing is required for SMB2_SESSION_SETUP
DEBUG:spnego._ntlm:NTLM step input: TlRMTVNTUAACAAAAEAAQADgAAAAHAoriqqqqqqqqqqoAAAAAAAAAAGAAYABIAAAA//////////94AEgATQBUAEQAQgBJAFYAAQAQAEEAVwB2AFAASQBJAEIAdwADABAAQQBXAHYAUABJAEkAQgB3AAIAEAB4AEgATQBUAEQAQgBJAFYABAAQAHgASABNAFQARABCAEkAVgAHAAgAANndrsZR2gEAAAAA
DEBUG:spnego._ntlm:NTLM step output: TlRMTVNTUAABAAAAN4II4gAAAAAoAAAAAAAAACgAAAAACgIAAAAADw==
INFO:smbprotocol.session:Sending SMB2_SESSION_SETUP request message
INFO:smbprotocol.session:Receiving SMB2_SESSION_SETUP response message
DEBUG:smbprotocol.transport:Socket recv() returned 4 bytes (total 4)
DEBUG:smbprotocol.transport:Socket recv(240) (total 240)
DEBUG:smbprotocol.transport:Socket recv() returned 240 bytes (total 240)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
INFO:smbprotocol.session:More processing is required for SMB2_SESSION_SETUP
DEBUG:spnego._ntlm:NTLM step input: TlRMTVNTUAACAAAAEAAQADgAAAAHAoriqqqqqqqqqqoAAAAAAAAAAGAAYABIAAAA//////////94AEgATQBUAEQAQgBJAFYAAQAQAEEAVwB2AFAASQBJAEIAdwADABAAQQBXAHYAUABJAEkAQgB3AAIAEAB4AEgATQBUAEQAQgBJAFYABAAQAHgASABNAFQARABCAEkAVgAHAAgAANndrsZR2gEAAAAA
DEBUG:spnego._ntlm:NTLM step output: TlRMTVNTUAABAAAAN4II4gAAAAAoAAAAAAAAACgAAAAACgIAAAAADw==
INFO:smbprotocol.session:Sending SMB2_SESSION_SETUP request message
^CTraceback (most recent call last):
  File "/home/stefan/tmp/impacket/connect.py", line 7, in <module>
    smbclient.register_session('127.0.0.1', username='abc', password='def', port=43794, auth_protocol='ntlm')  # , encrypt=False, require_signing=False)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbclient/_pool.py", line 422, in register_session
    session.connect()
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/session.py", line 295, in connect
    request = self.connection.send(session_setup, sid=self.session_id, credit_request=64)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 967, in send
    return self._send(
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 1268, in _send
    b_header = header.pack() + padding
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/structure.py", line 113, in pack
    field_data = field.pack()
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/structure.py", line 175, in pack
    value = self._get_calculated_value(self.value)
  File "/home/stefan/tmp/impacket/venv/lib/python3.10/site-packages/smbprotocol/structure.py", line 265, in _get_calculated_value
    def _get_calculated_value(self, value):
KeyboardInterrupt
INFO:smbprotocol.connection:Disconnecting transport connection
INFO:smbprotocol.transport:Disconnecting DirectTcp socket
DEBUG:smbprotocol.transport:Socket recv() returned 0 bytes (total 4)
jborean93 commented 9 months ago

Ok I see what is happening, the SMB server is set to return a response buffer on a successful response as per

https://github.com/fortra/impacket/blob/82267d842c405c2315bff9a9e730c81102c139d2/impacket/smbserver.py#L3003-L3007

This is not expected for NTLM normally where the server doesn't response with a token but because our loop continues to run if there is input it just loops back to the first message exchange

https://github.com/jborean93/smbprotocol/blob/ba9e9bc1ce56cf5a212e6e3b346928438692b5d0/src/smbprotocol/session.py#L280

I believe we should be only continuing the loop when the context isn't complete but I'll need to verify that is still the case for other authentication types.

Even when manually patching that there are all sorts of errors when it comes to signature verification. Having it enabled results in a signature mismatch and having it disabled results in another strange error about a missing session which I was not expecting. Ultimately it seems like the impacket SMB 2 server is quite experimental. I can fix the bad looping mechanism in my code but they should look at fixing up the signature problems that don't occur on other SMB servers.

stefan6419846 commented 9 months ago

Thanks for the explanations. impacket marks support for SMBv2 and SMBv3 as experimental, but generally considers it usable. It seems like the only short-term conclusion is that it means too much hassle to fix the recent SMB protocol versions within impacket.

I will leave this issue open for you to complete analysis on the infinite loop with "bad" server-side behavior.

jborean93 commented 9 months ago

Thanks for your understanding, I've merged https://github.com/jborean93/smbprotocol/pull/267 which removes the endless loop issue. While it won't fix the impacket server interoperability it at least won't hang indefinitely.