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

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

## 396 statements

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# Impacket - Collection of Python classes for working with network protocols.

2#

3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved.

4#

5# This software is provided under a slightly modified version

6# of the Apache Software License. See the accompanying LICENSE file

7# for more information.

8#

9# Description:

10# A Socks Proxy for the SMB Protocol

11#

12# A simple SOCKS server that proxy connection to relayed connections

13#

14# Author:

15# Alberto Solino (@agsolino)

16#

17 import calendar

18 import time

19 import random

20 import string

21 from struct import unpack

22 from binascii import hexlify

23 from six import b

24

25 from impacket import LOG

26 from impacket.examples.ntlmrelayx.servers.socksserver import SocksRelay

27 from impacket.nmb import NetBIOSTCPSession

28 from impacket.nt_errors import STATUS_MORE_PROCESSING_REQUIRED, STATUS_SUCCESS, STATUS_ACCESS_DENIED

29 from impacket.ntlm import NTLMAuthChallengeResponse, NTLMSSP_NEGOTIATE_SIGN

30 from 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

34 from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp, ASN1_AID

35 from 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

38 from impacket.spnego import MechTypes, ASN1_SUPPORTED_MECH

39 from impacket.smb import SMB_DIALECT

40 from impacket.smbserver import getFileTime

41

42# Besides using this base class you need to define one global variable when

43# writing a plugin:

44 PLUGIN_CLASS = "SMBSocksRelay"

45

46 class SMBSocksRelay(SocksRelay):

47 PLUGIN_NAME = 'SMB Socks Plugin'

48 PLUGIN_SCHEME = 'SMB'

49

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

55

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

64

65 @staticmethod

66 def getProtocolPort():

67 return 445

68

69 def initConnection(self):

70 # An incoming SMB Connection. Nice

71 self.__NBSession = NetBIOSTCPSession('', 'HOST', self.targetHost, sess_port=self.targetPort, sock=self.socksSocket)

72

73 def skipAuthentication(self):

74 packet, smbCommand = self.getSMBPacket()

75

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()

86

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()

97

98 if packet['Command'] == SMB2_SESSION_SETUP:

99 self.clientConnection, self.username = self.processSessionSetup(packet)

100 if self.clientConnection is None:

101 return False

102

103 return True

104

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()

111

112 if len(data) == 0:

113 break

114

115 if self.isSMB2 is False:

116 packet = NewSMBPacket(data=data)

117

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)

125

126 # 3. Get the target's answer

127 data = self.clientConnection.getSMBServer()._sess.recv_packet().get_trailer()

128

129 packet = NewSMBPacket(data=data)

130

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

144

145 if len(data) == 0:

146 break

147 else:

148 packet = SMB2Packet(data=data)

149 origID = packet['MessageID']

150

151 # Just in case, let's remove any signing attempt

152 packet['Signature'] = ""

153 packet['Flags'] &= ~(SMB2_FLAGS_SIGNED)

154

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

159

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)

167

168 # 3. Get the target's answer

169 packet = self.clientConnection.getSMBServer().recvSMB()

170

171 if len(packet.getData()) == 0:

172 break

173 else:

174 packet['MessageID'] = origID

175 data = packet.getData()

176

177 # 4. Send it back to the client

178 self.__NBSession.send_packet(data)

179

180 return True

181

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))

195

196 return packet, smbCommand

197

198 def getNegoAnswer(self, recvPacket):

199

200 if self.isSMB2 is False:

201 smbCommand = SMBCommand(recvPacket['Data'][0])

202 respSMBCommand = SMBCommand(SMB.SMB_COM_NEGOTIATE)

203

204 resp = NewSMBPacket()

205 resp['Flags1'] = SMB.FLAGS1_REPLY

206 resp['Pid'] = recvPacket['Pid']

207 resp['Tid'] = recvPacket['Tid']

208 resp['Mid'] = recvPacket['Mid']

209

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()

220

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

225

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

234

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

246

247 respSMBCommand['Data'] = _dialects_data

248 respSMBCommand['Parameters'] = _dialects_parameters

249

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

261

262 respSMBCommand = SMB2Negotiate_Response()

263

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

278

279 blob = SPNEGO_NegTokenInit()

280 blob['MechTypes'] = [TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],

281 TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]

282

283 respSMBCommand['Buffer'] = blob.getData()

284 respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])

285

286 resp['Data'] = respSMBCommand

287

288 return resp

289

290 def processSessionSetup(self, recvPacket):

291

292 if self.isSMB2 is False:

293 respSMBCommand = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)

294 smbCommand = SMBCommand(recvPacket['Data'][0])

295

296 if smbCommand['WordCount'] == 12:

297 respParameters = SMBSessionSetupAndX_Extended_Response_Parameters()

298 respData = SMBSessionSetupAndX_Extended_Response_Data()

299

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)

304

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()

310

311 respParameters['SecurityBlobLength'] = len(respToken.getData())

312 respData['SecurityBlobLength'] = respParameters['SecurityBlobLength']

313 respData['SecurityBlob'] = respToken.getData()

314

315 respData['NativeOS'] = ''

316 respData['NativeLanMan'] = ''

317 respSMBCommand['Parameters'] = respParameters

318 respSMBCommand['Data'] = respData

319

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)

331

332 self.__NBSession.send_packet(resp.getData())

333 recvPacket, smbCommand = self.getSMBPacket()

334

335 sessionSetupParameters = SMBSessionSetupAndX_Extended_Parameters(smbCommand['Parameters'])

336 sessionSetupData = SMBSessionSetupAndX_Extended_Data()

337 sessionSetupData['SecurityBlobLength'] = sessionSetupParameters['SecurityBlobLength']

338 sessionSetupData.fromString(smbCommand['Data'])

339

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']

348

349 # Now we should've received a type 3 message

350 authenticateMessage = NTLMAuthChallengeResponse()

351 authenticateMessage.fromString(token)

352

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()

359

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

371

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'] = ''

384

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()

395

396 respSMBCommand['Parameters'] = respParameters

397 respSMBCommand['Data'] = respData

398 resp.addCommand(respSMBCommand)

399

400 self.__NBSession.send_packet(resp.getData())

401

402

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'])

410

411 securityBlob = sessionSetupData['Buffer']

412

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

435

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

447

448 self.__NBSession.send_packet(resp.getData())

449 recvPacket, smbCommand = self.getSMBPacket()

450 return self.processSessionSetup(recvPacket)

451

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

460

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)

465

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']

471

472 respToken['ResponseToken'] = challengeMessage.getData()

473 else:

474 respToken = challengeMessage

475

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']

486

487 respSMBCommand['SecurityBufferOffset'] = 0x48

488 respSMBCommand['SecurityBufferLength'] = len(respToken)

489 respSMBCommand['Buffer'] = respToken.getData()

490 resp['Data'] = respSMBCommand

491

492 self.__NBSession.send_packet(resp.getData())

493 recvPacket, smbCommand = self.getSMBPacket()

494

495 sessionSetupData = SMB2SessionSetup(recvPacket['Data'])

496 securityBlob = sessionSetupData['Buffer']

497

498 blob = SPNEGO_NegTokenResp(securityBlob)

499 token = blob['ResponseToken']

500

501 # AUTHENTICATE_MESSAGE, here we deal with authentication

502 authenticateMessage = NTLMAuthChallengeResponse()

503 authenticateMessage.fromString(token)

504

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()

511

512 respToken = SPNEGO_NegTokenResp()

513

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

525

526 # accept-completed

527 respToken['NegState'] = b'\x00'

528

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']

539

540 respSMBCommand['SecurityBufferOffset'] = 0x48

541

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

548

549 self.__NBSession.send_packet(resp.getData())

550 return smbClient, username

551

552 def getLogOffAnswer(self, recvPacket):

553

554 if self.isSMB2 is False:

555 respSMBCommand = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX)

556

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']

563

564 respParameters = b''

565 respData = b''

566 respSMBCommand['Parameters'] = respParameters

567 respSMBCommand['Data'] = respData

568

569 resp.addCommand(respSMBCommand)

570

571 else:

572 respSMBCommand = SMB2Logoff_Response()

573

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

585

586 return resp