Skip to content

Commit

Permalink
Merge pull request #60 from TurtleARM/smb-drop-ess-ssp
Browse files Browse the repository at this point in the history
fortra#1360 Added flag to drop SSP from Net-NTLMv1 auth
  • Loading branch information
GeisericII authored Jun 3, 2024
2 parents 06ac3a6 + 0241d4a commit f4c6948
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
2 changes: 2 additions & 0 deletions examples/smbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')
parser.add_argument('-ip', '--interface-address', action='store', default='0.0.0.0', help='ip address of listening interface')
parser.add_argument('-port', action='store', default='445', help='TCP port for listening incoming connections (default 445)')
parser.add_argument('-dropssp', action='store_true', default=False, help='Disable NTLM ESS/SSP during negotiation')
parser.add_argument('-smb2support', action='store_true', default=False, help='SMB2 Support (experimental!)')

if len(sys.argv)==1:
Expand Down Expand Up @@ -72,6 +73,7 @@

server.addShare(options.shareName.upper(), options.sharePath, comment)
server.setSMB2Support(options.smb2support)
server.setDropSSP(options.dropssp)

# If a user was specified, let's add it to the credentials for the SMBServer. If no user is specified, anonymous
# connections will be allowed
Expand Down
7 changes: 5 additions & 2 deletions impacket/ntlm.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ def computeResponse(flags, serverChallenge, clientChallenge, serverName, domain,
# If set, the connection SHOULD be anonymous
NTLMSSP_NEGOTIATE_ANONYMOUS = 0x00000800

# Flags used by Responder to drop SSP (little endian)
NTLMSSP_DROP_SSP_STATIC = 0xe2818215

# If set, LM authentication is not allowed and only NT authentication is used.
NTLMSSP_NEGOTIATE_NT_ONLY = 0x00000400

Expand Down Expand Up @@ -270,7 +273,7 @@ class VERSION(Structure):
)

class NTLMAuthNegotiate(Structure):

structure = (
('','"NTLMSSP\x00'),
('message_type','<L=1'),
Expand Down Expand Up @@ -588,7 +591,7 @@ def getNTLMSSPType1(workstation='', domain='', signingRequired = False, use_ntlm
auth['flags'] |= NTLMSSP_NEGOTIATE_TARGET_INFO
auth['flags'] |= NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY | NTLMSSP_NEGOTIATE_UNICODE | \
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56

# We're not adding workstation / domain fields this time. Normally Windows clients don't add such information but,
# we will save the workstation name to be used later.
auth.setWorkstation(workstation)
Expand Down
24 changes: 20 additions & 4 deletions impacket/smbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2510,7 +2510,7 @@ def smbComSessionSetupAndX(connId, smbServer, SMBCommand, recvPacket):
ansFlags |= ntlm.NTLM_NEGOTIATE_OEM

ansFlags |= ntlm.NTLMSSP_NEGOTIATE_VERSION | ntlm.NTLMSSP_NEGOTIATE_TARGET_INFO | ntlm.NTLMSSP_TARGET_TYPE_SERVER | ntlm.NTLMSSP_NEGOTIATE_NTLM | ntlm.NTLMSSP_REQUEST_TARGET

# Generate the AV_PAIRS
av_pairs = ntlm.AV_PAIRS()
# TODO: Put the proper data from SMBSERVER config
Expand All @@ -2520,9 +2520,9 @@ def smbComSessionSetupAndX(connId, smbServer, SMBCommand, recvPacket):
ntlm.NTLMSSP_AV_DNS_DOMAINNAME] = smbServer.getServerDomain().encode('utf-16le')
av_pairs[ntlm.NTLMSSP_AV_TIME] = struct.pack('<q', (
116444736000000000 + calendar.timegm(time.gmtime()) * 10000000))

challengeMessage = ntlm.NTLMAuthChallenge()
challengeMessage['flags'] = ansFlags
challengeMessage['flags'] = (ntlm.NTLMSSP_DROP_SSP_STATIC | 0) if smbServer._SMBSERVER__dropSSP else ansFlags
challengeMessage['domain_len'] = len(smbServer.getServerDomain().encode('utf-16le'))
challengeMessage['domain_max_len'] = challengeMessage['domain_len']
challengeMessage['domain_offset'] = 40 + 16
Expand Down Expand Up @@ -2908,7 +2908,9 @@ def smb2SessionSetup(connId, smbServer, recvPacket):
ansFlags |= ntlm.NTLM_NEGOTIATE_OEM

ansFlags |= ntlm.NTLMSSP_NEGOTIATE_VERSION | ntlm.NTLMSSP_NEGOTIATE_TARGET_INFO | ntlm.NTLMSSP_TARGET_TYPE_SERVER | ntlm.NTLMSSP_NEGOTIATE_NTLM | ntlm.NTLMSSP_REQUEST_TARGET


if smbServer._SMBSERVER__dropSSP:
ansFlags = (ntlm.NTLMSSP_DROP_SSP_STATIC | 0)
# Generate the AV_PAIRS
av_pairs = ntlm.AV_PAIRS()
# TODO: Put the proper data from SMBSERVER config
Expand Down Expand Up @@ -4009,6 +4011,8 @@ def __init__(self, server_address, handler_class=SMBSERVERHandler, config_parser

# SMB2 Support flag = default not active
self.__SMB2Support = False

self.__dropSSP = False

# Allow anonymous logon
self.__anonymousLogon = True
Expand Down Expand Up @@ -4661,6 +4665,10 @@ def processConfigFile(self, configFile=None):
else:
self.__SMB2Support = False

if self.__serverConfig.has_option("global", "DropSSP"):
self.__dropSSP = self.__serverConfig.getboolean("global", "DropSSP")
else:
self.__dropSSP = False

if self.__serverConfig.has_option("global", "anonymous_logon"):
self.__anonymousLogon = self.__serverConfig.getboolean("global", "anonymous_logon")
Expand Down Expand Up @@ -4965,6 +4973,14 @@ def setSMB2Support(self, value):
self.__server.setServerConfig(self.__smbConfig)
self.__server.processConfigFile()

def setDropSSP(self, value):
if value is True:
self.__smbConfig.set("global", "DropSSP", "True")
else:
self.__smbConfig.set("global", "DropSSP", "False")
self.__server.setServerConfig(self.__smbConfig)
self.__server.processConfigFile()

def getAuthCallback(self):
return self.__server.getAuthCallback()

Expand Down

0 comments on commit f4c6948

Please sign in to comment.