jborean93 / smbprotocol

Python SMBv2 and v3 Client
MIT License
318 stars 73 forks source link

Error with Nutanix Files #150

Closed fbiesse closed 2 years ago

fbiesse commented 2 years ago

We are using Nutanix Files and it supports SMB protocol V2 and V3.

https://portal.nutanix.com/page/documents/kbs/details?targetId=kA00e000000LMXuCAO

I have the last version of smbprotocol

pip3 show smbprotocol                                                                                                                                                                                1 ↵
Name: smbprotocol
Version: 1.8.0

I tried the following program :

import smbclient
import pprint
import logging
import sys

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
entries = smbclient.scandir(
    '//myserver.com/my_folder',
    search_pattern="*",
    username='username',
    password='password',
    mode='r'
)
for entry in entries:
    pprint.pprint(entry.name)

But I have the following error :

INFO:smbprotocol.connection:Initialising connection, guid: 0b5f27fb-6d58-44d0-ace4-962801aa6498, require_signing: True, server_name: myserver.com, port: 445
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 0b5f27fb-6d58-44d0-ace4-962801aa6498 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'\x18=\xe5R\xf3W1MRW#\xfd[\xab\t=>\x9d\x86*)\\s\x18s`]\xf8\xcc\xa0-\xb0' 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 fs-ged.alptis.local 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 = 0b5f27fb-6d58-44d0-ace4-962801aa6498
    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 = 18 3D E5 52 F3 57 31 4D 52 57 23 FD 5B AB 09 3D 3E 9D 86 2A 29 5C 73 18 73 60 5D F8 CC A0 2D B0

                Raw Hex:
                    01 00 20 00 01 00 18 3D
                    E5 52 F3 57 31 4D 52 57
                    23 FD 5B AB 09 3D 3E 9D
                    86 2A 29 5C 73 18 73 60
                    5D F8 CC A0 2D B0
            padding = 00 00

            Raw Hex:
                01 00 26 00 00 00 00 00
                01 00 20 00 01 00 18 3D
                E5 52 F3 57 31 4D 52 57
                23 FD 5B AB 09 3D 3E 9D
                86 2A 29 5C 73 18 73 60
                5D F8 CC A0 2D B0 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 = 38
            reserved = 0
            data =
            SMB2NetnameNegotiateContextId:
                net_name = fs-ged.alptis.local

                Raw Hex:
                    66 00 73 00 2D 00 67 00
                    65 00 64 00 2E 00 61 00
                    6C 00 70 00 74 00 69 00
                    73 00 2E 00 6C 00 6F 00
                    63 00 61 00 6C 00
            padding = 00 00

            Raw Hex:
                05 00 26 00 00 00 00 00
                66 00 73 00 2D 00 67 00
                65 00 64 00 2E 00 61 00
                6C 00 70 00 74 00 69 00
                73 00 2E 00 6C 00 6F 00
                63 00 61 00 6C 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 0B 5F 27 FB
        6D 58 44 D0 AC E4 96 28
        01 AA 64 98 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 18 3D
        E5 52 F3 57 31 4D 52 57
        23 FD 5B AB 09 3D 3E 9D
        86 2A 29 5C 73 18 73 60
        5D F8 CC A0 2D B0 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 26 00 00 00 00 00
        66 00 73 00 2D 00 67 00
        65 00 64 00 2E 00 61 00
        6C 00 70 00 74 00 69 00
        73 00 2E 00 6C 00 6F 00
        63 00 61 00 6C 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(284) (total 284)
DEBUG:smbprotocol.transport:Socket recv() returned 284 bytes (total 284)
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 11 03 02 00 66 73 2D 67 65 64 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00 00 10 00 00 00 10 00 00 00 10 00 BA 34 0D A0 0F CB D7 01 00 00 00 00 00 00 00 00 80 00 60 00 E0 00 00 00 60 5E 06 06 2B 06 01 05 05 02 A0 54 30 52 A0 24 30 22 06 09 2A 86 48 82 F7 12 01 02 02 06 09 2A 86 48 86 F7 12 01 02 02 06 0A 2B 06 01 04 01 82 37 02 02 0A A3 2A 30 28 A0 26 1B 24 6E 6F 74 5F 64 65 66 69 6E 65 64 5F 69 6E 5F 52 46 43 34 31 37 38 40 70 6C 65 61 73 65 5F 69 67 6E 6F 72 65 01 00 26 00 00 00 00 00 01 00 20 00 01 00 3B 06 3E C1 F3 FA EE 96 1A 2E 05 02 9E 77 1E FD E3 98 4F 62 89 D3 8A 86 1D 89 D8 04 19 0D BE 45 00 00 02 00 04 00 00 00 00 00 01 00 02 00

    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 11 03 02 00
        66 73 2D 67 65 64 00 00
        00 00 00 00 00 00 00 00
        07 00 00 00 00 00 10 00
        00 00 10 00 00 00 10 00
        BA 34 0D A0 0F CB D7 01
        00 00 00 00 00 00 00 00
        80 00 60 00 E0 00 00 00
        60 5E 06 06 2B 06 01 05
        05 02 A0 54 30 52 A0 24
        30 22 06 09 2A 86 48 82
        F7 12 01 02 02 06 09 2A
        86 48 86 F7 12 01 02 02
        06 0A 2B 06 01 04 01 82
        37 02 02 0A A3 2A 30 28
        A0 26 1B 24 6E 6F 74 5F
        64 65 66 69 6E 65 64 5F
        69 6E 5F 52 46 43 34 31
        37 38 40 70 6C 65 61 73
        65 5F 69 67 6E 6F 72 65
        01 00 26 00 00 00 00 00
        01 00 20 00 01 00 3B 06
        3E C1 F3 FA EE 96 1A 2E
        05 02 9E 77 1E FD E3 98
        4F 62 89 D3 8A 86 1D 89
        D8 04 19 0D BE 45 00 00
        02 00 04 00 00 00 00 00
        01 00 02 00
INFO:smbprotocol.connection:Negotiated dialect: (785) SMB_3_1_1
INFO:smbprotocol.connection:Connection require signing: True
INFO:smbprotocol.session:Initialising session with username: username
DEBUG:smbprotocol.session:Decoding SPNEGO token containing supported auth mechanisms
DEBUG:spnego.negotiate:SPNEGO step input: YF4GBisGAQUFAqBUMFKgJDAiBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICCqMqMCigJhskbm90X2RlZmluZWRfaW5fUkZDNDE3OEBwbGVhc2VfaWdub3Jl
DEBUG:spnego.negotiate:SPNEGO step output: YEAGBisGAQUFAqA2MDSgDjAMBgorBgEEAYI3AgIKoiIEIE5UTE1TU1AAAQAAADeCCOAAAAAAIAAAAAAAAAAgAAAA
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(277) (total 277)
DEBUG:smbprotocol.transport:Socket recv() returned 277 bytes (total 277)
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: oYHKMIHHoAMKAQGhDAYKKwYBBAGCNwICCqKBsQSBrk5UTE1TU1AAAgAAAAwADAA4AAAAFYKJ4v67czCPJ4YfAAAAAAAAAABqAGoARAAAAAYBAAAAAAAPQQBMAFAAVABJAFMAAgAMAEEATABQAFQASQBTAAEADABGAFMALQBHAEUARAAEAAIAAAADADAAbgB0AG4AeAAtADEANwAyAC0AMQA2AC0AMwAtADEAMQAwAC0AYQAtAGYAcwB2AG0ABwAIAPyuD6APy9cBAAAAAA==
DEBUG:spnego.negotiate:SPNEGO step output: oYIBuzCCAbegAwoBAaKCAZoEggGWTlRMTVNTUAADAAAAGAAYAFgAAADWANYAcAAAABwAHABGAQAAGAAYAGIBAAAMAAwAegEAABAAEACGAQAAFYKJ4gABBgAAAAAPRzev8RCCcMIi/9fGS2kfUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMcXVn6op5hzDsVC8b1q75UBAQAAAAAAAPyuD6APy9cBzmL8uyqVYHwAAAAAAgAMAEEATABQAFQASQBTAAEADABGAFMALQBHAEUARAAEAAIAAAADADAAbgB0AG4AeAAtADEANwAyAC0AMQA2AC0AMwAtADEAMQAwAC0AYQAtAGYAcwB2AG0ABwAIAPyuD6APy9cBCQAwAEMASQBGAFMALwBmAHMALQBnAGUAZAAuAGEAbABwAHQAaQBzAC4AbABvAGMAYQBsAAYABAACAAAAAAAAAAAAAABsAGkAdgByAGEAaQBzAG8AbgBfAGIAZABvAGMAYQBsAHAAdABpAHMALgBsAG8AYwBhAGwAQQBMAFAAVABJAFMAvTDUSLHK994B92FruRLVd6MSBBABAAAAFWRl3ge4p/kAAAAA
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(73) (total 73)
DEBUG:smbprotocol.transport:Socket recv() returned 73 bytes (total 73)
DEBUG:smbprotocol.transport:Socket recv(4) (total 4)
Traceback (most recent call last):
  File "test.py", line 14, in <module>
    for entry in entries:
  File "/usr/local/lib/python3.6/dist-packages/smbclient/_os.py", line 526, in scandir
    with SMBDirectoryIO(path, share_access='rwd', **kwargs) as fd:
  File "/usr/local/lib/python3.6/dist-packages/smbclient/_io.py", line 374, in __init__
    tree, fd_path = get_smb_tree(path, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/smbclient/_pool.py", line 307, in get_smb_tree
    auth_protocol=auth_protocol)
  File "/usr/local/lib/python3.6/dist-packages/smbclient/_pool.py", line 373, in register_session
    session.connect()
  File "/usr/local/lib/python3.6/dist-packages/smbprotocol/session.py", line 295, in connect
    response = self.connection.receive(request)
  File "/usr/local/lib/python3.6/dist-packages/smbprotocol/connection.py", line 1006, in receive
    raise SMBResponseException(response)
smbprotocol.exceptions.LogonFailure: Received unexpected status from the server: The attempted logon is invalid. This is either due to a bad username or authentication information. (3221225581) STATUS_LOGON_FAILURE: 0xc000006d
INFO:smbprotocol.connection:Disconnecting transport connection
INFO:smbprotocol.transport:Disconnecting DirectTcp socket
DEBUG:smbprotocol.transport:Socket recv() returned 0 bytes (total 4)

When I tyy to mount the same shared folder with cifs-utils in Debian :

apt update
apt -y install cifs-utils
echo -e "username=username\npassword=password" > /tmp/credentials 
mkdir -p /tmp/test
mount -t cifs //myserver.com/my_folder /tmp/test -o credentials=/tmp/credentials,vers=3.0

Everything works fine.

Anyway, With the same user on a windows server share everything also works fine.

I don't know if there's enouth information to debug in the logging information....

Thank for this project that works great, If you could check ang give me a workaround, I'll be very happy.

jborean93 commented 2 years ago

Unfortunately these types of bugs are hard to figure out just from the debug logs alone. The last SPNEGO step output entry contains the NTLM authentication message which is what's being rejected by Nutanix and it's decoded value is

# python -m spnego --format yaml --token base64value
MessageType: SPNEGO NegTokenResp
Data:
  negState: accept-incomplete (1)
  supportedMech:
  responseToken:
    MessageType: AUTHENTICATE_MESSAGE (3)
    Data:
      LmChallengeResponseFields:
        Len: 24
        MaxLen: 24
        BufferOffset: 88
      NtChallengeResponseFields:
        Len: 214
        MaxLen: 214
        BufferOffset: 112
      DomainNameFields:
        Len: 28
        MaxLen: 28
        BufferOffset: 326
      UserNameFields:
        Len: 24
        MaxLen: 24
        BufferOffset: 354
      WorkstationFields:
        Len: 12
        MaxLen: 12
        BufferOffset: 378
      EncryptedRandomSessionKeyFields:
        Len: 16
        MaxLen: 16
        BufferOffset: 390
      NegotiateFlags:
        raw: 3800662549
        flags:
        - NTLMSSP_NEGOTIATE_56 (2147483648)
        - NTLMSSP_NEGOTIATE_KEY_EXCH (1073741824)
        - NTLMSSP_NEGOTIATE_128 (536870912)
        - NTLMSSP_NEGOTIATE_VERSION (33554432)
        - NTLMSSP_NEGOTIATE_TARGET_INFO (8388608)
        - NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY (524288)
        - NTLMSSP_TARGET_TYPE_DOMAIN (65536)
        - NTLMSSP_NEGOTIATE_ALWAYS_SIGN (32768)
        - NTLMSSP_NEGOTIATE_NTLM (512)
        - NTLMSSP_NEGOTIATE_SIGN (16)
        - NTLMSSP_REQUEST_TARGET (4)
        - NTLMSSP_NEGOTIATE_UNICODE (1)
      Version:
        Major: 0
        Minor: 1
        Build: 6
        Reserved: '000000'
        NTLMRevision: 15
      MIC: 4737AFF1108270C222FFD7C64B691F52
      Payload:
        LmChallengeResponse:
          ResponseType: LMv2
          LMProofStr: '00000000000000000000000000000000'
          ChallengeFromClient: '0000000000000000'
        NtChallengeResponse:
          ResponseType: NTLMv2
          NTProofStr: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
          ClientChallenge:
            RespType: 1
            HiRespType: 1
            Reserved1: 0
            Reserved2: 0
            TimeStamp: '2021-10-27T08:50:00.104934Z'
            ChallengeFromClient: CE62FCBB2A95607C
            Reserved3: 0
            AvPairs:
            - AvId: MSV_AV_NB_DOMAIN_NAME (2)
              Value: DOMAIN
            - AvId: MSV_AV_NB_COMPUTER_NAME (1)
              Value: TARGET
            - AvId: MSV_AV_DNS_DOMAIN_NAME (4)
              Value: "\0"
            - AvId: MSV_AV_DNS_COMPUTER_NAME (3)
              Value: target-dns
            - AvId: MSV_AV_TIMESTAMP (7)
              Value: '2021-10-27T08:50:00.104934Z'
            - AvId: MSV_AV_TARGET_NAME (9)
              Value: CIFS/target.domain.local
            - AvId: MSV_AV_FLAGS (6)
              Value:
                raw: 2
                flags:
                - MIC_PROVIDED (2)
            - AvId: MSV_AV_EOL (0)
              Value:
            Reserved4: 0
        DomainName: domain
        UserName: user.local
        Workstation: WORKSTATION
        EncryptedRandomSessionKey: BD30D448B1CAF7DE01F7616BB912D577
      SessionKey: Failed to derive
    RawData: Raw hex of NTLM auth token
  mechListMIC: 01000000156465DE07B8A7F900000000
RawData: Raw hex of token

Nothing is really jumping out at me as overly wrong but obviously there's a problem and the server doesn't like some component.

In these cases what I do is:

fbiesse commented 2 years ago

My bad, it works if I use the full username eg : domain\username

jborean93 commented 2 years ago

Glad you were able to figure it out. I've found that Linux hosts are a bit more touchy when it comes to the username. Typically it's best to always specify the domain or use the UPN format if it's a domain user.