Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SMB3 protocol #1642

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion impacket/examples/ntlmrelayx/clients/smbrelayclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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']
Expand Down
9 changes: 9 additions & 0 deletions impacket/smb3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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' : '', #
Expand Down Expand Up @@ -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' : '', #
Expand Down Expand Up @@ -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']
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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')


Expand Down Expand Up @@ -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'])
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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 ):
Expand Down
59 changes: 40 additions & 19 deletions impacket/smb3structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1576,3 +1582,18 @@ class FileSecInformation(Structure):
('OffsetToSACL','<I=0'),
('OffsetToDACL','<I=0'),
)


# SMB2_SERVER_TO_CLIENT_NOTIFICATION
class SMB2_SERVER_TO_CLIENT_NOTIFICATION(Structure):
structure = (
('StructureSize','<H=12'),
('Reserved','<H=0'),
('NotificationType','<I=0'),
('Notification',':'),
)

class SMB2_NOTIFY_SESSION_CLOSED(Structure):
structure = (
('Reserved','<I=0'),
)