Codebase list pysmb / 886d3fd
Fix bug in SMB message signing due to missing NTLM_NegotiateSign flag in the NTLM session negotiation message. The missing flag causes subsequent SMB operation requests with Windows to pass, but fails with Samba services. Michael Teo 3 years ago
4 changed file(s) with 44 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
375375 self.log.info('Performing NTLMv1 authentication (on SMB2) with server challenge "%s"', binascii.hexlify(server_challenge))
376376 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
377377
378 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
379 nt_challenge_response,
380 lm_challenge_response,
381 session_key,
382 self.username,
383 self.domain,
384 self.my_name)
378 ntlm_data, session_signing_key = ntlm.generateAuthenticateMessage(server_flags,
379 nt_challenge_response,
380 lm_challenge_response,
381 session_key,
382 self.username,
383 self.domain,
384 self.my_name)
385385
386386 if self.log.isEnabledFor(logging.DEBUG):
387387 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
401401
402402 if self.is_signing_active:
403403 self.log.info("SMB signing activated. All SMB messages will be signed.")
404 self.signing_session_key = session_key
404 self.signing_session_key = session_signing_key
405405 if self.log.isEnabledFor(logging.DEBUG):
406406 self.log.info("SMB signing key is %s", binascii.hexlify(self.signing_session_key))
407407
19071907 self.log.info('Performing NTLMv1 authentication (with extended security) with server challenge "%s"', binascii.hexlify(server_challenge))
19081908 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
19091909
1910 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
1911 nt_challenge_response,
1912 lm_challenge_response,
1913 session_key,
1914 self.username,
1915 self.domain,
1916 self.my_name)
1910 ntlm_data, session_signing_key = ntlm.generateAuthenticateMessage(server_flags,
1911 nt_challenge_response,
1912 lm_challenge_response,
1913 session_key,
1914 self.username,
1915 self.domain,
1916 self.my_name)
19171917
19181918 if self.log.isEnabledFor(logging.DEBUG):
19191919 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
19331933
19341934 if self.is_signing_active:
19351935 self.log.info("SMB signing activated. All SMB messages will be signed.")
1936 self.signing_session_key = session_key
1936 self.signing_session_key = session_signing_key
19371937 if self.capabilities & CAP_EXTENDED_SECURITY:
19381938 self.signing_challenge_response = None
19391939 else:
5858
5959 NTLM_FLAGS = NTLM_NegotiateUnicode | \
6060 NTLM_RequestTarget | \
61 NTLM_NegotiateSign | \
6162 NTLM_NegotiateNTLM | \
6263 NTLM_NegotiateAlwaysSign | \
6364 NTLM_NegotiateExtendedSecurity | \
6465 NTLM_NegotiateTargetInfo | \
6566 NTLM_NegotiateVersion | \
6667 NTLM_Negotiate128 | \
67 NTLM_NegotiateKeyExchange | \
68 NTLM_Negotiate56
68 NTLM_NegotiateKeyExchange
6969
7070 def generateNegotiateMessage():
7171 """
9292
9393 # [MS-NLMP]: 3.1.5.1.2
9494 # http://grutz.jingojango.net/exploits/davenport-ntlm.html
95 session_key = request_session_key
95 session_key = session_signing_key = request_session_key
9696 if challenge_flags & NTLM_NegotiateKeyExchange:
9797 cipher = ARC4.new(request_session_key)
98 session_key = cipher.encrypt("".join([ random.choice(string.digits+string.ascii_letters) for _ in range(16) ]).encode('ascii'))
98 session_signing_key = "".join([ random.choice(string.digits+string.ascii_letters) for _ in range(16) ]).encode('ascii')
99 session_key = cipher.encrypt(session_signing_key)
99100
100101 lm_response_length = len(lm_response)
101102 lm_response_offset = FORMAT_SIZE
132133 session_key_length, session_key_length, session_key_offset,
133134 auth_flags)
134135
135 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key
136 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key, session_signing_key
136137
137138
138139 def decodeChallengeMessage(ntlm_data):
370370 self.log.info('Performing NTLMv1 authentication (on SMB2) with server challenge "%s"', binascii.hexlify(server_challenge))
371371 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
372372
373 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
374 nt_challenge_response,
375 lm_challenge_response,
376 session_key,
377 self.username,
378 self.domain,
379 self.my_name)
373 ntlm_data, session_signing_key = ntlm.generateAuthenticateMessage(server_flags,
374 nt_challenge_response,
375 lm_challenge_response,
376 session_key,
377 self.username,
378 self.domain,
379 self.my_name)
380380
381381 if self.log.isEnabledFor(logging.DEBUG):
382382 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
396396
397397 if self.is_signing_active:
398398 self.log.info("SMB signing activated. All SMB messages will be signed.")
399 self.signing_session_key = session_key
399 self.signing_session_key = session_signing_key
400400 if self.log.isEnabledFor(logging.DEBUG):
401401 self.log.info("SMB signing key is %s", binascii.hexlify(self.signing_session_key))
402402
19041904 self.log.info('Performing NTLMv1 authentication (with extended security) with server challenge "%s"', binascii.hexlify(server_challenge))
19051905 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
19061906
1907 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
1908 nt_challenge_response,
1909 lm_challenge_response,
1910 session_key,
1911 self.username,
1912 self.domain,
1913 self.my_name)
1907 ntlm_data, signing_session_key = ntlm.generateAuthenticateMessage(server_flags,
1908 nt_challenge_response,
1909 lm_challenge_response,
1910 session_key,
1911 self.username,
1912 self.domain,
1913 self.my_name)
19141914
19151915 if self.log.isEnabledFor(logging.DEBUG):
19161916 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
19301930
19311931 if self.is_signing_active:
19321932 self.log.info("SMB signing activated. All SMB messages will be signed.")
1933 self.signing_session_key = session_key
1933 self.signing_session_key = signing_session_key
19341934 if self.capabilities & CAP_EXTENDED_SECURITY:
19351935 self.signing_challenge_response = None
19361936 else:
5858
5959 NTLM_FLAGS = NTLM_NegotiateUnicode | \
6060 NTLM_RequestTarget | \
61 NTLM_NegotiateSign | \
6162 NTLM_NegotiateNTLM | \
6263 NTLM_NegotiateAlwaysSign | \
6364 NTLM_NegotiateExtendedSecurity | \
6465 NTLM_NegotiateTargetInfo | \
6566 NTLM_NegotiateVersion | \
6667 NTLM_Negotiate128 | \
67 NTLM_NegotiateKeyExchange | \
68 NTLM_Negotiate56
68 NTLM_NegotiateKeyExchange
6969
7070 def generateNegotiateMessage():
7171 """
9292
9393 # [MS-NLMP]: 3.1.5.1.2
9494 # http://grutz.jingojango.net/exploits/davenport-ntlm.html
95 session_key = request_session_key
95 session_key = session_signing_key = request_session_key
9696 if challenge_flags & NTLM_NegotiateKeyExchange:
9797 cipher = ARC4.new(request_session_key)
98 session_key = cipher.encrypt("".join([ random.choice(string.digits+string.ascii_letters) for _ in range(16) ]).encode('ascii'))
98 session_signing_key = "".join([ random.choice(string.digits+string.ascii_letters) for _ in range(16) ]).encode('ascii')
99 session_key = cipher.encrypt(session_signing_key)
99100
100101 lm_response_length = len(lm_response)
101102 lm_response_offset = FORMAT_SIZE
132133 session_key_length, session_key_length, session_key_offset,
133134 auth_flags)
134135
135 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key
136 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key, session_signing_key
136137
137138
138139 def decodeChallengeMessage(ntlm_data):