diff --git a/impacket/examples/ntlmrelayx/clients/smbrelayclient.py b/impacket/examples/ntlmrelayx/clients/smbrelayclient.py index 6334f6cd3f..218a191722 100644 --- a/impacket/examples/ntlmrelayx/clients/smbrelayclient.py +++ b/impacket/examples/ntlmrelayx/clients/smbrelayclient.py @@ -34,7 +34,7 @@ from impacket.smb import SMB, NewSMBPacket, SMBCommand, SMBSessionSetupAndX_Extended_Parameters, \ SMBSessionSetupAndX_Extended_Data, SMBSessionSetupAndX_Extended_Response_Data, \ SMBSessionSetupAndX_Extended_Response_Parameters, SMBSessionSetupAndX_Data, SMBSessionSetupAndX_Parameters -from impacket.smb3 import SMB3, SMB2_GLOBAL_CAP_ENCRYPTION, SMB2_DIALECT_WILDCARD, SMB2Negotiate_Response, \ +from impacket.smb3 import SMB3, SMB2_GLOBAL_CAP_ENCRYPTION, SMB2_GLOBAL_CAP_NOTIFICATIONS, SMB2_DIALECT_WILDCARD, SMB2Negotiate_Response, \ SMB2_NEGOTIATE, SMB2Negotiate, SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30, SMB2_GLOBAL_CAP_LEASING, \ SMB3Packet, SMB2_GLOBAL_CAP_LARGE_MTU, SMB2_GLOBAL_CAP_DIRECTORY_LEASING, SMB2_GLOBAL_CAP_MULTI_CHANNEL, \ SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, SMB2_NEGOTIATE_SIGNING_REQUIRED, SMB2Packet,SMB2SessionSetup, SMB2_SESSION_SETUP, STATUS_MORE_PROCESSING_REQUIRED, SMB2SessionSetup_Response @@ -123,6 +123,8 @@ def negotiateSession(self, preferredDialect = None, negSessionResponse = None): self._Connection['SupportsPersistentHandles'] = True if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_ENCRYPTION) == SMB2_GLOBAL_CAP_ENCRYPTION: self._Connection['SupportsEncryption'] = True + if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_NOTIFICATIONS) == SMB2_GLOBAL_CAP_NOTIFICATIONS: + self._Connection['SupportsNotifications'] = True self._Connection['ServerCapabilities'] = negResp['Capabilities'] self._Connection['ServerSecurityMode'] = negResp['SecurityMode'] diff --git a/impacket/smb3.py b/impacket/smb3.py index c4c02d29fe..76a1be1982 100644 --- a/impacket/smb3.py +++ b/impacket/smb3.py @@ -179,6 +179,7 @@ def __init__(self, remote_name, remote_host, my_name=None, host_type=nmb.TYPE_SE 'ServerCapabilities' : 0, # 'ClientSecurityMode' : 0, # 'ServerSecurityMode' : 0, # + 'SupportsNotifications' : False, # Outside the protocol 'ServerIP' : '', # 'ClientName' : '', # @@ -209,6 +210,7 @@ def __init__(self, remote_name, remote_host, my_name=None, host_type=nmb.TYPE_SE 'DecryptionKey' : '', 'SigningKey' : '', 'ApplicationKey' : b'', + 'SupportsNotification' : False, # Outside the protocol 'SessionFlags' : 0, # 'ServerName' : '', # @@ -624,6 +626,8 @@ def negotiateSession(self, preferredDialect = None, negSessionResponse = None): self._Connection['SupportsPersistentHandles'] = True if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_ENCRYPTION) == SMB2_GLOBAL_CAP_ENCRYPTION: self._Connection['SupportsEncryption'] = True + if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_NOTIFICATIONS) == SMB2_GLOBAL_CAP_NOTIFICATIONS: + self._Connection['SupportsNotifications'] = True self._Connection['ServerCapabilities'] = negResp['Capabilities'] self._Connection['ServerSecurityMode'] = negResp['SecurityMode'] @@ -782,6 +786,7 @@ def kerberosLogin(self, user, password, domain = '', lmhash = '', nthash = '', a if ans.isValidAnswer(STATUS_SUCCESS): self._Session['SessionID'] = ans['SessionID'] self._Session['SigningRequired'] = self._Connection['RequireSigning'] + self._Session['SupportsNotification'] = self._Connection['SupportsNotifications'] self._Session['UserCredentials'] = (user, password, domain, lmhash, nthash) self._Session['Connection'] = self._NetBIOSSession.get_socket() @@ -889,6 +894,7 @@ def kerberosLogin(self, user, password, domain = '', lmhash = '', nthash = '', a self._Session['SigningActivated'] = False self._Session['CalculatePreAuthHash'] = False self._Session['PreauthIntegrityHashValue'] = a2b_hex(b'0'*128) + self._Session['SupportsNotification'] = False raise Exception('Unsuccessful Login') @@ -957,6 +963,7 @@ def login(self, user, password, domain = '', lmhash = '', nthash = ''): if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED): self._Session['SessionID'] = ans['SessionID'] self._Session['SigningRequired'] = self._Connection['RequireSigning'] + self._Session['SupportsNotification'] = self._Connection['SupportsNotifications'] self._Session['UserCredentials'] = (user, password, domain, lmhash, nthash) self._Session['Connection'] = self._NetBIOSSession.get_socket() sessionSetupResponse = SMB2SessionSetup_Response(ans['Data']) @@ -1094,6 +1101,7 @@ def login(self, user, password, domain = '', lmhash = '', nthash = ''): self._Session['SigningActivated'] = False self._Session['CalculatePreAuthHash'] = False self._Session['PreauthIntegrityHashValue'] = a2b_hex(b'0'*128) + self._Session['SupportsNotification'] = False raise def connectTree(self, share): @@ -1575,6 +1583,7 @@ def logoff(self): self._Session['SigningKey'] = '' self._Session['SessionKey'] = '' self._Session['SigningActivated'] = False + self._Session['SupportsNotification'] = False return True def queryInfo(self, treeId, fileId, inputBlob = '', infoType = SMB2_0_INFO_FILE, fileInfoClass = SMB2_FILE_STANDARD_INFO, additionalInformation = 0, flags = 0 ): diff --git a/impacket/smb3structs.py b/impacket/smb3structs.py index fffe6c942e..6218155117 100644 --- a/impacket/smb3structs.py +++ b/impacket/smb3structs.py @@ -24,25 +24,26 @@ SMB2_PACKET_SIZE = 64 # SMB Commands -SMB2_NEGOTIATE = 0x0000 # -SMB2_SESSION_SETUP = 0x0001 # -SMB2_LOGOFF = 0x0002 # -SMB2_TREE_CONNECT = 0x0003 # -SMB2_TREE_DISCONNECT = 0x0004 # -SMB2_CREATE = 0x0005 # -SMB2_CLOSE = 0x0006 # -SMB2_FLUSH = 0x0007 # -SMB2_READ = 0x0008 # -SMB2_WRITE = 0x0009 # -SMB2_LOCK = 0x000A # -SMB2_IOCTL = 0x000B # -SMB2_CANCEL = 0x000C # -SMB2_ECHO = 0x000D # -SMB2_QUERY_DIRECTORY = 0x000E # -SMB2_CHANGE_NOTIFY = 0x000F -SMB2_QUERY_INFO = 0x0010 # -SMB2_SET_INFO = 0x0011 -SMB2_OPLOCK_BREAK = 0x0012 +SMB2_NEGOTIATE = 0x0000 +SMB2_SESSION_SETUP = 0x0001 +SMB2_LOGOFF = 0x0002 +SMB2_TREE_CONNECT = 0x0003 +SMB2_TREE_DISCONNECT = 0x0004 +SMB2_CREATE = 0x0005 +SMB2_CLOSE = 0x0006 +SMB2_FLUSH = 0x0007 +SMB2_READ = 0x0008 +SMB2_WRITE = 0x0009 +SMB2_LOCK = 0x000A +SMB2_IOCTL = 0x000B +SMB2_CANCEL = 0x000C +SMB2_ECHO = 0x000D +SMB2_QUERY_DIRECTORY = 0x000E +SMB2_CHANGE_NOTIFY = 0x000F +SMB2_QUERY_INFO = 0x0010 +SMB2_SET_INFO = 0x0011 +SMB2_OPLOCK_BREAK = 0x0012 +SMB2_SERVER_TO_CLIENT_NOTIFICATION = 0x0013 # SMB Flags SMB2_FLAGS_SERVER_TO_REDIR = 0x00000001 @@ -86,6 +87,7 @@ SMB2_GLOBAL_CAP_PERSISTENT_HANDLES = 0x10 SMB2_GLOBAL_CAP_DIRECTORY_LEASING = 0x20 SMB2_GLOBAL_CAP_ENCRYPTION = 0x40 +SMB2_GLOBAL_CAP_NOTIFICATIONS = 0x80 # Dialects SMB2_DIALECT_002 = 0x0202 @@ -444,6 +446,10 @@ SMB2_ENCRYPTION_AES128_CCM = 0x0001 SMB2_ENCRYPTION_AES128_GCM = 0x0002 +# SMB_NOTIFICATION_ID +SmbNotifySessionClosed = 0x00000000 + + # STRUCtures # Represents a SMB2/3 Packet @@ -1576,3 +1582,18 @@ class FileSecInformation(Structure): ('OffsetToSACL','