Hide keyboard shortcuts

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# Copyright (C) 2001 Michael Teo <michaelteo@bigfoot.com> 

8# smb.py - SMB/CIFS library 

9# 

10# This software is provided 'as-is', without any express or implied warranty. 

11# In no event will the author be held liable for any damages arising from the 

12# use of this software. 

13# 

14# Permission is granted to anyone to use this software for any purpose, 

15# including commercial applications, and to alter it and redistribute it 

16# freely, subject to the following restrictions: 

17# 

18# 1. The origin of this software must not be misrepresented; you must not 

19# claim that you wrote the original software. If you use this software 

20# in a product, an acknowledgment in the product documentation would be 

21# appreciated but is not required. 

22# 

23# 2. Altered source versions must be plainly marked as such, and must not be 

24# misrepresented as being the original software. 

25# 

26# 3. This notice cannot be removed or altered from any source distribution. 

27# 

28# Altered source done by Alberto Solino (@agsolino) 

29 

30# Todo: 

31# [ ] Try [SMB]transport fragmentation using Transact requests 

32# [ ] Try other methods of doing write (write_raw, transact2, write, write_and_unlock, write_and_close, write_mpx) 

33# [-] Try replacements for SMB_COM_NT_CREATE_ANDX (CREATE, T_TRANSACT_CREATE, OPEN_ANDX works 

34# [x] Fix forceWriteAndx, which needs to send a RecvRequest, because recv() will not send it 

35# [x] Fix Recv() when using RecvAndx and the answer comes splet in several packets 

36# [ ] Try [SMB]transport fragmentation with overlapping segments 

37# [ ] Try [SMB]transport fragmentation with out of order segments 

38# [x] Do chained AndX requests 

39# [ ] Transform the rest of the calls to structure 

40# [X] Implement TRANS/TRANS2 reassembly for list_path 

41from __future__ import division 

42from __future__ import print_function 

43import os 

44import socket 

45from binascii import a2b_hex 

46import datetime 

47from struct import pack, unpack 

48from contextlib import contextmanager 

49from pyasn1.type.univ import noValue 

50 

51from impacket import nmb, ntlm, nt_errors, LOG 

52from impacket.structure import Structure 

53from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp, ASN1_OID, asn1encode, ASN1_AID 

54from impacket.krb5.gssapi import KRB5_AP_REQ 

55 

56# For signing 

57import hashlib 

58 

59unicode_support = 0 

60unicode_convert = 1 

61 

62# Dialect for SMB1 

63SMB_DIALECT = 'NT LM 0.12' 

64 

65# Shared Device Type 

66SHARED_DISK = 0x00 

67SHARED_DISK_HIDDEN = 0x80000000 

68SHARED_PRINT_QUEUE = 0x01 

69SHARED_DEVICE = 0x02 

70SHARED_IPC = 0x03 

71 

72# Extended attributes mask 

73ATTR_ARCHIVE = 0x020 

74ATTR_COMPRESSED = 0x800 

75ATTR_NORMAL = 0x080 

76ATTR_HIDDEN = 0x002 

77ATTR_READONLY = 0x001 

78ATTR_TEMPORARY = 0x100 

79ATTR_DIRECTORY = 0x010 

80ATTR_SYSTEM = 0x004 

81 

82# Service Type 

83SERVICE_DISK = 'A:' 

84SERVICE_PRINTER = 'LPT1:' 

85SERVICE_IPC = 'IPC' 

86SERVICE_COMM = 'COMM' 

87SERVICE_ANY = '?????' 

88 

89# Server Type (Can be used to mask with SMBMachine.get_type() or SMBDomain.get_type()) 

90SV_TYPE_WORKSTATION = 0x00000001 

91SV_TYPE_SERVER = 0x00000002 

92SV_TYPE_SQLSERVER = 0x00000004 

93SV_TYPE_DOMAIN_CTRL = 0x00000008 

94SV_TYPE_DOMAIN_BAKCTRL = 0x00000010 

95SV_TYPE_TIME_SOURCE = 0x00000020 

96SV_TYPE_AFP = 0x00000040 

97SV_TYPE_NOVELL = 0x00000080 

98SV_TYPE_DOMAIN_MEMBER = 0x00000100 

99SV_TYPE_PRINTQ_SERVER = 0x00000200 

100SV_TYPE_DIALIN_SERVER = 0x00000400 

101SV_TYPE_XENIX_SERVER = 0x00000800 

102SV_TYPE_NT = 0x00001000 

103SV_TYPE_WFW = 0x00002000 

104SV_TYPE_SERVER_NT = 0x00004000 

105SV_TYPE_POTENTIAL_BROWSER = 0x00010000 

106SV_TYPE_BACKUP_BROWSER = 0x00020000 

107SV_TYPE_MASTER_BROWSER = 0x00040000 

108SV_TYPE_DOMAIN_MASTER = 0x00080000 

109SV_TYPE_LOCAL_LIST_ONLY = 0x40000000 

110SV_TYPE_DOMAIN_ENUM = 0x80000000 

111 

112# Options values for SMB.stor_file and SMB.retr_file 

113SMB_O_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails. 

114SMB_O_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN. 

115SMB_O_OPEN = 0x01 # Open the file if the file exists 

116SMB_O_TRUNC = 0x02 # Truncate the file if the file exists 

117 

118# Share Access Mode 

119SMB_SHARE_COMPAT = 0x00 

120SMB_SHARE_DENY_EXCL = 0x10 

121SMB_SHARE_DENY_WRITE = 0x20 

122SMB_SHARE_DENY_READEXEC = 0x30 

123SMB_SHARE_DENY_NONE = 0x40 

124SMB_ACCESS_READ = 0x00 

125SMB_ACCESS_WRITE = 0x01 

126SMB_ACCESS_READWRITE = 0x02 

127SMB_ACCESS_EXEC = 0x03 

128 

129TRANS_DISCONNECT_TID = 1 

130TRANS_NO_RESPONSE = 2 

131 

132STATUS_SUCCESS = 0x00000000 

133STATUS_LOGON_FAILURE = 0xC000006D 

134STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B 

135MAX_TFRAG_SIZE = 5840 

136EVASION_NONE = 0 

137EVASION_LOW = 1 

138EVASION_HIGH = 2 

139EVASION_MAX = 3 

140RPC_X_BAD_STUB_DATA = 0x6F7 

141 

142# SMB_FILE_ATTRIBUTES 

143 

144SMB_FILE_ATTRIBUTE_NORMAL = 0x0000 

145SMB_FILE_ATTRIBUTE_READONLY = 0x0001 

146SMB_FILE_ATTRIBUTE_HIDDEN = 0x0002 

147SMB_FILE_ATTRIBUTE_SYSTEM = 0x0004 

148SMB_FILE_ATTRIBUTE_VOLUME = 0x0008 

149SMB_FILE_ATTRIBUTE_DIRECTORY = 0x0010 

150SMB_FILE_ATTRIBUTE_ARCHIVE = 0x0020 

151SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100 

152SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200 

153SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400 

154SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000 

155SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000 

156 

157# Session SetupAndX Action flags 

158SMB_SETUP_GUEST = 0x01 

159SMB_SETUP_USE_LANMAN_KEY = 0x02 

160 

161# QUERY_INFORMATION levels 

162SMB_INFO_ALLOCATION = 0x0001 

163SMB_INFO_VOLUME = 0x0002 

164FILE_FS_SIZE_INFORMATION = 0x0003 

165SMB_QUERY_FS_VOLUME_INFO = 0x0102 

166SMB_QUERY_FS_SIZE_INFO = 0x0103 

167SMB_QUERY_FILE_EA_INFO = 0x0103 

168SMB_QUERY_FS_DEVICE_INFO = 0x0104 

169SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105 

170SMB_QUERY_FILE_BASIC_INFO = 0x0101 

171SMB_QUERY_FILE_STANDARD_INFO = 0x0102 

172SMB_QUERY_FILE_ALL_INFO = 0x0107 

173FILE_FS_FULL_SIZE_INFORMATION = 0x03EF 

174 

175# SET_INFORMATION levels 

176SMB_SET_FILE_DISPOSITION_INFO = 0x0102 

177SMB_SET_FILE_BASIC_INFO = 0x0101 

178SMB_SET_FILE_END_OF_FILE_INFO = 0x0104 

179 

180 

181# File System Attributes 

182FILE_CASE_SENSITIVE_SEARCH = 0x00000001 

183FILE_CASE_PRESERVED_NAMES = 0x00000002 

184FILE_UNICODE_ON_DISK = 0x00000004 

185FILE_PERSISTENT_ACLS = 0x00000008 

186FILE_FILE_COMPRESSION = 0x00000010 

187FILE_VOLUME_IS_COMPRESSED = 0x00008000 

188 

189# FIND_FIRST2 flags and levels 

190SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001 

191SMB_FIND_CLOSE_AT_EOS = 0x0002 

192SMB_FIND_RETURN_RESUME_KEYS = 0x0004 

193SMB_FIND_CONTINUE_FROM_LAST = 0x0008 

194SMB_FIND_WITH_BACKUP_INTENT = 0x0010 

195 

196FILE_DIRECTORY_FILE = 0x00000001 

197FILE_DELETE_ON_CLOSE = 0x00001000 

198FILE_NON_DIRECTORY_FILE = 0x00000040 

199 

200SMB_FIND_INFO_STANDARD = 0x0001 

201SMB_FIND_FILE_DIRECTORY_INFO = 0x0101 

202SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102 

203SMB_FIND_FILE_NAMES_INFO = 0x0103 

204SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104 

205SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105 

206SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106 

207 

208 

209# DesiredAccess flags 

210FILE_READ_DATA = 0x00000001 

211FILE_WRITE_DATA = 0x00000002 

212FILE_APPEND_DATA = 0x00000004 

213FILE_EXECUTE = 0x00000020 

214MAXIMUM_ALLOWED = 0x02000000 

215GENERIC_ALL = 0x10000000 

216GENERIC_EXECUTE = 0x20000000 

217GENERIC_WRITE = 0x40000000 

218GENERIC_READ = 0x80000000 

219 

220# ShareAccess flags 

221FILE_SHARE_NONE = 0x00000000 

222FILE_SHARE_READ = 0x00000001 

223FILE_SHARE_WRITE = 0x00000002 

224FILE_SHARE_DELETE = 0x00000004 

225 

226# CreateDisposition flags 

227FILE_SUPERSEDE = 0x00000000 

228FILE_OPEN = 0x00000001 

229FILE_CREATE = 0x00000002 

230FILE_OPEN_IF = 0x00000003 

231FILE_OVERWRITE = 0x00000004 

232FILE_OVERWRITE_IF = 0x00000005 

233 

234def strerror(errclass, errcode): 

235 if errclass == 0x01: 

236 return 'OS error', ERRDOS.get(errcode, 'Unknown error') 

237 elif errclass == 0x02: 

238 return 'Server error', ERRSRV.get(errcode, 'Unknown error') 

239 elif errclass == 0x03: 

240 return 'Hardware error', ERRHRD.get(errcode, 'Unknown error') 

241 # This is not a standard error class for SMB 

242 #elif errclass == 0x80: 

243 # return 'Browse error', ERRBROWSE.get(errcode, 'Unknown error') 

244 elif errclass == 0xff: 

245 return 'Bad command', 'Bad command. Please file bug report' 

246 else: 

247 return 'Unknown error', 'Unknown error' 

248 

249# Raised when an error has occurred during a session 

250class SessionError(Exception): 

251 # SMB X/Open error codes for the ERRDOS error class 

252 ERRsuccess = 0 

253 ERRbadfunc = 1 

254 ERRbadfile = 2 

255 ERRbadpath = 3 

256 ERRnofids = 4 

257 ERRnoaccess = 5 

258 ERRbadfid = 6 

259 ERRbadmcb = 7 

260 ERRnomem = 8 

261 ERRbadmem = 9 

262 ERRbadenv = 10 

263 ERRbadaccess = 12 

264 ERRbaddata = 13 

265 ERRres = 14 

266 ERRbaddrive = 15 

267 ERRremcd = 16 

268 ERRdiffdevice = 17 

269 ERRnofiles = 18 

270 ERRgeneral = 31 

271 ERRbadshare = 32 

272 ERRlock = 33 

273 ERRunsup = 50 

274 ERRnetnamedel = 64 

275 ERRnosuchshare = 67 

276 ERRfilexists = 80 

277 ERRinvalidparam = 87 

278 ERRcannotopen = 110 

279 ERRinsufficientbuffer = 122 

280 ERRinvalidname = 123 

281 ERRunknownlevel = 124 

282 ERRnotlocked = 158 

283 ERRrename = 183 

284 ERRbadpipe = 230 

285 ERRpipebusy = 231 

286 ERRpipeclosing = 232 

287 ERRnotconnected = 233 

288 ERRmoredata = 234 

289 ERRnomoreitems = 259 

290 ERRbaddirectory = 267 

291 ERReasnotsupported = 282 

292 ERRlogonfailure = 1326 

293 ERRbuftoosmall = 2123 

294 ERRunknownipc = 2142 

295 ERRnosuchprintjob = 2151 

296 ERRinvgroup = 2455 

297 

298 # here's a special one from observing NT 

299 ERRnoipc = 66 

300 

301 # These errors seem to be only returned by the NT printer driver system 

302 ERRdriveralreadyinstalled = 1795 

303 ERRunknownprinterport = 1796 

304 ERRunknownprinterdriver = 1797 

305 ERRunknownprintprocessor = 1798 

306 ERRinvalidseparatorfile = 1799 

307 ERRinvalidjobpriority = 1800 

308 ERRinvalidprintername = 1801 

309 ERRprinteralreadyexists = 1802 

310 ERRinvalidprintercommand = 1803 

311 ERRinvaliddatatype = 1804 

312 ERRinvalidenvironment = 1805 

313 

314 ERRunknownprintmonitor = 3000 

315 ERRprinterdriverinuse = 3001 

316 ERRspoolfilenotfound = 3002 

317 ERRnostartdoc = 3003 

318 ERRnoaddjob = 3004 

319 ERRprintprocessoralreadyinstalled = 3005 

320 ERRprintmonitoralreadyinstalled = 3006 

321 ERRinvalidprintmonitor = 3007 

322 ERRprintmonitorinuse = 3008 

323 ERRprinterhasjobsqueued = 3009 

324 

325 # Error codes for the ERRSRV class 

326 

327 ERRerror = 1 

328 ERRbadpw = 2 

329 ERRbadtype = 3 

330 ERRaccess = 4 

331 ERRinvnid = 5 

332 ERRinvnetname = 6 

333 ERRinvdevice = 7 

334 ERRqfull = 49 

335 ERRqtoobig = 50 

336 ERRinvpfid = 52 

337 ERRsmbcmd = 64 

338 ERRsrverror = 65 

339 ERRfilespecs = 67 

340 ERRbadlink = 68 

341 ERRbadpermits = 69 

342 ERRbadpid = 70 

343 ERRsetattrmode = 71 

344 ERRpaused = 81 

345 ERRmsgoff = 82 

346 ERRnoroom = 83 

347 ERRrmuns = 87 

348 ERRtimeout = 88 

349 ERRnoresource = 89 

350 ERRtoomanyuids = 90 

351 ERRbaduid = 91 

352 ERRuseMPX = 250 

353 ERRuseSTD = 251 

354 ERRcontMPX = 252 

355 ERRbadPW = None 

356 ERRnosupport = 0 

357 ERRunknownsmb = 22 

358 

359 # Error codes for the ERRHRD class 

360 

361 ERRnowrite = 19 

362 ERRbadunit = 20 

363 ERRnotready = 21 

364 ERRbadcmd = 22 

365 ERRdata = 23 

366 ERRbadreq = 24 

367 ERRseek = 25 

368 ERRbadmedia = 26 

369 ERRbadsector = 27 

370 ERRnopaper = 28 

371 ERRwrite = 29 

372 ERRread = 30 

373 ERRwrongdisk = 34 

374 ERRFCBunavail = 35 

375 ERRsharebufexc = 36 

376 ERRdiskfull = 39 

377 

378 

379 hard_msgs = { 

380 19: ("ERRnowrite", "Attempt to write on write-protected diskette."), 

381 20: ("ERRbadunit", "Unknown unit."), 

382 21: ("ERRnotready", "Drive not ready."), 

383 22: ("ERRbadcmd", "Unknown command."), 

384 23: ("ERRdata", "Data error (CRC)."), 

385 24: ("ERRbadreq", "Bad request structure length."), 

386 25: ("ERRseek", "Seek error."), 

387 26: ("ERRbadmedia", "Unknown media type."), 

388 27: ("ERRbadsector", "Sector not found."), 

389 28: ("ERRnopaper", "Printer out of paper."), 

390 29: ("ERRwrite", "Write fault."), 

391 30: ("ERRread", "Read fault."), 

392 31: ("ERRgeneral", "General failure."), 

393 32: ("ERRbadshare", "An open conflicts with an existing open."), 

394 33: ("ERRlock", "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."), 

395 34: ("ERRwrongdisk", "The wrong disk was found in a drive."), 

396 35: ("ERRFCBUnavail", "No FCBs are available to process request."), 

397 36: ("ERRsharebufexc", "A sharing buffer has been exceeded.") 

398 } 

399 

400 dos_msgs = { 

401 ERRbadfunc: ("ERRbadfunc", "Invalid function."), 

402 ERRbadfile: ("ERRbadfile", "File not found."), 

403 ERRbadpath: ("ERRbadpath", "Directory invalid."), 

404 ERRnofids: ("ERRnofids", "No file descriptors available"), 

405 ERRnoaccess: ("ERRnoaccess", "Access denied."), 

406 ERRbadfid: ("ERRbadfid", "Invalid file handle."), 

407 ERRbadmcb: ("ERRbadmcb", "Memory control blocks destroyed."), 

408 ERRnomem: ("ERRnomem", "Insufficient server memory to perform the requested function."), 

409 ERRbadmem: ("ERRbadmem", "Invalid memory block address."), 

410 ERRbadenv: ("ERRbadenv", "Invalid environment."), 

411 11: ("ERRbadformat", "Invalid format."), 

412 ERRbadaccess: ("ERRbadaccess", "Invalid open mode."), 

413 ERRbaddata: ("ERRbaddata", "Invalid data."), 

414 ERRres: ("ERRres", "reserved."), 

415 ERRbaddrive: ("ERRbaddrive", "Invalid drive specified."), 

416 ERRremcd: ("ERRremcd", "A Delete Directory request attempted to remove the server's current directory."), 

417 ERRdiffdevice: ("ERRdiffdevice", "Not same device."), 

418 ERRnofiles: ("ERRnofiles", "A File Search command can find no more files matching the specified criteria."), 

419 ERRbadshare: ("ERRbadshare", "The sharing mode specified for an Open conflicts with existing FIDs on the file."), 

420 ERRlock: ("ERRlock", "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."), 

421 ERRunsup: ("ERRunsup", "The operation is unsupported"), 

422 ERRnosuchshare: ("ERRnosuchshare", "You specified an invalid share name"), 

423 ERRfilexists: ("ERRfilexists", "The file named in a Create Directory, Make New File or Link request already exists."), 

424 ERRinvalidname: ("ERRinvalidname", "Invalid name"), 

425 ERRbadpipe: ("ERRbadpipe", "Pipe invalid."), 

426 ERRpipebusy: ("ERRpipebusy", "All instances of the requested pipe are busy."), 

427 ERRpipeclosing: ("ERRpipeclosing", "Pipe close in progress."), 

428 ERRnotconnected: ("ERRnotconnected", "No process on other end of pipe."), 

429 ERRmoredata: ("ERRmoredata", "There is more data to be returned."), 

430 ERRinvgroup: ("ERRinvgroup", "Invalid workgroup (try the -W option)"), 

431 ERRlogonfailure: ("ERRlogonfailure", "Logon failure"), 

432 ERRdiskfull: ("ERRdiskfull", "Disk full"), 

433 ERRgeneral: ("ERRgeneral", "General failure"), 

434 ERRunknownlevel: ("ERRunknownlevel", "Unknown info level") 

435 } 

436 

437 server_msgs = { 

438 1: ("ERRerror", "Non-specific error code."), 

439 2: ("ERRbadpw", "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."), 

440 3: ("ERRbadtype", "reserved."), 

441 4: ("ERRaccess", "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."), 

442 5: ("ERRinvnid", "The tree ID (TID) specified in a command was invalid."), 

443 6: ("ERRinvnetname", "Invalid network name in tree connect."), 

444 7: ("ERRinvdevice", "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."), 

445 49: ("ERRqfull", "Print queue full (files) -- returned by open print file."), 

446 50: ("ERRqtoobig", "Print queue full -- no space."), 

447 51: ("ERRqeof", "EOF on print queue dump."), 

448 52: ("ERRinvpfid", "Invalid print file FID."), 

449 64: ("ERRsmbcmd", "The server did not recognize the command received."), 

450 65: ("ERRsrverror","The server encountered an internal error, e.g., system file unavailable."), 

451 67: ("ERRfilespecs", "The file handle (FID) and pathname parameters contained an invalid combination of values."), 

452 68: ("ERRreserved", "reserved."), 

453 69: ("ERRbadpermits", "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."), 

454 70: ("ERRreserved", "reserved."), 

455 71: ("ERRsetattrmode", "The attribute mode in the Set File Attribute request is invalid."), 

456 81: ("ERRpaused", "Server is paused."), 

457 82: ("ERRmsgoff", "Not receiving messages."), 

458 83: ("ERRnoroom", "No room to buffer message."), 

459 87: ("ERRrmuns", "Too many remote user names."), 

460 88: ("ERRtimeout", "Operation timed out."), 

461 89: ("ERRnoresource", "No resources currently available for request."), 

462 90: ("ERRtoomanyuids", "Too many UIDs active on this session."), 

463 91: ("ERRbaduid", "The UID is not known as a valid ID on this session."), 

464 250: ("ERRusempx","Temp unable to support Raw, use MPX mode."), 

465 251: ("ERRusestd","Temp unable to support Raw, use standard read/write."), 

466 252: ("ERRcontmpx", "Continue in MPX mode."), 

467 253: ("ERRreserved", "reserved."), 

468 254: ("ERRreserved", "reserved."), 

469 0xFFFF: ("ERRnosupport", "Function not supported.") 

470 } 

471 # Error clases 

472 

473 ERRDOS = 0x1 

474 error_classes = { 0: ("SUCCESS", {}), 

475 ERRDOS: ("ERRDOS", dos_msgs), 

476 0x02: ("ERRSRV",server_msgs), 

477 0x03: ("ERRHRD",hard_msgs), 

478 0x04: ("ERRXOS", {} ), 

479 0xE1: ("ERRRMX1", {} ), 

480 0xE2: ("ERRRMX2", {} ), 

481 0xE3: ("ERRRMX3", {} ), 

482 0xFF: ("ERRCMD", {} ) } 

483 

484 

485 

486 def __init__( self, error_string, error_class, error_code, nt_status = 0, packet=0): 

487 Exception.__init__(self, error_string) 

488 self.nt_status = nt_status 

489 self._args = error_string 

490 if nt_status: 490 ↛ 494line 490 didn't jump to line 494, because the condition on line 490 was never false

491 self.error_class = 0 

492 self.error_code = (error_code << 16) + error_class 

493 else: 

494 self.error_class = error_class 

495 self.error_code = error_code 

496 self.packet = packet 

497 

498 def get_error_class( self ): 

499 return self.error_class 

500 

501 def get_error_code( self ): 

502 return self.error_code 

503 

504 def get_error_packet(self): 

505 return self.packet 

506 

507 def __str__( self ): 

508 error_class = SessionError.error_classes.get( self.error_class, None ) 

509 if not error_class: 

510 error_code_str = self.error_code 

511 error_class_str = self.error_class 

512 else: 

513 error_class_str = error_class[0] 

514 error_code = error_class[1].get( self.error_code, None ) 

515 if not error_code: 

516 error_code_str = self.error_code 

517 else: 

518 error_code_str = '%s(%s)' % error_code 

519 

520 if self.nt_status: 

521 return 'SMB SessionError: %s(%s)' % nt_errors.ERROR_MESSAGES[self.error_code] 

522 else: 

523 # Fall back to the old format 

524 return 'SMB SessionError: class: %s, code: %s' % (error_class_str, error_code_str) 

525 

526 

527# Raised when an supported feature is present/required in the protocol but is not 

528# currently supported by pysmb 

529class UnsupportedFeature(Exception): 

530 pass 

531 

532# Contains information about a SMB shared device/service 

533class SharedDevice: 

534 def __init__(self, name, share_type, comment): 

535 self.__name = name 

536 self.__type = share_type 

537 self.__comment = comment 

538 

539 def get_name(self): 

540 return self.__name 

541 

542 def get_type(self): 

543 return self.__type 

544 

545 def get_comment(self): 

546 return self.__comment 

547 

548 def __repr__(self): 

549 return '<SharedDevice instance: name=' + self.__name + ', type=' + str(self.__type) + ', comment="' + self.__comment + '">' 

550 

551 

552# Contains information about the shared file/directory 

553class SharedFile: 

554 def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, shortname, longname): 

555 self.__ctime = ctime 

556 self.__atime = atime 

557 self.__mtime = mtime 

558 self.__filesize = filesize 

559 self.__allocsize = allocsize 

560 self.__attribs = attribs 

561 try: 

562 if isinstance(shortname,bytes): 562 ↛ 563line 562 didn't jump to line 563, because the condition on line 562 was never true

563 self.__shortname = shortname[:shortname.index(b'\0')] 

564 else: 

565 self.__shortname = shortname[:shortname.index('\0')] 

566 except (ValueError, TypeError): 

567 self.__shortname = shortname 

568 try: 

569 if isinstance(shortname,bytes): 569 ↛ 570line 569 didn't jump to line 570, because the condition on line 569 was never true

570 self.__longname = longname[:longname.index(b'\0')] 

571 else: 

572 self.__longname = longname[:longname.index('\0')] 

573 except (ValueError, TypeError): 

574 self.__longname = longname 

575 

576 def get_ctime(self): 

577 return self.__ctime 

578 

579 def get_ctime_epoch(self): 

580 return self.__convert_smbtime(self.__ctime) 

581 

582 def get_mtime(self): 

583 return self.__mtime 

584 

585 def get_mtime_epoch(self): 

586 return self.__convert_smbtime(self.__mtime) 

587 

588 def get_atime(self): 

589 return self.__atime 

590 

591 def get_atime_epoch(self): 

592 return self.__convert_smbtime(self.__atime) 

593 

594 def get_filesize(self): 

595 return self.__filesize 

596 

597 def get_allocsize(self): 

598 return self.__allocsize 

599 

600 def get_attributes(self): 

601 return self.__attribs 

602 

603 def is_archive(self): 

604 return self.__attribs & ATTR_ARCHIVE 

605 

606 def is_compressed(self): 

607 return self.__attribs & ATTR_COMPRESSED 

608 

609 def is_normal(self): 

610 return self.__attribs & ATTR_NORMAL 

611 

612 def is_hidden(self): 

613 return self.__attribs & ATTR_HIDDEN 

614 

615 def is_readonly(self): 

616 return self.__attribs & ATTR_READONLY 

617 

618 def is_temporary(self): 

619 return self.__attribs & ATTR_TEMPORARY 

620 

621 def is_directory(self): 

622 return self.__attribs & ATTR_DIRECTORY 

623 

624 def is_system(self): 

625 return self.__attribs & ATTR_SYSTEM 

626 

627 def get_shortname(self): 

628 return self.__shortname 

629 

630 def get_longname(self): 

631 return self.__longname 

632 

633 def __repr__(self): 

634 return '<SharedFile instance: shortname="' + self.__shortname + '", longname="' + self.__longname + '", filesize=' + str(self.__filesize) + '>' 

635 

636 @staticmethod 

637 def __convert_smbtime(t): 

638 x = t >> 32 

639 y = t & 0xffffffff 

640 geo_cal_offset = 11644473600.0 # = 369.0 * 365.25 * 24 * 60 * 60 - (3.0 * 24 * 60 * 60 + 6.0 * 60 * 60) 

641 return (x * 4.0 * (1 << 30) + (y & 0xfff00000)) * 1.0e-7 - geo_cal_offset 

642 

643 

644# Contain information about a SMB machine 

645class SMBMachine: 

646 def __init__(self, nbname, nbt_type, comment): 

647 self.__nbname = nbname 

648 self.__type = nbt_type 

649 self.__comment = comment 

650 

651 def __repr__(self): 

652 return '<SMBMachine instance: nbname="' + self.__nbname + '", type=' + hex(self.__type) + ', comment="' + self.__comment + '">' 

653 

654class SMBDomain: 

655 def __init__(self, nbgroup, domain_type, master_browser): 

656 self.__nbgroup = nbgroup 

657 self.__type = domain_type 

658 self.__master_browser = master_browser 

659 

660 def __repr__(self): 

661 return '<SMBDomain instance: nbgroup="' + self.__nbgroup + '", type=' + hex(self.__type) + ', master browser="' + self.__master_browser + '">' 

662 

663# Represents a SMB Packet 

664class NewSMBPacket(Structure): 

665 structure = ( 

666 ('Signature', '"\xffSMB'), 

667 ('Command','B=0'), 

668 ('ErrorClass','B=0'), 

669 ('_reserved','B=0'), 

670 ('ErrorCode','<H=0'), 

671 ('Flags1','B=0'), 

672 ('Flags2','<H=0'), 

673 ('PIDHigh','<H=0'), 

674 ('SecurityFeatures','8s=""'), 

675 ('Reserved','<H=0'), 

676 ('Tid','<H=0xffff'), 

677 ('Pid','<H=0'), 

678 ('Uid','<H=0'), 

679 ('Mid','<H=0'), 

680 ('Data','*:'), 

681 ) 

682 

683 def __init__(self, **kargs): 

684 Structure.__init__(self, **kargs) 

685 

686 if ('Flags2' in self.fields) is False: 

687 self['Flags2'] = 0 

688 if ('Flags1' in self.fields) is False: 

689 self['Flags1'] = 0 

690 

691 if 'data' not in kargs: 

692 self['Data'] = [] 

693 

694 def addCommand(self, command): 

695 if len(self['Data']) == 0: 695 ↛ 698line 695 didn't jump to line 698, because the condition on line 695 was never false

696 self['Command'] = command.command 

697 else: 

698 self['Data'][-1]['Parameters']['AndXCommand'] = command.command 

699 self['Data'][-1]['Parameters']['AndXOffset'] = len(self) 

700 self['Data'].append(command) 

701 

702 def isMoreData(self): 

703 return (self['Command'] in [SMB.SMB_COM_TRANSACTION, SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and 

704 self['ErrorClass'] == 1 and self['ErrorCode'] == SessionError.ERRmoredata) 

705 

706 def isMoreProcessingRequired(self): 

707 return self['ErrorClass'] == 0x16 and self['ErrorCode'] == 0xc000 

708 

709 def isValidAnswer(self, cmd): 

710 # this was inside a loop reading more from the net (with recv_packet(None)) 

711 if self['Command'] == cmd: 711 ↛ 720line 711 didn't jump to line 720, because the condition on line 711 was never false

712 if (self['ErrorClass'] == 0x00 and self['ErrorCode'] == 0x00): 

713 return 1 

714 elif self.isMoreData(): 714 ↛ 715line 714 didn't jump to line 715, because the condition on line 714 was never true

715 return 1 

716 elif self.isMoreProcessingRequired(): 

717 return 1 

718 raise SessionError("SMB Library Error", self['ErrorClass'] + (self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & SMB.FLAGS2_NT_STATUS, self) 

719 else: 

720 raise UnsupportedFeature("Unexpected answer from server: Got %d, Expected %d" % (self['Command'], cmd)) 

721 

722 

723class SMBCommand(Structure): 

724 structure = ( 

725 ('WordCount', 'B=len(Parameters)//2'), 

726 ('_ParametersLength','_-Parameters','WordCount*2'), 

727 ('Parameters',':'), # default set by constructor 

728 ('ByteCount','<H-Data'), 

729 ('Data',':'), # default set by constructor 

730 ) 

731 

732 def __init__(self, commandOrData = None, data = None, **kargs): 

733 if type(commandOrData) == type(0): 

734 self.command = commandOrData 

735 else: 

736 data = data or commandOrData 

737 

738 Structure.__init__(self, data = data, **kargs) 

739 

740 if data is None: 

741 self['Parameters'] = '' 

742 self['Data'] = '' 

743 

744class AsciiOrUnicodeStructure(Structure): 

745 UnicodeStructure = () 

746 AsciiStructure = () 

747 def __init__(self, flags = 0, **kargs): 

748 if flags & SMB.FLAGS2_UNICODE: 

749 self.structure = self.UnicodeStructure 

750 else: 

751 self.structure = self.AsciiStructure 

752 Structure.__init__(self, **kargs) 

753 

754class SMBCommand_Parameters(Structure): 

755 pass 

756 

757class SMBAndXCommand_Parameters(Structure): 

758 commonHdr = ( 

759 ('AndXCommand','B=0xff'), 

760 ('_reserved','B=0'), 

761 ('AndXOffset','<H=0'), 

762 ) 

763 structure = ( # default structure, overridden by subclasses 

764 ('Data',':=""'), 

765 ) 

766 

767############# TRANSACTIONS RELATED 

768# TRANS2_QUERY_FS_INFORMATION 

769# QUERY_FS Information Levels 

770# SMB_QUERY_FS_ATTRIBUTE_INFO 

771class SMBQueryFsAttributeInfo(Structure): 

772 structure = ( 

773 ('FileSystemAttributes','<L'), 

774 ('MaxFilenNameLengthInBytes','<L'), 

775 ('LengthOfFileSystemName','<L-FileSystemName'), 

776 ('FileSystemName',':'), 

777 ) 

778 

779class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure): 

780 commonHdr = ( 

781 ('ulVolSerialNbr','<L=0xABCDEFAA'), 

782 ('cCharCount','<B-VolumeLabel'), 

783 ) 

784 AsciiStructure = ( 

785 ('VolumeLabel','z'), 

786 ) 

787 UnicodeStructure = ( 

788 ('VolumeLabel','u'), 

789 ) 

790 

791# FILE_FS_SIZE_INFORMATION 

792class FileFsSizeInformation(Structure): 

793 structure = ( 

794 ('TotalAllocationUnits','<q=148529400'), 

795 ('AvailableAllocationUnits','<q=14851044'), 

796 ('SectorsPerAllocationUnit','<L=2'), 

797 ('BytesPerSector','<L=512'), 

798 ) 

799 

800# SMB_QUERY_FS_SIZE_INFO 

801class SMBQueryFsSizeInfo(Structure): 

802 structure = ( 

803 ('TotalAllocationUnits','<q=148529400'), 

804 ('TotalFreeAllocationUnits','<q=14851044'), 

805 ('SectorsPerAllocationUnit','<L=2'), 

806 ('BytesPerSector','<L=512'), 

807 ) 

808# FILE_FS_FULL_SIZE_INFORMATION 

809class SMBFileFsFullSizeInformation(Structure): 

810 structure = ( 

811 ('TotalAllocationUnits','<q=148529400'), 

812 ('CallerAvailableAllocationUnits','<q=148529400'), 

813 ('ActualAvailableAllocationUnits','<q=148529400'), 

814 ('SectorsPerAllocationUnit','<L=15'), 

815 ('BytesPerSector','<L=512') 

816 ) 

817# SMB_QUERY_FS_VOLUME_INFO 

818class SMBQueryFsVolumeInfo(Structure): 

819 structure = ( 

820 ('VolumeCreationTime','<q'), 

821 ('SerialNumber','<L=0xABCDEFAA'), 

822 ('VolumeLabelSize','<L=len(VolumeLabel)'), 

823 ('Reserved','<H=0x10'), 

824 ('VolumeLabel',':') 

825 ) 

826# SMB_FIND_FILE_BOTH_DIRECTORY_INFO level 

827class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure): 

828 commonHdr = ( 

829 ('NextEntryOffset','<L=0'), 

830 ('FileIndex','<L=0'), 

831 ('CreationTime','<q'), 

832 ('LastAccessTime','<q'), 

833 ('LastWriteTime','<q'), 

834 ('LastChangeTime','<q'), 

835 ('EndOfFile','<q=0'), 

836 ('AllocationSize','<q=0'), 

837 ('ExtFileAttributes','<L=0'), 

838 ) 

839 AsciiStructure = ( 

840 ('FileNameLength','<L-FileName','len(FileName)'), 

841 ('EaSize','<L=0'), 

842 ('ShortNameLength','<B=0'), 

843 ('Reserved','<B=0'), 

844 ('ShortName','24s'), 

845 ('FileName',':'), 

846 ) 

847 UnicodeStructure = ( 

848 ('FileNameLength','<L-FileName','len(FileName)*2'), 

849 ('EaSize','<L=0'), 

850 ('ShortNameLength','<B=0'), 

851 ('Reserved','<B=0'), 

852 ('ShortName','24s'), 

853 ('FileName',':'), 

854 ) 

855 

856# SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level 

857class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure): 

858 commonHdr = ( 

859 ('NextEntryOffset','<L=0'), 

860 ('FileIndex','<L=0'), 

861 ('CreationTime','<q'), 

862 ('LastAccessTime','<q'), 

863 ('LastWriteTime','<q'), 

864 ('LastChangeTime','<q'), 

865 ('EndOfFile','<q=0'), 

866 ('AllocationSize','<q=0'), 

867 ('ExtFileAttributes','<L=0'), 

868 ) 

869 AsciiStructure = ( 

870 ('FileNameLength','<L-FileName','len(FileName)'), 

871 ('EaSize','<L=0'), 

872 ('FileID','<q=0'), 

873 ('FileName',':'), 

874 ) 

875 UnicodeStructure = ( 

876 ('FileNameLength','<L-FileName','len(FileName)*2'), 

877 ('EaSize','<L=0'), 

878 ('FileID','<q=0'), 

879 ('FileName',':'), 

880 ) 

881 

882# SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level 

883class SMBFindFileIdBothDirectoryInfo(AsciiOrUnicodeStructure): 

884 commonHdr = ( 

885 ('NextEntryOffset','<L=0'), 

886 ('FileIndex','<L=0'), 

887 ('CreationTime','<q'), 

888 ('LastAccessTime','<q'), 

889 ('LastWriteTime','<q'), 

890 ('LastChangeTime','<q'), 

891 ('EndOfFile','<q=0'), 

892 ('AllocationSize','<q=0'), 

893 ('ExtFileAttributes','<L=0'), 

894 ) 

895 AsciiStructure = ( 

896 ('FileNameLength','<L-FileName','len(FileName)'), 

897 ('EaSize','<L=0'), 

898 ('ShortNameLength','<B=0'), 

899 ('Reserved','<B=0'), 

900 ('ShortName','24s'), 

901 ('Reserved','<H=0'), 

902 ('FileID','<q=0'), 

903 ('FileName','z'), 

904 ) 

905 UnicodeStructure = ( 

906 ('FileNameLength','<L-FileName','len(FileName)*2'), 

907 ('EaSize','<L=0'), 

908 ('ShortNameLength','<B=0'), 

909 ('Reserved','<B=0'), 

910 ('ShortName','24s'), 

911 ('Reserved','<H=0'), 

912 ('FileID','<q=0'), 

913 ('FileName',':'), 

914 ) 

915 

916# SMB_FIND_FILE_DIRECTORY_INFO level 

917class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure): 

918 commonHdr = ( 

919 ('NextEntryOffset','<L=0'), 

920 ('FileIndex','<L=0'), 

921 ('CreationTime','<q'), 

922 ('LastAccessTime','<q'), 

923 ('LastWriteTime','<q'), 

924 ('LastChangeTime','<q'), 

925 ('EndOfFile','<q=0'), 

926 ('AllocationSize','<q=1'), 

927 ('ExtFileAttributes','<L=0'), 

928 ) 

929 AsciiStructure = ( 

930 ('FileNameLength','<L-FileName','len(FileName)'), 

931 ('FileName','z'), 

932 ) 

933 UnicodeStructure = ( 

934 ('FileNameLength','<L-FileName','len(FileName)*2'), 

935 ('FileName',':'), 

936 ) 

937 

938# SMB_FIND_FILE_NAMES_INFO level 

939class SMBFindFileNamesInfo(AsciiOrUnicodeStructure): 

940 commonHdr = ( 

941 ('NextEntryOffset','<L=0'), 

942 ('FileIndex','<L=0'), 

943 ) 

944 AsciiStructure = ( 

945 ('FileNameLength','<L-FileName','len(FileName)'), 

946 ('FileName','z'), 

947 ) 

948 UnicodeStructure = ( 

949 ('FileNameLength','<L-FileName','len(FileName)*2'), 

950 ('FileName',':'), 

951 ) 

952 

953# SMB_FIND_FILE_FULL_DIRECTORY_INFO level 

954class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure): 

955 commonHdr = ( 

956 ('NextEntryOffset','<L=0'), 

957 ('FileIndex','<L=0'), 

958 ('CreationTime','<q'), 

959 ('LastAccessTime','<q'), 

960 ('LastWriteTime','<q'), 

961 ('LastChangeTime','<q'), 

962 ('EndOfFile','<q=0'), 

963 ('AllocationSize','<q=1'), 

964 ('ExtFileAttributes','<L=0'), 

965 ) 

966 AsciiStructure = ( 

967 ('FileNameLength','<L-FileName','len(FileName)'), 

968 ('EaSize','<L'), 

969 ('FileName','z'), 

970 ) 

971 UnicodeStructure = ( 

972 ('FileNameLength','<L-FileName','len(FileName)*2'), 

973 ('EaSize','<L'), 

974 ('FileName',':'), 

975 ) 

976 

977# SMB_FIND_INFO_STANDARD level 

978class SMBFindInfoStandard(AsciiOrUnicodeStructure): 

979 commonHdr = ( 

980 ('ResumeKey','<L=0xff'), 

981 ('CreationDate','<H=0'), 

982 ('CreationTime','<H=0'), 

983 ('LastAccessDate','<H=0'), 

984 ('LastAccessTime','<H=0'), 

985 ('LastWriteDate','<H=0'), 

986 ('LastWriteTime','<H=0'), 

987 ('EaSize','<L'), 

988 ('AllocationSize','<L=1'), 

989 ('ExtFileAttributes','<H=0'), 

990 ) 

991 AsciiStructure = ( 

992 ('FileNameLength','<B-FileName','len(FileName)'), 

993 ('FileName','z'), 

994 ) 

995 UnicodeStructure = ( 

996 ('FileNameLength','<B-FileName','len(FileName)*2'), 

997 ('FileName',':'), 

998 ) 

999 

1000# SET_FILE_INFORMATION structures 

1001# SMB_SET_FILE_DISPOSITION_INFO 

1002class SMBSetFileDispositionInfo(Structure): 

1003 structure = ( 

1004 ('DeletePending','<B'), 

1005 ) 

1006 

1007# SMB_SET_FILE_BASIC_INFO 

1008class SMBSetFileBasicInfo(Structure): 

1009 structure = ( 

1010 ('CreationTime','<q'), 

1011 ('LastAccessTime','<q'), 

1012 ('LastWriteTime','<q'), 

1013 ('ChangeTime','<q'), 

1014 ('ExtFileAttributes','<H'), 

1015 ('Reserved','<L'), 

1016 ) 

1017 

1018# FILE_STREAM_INFORMATION 

1019class SMBFileStreamInformation(Structure): 

1020 commonHdr = ( 

1021 ('NextEntryOffset','<L=0'), 

1022 ('StreamNameLength','<L=0'), 

1023 ('StreamSize','<q=0'), 

1024 ('StreamAllocationSize','<q=0'), 

1025 ('StreamName',':=""'), 

1026 ) 

1027 

1028# FILE_NETWORK_OPEN_INFORMATION 

1029class SMBFileNetworkOpenInfo(Structure): 

1030 structure = ( 

1031 ('CreationTime','<q=0'), 

1032 ('LastAccessTime','<q=0'), 

1033 ('LastWriteTime','<q=0'), 

1034 ('ChangeTime','<q=0'), 

1035 ('AllocationSize','<q=0'), 

1036 ('EndOfFile','<q=0'), 

1037 ('FileAttributes','<L=0'), 

1038 ('Reserved','<L=0'), 

1039 ) 

1040 

1041# SMB_SET_FILE_END_OF_FILE_INFO 

1042class SMBSetFileEndOfFileInfo(Structure): 

1043 structure = ( 

1044 ('EndOfFile','<q'), 

1045 ) 

1046 

1047# TRANS2_FIND_NEXT2 

1048class SMBFindNext2_Parameters(AsciiOrUnicodeStructure): 

1049 commonHdr = ( 

1050 ('SID','<H'), 

1051 ('SearchCount','<H'), 

1052 ('InformationLevel','<H'), 

1053 ('ResumeKey','<L'), 

1054 ('Flags','<H'), 

1055 ) 

1056 AsciiStructure = ( 

1057 ('FileName','z'), 

1058 ) 

1059 UnicodeStructure = ( 

1060 ('FileName','u'), 

1061 ) 

1062 

1063class SMBFindNext2Response_Parameters(Structure): 

1064 structure = ( 

1065 ('SearchCount','<H'), 

1066 ('EndOfSearch','<H=1'), 

1067 ('EaErrorOffset','<H=0'), 

1068 ('LastNameOffset','<H=0'), 

1069 ) 

1070 

1071class SMBFindNext2_Data(Structure): 

1072 structure = ( 

1073 ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'), 

1074 ('GetExtendedAttributesList',':'), 

1075 ) 

1076 

1077 

1078# TRANS2_FIND_FIRST2 

1079class SMBFindFirst2Response_Parameters(Structure): 

1080 structure = ( 

1081 ('SID','<H'), 

1082 ('SearchCount','<H'), 

1083 ('EndOfSearch','<H=1'), 

1084 ('EaErrorOffset','<H=0'), 

1085 ('LastNameOffset','<H=0'), 

1086 ) 

1087 

1088class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure): 

1089 commonHdr = ( 

1090 ('SearchAttributes','<H'), 

1091 ('SearchCount','<H'), 

1092 ('Flags','<H'), 

1093 ('InformationLevel','<H'), 

1094 ('SearchStorageType','<L'), 

1095 ) 

1096 AsciiStructure = ( 

1097 ('FileName','z'), 

1098 ) 

1099 UnicodeStructure = ( 

1100 ('FileName','u'), 

1101 ) 

1102 

1103class SMBFindFirst2_Data(Structure): 

1104 structure = ( 

1105 ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'), 

1106 ('GetExtendedAttributesList',':'), 

1107 ) 

1108 

1109# TRANS2_SET_PATH_INFORMATION 

1110class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure): 

1111 commonHdr = ( 

1112 ('InformationLevel','<H'), 

1113 ('Reserved','<L'), 

1114 ) 

1115 AsciiStructure = ( 

1116 ('FileName','z'), 

1117 ) 

1118 UnicodeStructure = ( 

1119 ('FileName','u'), 

1120 ) 

1121 

1122class SMBSetPathInformationResponse_Parameters(Structure): 

1123 structure = ( 

1124 ('EaErrorOffset','<H=0'), 

1125 ) 

1126 

1127# TRANS2_SET_FILE_INFORMATION 

1128class SMBSetFileInformation_Parameters(Structure): 

1129 structure = ( 

1130 ('FID','<H'), 

1131 ('InformationLevel','<H'), 

1132 ('Reserved','<H'), 

1133 ) 

1134 

1135class SMBSetFileInformationResponse_Parameters(Structure): 

1136 structure = ( 

1137 ('EaErrorOffset','<H=0'), 

1138 ) 

1139 

1140# TRANS2_QUERY_FILE_INFORMATION 

1141class SMBQueryFileInformation_Parameters(Structure): 

1142 structure = ( 

1143 ('FID','<H'), 

1144 ('InformationLevel','<H'), 

1145 ) 

1146 

1147class SMBQueryFileInformationResponse_Parameters(Structure): 

1148 structure = ( 

1149 ('EaErrorOffset','<H=0'), 

1150 ) 

1151 

1152class SMBQueryFileInformation_Data(Structure): 

1153 structure = ( 

1154 ('GetExtendedAttributeList',':'), 

1155 ) 

1156 

1157# TRANS2_QUERY_PATH_INFORMATION 

1158class SMBQueryPathInformationResponse_Parameters(Structure): 

1159 structure = ( 

1160 ('EaErrorOffset','<H=0'), 

1161 ) 

1162 

1163class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure): 

1164 commonHdr = ( 

1165 ('InformationLevel','<H'), 

1166 ('Reserved','<L=0'), 

1167 ) 

1168 AsciiStructure = ( 

1169 ('FileName','z'), 

1170 ) 

1171 UnicodeStructure = ( 

1172 ('FileName','u'), 

1173 ) 

1174 

1175class SMBQueryPathInformation_Data(Structure): 

1176 structure = ( 

1177 ('GetExtendedAttributeList',':'), 

1178 ) 

1179 

1180 

1181# SMB_QUERY_FILE_EA_INFO 

1182class SMBQueryFileEaInfo(Structure): 

1183 structure = ( 

1184 ('EaSize','<L=0'), 

1185 ) 

1186 

1187# SMB_QUERY_FILE_BASIC_INFO 

1188class SMBQueryFileBasicInfo(Structure): 

1189 structure = ( 

1190 ('CreationTime','<q'), 

1191 ('LastAccessTime','<q'), 

1192 ('LastWriteTime','<q'), 

1193 ('LastChangeTime','<q'), 

1194 ('ExtFileAttributes','<L'), 

1195 #('Reserved','<L=0'), 

1196 ) 

1197 

1198# SMB_QUERY_FILE_STANDARD_INFO 

1199class SMBQueryFileStandardInfo(Structure): 

1200 structure = ( 

1201 ('AllocationSize','<q'), 

1202 ('EndOfFile','<q'), 

1203 ('NumberOfLinks','<L=0'), 

1204 ('DeletePending','<B=0'), 

1205 ('Directory','<B'), 

1206 ) 

1207 

1208# SMB_QUERY_FILE_ALL_INFO 

1209class SMBQueryFileAllInfo(Structure): 

1210 structure = ( 

1211 ('CreationTime','<q'), 

1212 ('LastAccessTime','<q'), 

1213 ('LastWriteTime','<q'), 

1214 ('LastChangeTime','<q'), 

1215 ('ExtFileAttributes','<L'), 

1216 ('Reserved','<L=0'), 

1217 ('AllocationSize','<q'), 

1218 ('EndOfFile','<q'), 

1219 ('NumberOfLinks','<L=0'), 

1220 ('DeletePending','<B=0'), 

1221 ('Directory','<B'), 

1222 ('Reserved','<H=0'), 

1223 ('EaSize','<L=0'), 

1224 ('FileNameLength','<L-FileName','len(FileName)'), 

1225 ('FileName',':'), 

1226 ) 

1227 

1228# \PIPE\LANMAN NetShareEnum 

1229class SMBNetShareEnum(Structure): 

1230 structure = ( 

1231 ('RAPOpcode','<H=0'), 

1232 ('ParamDesc','z'), 

1233 ('DataDesc','z'), 

1234 ('InfoLevel','<H'), 

1235 ('ReceiveBufferSize','<H'), 

1236 ) 

1237 

1238class SMBNetShareEnumResponse(Structure): 

1239 structure = ( 

1240 ('Status','<H=0'), 

1241 ('Convert','<H=0'), 

1242 ('EntriesReturned','<H'), 

1243 ('EntriesAvailable','<H'), 

1244 ) 

1245 

1246class NetShareInfo1(Structure): 

1247 structure = ( 

1248 ('NetworkName','13s'), 

1249 ('Pad','<B=0'), 

1250 ('Type','<H=0'), 

1251 ('RemarkOffsetLow','<H=0'), 

1252 ('RemarkOffsetHigh','<H=0'), 

1253 ) 

1254 

1255# \PIPE\LANMAN NetServerGetInfo 

1256class SMBNetServerGetInfoResponse(Structure): 

1257 structure = ( 

1258 ('Status','<H=0'), 

1259 ('Convert','<H=0'), 

1260 ('TotalBytesAvailable','<H'), 

1261 ) 

1262 

1263class SMBNetServerInfo1(Structure): 

1264 # Level 1 Response 

1265 structure = ( 

1266 ('ServerName','16s'), 

1267 ('MajorVersion','B=5'), 

1268 ('MinorVersion','B=0'), 

1269 ('ServerType','<L=3'), 

1270 ('ServerCommentLow','<H=0'), 

1271 ('ServerCommentHigh','<H=0'), 

1272 ) 

1273 

1274# \PIPE\LANMAN NetShareGetInfo 

1275class SMBNetShareGetInfo(Structure): 

1276 structure = ( 

1277 ('RAPOpcode','<H=0'), 

1278 ('ParamDesc','z'), 

1279 ('DataDesc','z'), 

1280 ('ShareName','z'), 

1281 ('InfoLevel','<H'), 

1282 ('ReceiveBufferSize','<H'), 

1283 ) 

1284 

1285class SMBNetShareGetInfoResponse(Structure): 

1286 structure = ( 

1287 ('Status','<H=0'), 

1288 ('Convert','<H=0'), 

1289 ('TotalBytesAvailable','<H'), 

1290 ) 

1291 

1292############# Security Features 

1293class SecurityFeatures(Structure): 

1294 structure = ( 

1295 ('Key','<L=0'), 

1296 ('CID','<H=0'), 

1297 ('SequenceNumber','<H=0'), 

1298 ) 

1299 

1300############# SMB_COM_QUERY_INFORMATION2 (0x23) 

1301class SMBQueryInformation2_Parameters(Structure): 

1302 structure = ( 

1303 ('Fid','<H'), 

1304 ) 

1305 

1306class SMBQueryInformation2Response_Parameters(Structure): 

1307 structure = ( 

1308 ('CreateDate','<H'), 

1309 ('CreationTime','<H'), 

1310 ('LastAccessDate','<H'), 

1311 ('LastAccessTime','<H'), 

1312 ('LastWriteDate','<H'), 

1313 ('LastWriteTime','<H'), 

1314 ('FileDataSize','<L'), 

1315 ('FileAllocationSize','<L'), 

1316 ('FileAttributes','<L'), 

1317 ) 

1318 

1319 

1320 

1321############# SMB_COM_SESSION_SETUP_ANDX (0x73) 

1322class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters): 

1323 structure = ( 

1324 ('MaxBuffer','<H'), 

1325 ('MaxMpxCount','<H'), 

1326 ('VCNumber','<H'), 

1327 ('SessionKey','<L'), 

1328 ('AnsiPwdLength','<H'), 

1329 ('UnicodePwdLength','<H'), 

1330 ('_reserved','<L=0'), 

1331 ('Capabilities','<L'), 

1332 ) 

1333 

1334class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters): 

1335 structure = ( 

1336 ('MaxBufferSize','<H'), 

1337 ('MaxMpxCount','<H'), 

1338 ('VcNumber','<H'), 

1339 ('SessionKey','<L'), 

1340 ('SecurityBlobLength','<H'), 

1341 ('Reserved','<L=0'), 

1342 ('Capabilities','<L'), 

1343 ) 

1344 

1345class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure): 

1346 AsciiStructure = ( 

1347 ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'), 

1348 ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'), 

1349 ('AnsiPwd',':=""'), 

1350 ('UnicodePwd',':=""'), 

1351 ('Account','z=""'), 

1352 ('PrimaryDomain','z=""'), 

1353 ('NativeOS','z=""'), 

1354 ('NativeLanMan','z=""'), 

1355 ) 

1356 

1357 UnicodeStructure = ( 

1358 ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'), 

1359 ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'), 

1360 ('AnsiPwd',':=""'), 

1361 ('UnicodePwd',':=""'), 

1362 ('Account','u=""'), 

1363 ('PrimaryDomain','u=""'), 

1364 ('NativeOS','u=""'), 

1365 ('NativeLanMan','u=""'), 

1366 ) 

1367 

1368class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure): 

1369 AsciiStructure = ( 

1370 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1371 ('SecurityBlob',':'), 

1372 ('NativeOS','z=""'), 

1373 ('NativeLanMan','z=""'), 

1374 ) 

1375 

1376 UnicodeStructure = ( 

1377 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1378 ('SecurityBlob',':'), 

1379 ('NativeOS','u=""'), 

1380 ('NativeLanMan','u=""'), 

1381 ) 

1382 

1383class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1384 structure = ( 

1385 ('Action','<H'), 

1386 ) 

1387 

1388class SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters): 

1389 structure = ( 

1390 ('Action','<H=0'), 

1391 ('SecurityBlobLength','<H'), 

1392 ) 

1393 

1394class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure): 

1395 AsciiStructure = ( 

1396 ('NativeOS','z=""'), 

1397 ('NativeLanMan','z=""'), 

1398 ('PrimaryDomain','z=""'), 

1399 ) 

1400 

1401 UnicodeStructure = ( 

1402 ('NativeOS','u=""'), 

1403 ('NativeLanMan','u=""'), 

1404 ('PrimaryDomain','u=""'), 

1405 ) 

1406 

1407class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure): 

1408 AsciiStructure = ( 

1409 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1410 ('SecurityBlob',':'), 

1411 ('NativeOS','z=""'), 

1412 ('NativeLanMan','z=""'), 

1413 ) 

1414 

1415 UnicodeStructure = ( 

1416 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1417 ('SecurityBlob',':'), 

1418 ('PadLen','_-Pad','1 if (len(self["SecurityBlob"]) % 2 == 0) else 0'), 

1419 ('Pad',':=""'), 

1420 ('NativeOS','u=""'), 

1421 ('NativeLanMan','u=""'), 

1422 ) 

1423 def getData(self): 

1424 if self.structure == self.UnicodeStructure: 

1425 if len(str(self['SecurityBlob'])) % 2 == 0: 

1426 self['Pad'] = '\x00' 

1427 return AsciiOrUnicodeStructure.getData(self) 

1428 

1429############# SMB_COM_TREE_CONNECT (0x70) 

1430class SMBTreeConnect_Parameters(SMBCommand_Parameters): 

1431 structure = ( 

1432 ) 

1433 

1434class SMBTreeConnect_Data(SMBCommand_Parameters): 

1435 structure = ( 

1436 ('PathFormat','"\x04'), 

1437 ('Path','z'), 

1438 ('PasswordFormat','"\x04'), 

1439 ('Password','z'), 

1440 ('ServiceFormat','"\x04'), 

1441 ('Service','z'), 

1442 ) 

1443 

1444############# SMB_COM_TREE_CONNECT_ANDX (0x75) 

1445class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters): 

1446 structure = ( 

1447 ('Flags','<H=0'), 

1448 ('PasswordLength','<H'), 

1449 ) 

1450 

1451class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1452 structure = ( 

1453 ('OptionalSupport','<H=0'), 

1454 ) 

1455 

1456class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 

1457 structure = ( 

1458 ('OptionalSupport','<H=1'), 

1459 ('MaximalShareAccessRights','<L=0x1fffff'), 

1460 ('GuestMaximalShareAccessRights','<L=0x1fffff'), 

1461 ) 

1462 

1463class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure): 

1464 AsciiStructure = ( 

1465 ('_PasswordLength','_-Password','self["_PasswordLength"]'), 

1466 ('Password',':'), 

1467 ('Path','z'), 

1468 ('Service','z'), 

1469 ) 

1470 

1471 UnicodeStructure = ( 

1472 ('_PasswordLength','_-Password','self["_PasswordLength"] if self["_PasswordLength"] > 0 else 1'), 

1473 ('Password',':'), 

1474 ('Path','u'), 

1475 ('Service','z'), 

1476 ) 

1477 

1478class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure): 

1479 AsciiStructure = ( 

1480 ('Service','z'), 

1481 ('PadLen','_-Pad','self["PadLen"]'), 

1482 ('Pad',':=""'), 

1483 ('NativeFileSystem','z'), 

1484 ) 

1485 UnicodeStructure = ( 

1486 ('Service','z'), 

1487 ('PadLen','_-Pad','self["PadLen"]'), 

1488 ('Pad',':=""'), 

1489 ('NativeFileSystem','u'), 

1490 ) 

1491 

1492############# SMB_COM_NT_CREATE_ANDX (0xA2) 

1493class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters): 

1494 structure = ( 

1495 ('_reserved', 'B=0'), 

1496 ('FileNameLength','<H'), # NameLength 

1497 ('CreateFlags','<L'), # Flags 

1498 ('RootFid','<L=0'), # RootDirectoryFID 

1499 ('AccessMask','<L'), # DesiredAccess 

1500 ('AllocationSizeLo','<L=0'), # AllocationSize 

1501 ('AllocationSizeHi','<L=0'), 

1502 ('FileAttributes','<L=0'), # ExtFileAttributes 

1503 ('ShareAccess','<L=3'), # 

1504 ('Disposition','<L=1'), # CreateDisposition 

1505 ('CreateOptions','<L'), # CreateOptions 

1506 ('Impersonation','<L=2'), 

1507 ('SecurityFlags','B=3'), 

1508 ) 

1509 

1510class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1511 # XXX Is there a memory leak in the response for NTCreate (where the Data section would be) in Win 2000, Win XP, and Win 2003? 

1512 structure = ( 

1513 ('OplockLevel', 'B=0'), 

1514 ('Fid','<H'), 

1515 ('CreateAction','<L'), 

1516 ('CreateTime','<q=0'), 

1517 ('LastAccessTime','<q=0'), 

1518 ('LastWriteTime','<q=0'), 

1519 ('LastChangeTime','<q=0'), 

1520 ('FileAttributes','<L=0x80'), 

1521 ('AllocationSize','<q=0'), 

1522 ('EndOfFile','<q=0'), 

1523 ('FileType','<H=0'), 

1524 ('IPCState','<H=0'), 

1525 ('IsDirectory','B'), 

1526 ) 

1527 

1528class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 

1529 # [MS-SMB] Extended response description 

1530 structure = ( 

1531 ('OplockLevel', 'B=0'), 

1532 ('Fid','<H'), 

1533 ('CreateAction','<L'), 

1534 ('CreateTime','<q=0'), 

1535 ('LastAccessTime','<q=0'), 

1536 ('LastWriteTime','<q=0'), 

1537 ('LastChangeTime','<q=0'), 

1538 ('FileAttributes','<L=0x80'), 

1539 ('AllocationSize','<q=0'), 

1540 ('EndOfFile','<q=0'), 

1541 ('FileType','<H=0'), 

1542 ('IPCState','<H=0'), 

1543 ('IsDirectory','B'), 

1544 ('VolumeGUID','16s'), 

1545 ('FileIdLow','<L=0'), 

1546 ('FileIdHigh','<L=0'), 

1547 ('MaximalAccessRights','<L=0x12019b'), 

1548 ('GuestMaximalAccessRights','<L=0x120089'), 

1549 ) 

1550 

1551class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure): 

1552 AsciiStructure = ( 

1553 ('FileName','z'), 

1554 ) 

1555 UnicodeStructure = ( 

1556 ('Pad','B'), 

1557 ('FileName','u'), 

1558 ) 

1559 

1560############# SMB_COM_OPEN_ANDX (0xD2) 

1561class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters): 

1562 structure = ( 

1563 ('Flags','<H=0'), 

1564 ('DesiredAccess','<H=0'), 

1565 ('SearchAttributes','<H=0'), 

1566 ('FileAttributes','<H=0'), 

1567 ('CreationTime','<L=0'), 

1568 ('OpenMode','<H=1'), # SMB_O_OPEN = 1 

1569 ('AllocationSize','<L=0'), 

1570 ('Reserved','8s=""'), 

1571 ) 

1572 

1573class SMBOpenAndX_Data(SMBNtCreateAndX_Data): 

1574 pass 

1575 

1576class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1577 structure = ( 

1578 ('Fid','<H=0'), 

1579 ('FileAttributes','<H=0'), 

1580 ('LastWriten','<L=0'), 

1581 ('FileSize','<L=0'), 

1582 ('GrantedAccess','<H=0'), 

1583 ('FileType','<H=0'), 

1584 ('IPCState','<H=0'), 

1585 ('Action','<H=0'), 

1586 ('ServerFid','<L=0'), 

1587 ('_reserved','<H=0'), 

1588 ) 

1589 

1590############# SMB_COM_WRITE (0x0B) 

1591class SMBWrite_Parameters(SMBCommand_Parameters): 

1592 structure = ( 

1593 ('Fid','<H'), 

1594 ('Count','<H'), 

1595 ('Offset','<L'), 

1596 ('Remaining','<H'), 

1597 ) 

1598 

1599class SMBWriteResponse_Parameters(SMBCommand_Parameters): 

1600 structure = ( 

1601 ('Count','<H'), 

1602 ) 

1603 

1604class SMBWrite_Data(Structure): 

1605 structure = ( 

1606 ('BufferFormat','<B=1'), 

1607 ('DataLength','<H-Data'), 

1608 ('Data',':'), 

1609 ) 

1610 

1611 

1612############# SMB_COM_WRITE_ANDX (0x2F) 

1613class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters): 

1614 structure = ( 

1615 ('Fid','<H=0'), 

1616 ('Offset','<L=0'), 

1617 ('_reserved','<L=0xff'), 

1618 ('WriteMode','<H=8'), 

1619 ('Remaining','<H=0'), 

1620 ('DataLength_Hi','<H=0'), 

1621 ('DataLength','<H=0'), 

1622 ('DataOffset','<H=0'), 

1623 ('HighOffset','<L=0'), 

1624 ) 

1625 

1626class SMBWriteAndX_Data_Short(Structure): 

1627 structure = ( 

1628 ('_PadLen','_-Pad','self["DataOffset"] - 59'), 

1629 ('Pad',':'), 

1630 #('Pad','<B=0'), 

1631 ('DataLength','_-Data','self["DataLength"]'), 

1632 ('Data',':'), 

1633 ) 

1634 

1635class SMBWriteAndX_Data(Structure): 

1636 structure = ( 

1637 ('_PadLen','_-Pad','self["DataOffset"] - 63'), 

1638 ('Pad',':'), 

1639 #('Pad','<B=0'), 

1640 ('DataLength','_-Data','self["DataLength"]'), 

1641 ('Data',':'), 

1642 ) 

1643 

1644 

1645class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters): 

1646 structure = ( 

1647 ('Fid','<H'), 

1648 ('Offset','<L'), 

1649 ('_reserved','<L=0xff'), 

1650 ('WriteMode','<H=8'), 

1651 ('Remaining','<H'), 

1652 ('DataLength_Hi','<H=0'), 

1653 ('DataLength','<H'), 

1654 ('DataOffset','<H=0'), 

1655 ) 

1656 

1657class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1658 structure = ( 

1659 ('Count','<H'), 

1660 ('Available','<H'), 

1661 ('Reserved','<L=0'), 

1662 ) 

1663 

1664############# SMB_COM_WRITE_RAW (0x1D) 

1665class SMBWriteRaw_Parameters(SMBCommand_Parameters): 

1666 structure = ( 

1667 ('Fid','<H'), 

1668 ('Count','<H'), 

1669 ('_reserved','<H=0'), 

1670 ('Offset','<L'), 

1671 ('Timeout','<L=0'), 

1672 ('WriteMode','<H=0'), 

1673 ('_reserved2','<L=0'), 

1674 ('DataLength','<H'), 

1675 ('DataOffset','<H=0'), 

1676 ) 

1677 

1678############# SMB_COM_READ (0x0A) 

1679class SMBRead_Parameters(SMBCommand_Parameters): 

1680 structure = ( 

1681 ('Fid','<H'), 

1682 ('Count','<H'), 

1683 ('Offset','<L'), 

1684 ('Remaining','<H=Count'), 

1685 ) 

1686 

1687class SMBReadResponse_Parameters(Structure): 

1688 structure = ( 

1689 ('Count','<H=0'), 

1690 ('_reserved','8s=""'), 

1691 ) 

1692 

1693class SMBReadResponse_Data(Structure): 

1694 structure = ( 

1695 ('BufferFormat','<B=0x1'), 

1696 ('DataLength','<H-Data'), 

1697 ('Data',':'), 

1698 ) 

1699 

1700############# SMB_COM_READ_RAW (0x1A) 

1701class SMBReadRaw_Parameters(SMBCommand_Parameters): 

1702 structure = ( 

1703 ('Fid','<H'), 

1704 ('Offset','<L'), 

1705 ('MaxCount','<H'), 

1706 ('MinCount','<H=MaxCount'), 

1707 ('Timeout','<L=0'), 

1708 ('_reserved','<H=0'), 

1709 ) 

1710 

1711############# SMB_COM_NT_TRANSACT (0xA0) 

1712class SMBNTTransaction_Parameters(SMBCommand_Parameters): 

1713 structure = ( 

1714 ('MaxSetupCount','<B=0'), 

1715 ('Reserved1','<H=0'), 

1716 ('TotalParameterCount','<L'), 

1717 ('TotalDataCount','<L'), 

1718 ('MaxParameterCount','<L=1024'), 

1719 ('MaxDataCount','<L=65504'), 

1720 ('ParameterCount','<L'), 

1721 ('ParameterOffset','<L'), 

1722 ('DataCount','<L'), 

1723 ('DataOffset','<L'), 

1724 ('SetupCount','<B=len(Setup)//2'), 

1725 ('Function','<H=0'), 

1726 ('SetupLength','_-Setup','SetupCount*2'), 

1727 ('Setup',':'), 

1728 ) 

1729 

1730class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters): 

1731 structure = ( 

1732 ('Reserved1','3s=""'), 

1733 ('TotalParameterCount','<L'), 

1734 ('TotalDataCount','<L'), 

1735 ('ParameterCount','<L'), 

1736 ('ParameterOffset','<L'), 

1737 ('ParameterDisplacement','<L=0'), 

1738 ('DataCount','<L'), 

1739 ('DataOffset','<L'), 

1740 ('DataDisplacement','<L=0'), 

1741 ('SetupCount','<B=0'), 

1742 ('SetupLength','_-Setup','SetupCount*2'), 

1743 ('Setup',':'), 

1744 ) 

1745 

1746class SMBNTTransaction_Data(Structure): 

1747 structure = ( 

1748 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1749 ('Pad1',':'), 

1750 ('NT_Trans_ParametersLength','_-NT_Trans_Parameters','self["NT_Trans_ParametersLength"]'), 

1751 ('NT_Trans_Parameters',':'), 

1752 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1753 ('Pad2',':'), 

1754 ('NT_Trans_DataLength','_-NT_Trans_Data','self["NT_Trans_DataLength"]'), 

1755 ('NT_Trans_Data',':'), 

1756 ) 

1757 

1758class SMBNTTransactionResponse_Data(Structure): 

1759 structure = ( 

1760 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1761 ('Pad1',':'), 

1762 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1763 ('Trans_Parameters',':'), 

1764 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1765 ('Pad2',':'), 

1766 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1767 ('Trans_Data',':'), 

1768 ) 

1769 

1770 

1771############# SMB_COM_TRANSACTION2_SECONDARY (0x33) 

1772class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters): 

1773 structure = ( 

1774 ('TotalParameterCount','<H'), 

1775 ('TotalDataCount','<H'), 

1776 ('ParameterCount','<H'), 

1777 ('ParameterOffset','<H'), 

1778 ('ParameterDisplacement','<H'), 

1779 ('DataCount','<H'), 

1780 ('DataOffset','<H'), 

1781 ('DataDisplacement','<H=0'), 

1782 ('FID','<H'), 

1783 ) 

1784 

1785class SMBTransaction2Secondary_Data(Structure): 

1786 structure = ( 

1787 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1788 ('Pad1',':'), 

1789 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1790 ('Trans_Parameters',':'), 

1791 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1792 ('Pad2',':'), 

1793 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1794 ('Trans_Data',':'), 

1795 ) 

1796 

1797 

1798############# SMB_COM_TRANSACTION2 (0x32) 

1799 

1800class SMBTransaction2_Parameters(SMBCommand_Parameters): 

1801 structure = ( 

1802 ('TotalParameterCount','<H'), 

1803 ('TotalDataCount','<H'), 

1804 ('MaxParameterCount','<H=1024'), 

1805 ('MaxDataCount','<H=65504'), 

1806 ('MaxSetupCount','<B=0'), 

1807 ('Reserved1','<B=0'), 

1808 ('Flags','<H=0'), 

1809 ('Timeout','<L=0'), 

1810 ('Reserved2','<H=0'), 

1811 ('ParameterCount','<H'), 

1812 ('ParameterOffset','<H'), 

1813 ('DataCount','<H'), 

1814 ('DataOffset','<H'), 

1815 ('SetupCount','<B=len(Setup)//2'), 

1816 ('Reserved3','<B=0'), 

1817 ('SetupLength','_-Setup','SetupCount*2'), 

1818 ('Setup',':'), 

1819 ) 

1820 

1821class SMBTransaction2Response_Parameters(SMBCommand_Parameters): 

1822 structure = ( 

1823 ('TotalParameterCount','<H'), 

1824 ('TotalDataCount','<H'), 

1825 ('Reserved1','<H=0'), 

1826 ('ParameterCount','<H'), 

1827 ('ParameterOffset','<H'), 

1828 ('ParameterDisplacement','<H=0'), 

1829 ('DataCount','<H'), 

1830 ('DataOffset','<H'), 

1831 ('DataDisplacement','<H=0'), 

1832 ('SetupCount','<B=0'), 

1833 ('Reserved2','<B=0'), 

1834 ('SetupLength','_-Setup','SetupCount*2'), 

1835 ('Setup',':'), 

1836 ) 

1837 

1838class SMBTransaction2_Data(Structure): 

1839 structure = ( 

1840# ('NameLength','_-Name','1'), 

1841# ('Name',':'), 

1842 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1843 ('Pad1',':'), 

1844 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1845 ('Trans_Parameters',':'), 

1846 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1847 ('Pad2',':'), 

1848 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1849 ('Trans_Data',':'), 

1850 ) 

1851 

1852class SMBTransaction2Response_Data(Structure): 

1853 structure = ( 

1854 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1855 ('Pad1',':'), 

1856 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1857 ('Trans_Parameters',':'), 

1858 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1859 ('Pad2',':'), 

1860 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1861 ('Trans_Data',':'), 

1862 ) 

1863 

1864############# SMB_COM_QUERY_INFORMATION (0x08) 

1865 

1866class SMBQueryInformation_Data(AsciiOrUnicodeStructure): 

1867 AsciiStructure = ( 

1868 ('BufferFormat','B=4'), 

1869 ('FileName','z'), 

1870 ) 

1871 UnicodeStructure = ( 

1872 ('BufferFormat','B=4'), 

1873 ('FileName','u'), 

1874 ) 

1875 

1876 

1877class SMBQueryInformationResponse_Parameters(Structure): 

1878 structure = ( 

1879 ('FileAttributes','<H'), 

1880 ('LastWriteTime','<L'), 

1881 ('FileSize','<L'), 

1882 ('Reserved','"0123456789'), 

1883 ) 

1884 

1885############# SMB_COM_TRANSACTION (0x25) 

1886class SMBTransaction_Parameters(SMBCommand_Parameters): 

1887 structure = ( 

1888 ('TotalParameterCount','<H'), 

1889 ('TotalDataCount','<H'), 

1890 ('MaxParameterCount','<H=1024'), 

1891 ('MaxDataCount','<H=65504'), 

1892 ('MaxSetupCount','<B=0'), 

1893 ('Reserved1','<B=0'), 

1894 ('Flags','<H=0'), 

1895 ('Timeout','<L=0'), 

1896 ('Reserved2','<H=0'), 

1897 ('ParameterCount','<H'), 

1898 ('ParameterOffset','<H'), 

1899 ('DataCount','<H'), 

1900 ('DataOffset','<H'), 

1901 ('SetupCount','<B=len(Setup)//2'), 

1902 ('Reserved3','<B=0'), 

1903 ('SetupLength','_-Setup','SetupCount*2'), 

1904 ('Setup',':'), 

1905 ) 

1906 

1907class SMBTransactionResponse_Parameters(SMBCommand_Parameters): 

1908 structure = ( 

1909 ('TotalParameterCount','<H'), 

1910 ('TotalDataCount','<H'), 

1911 ('Reserved1','<H=0'), 

1912 ('ParameterCount','<H'), 

1913 ('ParameterOffset','<H'), 

1914 ('ParameterDisplacement','<H=0'), 

1915 ('DataCount','<H'), 

1916 ('DataOffset','<H'), 

1917 ('DataDisplacement','<H=0'), 

1918 ('SetupCount','<B'), 

1919 ('Reserved2','<B=0'), 

1920 ('SetupLength','_-Setup','SetupCount*2'), 

1921 ('Setup',':'), 

1922 ) 

1923 

1924# TODO: We should merge these both. But this will require fixing 

1925# the instances where this structure is used on the client side 

1926class SMBTransaction_SData(AsciiOrUnicodeStructure): 

1927 AsciiStructure = ( 

1928 ('Name','z'), 

1929 ('Trans_ParametersLength','_-Trans_Parameters'), 

1930 ('Trans_Parameters',':'), 

1931 ('Trans_DataLength','_-Trans_Data'), 

1932 ('Trans_Data',':'), 

1933 ) 

1934 UnicodeStructure = ( 

1935 ('Pad','B'), 

1936 ('Name','u'), 

1937 ('Trans_ParametersLength','_-Trans_Parameters'), 

1938 ('Trans_Parameters',':'), 

1939 ('Trans_DataLength','_-Trans_Data'), 

1940 ('Trans_Data',':'), 

1941 ) 

1942 

1943class SMBTransaction_Data(Structure): 

1944 structure = ( 

1945 ('NameLength','_-Name'), 

1946 ('Name',':'), 

1947 ('Trans_ParametersLength','_-Trans_Parameters'), 

1948 ('Trans_Parameters',':'), 

1949 ('Trans_DataLength','_-Trans_Data'), 

1950 ('Trans_Data',':'), 

1951 ) 

1952 

1953class SMBTransactionResponse_Data(Structure): 

1954 structure = ( 

1955 ('Trans_ParametersLength','_-Trans_Parameters'), 

1956 ('Trans_Parameters',':'), 

1957 ('Trans_DataLength','_-Trans_Data'), 

1958 ('Trans_Data',':'), 

1959 ) 

1960 

1961############# SMB_COM_READ_ANDX (0x2E) 

1962class SMBReadAndX_Parameters(SMBAndXCommand_Parameters): 

1963 structure = ( 

1964 ('Fid','<H'), 

1965 ('Offset','<L'), 

1966 ('MaxCount','<H'), 

1967 ('MinCount','<H=MaxCount'), 

1968 ('_reserved','<L=0x0'), 

1969 ('Remaining','<H=MaxCount'), 

1970 ('HighOffset','<L=0'), 

1971 ) 

1972 

1973class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters): 

1974 structure = ( 

1975 ('Fid','<H'), 

1976 ('Offset','<L'), 

1977 ('MaxCount','<H'), 

1978 ('MinCount','<H=MaxCount'), 

1979 ('_reserved','<L=0xffffffff'), 

1980 ('Remaining','<H=MaxCount'), 

1981 ) 

1982 

1983class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1984 structure = ( 

1985 ('Remaining','<H=0'), 

1986 ('DataMode','<H=0'), 

1987 ('_reserved','<H=0'), 

1988 ('DataCount','<H'), 

1989 ('DataOffset','<H'), 

1990 ('DataCount_Hi','<L'), 

1991 ('_reserved2','6s=""'), 

1992 ) 

1993 

1994############# SMB_COM_ECHO (0x2B) 

1995class SMBEcho_Data(Structure): 

1996 structure = ( 

1997 ('Data',':'), 

1998 ) 

1999 

2000class SMBEcho_Parameters(Structure): 

2001 structure = ( 

2002 ('EchoCount','<H'), 

2003 ) 

2004 

2005class SMBEchoResponse_Data(Structure): 

2006 structure = ( 

2007 ('Data',':'), 

2008 ) 

2009 

2010class SMBEchoResponse_Parameters(Structure): 

2011 structure = ( 

2012 ('SequenceNumber','<H=1'), 

2013 ) 

2014 

2015############# SMB_COM_QUERY_INFORMATION_DISK (0x80) 

2016class SMBQueryInformationDiskResponse_Parameters(Structure): 

2017 structure = ( 

2018 ('TotalUnits','<H'), 

2019 ('BlocksPerUnit','<H'), 

2020 ('BlockSize','<H'), 

2021 ('FreeUnits','<H'), 

2022 ('Reserved','<H=0'), 

2023 ) 

2024 

2025 

2026############# SMB_COM_LOGOFF_ANDX (0x74) 

2027class SMBLogOffAndX(SMBAndXCommand_Parameters): 

2028 strucure = () 

2029 

2030############# SMB_COM_CLOSE (0x04) 

2031class SMBClose_Parameters(SMBCommand_Parameters): 

2032 structure = ( 

2033 ('FID','<H'), 

2034 ('Time','<L=0'), 

2035 ) 

2036 

2037############# SMB_COM_FLUSH (0x05) 

2038class SMBFlush_Parameters(SMBCommand_Parameters): 

2039 structure = ( 

2040 ('FID','<H'), 

2041 ) 

2042 

2043############# SMB_COM_CREATE_DIRECTORY (0x00) 

2044class SMBCreateDirectory_Data(AsciiOrUnicodeStructure): 

2045 AsciiStructure = ( 

2046 ('BufferFormat','<B=4'), 

2047 ('DirectoryName','z'), 

2048 ) 

2049 UnicodeStructure = ( 

2050 ('BufferFormat','<B=4'), 

2051 ('DirectoryName','u'), 

2052 ) 

2053 

2054############# SMB_COM_DELETE (0x06) 

2055class SMBDelete_Data(AsciiOrUnicodeStructure): 

2056 AsciiStructure = ( 

2057 ('BufferFormat','<B=4'), 

2058 ('FileName','z'), 

2059 ) 

2060 UnicodeStructure = ( 

2061 ('BufferFormat','<B=4'), 

2062 ('FileName','u'), 

2063 ) 

2064 

2065class SMBDelete_Parameters(Structure): 

2066 structure = ( 

2067 ('SearchAttributes','<H'), 

2068 ) 

2069 

2070############# SMB_COM_DELETE_DIRECTORY (0x01) 

2071class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure): 

2072 AsciiStructure = ( 

2073 ('BufferFormat','<B=4'), 

2074 ('DirectoryName','z'), 

2075 ) 

2076 UnicodeStructure = ( 

2077 ('BufferFormat','<B=4'), 

2078 ('DirectoryName','u'), 

2079 ) 

2080 

2081############# SMB_COM_CHECK_DIRECTORY (0x10) 

2082class SMBCheckDirectory_Data(AsciiOrUnicodeStructure): 

2083 AsciiStructure = ( 

2084 ('BufferFormat','<B=4'), 

2085 ('DirectoryName','z'), 

2086 ) 

2087 UnicodeStructure = ( 

2088 ('BufferFormat','<B=4'), 

2089 ('DirectoryName','u'), 

2090 ) 

2091 

2092############# SMB_COM_RENAME (0x07) 

2093class SMBRename_Parameters(SMBCommand_Parameters): 

2094 structure = ( 

2095 ('SearchAttributes','<H'), 

2096 ) 

2097 

2098class SMBRename_Data(AsciiOrUnicodeStructure): 

2099 AsciiStructure = ( 

2100 ('BufferFormat1','<B=4'), 

2101 ('OldFileName','z'), 

2102 ('BufferFormat2','<B=4'), 

2103 ('NewFileName','z'), 

2104 ) 

2105 UnicodeStructure = ( 

2106 ('BufferFormat1','<B=4'), 

2107 ('OldFileName','u'), 

2108 ('BufferFormat2','<B=4'), 

2109 ('Pad','B=0'), 

2110 ('NewFileName','u'), 

2111 ) 

2112 

2113 

2114############# SMB_COM_OPEN (0x02) 

2115class SMBOpen_Parameters(SMBCommand_Parameters): 

2116 structure = ( 

2117 ('DesiredAccess','<H=0'), 

2118 ('SearchAttributes','<H=0'), 

2119 ) 

2120 

2121class SMBOpen_Data(AsciiOrUnicodeStructure): 

2122 AsciiStructure = ( 

2123 ('FileNameFormat','"\x04'), 

2124 ('FileName','z'), 

2125 ) 

2126 UnicodeStructure = ( 

2127 ('FileNameFormat','"\x04'), 

2128 ('FileName','u'), 

2129 ) 

2130 

2131class SMBOpenResponse_Parameters(SMBCommand_Parameters): 

2132 structure = ( 

2133 ('Fid','<H=0'), 

2134 ('FileAttributes','<H=0'), 

2135 ('LastWriten','<L=0'), 

2136 ('FileSize','<L=0'), 

2137 ('GrantedAccess','<H=0'), 

2138 ) 

2139 

2140############# EXTENDED SECURITY CLASSES 

2141class SMBExtended_Security_Parameters(Structure): 

2142 structure = ( 

2143 ('DialectIndex','<H'), 

2144 ('SecurityMode','<B'), 

2145 ('MaxMpxCount','<H'), 

2146 ('MaxNumberVcs','<H'), 

2147 ('MaxBufferSize','<L'), 

2148 ('MaxRawSize','<L'), 

2149 ('SessionKey','<L'), 

2150 ('Capabilities','<L'), 

2151 ('LowDateTime','<L'), 

2152 ('HighDateTime','<L'), 

2153 ('ServerTimeZone','<H'), 

2154 ('ChallengeLength','<B'), 

2155 ) 

2156 

2157class SMBExtended_Security_Data(Structure): 

2158 structure = ( 

2159 ('ServerGUID','16s'), 

2160 ('SecurityBlob',':'), 

2161 ) 

2162 

2163class SMBNTLMDialect_Parameters(Structure): 

2164 structure = ( 

2165 ('DialectIndex','<H'), 

2166 ('SecurityMode','<B'), 

2167 ('MaxMpxCount','<H'), 

2168 ('MaxNumberVcs','<H'), 

2169 ('MaxBufferSize','<L'), 

2170 ('MaxRawSize','<L'), 

2171 ('SessionKey','<L'), 

2172 ('Capabilities','<L'), 

2173 ('LowDateTime','<L'), 

2174 ('HighDateTime','<L'), 

2175 ('ServerTimeZone','<H'), 

2176 ('ChallengeLength','<B'), 

2177 ) 

2178 

2179class SMBNTLMDialect_Data(Structure): 

2180 structure = ( 

2181 ('ChallengeLength','_-Challenge','self["ChallengeLength"]'), 

2182 ('Challenge',':'), 

2183 ('Payload',':'), 

2184# For some reason on an old Linux this field is not present, we have to check this out. There must be a flag stating this. 

2185 ('DomainName','_'), 

2186 ('ServerName','_'), 

2187 ) 

2188 def __init__(self,data = None, alignment = 0): 

2189 Structure.__init__(self,data,alignment) 

2190 #self['ChallengeLength']=8 

2191 

2192 def fromString(self,data): 

2193 Structure.fromString(self,data) 

2194 self['DomainName'] = '' 

2195 self['ServerName'] = '' 

2196 

2197class SMB(object): 

2198 

2199 class HostnameValidationException(Exception): 

2200 pass 

2201 

2202 # SMB Command Codes 

2203 SMB_COM_CREATE_DIRECTORY = 0x00 

2204 SMB_COM_DELETE_DIRECTORY = 0x01 

2205 SMB_COM_OPEN = 0x02 

2206 SMB_COM_CREATE = 0x03 

2207 SMB_COM_CLOSE = 0x04 

2208 SMB_COM_FLUSH = 0x05 

2209 SMB_COM_DELETE = 0x06 

2210 SMB_COM_RENAME = 0x07 

2211 SMB_COM_QUERY_INFORMATION = 0x08 

2212 SMB_COM_SET_INFORMATION = 0x09 

2213 SMB_COM_READ = 0x0A 

2214 SMB_COM_WRITE = 0x0B 

2215 SMB_COM_LOCK_BYTE_RANGE = 0x0C 

2216 SMB_COM_UNLOCK_BYTE_RANGE = 0x0D 

2217 SMB_COM_CREATE_TEMPORARY = 0x0E 

2218 SMB_COM_CREATE_NEW = 0x0F 

2219 SMB_COM_CHECK_DIRECTORY = 0x10 

2220 SMB_COM_PROCESS_EXIT = 0x11 

2221 SMB_COM_SEEK = 0x12 

2222 SMB_COM_LOCK_AND_READ = 0x13 

2223 SMB_COM_WRITE_AND_UNLOCK = 0x14 

2224 SMB_COM_READ_RAW = 0x1A 

2225 SMB_COM_READ_MPX = 0x1B 

2226 SMB_COM_READ_MPX_SECONDARY = 0x1C 

2227 SMB_COM_WRITE_RAW = 0x1D 

2228 SMB_COM_WRITE_MPX = 0x1E 

2229 SMB_COM_WRITE_MPX_SECONDARY = 0x1F 

2230 SMB_COM_WRITE_COMPLETE = 0x20 

2231 SMB_COM_QUERY_SERVER = 0x21 

2232 SMB_COM_SET_INFORMATION2 = 0x22 

2233 SMB_COM_QUERY_INFORMATION2 = 0x23 

2234 SMB_COM_LOCKING_ANDX = 0x24 

2235 SMB_COM_TRANSACTION = 0x25 

2236 SMB_COM_TRANSACTION_SECONDARY = 0x26 

2237 SMB_COM_IOCTL = 0x27 

2238 SMB_COM_IOCTL_SECONDARY = 0x28 

2239 SMB_COM_COPY = 0x29 

2240 SMB_COM_MOVE = 0x2A 

2241 SMB_COM_ECHO = 0x2B 

2242 SMB_COM_WRITE_AND_CLOSE = 0x2C 

2243 SMB_COM_OPEN_ANDX = 0x2D 

2244 SMB_COM_READ_ANDX = 0x2E 

2245 SMB_COM_WRITE_ANDX = 0x2F 

2246 SMB_COM_NEW_FILE_SIZE = 0x30 

2247 SMB_COM_CLOSE_AND_TREE_DISC = 0x31 

2248 SMB_COM_TRANSACTION2 = 0x32 

2249 SMB_COM_TRANSACTION2_SECONDARY = 0x33 

2250 SMB_COM_FIND_CLOSE2 = 0x34 

2251 SMB_COM_FIND_NOTIFY_CLOSE = 0x35 

2252 # Used by Xenix/Unix 0x60 - 0x6E 

2253 SMB_COM_TREE_CONNECT = 0x70 

2254 SMB_COM_TREE_DISCONNECT = 0x71 

2255 SMB_COM_NEGOTIATE = 0x72 

2256 SMB_COM_SESSION_SETUP_ANDX = 0x73 

2257 SMB_COM_LOGOFF_ANDX = 0x74 

2258 SMB_COM_TREE_CONNECT_ANDX = 0x75 

2259 SMB_COM_QUERY_INFORMATION_DISK = 0x80 

2260 SMB_COM_SEARCH = 0x81 

2261 SMB_COM_FIND = 0x82 

2262 SMB_COM_FIND_UNIQUE = 0x83 

2263 SMB_COM_FIND_CLOSE = 0x84 

2264 SMB_COM_NT_TRANSACT = 0xA0 

2265 SMB_COM_NT_TRANSACT_SECONDARY = 0xA1 

2266 SMB_COM_NT_CREATE_ANDX = 0xA2 

2267 SMB_COM_NT_CANCEL = 0xA4 

2268 SMB_COM_NT_RENAME = 0xA5 

2269 SMB_COM_OPEN_PRINT_FILE = 0xC0 

2270 SMB_COM_WRITE_PRINT_FILE = 0xC1 

2271 SMB_COM_CLOSE_PRINT_FILE = 0xC2 

2272 SMB_COM_GET_PRINT_QUEUE = 0xC3 

2273 SMB_COM_READ_BULK = 0xD8 

2274 SMB_COM_WRITE_BULK = 0xD9 

2275 SMB_COM_WRITE_BULK_DATA = 0xDA 

2276 

2277 # TRANSACT codes 

2278 TRANS_TRANSACT_NMPIPE = 0x26 

2279 

2280 # TRANSACT2 codes 

2281 TRANS2_FIND_FIRST2 = 0x0001 

2282 TRANS2_FIND_NEXT2 = 0x0002 

2283 TRANS2_QUERY_FS_INFORMATION = 0x0003 

2284 TRANS2_QUERY_PATH_INFORMATION = 0x0005 

2285 TRANS2_QUERY_FILE_INFORMATION = 0x0007 

2286 TRANS2_SET_FILE_INFORMATION = 0x0008 

2287 TRANS2_SET_PATH_INFORMATION = 0x0006 

2288 

2289 # Security Share Mode (Used internally by SMB class) 

2290 SECURITY_SHARE_MASK = 0x01 

2291 SECURITY_SHARE_SHARE = 0x00 

2292 SECURITY_SHARE_USER = 0x01 

2293 SECURITY_SIGNATURES_ENABLED = 0X04 

2294 SECURITY_SIGNATURES_REQUIRED = 0X08 

2295 

2296 # Security Auth Mode (Used internally by SMB class) 

2297 SECURITY_AUTH_MASK = 0x02 

2298 SECURITY_AUTH_ENCRYPTED = 0x02 

2299 SECURITY_AUTH_PLAINTEXT = 0x00 

2300 

2301 # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and including LANMAN2.1) 

2302 RAW_READ_MASK = 0x01 

2303 RAW_WRITE_MASK = 0x02 

2304 

2305 # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 0.12) 

2306 CAP_RAW_MODE = 0x00000001 

2307 CAP_MPX_MODE = 0x0002 

2308 CAP_UNICODE = 0x0004 

2309 CAP_LARGE_FILES = 0x0008 

2310 CAP_EXTENDED_SECURITY = 0x80000000 

2311 CAP_USE_NT_ERRORS = 0x40 

2312 CAP_NT_SMBS = 0x10 

2313 CAP_LARGE_READX = 0x00004000 

2314 CAP_LARGE_WRITEX = 0x00008000 

2315 CAP_RPC_REMOTE_APIS = 0x20 

2316 

2317 # Flags1 Mask 

2318 FLAGS1_LOCK_AND_READ_OK = 0x01 

2319 FLAGS1_PATHCASELESS = 0x08 

2320 FLAGS1_CANONICALIZED_PATHS = 0x10 

2321 FLAGS1_REPLY = 0x80 

2322 

2323 # Flags2 Mask 

2324 FLAGS2_LONG_NAMES = 0x0001 

2325 FLAGS2_EAS = 0x0002 

2326 FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004 

2327 FLAGS2_IS_LONG_NAME = 0x0040 

2328 FLAGS2_DFS = 0x1000 

2329 FLAGS2_PAGING_IO = 0x2000 

2330 FLAGS2_NT_STATUS = 0x4000 

2331 FLAGS2_UNICODE = 0x8000 

2332 FLAGS2_COMPRESSED = 0x0008 

2333 FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED = 0x0010 

2334 FLAGS2_EXTENDED_SECURITY = 0x0800 

2335 

2336 # Dialect's Security Mode flags 

2337 NEGOTIATE_USER_SECURITY = 0x01 

2338 NEGOTIATE_ENCRYPT_PASSWORDS = 0x02 

2339 NEGOTIATE_SECURITY_SIGNATURE_ENABLE = 0x04 

2340 NEGOTIATE_SECURITY_SIGNATURE_REQUIRED = 0x08 

2341 

2342 # Tree Connect AndX Response optionalSuppor flags 

2343 SMB_SUPPORT_SEARCH_BITS = 0x01 

2344 SMB_SHARE_IS_IN_DFS = 0x02 

2345 

2346 def __init__(self, remote_name, remote_host, my_name=None, host_type=nmb.TYPE_SERVER, sess_port=445, timeout=None, 

2347 UDP=0, session=None, negPacket=None): 

2348 # The uid attribute will be set when the client calls the login() method 

2349 self._uid = 0 

2350 self.__server_name = '' 

2351 self.__client_name = '' 

2352 self.__server_os = '' 

2353 self.__server_os_major = None 

2354 self.__server_os_minor = None 

2355 self.__server_os_build = None 

2356 self.__server_lanman = '' 

2357 self.__server_domain = '' 

2358 self.__server_dns_domain_name = '' 

2359 self.__server_dns_host_name = '' 

2360 self.__remote_name = remote_name.upper() 

2361 self.__remote_host = remote_host 

2362 self.__isNTLMv2 = True 

2363 self._dialects_parameters = None 

2364 self._dialects_data = None 

2365 self._doKerberos = False 

2366 

2367 # Credentials 

2368 self.__userName = b'' 

2369 self.__password = b'' 

2370 self.__domain = b'' 

2371 self.__lmhash = b'' 

2372 self.__nthash = b'' 

2373 self.__aesKey = b'' 

2374 self.__kdc = b'' 

2375 self.__TGT = None 

2376 self.__TGS = None 

2377 

2378 # Negotiate Protocol Result, used everywhere 

2379 # Could be extended or not, flags should be checked before 

2380 self._dialect_data = 0 

2381 self._dialect_parameters = 0 

2382 self._action = 0 

2383 self._sess = None 

2384 self.encrypt_passwords = True 

2385 self.tid = 0 

2386 self.fid = 0 

2387 

2388 # Strict host validation - off by default 

2389 self._strict_hostname_validation = False 

2390 self._validation_allow_absent = True 

2391 self._accepted_hostname = '' 

2392 

2393 # Signing stuff 

2394 self._SignSequenceNumber = 0 

2395 self._SigningSessionKey = b'' 

2396 self._SigningChallengeResponse = b'' 

2397 self._SignatureEnabled = False 

2398 self._SignatureVerificationEnabled = False 

2399 self._SignatureRequired = False 

2400 

2401 # Base flags (default flags, can be overridden using set_flags()) 

2402 self.__flags1 = SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS 

2403 self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES 

2404 

2405 if timeout is None: 2405 ↛ 2406line 2405 didn't jump to line 2406, because the condition on line 2405 was never true

2406 self.__timeout = 60 

2407 else: 

2408 self.__timeout = timeout 

2409 

2410 # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP. 

2411 # This is to help some old applications still believing 

2412 # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better 

2413 # know about *SMBSERVER's limitations 

2414 if sess_port == 445 and remote_name == '*SMBSERVER': 2414 ↛ 2415line 2414 didn't jump to line 2415, because the condition on line 2414 was never true

2415 self.__remote_name = remote_host 

2416 

2417 # This is on purpose. I'm still not convinced to do a socket.gethostname() if not specified 

2418 if my_name is None: 2418 ↛ 2421line 2418 didn't jump to line 2421, because the condition on line 2418 was never false

2419 self.__client_name = b'' 

2420 else: 

2421 self.__client_name = my_name 

2422 

2423 if session is None: 2423 ↛ 2445line 2423 didn't jump to line 2445, because the condition on line 2423 was never false

2424 if not my_name: 2424 ↛ 2431line 2424 didn't jump to line 2431, because the condition on line 2424 was never false

2425 # If destination port is 139 yes, there's some client disclosure 

2426 my_name = socket.gethostname() 

2427 i = my_name.find('.') 

2428 if i > -1: 2428 ↛ 2429line 2428 didn't jump to line 2429, because the condition on line 2428 was never true

2429 my_name = my_name[:i] 

2430 

2431 if UDP: 2431 ↛ 2432line 2431 didn't jump to line 2432, because the condition on line 2431 was never true

2432 self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 

2433 else: 

2434 self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 

2435 

2436 # Initialize session values (_dialect_data and _dialect_parameters) 

2437 self.neg_session() 

2438 

2439 # Call login() without any authentication information to 

2440 # setup a session if the remote server 

2441 # is in share mode. 

2442 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 2442 ↛ 2443line 2442 didn't jump to line 2443, because the condition on line 2442 was never true

2443 self.login('', '') 

2444 else: 

2445 self._sess = session 

2446 self.neg_session(negPacket = negPacket) 

2447 # Call login() without any authentication information to 

2448 # setup a session if the remote server 

2449 # is in share mode. 

2450 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 

2451 self.login('', '') 

2452 

2453 @staticmethod 

2454 def ntlm_supported(): 

2455 return False 

2456 

2457 def getKerberos(self): 

2458 return self._doKerberos 

2459 

2460 def get_remote_name(self): 

2461 return self.__remote_name 

2462 

2463 def set_remote_name(self, name): 

2464 self.__remote_name = name 

2465 return True 

2466 

2467 def set_hostname_validation(self, validate, accept_empty, hostname): 

2468 self._strict_hostname_validation = validate 

2469 self._validation_allow_absent = accept_empty 

2470 self._accepted_hostname = hostname 

2471 

2472 def get_remote_host(self): 

2473 return self.__remote_host 

2474 

2475 def get_flags(self): 

2476 return self.__flags1, self.__flags2 

2477 

2478 def set_flags(self, flags1=None, flags2=None): 

2479 if flags1 is not None: 

2480 self.__flags1 = flags1 

2481 if flags2 is not None: 2481 ↛ exitline 2481 didn't return from function 'set_flags', because the condition on line 2481 was never false

2482 self.__flags2 = flags2 

2483 

2484 def set_timeout(self, timeout): 

2485 prev_timeout = self.__timeout 

2486 self.__timeout = timeout 

2487 return prev_timeout 

2488 

2489 def get_timeout(self): 

2490 return self.__timeout 

2491 

2492 @contextmanager 

2493 def use_timeout(self, timeout): 

2494 prev_timeout = self.set_timeout(timeout) 

2495 try: 

2496 yield 

2497 finally: 

2498 self.set_timeout(prev_timeout) 

2499 

2500 def get_session(self): 

2501 return self._sess 

2502 

2503 def get_tid(self): 

2504 return self.tid 

2505 

2506 def get_fid(self): 

2507 return self.fid 

2508 

2509 def isGuestSession(self): 

2510 return self._action & SMB_SETUP_GUEST 

2511 

2512 def doesSupportNTLMv2(self): 

2513 return self.__isNTLMv2 

2514 

2515 def close_session(self): 

2516 if self._sess: 2516 ↛ exitline 2516 didn't return from function 'close_session', because the condition on line 2516 was never false

2517 self._sess.close() 

2518 self._sess = None 

2519 

2520 def recvSMB(self): 

2521 r = self._sess.recv_packet(self.__timeout) 

2522 return NewSMBPacket(data = r.get_trailer()) 

2523 

2524 @staticmethod 

2525 def __decode_trans(params, data): 

2526 totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19]) 

2527 if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt: 

2528 has_more = 1 

2529 else: 

2530 has_more = 0 

2531 paramoffset = paramoffset - 55 - setupcnt * 2 

2532 dataoffset = dataoffset - 55 - setupcnt * 2 

2533 return has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt] 

2534 

2535 # TODO: Move this to NewSMBPacket, it belongs there 

2536 def signSMB(self, packet, signingSessionKey, signingChallengeResponse): 

2537 # This logic MUST be applied for messages sent in response to any of the higher-layer actions and in 

2538 # compliance with the message sequencing rules. 

2539 # * The client or server that sends the message MUST provide the 32-bit sequence number for this 

2540 # message, as specified in sections 3.2.4.1 and 3.3.4.1. 

2541 # * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be set. 

2542 # * To generate the signature, a 32-bit sequence number is copied into the 

2543 # least significant 32 bits of the SecuritySignature field and the remaining 

2544 # 4 bytes are set to 0x00. 

2545 # * The MD5 algorithm, as specified in [RFC1321], MUST be used to generate a hash of the SMB 

2546 # message from the start of the SMB Header, which is defined as follows. 

2547 # CALL MD5Init( md5context ) 

2548 # CALL MD5Update( md5context, Connection.SigningSessionKey ) 

2549 # CALL MD5Update( md5context, Connection.SigningChallengeResponse ) 

2550 # CALL MD5Update( md5context, SMB message ) 

2551 # CALL MD5Final( digest, md5context ) 

2552 # SET signature TO the first 8 bytes of the digest 

2553 # The resulting 8-byte signature MUST be copied into the SecuritySignature field of the SMB Header, 

2554 # after which the message can be transmitted. 

2555 

2556 #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % (self._SignSequenceNumber, signingSessionKey, signingChallengeResponse) 

2557 packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber) 

2558 # Sign with the sequence 

2559 m = hashlib.md5() 

2560 m.update( signingSessionKey ) 

2561 m.update( signingChallengeResponse ) 

2562 m.update( packet.getData() ) 

2563 # Replace sequence with acual hash 

2564 packet['SecurityFeatures'] = m.digest()[:8] 

2565 if self._SignatureVerificationEnabled: 2565 ↛ 2566line 2565 didn't jump to line 2566, because the condition on line 2565 was never true

2566 self._SignSequenceNumber +=1 

2567 else: 

2568 self._SignSequenceNumber +=2 

2569 

2570 def checkSignSMB(self, packet, signingSessionKey, signingChallengeResponse): 

2571 # Let's check 

2572 signature = packet['SecurityFeatures'] 

2573 #print "Signature received: %r " % signature 

2574 self.signSMB(packet, signingSessionKey, signingChallengeResponse) 

2575 #print "Signature calculated: %r" % packet['SecurityFeatures'] 

2576 if self._SignatureVerificationEnabled is not True: 

2577 self._SignSequenceNumber -= 1 

2578 return packet['SecurityFeatures'] == signature 

2579 

2580 def sendSMB(self,smb): 

2581 smb['Uid'] = self._uid 

2582 #At least on AIX, PIDs can exceed 16 bits, so we mask them out 

2583 smb['Pid'] = (os.getpid() & 0xFFFF) 

2584 # set flags 

2585 smb['Flags1'] |= self.__flags1 

2586 smb['Flags2'] |= self.__flags2 

2587 if self._SignatureEnabled: 

2588 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

2589 self.signSMB(smb, self._SigningSessionKey, self._SigningChallengeResponse) 

2590 

2591 self._sess.send_packet(smb.getData()) 

2592 

2593 @staticmethod 

2594 def isValidAnswer(s, cmd): 

2595 while 1: 

2596 if s.rawData(): 

2597 if s.get_command() == cmd: 

2598 if s.get_error_class() == 0x00 and s.get_error_code() == 0x00: 

2599 return 1 

2600 else: 

2601 raise SessionError( "SMB Library Error", s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , s.get_flags2() & SMB.FLAGS2_NT_STATUS) 

2602 else: 

2603 break 

2604 return 0 

2605 

2606 def neg_session(self, extended_security = True, negPacket = None): 

2607 def parsePacket(smb): 

2608 # If server speaks Unicode, let's set that flag from now on 

2609 if smb['Flags2'] & SMB.FLAGS2_UNICODE: 2609 ↛ 2610line 2609 didn't jump to line 2610, because the condition on line 2609 was never true

2610 self.__flags2 |= SMB.FLAGS2_UNICODE 

2611 

2612 if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE): 2612 ↛ 2641line 2612 didn't jump to line 2641, because the condition on line 2612 was never false

2613 sessionResponse = SMBCommand(smb['Data'][0]) 

2614 self._dialects_parameters = SMBNTLMDialect_Parameters(sessionResponse['Parameters']) 

2615 self._dialects_data = SMBNTLMDialect_Data() 

2616 self._dialects_data['ChallengeLength'] = self._dialects_parameters['ChallengeLength'] 

2617 self._dialects_data.fromString(sessionResponse['Data']) 

2618 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 2618 ↛ 2634line 2618 didn't jump to line 2634, because the condition on line 2618 was never false

2619 # Whether we choose it or it is enforced by the server, we go for extended security 

2620 self._dialects_parameters = SMBExtended_Security_Parameters(sessionResponse['Parameters']) 

2621 self._dialects_data = SMBExtended_Security_Data(sessionResponse['Data']) 

2622 # Let's setup some variable for later use 

2623 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 2623 ↛ 2630line 2623 didn't jump to line 2630, because the condition on line 2623 was never false

2624 self._SignatureRequired = True 

2625 

2626 # Interestingly, the security Blob might be missing sometimes. 

2627 #spnego = SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob']) 

2628 #for i in spnego['MechTypes']: 

2629 # print "Mech Found: %s" % MechTypes[i] 

2630 return 1 

2631 

2632 # If not, let's try the old way 

2633 else: 

2634 if self._dialects_data['ServerName'] is not None: 

2635 self.__server_name = self._dialects_data['ServerName'] 

2636 

2637 if self._dialects_parameters['DialectIndex'] == 0xffff: 

2638 raise UnsupportedFeature("Remote server does not know NT LM 0.12") 

2639 return 1 

2640 else: 

2641 return 0 

2642 

2643 if negPacket is None: 2643 ↛ 2661line 2643 didn't jump to line 2661, because the condition on line 2643 was never false

2644 smb = NewSMBPacket() 

2645 negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE) 

2646 flags2 = self.get_flags()[1] 

2647 if extended_security is True: 2647 ↛ 2650line 2647 didn't jump to line 2650, because the condition on line 2647 was never false

2648 self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY) 

2649 else: 

2650 self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY)) 

2651 

2652 negSession['Data'] = b'\x02NT LM 0.12\x00' 

2653 smb.addCommand(negSession) 

2654 self.sendSMB(smb) 

2655 

2656 while 1: 

2657 smb = self.recvSMB() 

2658 return parsePacket(smb) 

2659 else: 

2660 

2661 return parsePacket( NewSMBPacket( data = negPacket)) 

2662 

2663 def tree_connect(self, path, password = '', service = SERVICE_ANY): 

2664 LOG.warning("[MS-CIFS] This is an original Core Protocol command.This command has been deprecated.Client Implementations SHOULD use SMB_COM_TREE_CONNECT_ANDX") 

2665 

2666 # return 0x800 

2667 if password: 

2668 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 

2669 if self._dialects_parameters['ChallengeLength'] > 0: 

2670 # this code is untested 

2671 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 

2672 

2673 if not unicode_support: 

2674 if unicode_convert: 

2675 path = str(path) 

2676 else: 

2677 raise Exception('SMB: Can\t conver path from unicode!') 

2678 

2679 smb = NewSMBPacket() 

2680 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT) 

2681 treeConnect['Parameters'] = SMBTreeConnect_Parameters() 

2682 treeConnect['Data'] = SMBTreeConnect_Data() 

2683 treeConnect['Data']['Path'] = path.upper() 

2684 treeConnect['Data']['Password'] = password 

2685 treeConnect['Data']['Service'] = service 

2686 smb.addCommand(treeConnect) 

2687 self.sendSMB(smb) 

2688 

2689 while 1: 

2690 smb = self.recvSMB() 

2691 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT): 

2692 # XXX Here we are ignoring the rest of the response 

2693 return smb['Tid'] 

2694 return smb['Tid'] 

2695 

2696 def get_uid(self): 

2697 return self._uid 

2698 

2699 def set_uid(self, uid): 

2700 self._uid = uid 

2701 

2702 def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, smb_packet=None): 

2703 if password: 2703 ↛ 2705line 2703 didn't jump to line 2705, because the condition on line 2703 was never true

2704 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 

2705 if self._dialects_parameters['ChallengeLength'] > 0: 

2706 # this code is untested 

2707 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 

2708 else: 

2709 password = '\x00' 

2710 

2711 if not unicode_support: 2711 ↛ 2717line 2711 didn't jump to line 2717, because the condition on line 2711 was never false

2712 if unicode_convert: 2712 ↛ 2715line 2712 didn't jump to line 2715, because the condition on line 2712 was never false

2713 path = str(path) 

2714 else: 

2715 raise Exception('SMB: Can\t convert path from unicode!') 

2716 

2717 if smb_packet is None: 2717 ↛ 2720line 2717 didn't jump to line 2720, because the condition on line 2717 was never false

2718 smb = NewSMBPacket() 

2719 else: 

2720 smb = smb_packet 

2721 

2722 # Just in case this came with the full path ,let's just leave 

2723 # the sharename, we'll take care of the rest 

2724 

2725 share = path.split('\\')[-1] 

2726 try: 

2727 _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 80, 0, 0, socket.IPPROTO_TCP)[0] 

2728 remote_host = sockaddr[0] 

2729 except Exception: 

2730 remote_host = self.get_remote_host() 

2731 

2732 path = '\\\\' + remote_host + '\\' +share 

2733 path = path.upper().encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

2734 

2735 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX) 

2736 treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters() 

2737 treeConnect['Data'] = SMBTreeConnectAndX_Data(flags=self.__flags2) 

2738 treeConnect['Parameters']['PasswordLength'] = len(password) 

2739 treeConnect['Data']['Password'] = password 

2740 treeConnect['Data']['Path'] = path 

2741 treeConnect['Data']['Service'] = service 

2742 

2743 if self.__flags2 & SMB.FLAGS2_UNICODE: 

2744 treeConnect['Data']['Pad'] = 0x0 

2745 

2746 smb.addCommand(treeConnect) 

2747 

2748 # filename = "\PIPE\epmapper" 

2749 

2750 # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 

2751 # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 

2752 # ntCreate['Data'] = SMBNtCreateAndX_Data() 

2753 # ntCreate['Parameters']['FileNameLength'] = len(filename) 

2754 # ntCreate['Parameters']['CreateFlags'] = 0 

2755 # ntCreate['Parameters']['AccessMask'] = 0x3 

2756 # ntCreate['Parameters']['CreateOptions'] = 0x0 

2757 # ntCreate['Data']['FileName'] = filename 

2758 

2759 # smb.addCommand(ntCreate) 

2760 self.sendSMB(smb) 

2761 

2762 while 1: 

2763 smb = self.recvSMB() 

2764 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX): 2764 ↛ 2768line 2764 didn't jump to line 2768, because the condition on line 2764 was never false

2765 # XXX Here we are ignoring the rest of the response 

2766 self.tid = smb['Tid'] 

2767 return self.tid 

2768 self.tid = smb['Tid'] 

2769 return self.tid 

2770 

2771 # backwars compatibility 

2772 connect_tree = tree_connect_andx 

2773 

2774 @staticmethod 

2775 def getDialect(): 

2776 return SMB_DIALECT 

2777 

2778 def get_server_name(self): 

2779 #return self._dialects_data['ServerName'] 

2780 return self.__server_name 

2781 

2782 def get_client_name(self): 

2783 return self.__client_name 

2784 

2785 def get_session_key(self): 

2786 return self._SigningSessionKey 

2787 

2788 def set_session_key(self, key): 

2789 self._SignatureEnabled = True 

2790 self._SignSequenceNumber = 2 

2791 self._SigningSessionKey = key 

2792 

2793 def get_encryption_key(self): 

2794 if 'Challenge' in self._dialects_data.fields: 

2795 return self._dialects_data['Challenge'] 

2796 else: 

2797 return None 

2798 

2799 def get_server_time(self): 

2800 timestamp = self._dialects_parameters['HighDateTime'] 

2801 timestamp <<= 32 

2802 timestamp |= self._dialects_parameters['LowDateTime'] 

2803 timestamp -= 116444736000000000 

2804 timestamp //= 10000000 

2805 d = datetime.datetime.utcfromtimestamp(timestamp) 

2806 return d.strftime("%a, %d %b %Y %H:%M:%S GMT") 

2807 

2808 def disconnect_tree(self, tid): 

2809 smb = NewSMBPacket() 

2810 smb['Tid'] = tid 

2811 

2812 smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT)) 

2813 

2814 self.sendSMB(smb) 

2815 self.recvSMB() 

2816 

2817 def open(self, tid, filename, open_mode, desired_access): 

2818 filename = filename.replace('/', '\\') 

2819 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

2820 

2821 smb = NewSMBPacket() 

2822 smb['Tid'] = tid 

2823 

2824 openFile = SMBCommand(SMB.SMB_COM_OPEN) 

2825 openFile['Parameters'] = SMBOpen_Parameters() 

2826 openFile['Parameters']['DesiredAccess'] = desired_access 

2827 openFile['Parameters']['OpenMode'] = open_mode 

2828 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 

2829 openFile['Data'] = SMBOpen_Data(flags=self.__flags2) 

2830 openFile['Data']['FileName'] = filename 

2831 

2832 smb.addCommand(openFile) 

2833 

2834 self.sendSMB(smb) 

2835 

2836 smb = self.recvSMB() 

2837 if smb.isValidAnswer(SMB.SMB_COM_OPEN): 

2838 # XXX Here we are ignoring the rest of the response 

2839 openFileResponse = SMBCommand(smb['Data'][0]) 

2840 openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters']) 

2841 

2842 return ( 

2843 openFileParameters['Fid'], 

2844 openFileParameters['FileAttributes'], 

2845 openFileParameters['LastWriten'], 

2846 openFileParameters['FileSize'], 

2847 openFileParameters['GrantedAccess'], 

2848 ) 

2849 

2850 def open_andx(self, tid, filename, open_mode, desired_access): 

2851 filename = filename.replace('/', '\\') 

2852 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

2853 

2854 smb = NewSMBPacket() 

2855 smb['Tid'] = tid 

2856 

2857 openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX) 

2858 openFile['Parameters'] = SMBOpenAndX_Parameters() 

2859 openFile['Parameters']['DesiredAccess'] = desired_access 

2860 openFile['Parameters']['OpenMode'] = open_mode 

2861 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 

2862 openFile['Data'] = SMBOpenAndX_Data(flags=self.__flags2) 

2863 openFile['Data']['FileName'] = filename 

2864 

2865 if self.__flags2 & SMB.FLAGS2_UNICODE: 

2866 openFile['Data']['Pad'] = 0x0 

2867 

2868 smb.addCommand(openFile) 

2869 

2870 self.sendSMB(smb) 

2871 

2872 smb = self.recvSMB() 

2873 if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX): 

2874 # XXX Here we are ignoring the rest of the response 

2875 openFileResponse = SMBCommand(smb['Data'][0]) 

2876 openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters']) 

2877 

2878 return ( 

2879 openFileParameters['Fid'], 

2880 openFileParameters['FileAttributes'], 

2881 openFileParameters['LastWriten'], 

2882 openFileParameters['FileSize'], 

2883 openFileParameters['GrantedAccess'], 

2884 openFileParameters['FileType'], 

2885 openFileParameters['IPCState'], 

2886 openFileParameters['Action'], 

2887 openFileParameters['ServerFid'], 

2888 ) 

2889 

2890 def close(self, tid, fid): 

2891 smb = NewSMBPacket() 

2892 smb['Tid'] = tid 

2893 

2894 closeFile = SMBCommand(SMB.SMB_COM_CLOSE) 

2895 closeFile['Parameters'] = SMBClose_Parameters() 

2896 closeFile['Parameters']['FID'] = fid 

2897 smb.addCommand(closeFile) 

2898 

2899 self.sendSMB(smb) 

2900 smb = self.recvSMB() 

2901 if smb.isValidAnswer(SMB.SMB_COM_CLOSE): 2901 ↛ 2903line 2901 didn't jump to line 2903, because the condition on line 2901 was never false

2902 return 1 

2903 return 0 

2904 

2905 def send_trans(self, tid, setup, name, param, data, noAnswer = 0): 

2906 smb = NewSMBPacket() 

2907 smb['Tid'] = tid 

2908 

2909 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 

2910 transCommand['Parameters'] = SMBTransaction_Parameters() 

2911 transCommand['Data'] = SMBTransaction_Data() 

2912 

2913 transCommand['Parameters']['Setup'] = setup 

2914 transCommand['Parameters']['TotalParameterCount'] = len(param) 

2915 transCommand['Parameters']['TotalDataCount'] = len(data) 

2916 

2917 transCommand['Parameters']['ParameterCount'] = len(param) 

2918 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 

2919 

2920 transCommand['Parameters']['DataCount'] = len(data) 

2921 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) 

2922 

2923 transCommand['Data']['Name'] = name 

2924 transCommand['Data']['Trans_Parameters'] = param 

2925 transCommand['Data']['Trans_Data'] = data 

2926 

2927 if noAnswer: 

2928 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 

2929 

2930 smb.addCommand(transCommand) 

2931 

2932 self.sendSMB(smb) 

2933 

2934 def send_trans2(self, tid, setup, name, param, data): 

2935 smb = NewSMBPacket() 

2936 smb['Tid'] = tid 

2937 

2938 command = pack('<H', setup) 

2939 

2940 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2) 

2941 transCommand['Parameters'] = SMBTransaction2_Parameters() 

2942 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 

2943 transCommand['Data'] = SMBTransaction2_Data() 

2944 

2945 transCommand['Parameters']['Setup'] = command 

2946 transCommand['Parameters']['TotalParameterCount'] = len(param) 

2947 transCommand['Parameters']['TotalDataCount'] = len(data) 

2948 

2949 if len(param) > 0: 2949 ↛ 2954line 2949 didn't jump to line 2954, because the condition on line 2949 was never false

2950 padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4 

2951 padBytes = '\xFF' * padLen 

2952 transCommand['Data']['Pad1'] = padBytes 

2953 else: 

2954 transCommand['Data']['Pad1'] = '' 

2955 padLen = 0 

2956 

2957 transCommand['Parameters']['ParameterCount'] = len(param) 

2958 transCommand['Parameters']['ParameterOffset'] = 32+2+28+len(command)+len(name) + padLen 

2959 

2960 if len(data) > 0: 2960 ↛ 2961line 2960 didn't jump to line 2961, because the condition on line 2960 was never true

2961 pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) % 4 

2962 transCommand['Data']['Pad2'] = '\xFF' * pad2Len 

2963 else: 

2964 transCommand['Data']['Pad2'] = '' 

2965 pad2Len = 0 

2966 

2967 transCommand['Parameters']['DataCount'] = len(data) 

2968 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len 

2969 

2970 transCommand['Data']['Name'] = name 

2971 transCommand['Data']['Trans_Parameters'] = param 

2972 transCommand['Data']['Trans_Data'] = data 

2973 smb.addCommand(transCommand) 

2974 

2975 self.sendSMB(smb) 

2976 

2977 def query_file_info(self, tid, fid, fileInfoClass = SMB_QUERY_FILE_STANDARD_INFO): 

2978 self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', pack('<HH', fid, fileInfoClass), '') 

2979 

2980 resp = self.recvSMB() 

2981 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 2981 ↛ exitline 2981 didn't return from function 'query_file_info', because the condition on line 2981 was never false

2982 trans2Response = SMBCommand(resp['Data'][0]) 

2983 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

2984 # Remove Potential Prefix Padding 

2985 return trans2Response['Data'][-trans2Parameters['TotalDataCount']:] 

2986 

2987 def __nonraw_retr_file(self, tid, fid, offset, datasize, callback): 

2988 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 2988 ↛ 2989line 2988 didn't jump to line 2989, because the condition on line 2988 was never true

2989 max_buf_size = 65000 

2990 else: 

2991 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Read in multiple KB blocks 

2992 

2993 read_offset = offset 

2994 while read_offset < datasize: 

2995 data = self.read_andx(tid, fid, read_offset, max_buf_size) 

2996 

2997 callback(data) 

2998 read_offset += len(data) 

2999 

3000 def __nonraw_stor_file(self, tid, fid, offset, datasize, callback): 

3001 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 3001 ↛ 3002line 3001 didn't jump to line 3002, because the condition on line 3001 was never true

3002 max_buf_size = 65000 

3003 else: 

3004 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 

3005 

3006 write_offset = offset 

3007 while 1: 

3008 data = callback(max_buf_size) 

3009 if not data: 

3010 break 

3011 

3012 smb = self.write_andx(tid,fid,data, write_offset) 

3013 writeResponse = SMBCommand(smb['Data'][0]) 

3014 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 

3015 write_offset += writeResponseParameters['Count'] 

3016 

3017 def get_server_domain(self): 

3018 return self.__server_domain 

3019 

3020 def get_server_dns_domain_name(self): 

3021 return self.__server_dns_domain_name 

3022 

3023 def get_server_dns_host_name(self): 

3024 return self.__server_dns_host_name 

3025 

3026 def get_server_os(self): 

3027 return self.__server_os 

3028 

3029 def get_server_os_major(self): 

3030 return self.__server_os_major 

3031 

3032 def get_server_os_minor(self): 

3033 return self.__server_os_minor 

3034 

3035 def get_server_os_build(self): 

3036 return self.__server_os_build 

3037 

3038 def set_server_os(self, os): 

3039 self.__server_os = os 

3040 

3041 def get_server_lanman(self): 

3042 return self.__server_lanman 

3043 

3044 def is_login_required(self): 

3045 # Login is required if share mode is user. 

3046 # Otherwise only public services or services in share mode 

3047 # are allowed. 

3048 return (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER 

3049 

3050 def is_signing_required(self): 

3051 return self._SignatureRequired 

3052 

3053 def get_ntlmv1_response(self, key): 

3054 challenge = self._dialects_data['Challenge'] 

3055 return ntlm.get_ntlmv1_response(key, challenge) 

3056 

3057 def perform_hostname_validation(self): 

3058 if self.__server_name == '': 

3059 if not self._validation_allow_absent: 

3060 raise self.HostnameValidationException('Hostname was not supplied by target host and absent validation is disallowed') 

3061 return 

3062 if self.__server_name.lower() != self._accepted_hostname.lower() and self.__server_dns_host_name.lower() != self._accepted_hostname.lower(): 

3063 raise self.HostnameValidationException('Supplied hostname %s does not match reported hostnames %s or %s' % 

3064 (self._accepted_hostname.lower(), self.__server_name.lower(), self.__server_dns_host_name.lower())) 

3065 

3066 

3067 def kerberos_login(self, user, password, domain = '', lmhash = '', nthash = '', aesKey = '', kdcHost = '', TGT=None, TGS=None): 

3068 # Importing down here so pyasn1 is not required if kerberos is not used. 

3069 from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set 

3070 from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS 

3071 from impacket.krb5 import constants 

3072 from impacket.krb5.types import Principal, KerberosTime, Ticket 

3073 from pyasn1.codec.der import decoder, encoder 

3074 import datetime 

3075 

3076 # login feature does not support unicode 

3077 # disable it if enabled 

3078 flags2 = self.__flags2 

3079 if flags2 & SMB.FLAGS2_UNICODE: 

3080 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3081 

3082 # If TGT or TGS are specified, they are in the form of: 

3083 # TGS['KDC_REP'] = the response from the server 

3084 # TGS['cipher'] = the cipher used 

3085 # TGS['sessionKey'] = the sessionKey 

3086 # If we have hashes, normalize them 

3087 if lmhash != '' or nthash != '': 

3088 if len(lmhash) % 2: 3088 ↛ 3089line 3088 didn't jump to line 3089, because the condition on line 3088 was never true

3089 lmhash = '0%s' % lmhash 

3090 if len(nthash) % 2: 3090 ↛ 3091line 3090 didn't jump to line 3091, because the condition on line 3090 was never true

3091 nthash = '0%s' % nthash 

3092 try: # just in case they were converted already 

3093 lmhash = a2b_hex(lmhash) 

3094 nthash = a2b_hex(nthash) 

3095 except: 

3096 pass 

3097 

3098 self.__userName = user 

3099 self.__password = password 

3100 self.__domain = domain 

3101 self.__lmhash = lmhash 

3102 self.__nthash = nthash 

3103 self.__aesKey = aesKey 

3104 self.__kdc = kdcHost 

3105 self.__TGT = TGT 

3106 self.__TGS = TGS 

3107 self._doKerberos= True 

3108 

3109 # First of all, we need to get a TGT for the user 

3110 userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) 

3111 if TGT is None: 3111 ↛ 3115line 3111 didn't jump to line 3115, because the condition on line 3111 was never false

3112 if TGS is None: 3112 ↛ 3121line 3112 didn't jump to line 3121, because the condition on line 3112 was never false

3113 tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost) 

3114 else: 

3115 tgt = TGT['KDC_REP'] 

3116 cipher = TGT['cipher'] 

3117 sessionKey = TGT['sessionKey'] 

3118 

3119 # Now that we have the TGT, we should ask for a TGS for cifs 

3120 

3121 if TGS is None: 3121 ↛ 3125line 3121 didn't jump to line 3125, because the condition on line 3121 was never false

3122 serverName = Principal('cifs/%s' % self.__remote_name, type=constants.PrincipalNameType.NT_SRV_INST.value) 

3123 tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey) 

3124 else: 

3125 tgs = TGS['KDC_REP'] 

3126 cipher = TGS['cipher'] 

3127 sessionKey = TGS['sessionKey'] 

3128 

3129 smb = NewSMBPacket() 

3130 

3131 # Are we required to sign SMB? If so we do it, if not we skip it 

3132 if self._SignatureRequired: 3132 ↛ 3136line 3132 didn't jump to line 3136, because the condition on line 3132 was never false

3133 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3134 

3135 

3136 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3137 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 

3138 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 

3139 

3140 sessionSetup['Parameters']['MaxBufferSize'] = 61440 

3141 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3142 sessionSetup['Parameters']['VcNumber'] = 1 

3143 sessionSetup['Parameters']['SessionKey'] = 0 

3144 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3145 

3146 

3147 # Let's build a NegTokenInit with the NTLMSSP 

3148 # TODO: In the future we should be able to choose different providers 

3149 

3150 blob = SPNEGO_NegTokenInit() 

3151 

3152 # Kerberos v5 mech 

3153 blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']] 

3154 

3155 # Let's extract the ticket from the TGS 

3156 tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0] 

3157 ticket = Ticket() 

3158 ticket.from_asn1(tgs['ticket']) 

3159 

3160 # Now let's build the AP_REQ 

3161 apReq = AP_REQ() 

3162 apReq['pvno'] = 5 

3163 apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value) 

3164 

3165 opts = list() 

3166 apReq['ap-options'] = constants.encodeFlags(opts) 

3167 seq_set(apReq,'ticket', ticket.to_asn1) 

3168 

3169 authenticator = Authenticator() 

3170 authenticator['authenticator-vno'] = 5 

3171 authenticator['crealm'] = domain 

3172 seq_set(authenticator, 'cname', userName.components_to_asn1) 

3173 now = datetime.datetime.utcnow() 

3174 

3175 authenticator['cusec'] = now.microsecond 

3176 authenticator['ctime'] = KerberosTime.to_asn1(now) 

3177 

3178 encodedAuthenticator = encoder.encode(authenticator) 

3179 

3180 # Key Usage 11 

3181 # AP-REQ Authenticator (includes application authenticator 

3182 # subkey), encrypted with the application session key 

3183 # (Section 5.5.1) 

3184 encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) 

3185 

3186 apReq['authenticator'] = noValue 

3187 apReq['authenticator']['etype'] = cipher.enctype 

3188 apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator 

3189 

3190 blob['MechToken'] = pack('B', ASN1_AID) + asn1encode(pack('B', ASN1_OID) + asn1encode( 

3191 TypesMech['KRB5 - Kerberos 5']) + KRB5_AP_REQ + encoder.encode(apReq)) 

3192 

3193 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 

3194 sessionSetup['Parameters'].getData() 

3195 sessionSetup['Data']['SecurityBlob'] = blob.getData() 

3196 

3197 # Fake Data here, don't want to get us fingerprinted 

3198 sessionSetup['Data']['NativeOS'] = 'Unix' 

3199 sessionSetup['Data']['NativeLanMan'] = 'Samba' 

3200 

3201 smb.addCommand(sessionSetup) 

3202 self.sendSMB(smb) 

3203 

3204 smb = self.recvSMB() 

3205 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3205 ↛ 3229line 3205 didn't jump to line 3229, because the condition on line 3205 was never false

3206 # We will need to use this uid field for all future requests/responses 

3207 self._uid = smb['Uid'] 

3208 

3209 # Now we have to extract the blob to continue the auth process 

3210 sessionResponse = SMBCommand(smb['Data'][0]) 

3211 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 

3212 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 

3213 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 

3214 sessionData.fromString(sessionResponse['Data']) 

3215 

3216 self._action = sessionParameters['Action'] 

3217 # If smb sign required, let's enable it for the rest of the connection 

3218 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3218 ↛ 3224line 3218 didn't jump to line 3224, because the condition on line 3218 was never false

3219 self._SigningSessionKey = sessionKey.contents 

3220 self._SignSequenceNumber = 2 

3221 self._SignatureEnabled = True 

3222 

3223 # restore unicode flag if needed 

3224 if flags2 & SMB.FLAGS2_UNICODE: 

3225 self.__flags2 |= SMB.FLAGS2_UNICODE 

3226 

3227 return 1 

3228 else: 

3229 raise Exception('Error: Could not login successfully') 

3230 

3231 def login_extended(self, user, password, domain = '', lmhash = '', nthash = '', use_ntlmv2 = True ): 

3232 

3233 # login feature does not support unicode 

3234 # disable it if enabled 

3235 flags2 = self.__flags2 

3236 if flags2 & SMB.FLAGS2_UNICODE: 

3237 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3238 

3239 # Once everything's working we should join login methods into a single one 

3240 smb = NewSMBPacket() 

3241 # Are we required to sign SMB? If so we do it, if not we skip it 

3242 if self._SignatureRequired: 3242 ↛ 3245line 3242 didn't jump to line 3245, because the condition on line 3242 was never false

3243 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3244 

3245 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3246 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 

3247 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 

3248 

3249 sessionSetup['Parameters']['MaxBufferSize'] = 61440 

3250 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3251 sessionSetup['Parameters']['VcNumber'] = 1 

3252 sessionSetup['Parameters']['SessionKey'] = 0 

3253 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3254 

3255 

3256 # Let's build a NegTokenInit with the NTLMSSP 

3257 # TODO: In the future we should be able to choose different providers 

3258 

3259 blob = SPNEGO_NegTokenInit() 

3260 

3261 # NTLMSSP 

3262 blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']] 

3263 auth = ntlm.getNTLMSSPType1(self.get_client_name(),domain,self._SignatureRequired, use_ntlmv2 = use_ntlmv2) 

3264 blob['MechToken'] = auth.getData() 

3265 

3266 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 

3267 sessionSetup['Parameters'].getData() 

3268 sessionSetup['Data']['SecurityBlob'] = blob.getData() 

3269 

3270 # Fake Data here, don't want to get us fingerprinted 

3271 sessionSetup['Data']['NativeOS'] = 'Unix' 

3272 sessionSetup['Data']['NativeLanMan'] = 'Samba' 

3273 

3274 smb.addCommand(sessionSetup) 

3275 self.sendSMB(smb) 

3276 

3277 smb = self.recvSMB() 

3278 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3278 ↛ 3375line 3278 didn't jump to line 3375, because the condition on line 3278 was never false

3279 # We will need to use this uid field for all future requests/responses 

3280 self._uid = smb['Uid'] 

3281 

3282 # Now we have to extract the blob to continue the auth process 

3283 sessionResponse = SMBCommand(smb['Data'][0]) 

3284 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 

3285 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 

3286 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 

3287 sessionData.fromString(sessionResponse['Data']) 

3288 respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob']) 

3289 

3290 # Let's parse some data and keep it to ourselves in case it is asked 

3291 ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken']) 

3292 if ntlmChallenge['TargetInfoFields_len'] > 0: 3292 ↛ 3321line 3292 didn't jump to line 3321, because the condition on line 3292 was never false

3293 av_pairs = ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']]) 

3294 if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None: 3294 ↛ 3300line 3294 didn't jump to line 3300, because the condition on line 3294 was never false

3295 try: 

3296 self.__server_name = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le') 

3297 except UnicodeDecodeError: 

3298 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3299 pass 

3300 if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None: 3300 ↛ 3307line 3300 didn't jump to line 3307, because the condition on line 3300 was never false

3301 try: 

3302 if self.__server_name != av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'): 3302 ↛ 3307line 3302 didn't jump to line 3307, because the condition on line 3302 was never false

3303 self.__server_domain = av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le') 

3304 except UnicodeDecodeError: 

3305 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3306 pass 

3307 if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None: 3307 ↛ 3314line 3307 didn't jump to line 3314, because the condition on line 3307 was never false

3308 try: 

3309 self.__server_dns_domain_name = av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le') 

3310 except UnicodeDecodeError: 

3311 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3312 pass 

3313 

3314 if av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME] is not None: 3314 ↛ 3321line 3314 didn't jump to line 3321, because the condition on line 3314 was never false

3315 try: 

3316 self.__server_dns_host_name = av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME][1].decode('utf-16le') 

3317 except UnicodeDecodeError: 

3318 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3319 pass 

3320 

3321 if self._strict_hostname_validation: 3321 ↛ 3322line 3321 didn't jump to line 3322, because the condition on line 3321 was never true

3322 self.perform_hostname_validation() 

3323 

3324 # Parse Version to know the target Operating system name. Not provided elsewhere anymore 

3325 if 'Version' in ntlmChallenge.fields: 3325 ↛ 3331line 3325 didn't jump to line 3331, because the condition on line 3325 was never false

3326 version = ntlmChallenge['Version'] 

3327 

3328 if len(version) >= 4: 3328 ↛ 3331line 3328 didn't jump to line 3331, because the condition on line 3328 was never false

3329 self.__server_os_major, self.__server_os_minor, self.__server_os_build = unpack('<BBH',version[:4]) 

3330 

3331 type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2) 

3332 

3333 if exportedSessionKey is not None: 3333 ↛ 3336line 3333 didn't jump to line 3336, because the condition on line 3333 was never false

3334 self._SigningSessionKey = exportedSessionKey 

3335 

3336 smb = NewSMBPacket() 

3337 

3338 # Are we required to sign SMB? If so we do it, if not we skip it 

3339 if self._SignatureRequired: 3339 ↛ 3342line 3339 didn't jump to line 3342, because the condition on line 3339 was never false

3340 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3341 

3342 respToken2 = SPNEGO_NegTokenResp() 

3343 respToken2['ResponseToken'] = type3.getData() 

3344 

3345 # Reusing the previous structure 

3346 sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2) 

3347 sessionSetup['Data']['SecurityBlob'] = respToken2.getData() 

3348 

3349 # Storing some info for later use 

3350 self.__server_os = sessionData['NativeOS'] 

3351 self.__server_lanman = sessionData['NativeLanMan'] 

3352 

3353 smb.addCommand(sessionSetup) 

3354 self.sendSMB(smb) 

3355 

3356 smb = self.recvSMB() 

3357 self._uid = 0 

3358 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3358 ↛ exitline 3358 didn't return from function 'login_extended', because the condition on line 3358 was never false

3359 self._uid = smb['Uid'] 

3360 sessionResponse = SMBCommand(smb['Data'][0]) 

3361 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 

3362 

3363 self._action = sessionParameters['Action'] 

3364 # If smb sign required, let's enable it for the rest of the connection 

3365 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3365 ↛ 3370line 3365 didn't jump to line 3370, because the condition on line 3365 was never false

3366 self._SignSequenceNumber = 2 

3367 self._SignatureEnabled = True 

3368 

3369 # restore unicode flag if needed 

3370 if flags2 & SMB.FLAGS2_UNICODE: 

3371 self.__flags2 |= SMB.FLAGS2_UNICODE 

3372 

3373 return 1 

3374 else: 

3375 raise Exception('Error: Could not login successfully') 

3376 

3377 def getCredentials(self): 

3378 return ( 

3379 self.__userName, 

3380 self.__password, 

3381 self.__domain, 

3382 self.__lmhash, 

3383 self.__nthash, 

3384 self.__aesKey, 

3385 self.__TGT, 

3386 self.__TGS) 

3387 

3388 def getIOCapabilities(self): 

3389 res = dict() 

3390 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3390 ↛ 3391line 3390 didn't jump to line 3391, because the condition on line 3390 was never true

3391 max_size = 65000 

3392 else: 

3393 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3394 res['MaxReadSize'] = max_size 

3395 res['MaxWriteSize'] = max_size 

3396 return res 

3397 

3398 def login(self, user, password, domain = '', lmhash = '', nthash = '', ntlm_fallback = True): 

3399 

3400 # If we have hashes, normalize them 

3401 if lmhash != '' or nthash != '': 

3402 if len(lmhash) % 2: 3402 ↛ 3403line 3402 didn't jump to line 3403, because the condition on line 3402 was never true

3403 lmhash = '0%s' % lmhash 

3404 if len(nthash) % 2: 3404 ↛ 3405line 3404 didn't jump to line 3405, because the condition on line 3404 was never true

3405 nthash = '0%s' % nthash 

3406 try: # just in case they were converted already 

3407 lmhash = a2b_hex(lmhash) 

3408 nthash = a2b_hex(nthash) 

3409 except: 

3410 pass 

3411 

3412 self.__userName = user 

3413 self.__password = password 

3414 self.__domain = domain 

3415 self.__lmhash = lmhash 

3416 self.__nthash = nthash 

3417 self.__aesKey = '' 

3418 self.__TGT = None 

3419 self.__TGS = None 

3420 

3421 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 3421 ↛ 3431line 3421 didn't jump to line 3431, because the condition on line 3421 was never false

3422 try: 

3423 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True) 

3424 except: 

3425 # If the target OS is Windows 5.0 or Samba, let's try using NTLMv1 

3426 if ntlm_fallback and ((self.get_server_lanman().find('Windows 2000') != -1) or (self.get_server_lanman().find('Samba') != -1)): 

3427 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = False) 

3428 self.__isNTLMv2 = False 

3429 else: 

3430 raise 

3431 elif ntlm_fallback: 

3432 self.login_standard(user, password, domain, lmhash, nthash) 

3433 self.__isNTLMv2 = False 

3434 else: 

3435 raise SessionError('Cannot authenticate against target, enable ntlm_fallback') 

3436 

3437 def login_standard(self, user, password, domain = '', lmhash = '', nthash = ''): 

3438 

3439 # login feature does not support unicode 

3440 # disable it if enabled 

3441 flags2 = self.__flags2 

3442 if flags2 & SMB.FLAGS2_UNICODE: 

3443 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3444 

3445 # Only supports NTLMv1 

3446 # Password is only encrypted if the server passed us an "encryption key" during protocol dialect negotiation 

3447 if self._dialects_parameters['ChallengeLength'] > 0: 

3448 if lmhash != '' or nthash != '': 

3449 pwd_ansi = self.get_ntlmv1_response(lmhash) 

3450 pwd_unicode = self.get_ntlmv1_response(nthash) 

3451 elif password: 

3452 lmhash = ntlm.compute_lmhash(password) 

3453 nthash = ntlm.compute_nthash(password) 

3454 pwd_ansi = self.get_ntlmv1_response(lmhash) 

3455 pwd_unicode = self.get_ntlmv1_response(nthash) 

3456 else: # NULL SESSION 

3457 pwd_ansi = '' 

3458 pwd_unicode = '' 

3459 else: 

3460 pwd_ansi = password 

3461 pwd_unicode = '' 

3462 

3463 smb = NewSMBPacket() 

3464 

3465 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3466 sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters() 

3467 sessionSetup['Data'] = SMBSessionSetupAndX_Data() 

3468 

3469 sessionSetup['Parameters']['MaxBuffer'] = 61440 

3470 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3471 sessionSetup['Parameters']['VCNumber'] = os.getpid() & 0xFFFF # Value has to be expressed in 2 bytes 

3472 sessionSetup['Parameters']['SessionKey'] = self._dialects_parameters['SessionKey'] 

3473 sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi) 

3474 sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode) 

3475 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE | SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3476 

3477 sessionSetup['Data']['AnsiPwd'] = pwd_ansi 

3478 sessionSetup['Data']['UnicodePwd'] = pwd_unicode 

3479 sessionSetup['Data']['Account'] = str(user) 

3480 sessionSetup['Data']['PrimaryDomain'] = str(domain) 

3481 sessionSetup['Data']['NativeOS'] = str(os.name) 

3482 sessionSetup['Data']['NativeLanMan'] = 'pysmb' 

3483 smb.addCommand(sessionSetup) 

3484 

3485 self.sendSMB(smb) 

3486 

3487 smb = self.recvSMB() 

3488 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 

3489 # We will need to use this uid field for all future requests/responses 

3490 self._uid = smb['Uid'] 

3491 sessionResponse = SMBCommand(smb['Data'][0]) 

3492 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 

3493 sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data']) 

3494 

3495 self._action = sessionParameters['Action'] 

3496 

3497 # Still gotta figure out how to do this with no EXTENDED_SECURITY 

3498 if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0: 

3499 self._SigningChallengeResponse = sessionSetup['Data']['UnicodePwd'] 

3500 self._SigningSessionKey = nthash 

3501 else: 

3502 self._SigningChallengeResponse = sessionSetup['Data']['AnsiPwd'] 

3503 self._SigningSessionKey = lmhash 

3504 

3505 #self._SignSequenceNumber = 1 

3506 #self.checkSignSMB(smb, self._SigningSessionKey ,self._SigningChallengeResponse) 

3507 #self._SignatureEnabled = True 

3508 self.__server_os = sessionData['NativeOS'] 

3509 self.__server_lanman = sessionData['NativeLanMan'] 

3510 self.__server_domain = sessionData['PrimaryDomain'] 

3511 

3512 # restore unicode flag if needed 

3513 if flags2 & SMB.FLAGS2_UNICODE: 

3514 self.__flags2 |= SMB.FLAGS2_UNICODE 

3515 

3516 return 1 

3517 else: 

3518 raise Exception('Error: Could not login successfully') 

3519 

3520 def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0): 

3521 smb = NewSMBPacket() 

3522 smb['Tid'] = tid 

3523 

3524 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 

3525 transCommand['Parameters'] = SMBTransaction_Parameters() 

3526 transCommand['Data'] = SMBTransaction_Data() 

3527 

3528 setup = '\x53\x00\x00\x00' 

3529 name = '\\PIPE%s\x00' % pipe 

3530 transCommand['Parameters']['Setup'] = setup 

3531 transCommand['Parameters']['TotalParameterCount'] = 0 

3532 transCommand['Parameters']['TotalDataCount'] = 0 

3533 transCommand['Parameters']['MaxParameterCount'] = 0 

3534 transCommand['Parameters']['MaxDataCount'] = 0 

3535 transCommand['Parameters']['Timeout'] = timeout * 1000 

3536 

3537 transCommand['Parameters']['ParameterCount'] = 0 

3538 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 

3539 

3540 transCommand['Parameters']['DataCount'] = 0 

3541 transCommand['Parameters']['DataOffset'] = 0 

3542 

3543 transCommand['Data']['Name'] = name 

3544 transCommand['Data']['Trans_Parameters'] = '' 

3545 transCommand['Data']['Trans_Data'] = '' 

3546 

3547 if noAnswer: 

3548 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 

3549 

3550 smb.addCommand(transCommand) 

3551 self.sendSMB(smb) 

3552 

3553 smb = self.recvSMB() 

3554 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3555 return 1 

3556 return 0 

3557 

3558 def read(self, tid, fid, offset=0, max_size = None, wait_answer=1): 

3559 if not max_size: 

3560 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3561 

3562 # max_size is not working, because although it would, the server returns an error (More data avail) 

3563 

3564 smb = NewSMBPacket() 

3565 smb['Tid'] = tid 

3566 

3567 read = SMBCommand(SMB.SMB_COM_READ) 

3568 read['Parameters'] = SMBRead_Parameters() 

3569 read['Parameters']['Fid'] = fid 

3570 read['Parameters']['Offset'] = offset 

3571 read['Parameters']['Count'] = max_size 

3572 smb.addCommand(read) 

3573 

3574 if wait_answer: 

3575 while 1: 

3576 self.sendSMB(smb) 

3577 ans = self.recvSMB() 

3578 

3579 if ans.isValidAnswer(SMB.SMB_COM_READ): 

3580 readResponse = SMBCommand(ans['Data'][0]) 

3581 readData = SMBReadResponse_Data(readResponse['Data']) 

3582 

3583 return readData['Data'] 

3584 

3585 return None 

3586 

3587 def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, smb_packet=None): 

3588 if not max_size: 3588 ↛ 3589line 3588 didn't jump to line 3589, because the condition on line 3588 was never true

3589 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 

3590 max_size = 65000 

3591 else: 

3592 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3593 

3594 # max_size is not working, because although it would, the server returns an error (More data avail) 

3595 

3596 if smb_packet is None: 3596 ↛ 3607line 3596 didn't jump to line 3607, because the condition on line 3596 was never false

3597 smb = NewSMBPacket() 

3598 smb['Tid'] = tid 

3599 

3600 readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX) 

3601 readAndX['Parameters'] = SMBReadAndX_Parameters() 

3602 readAndX['Parameters']['Fid'] = fid 

3603 readAndX['Parameters']['Offset'] = offset 

3604 readAndX['Parameters']['MaxCount'] = max_size 

3605 smb.addCommand(readAndX) 

3606 else: 

3607 smb = smb_packet 

3608 

3609 if wait_answer: 3609 ↛ 3628line 3609 didn't jump to line 3628, because the condition on line 3609 was never false

3610 answer = b'' 

3611 while 1: 

3612 self.sendSMB(smb) 

3613 ans = self.recvSMB() 

3614 

3615 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 3615 ↛ 3612line 3615 didn't jump to line 3612, because the condition on line 3615 was never false

3616 # XXX Here we are only using a few fields from the response 

3617 readAndXResponse = SMBCommand(ans['Data'][0]) 

3618 readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters']) 

3619 

3620 offset = readAndXParameters['DataOffset'] 

3621 count = readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi'] 

3622 answer += ans.getData()[offset:offset+count] 

3623 if not ans.isMoreData(): 3623 ↛ 3625line 3623 didn't jump to line 3625, because the condition on line 3623 was never false

3624 return answer 

3625 max_size = min(max_size, readAndXParameters['Remaining']) 

3626 readAndX['Parameters']['Offset'] += count # XXX Offset is not important (apparently) 

3627 else: 

3628 self.sendSMB(smb) 

3629 ans = self.recvSMB() 

3630 

3631 try: 

3632 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 

3633 return ans 

3634 else: 

3635 return None 

3636 except: 

3637 return ans 

3638 

3639 return None 

3640 

3641 def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1): 

3642 if not max_size: 

3643 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3644 

3645 # max_size is not working, because although it would, the server returns an error (More data avail) 

3646 smb = NewSMBPacket() 

3647 smb['Tid'] = tid 

3648 

3649 readRaw = SMBCommand(SMB.SMB_COM_READ_RAW) 

3650 readRaw['Parameters'] = SMBReadRaw_Parameters() 

3651 readRaw['Parameters']['Fid'] = fid 

3652 readRaw['Parameters']['Offset'] = offset 

3653 readRaw['Parameters']['MaxCount'] = max_size 

3654 smb.addCommand(readRaw) 

3655 

3656 self.sendSMB(smb) 

3657 if wait_answer: 

3658 data = self._sess.recv_packet(self.__timeout).get_trailer() 

3659 if not data: 

3660 # If there is no data it means there was an error 

3661 data = self.read_andx(tid, fid, offset, max_size) 

3662 return data 

3663 

3664 return None 

3665 

3666 def write(self,tid,fid,data, offset = 0, wait_answer=1): 

3667 smb = NewSMBPacket() 

3668 smb['Tid'] = tid 

3669 

3670 write = SMBCommand(SMB.SMB_COM_WRITE) 

3671 write['Parameters'] = SMBWrite_Parameters() 

3672 write['Data'] = SMBWrite_Data() 

3673 write['Parameters']['Fid'] = fid 

3674 write['Parameters']['Count'] = len(data) 

3675 write['Parameters']['Offset'] = offset 

3676 write['Parameters']['Remaining'] = len(data) 

3677 write['Data']['Data'] = data 

3678 smb.addCommand(write) 

3679 

3680 self.sendSMB(smb) 

3681 

3682 if wait_answer: 

3683 smb = self.recvSMB() 

3684 if smb.isValidAnswer(SMB.SMB_COM_WRITE): 

3685 return smb 

3686 return None 

3687 

3688 def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, write_pipe_mode = False, smb_packet=None): 

3689 if smb_packet is None: 3689 ↛ 3739line 3689 didn't jump to line 3739, because the condition on line 3689 was never false

3690 smb = NewSMBPacket() 

3691 smb['Tid'] = tid 

3692 

3693 writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX) 

3694 smb.addCommand(writeAndX) 

3695 

3696 writeAndX['Parameters'] = SMBWriteAndX_Parameters() 

3697 writeAndX['Parameters']['Fid'] = fid 

3698 writeAndX['Parameters']['Offset'] = offset 

3699 writeAndX['Parameters']['WriteMode'] = 8 

3700 writeAndX['Parameters']['Remaining'] = len(data) 

3701 writeAndX['Parameters']['DataLength'] = len(data) 

3702 writeAndX['Parameters']['DataOffset'] = len(smb) # this length already includes the parameter 

3703 writeAndX['Data'] = data 

3704 

3705 if write_pipe_mode is True: 3705 ↛ 3707line 3705 didn't jump to line 3707, because the condition on line 3705 was never true

3706 # First of all we gotta know what the MaxBuffSize is 

3707 maxBuffSize = self._dialects_parameters['MaxBufferSize'] 

3708 if len(data) > maxBuffSize: 

3709 chunks_size = maxBuffSize - 60 

3710 writeAndX['Parameters']['WriteMode'] = 0x0c 

3711 sendData = b'\xff\xff' + data 

3712 totalLen = len(sendData) 

3713 writeAndX['Parameters']['DataLength'] = chunks_size 

3714 writeAndX['Parameters']['Remaining'] = totalLen-2 

3715 writeAndX['Data'] = sendData[:chunks_size] 

3716 

3717 self.sendSMB(smb) 

3718 if wait_answer: 

3719 smbResp = self.recvSMB() 

3720 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 

3721 

3722 alreadySent = chunks_size 

3723 sendData = sendData[chunks_size:] 

3724 

3725 while alreadySent < totalLen: 

3726 writeAndX['Parameters']['WriteMode'] = 0x04 

3727 writeAndX['Parameters']['DataLength'] = len(sendData[:chunks_size]) 

3728 writeAndX['Data'] = sendData[:chunks_size] 

3729 self.sendSMB(smb) 

3730 if wait_answer: 

3731 smbResp = self.recvSMB() 

3732 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 

3733 alreadySent += writeAndX['Parameters']['DataLength'] 

3734 sendData = sendData[chunks_size:] 

3735 

3736 return smbResp 

3737 

3738 else: 

3739 smb = smb_packet 

3740 

3741 self.sendSMB(smb) 

3742 

3743 if wait_answer: 3743 ↛ 3747line 3743 didn't jump to line 3747, because the condition on line 3743 was never false

3744 smb = self.recvSMB() 

3745 if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX): 3745 ↛ 3747line 3745 didn't jump to line 3747, because the condition on line 3745 was never false

3746 return smb 

3747 return None 

3748 

3749 def write_raw(self,tid,fid,data, offset = 0, wait_answer=1): 

3750 LOG.warning("[MS-CIFS] This command was introduced in the CorePlus dialect, but is often listed as part of the LAN Manager 1.0 dialect.This command has been deprecated.Clients SHOULD use SMB_COM_WRITE_ANDX") 

3751 smb = NewSMBPacket() 

3752 smb['Tid'] = tid 

3753 

3754 writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW) 

3755 writeRaw['Parameters'] = SMBWriteRaw_Parameters() 

3756 writeRaw['Parameters']['Fid'] = fid 

3757 writeRaw['Parameters']['Offset'] = offset 

3758 writeRaw['Parameters']['Count'] = len(data) 

3759 writeRaw['Parameters']['DataLength'] = 0 

3760 writeRaw['Parameters']['DataOffset'] = 0 

3761 smb.addCommand(writeRaw) 

3762 

3763 self.sendSMB(smb) 

3764 self._sess.send_packet(data) 

3765 

3766 if wait_answer: 

3767 smb = self.recvSMB() 

3768 if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW): 

3769 return smb 

3770 return None 

3771 

3772 def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0): 

3773 self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, noAnswer = noAnswer) 

3774 

3775 if noAnswer or not waitAnswer: 

3776 return 

3777 smb = self.recvSMB() 

3778 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3779 transResponse = SMBCommand(smb['Data'][0]) 

3780 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 

3781 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 

3782 return None 

3783 

3784 def TransactNamedPipeRecv(self): 

3785 s = self.recvSMB() 

3786 if s.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3787 transResponse = SMBCommand(s['Data'][0]) 

3788 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 

3789 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 

3790 return None 

3791 

3792 def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, accessMask = 0x2019f): 

3793 filename = filename.replace('/', '\\') 

3794 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

3795 

3796 if smb_packet is None: 3796 ↛ 3800line 3796 didn't jump to line 3800, because the condition on line 3796 was never false

3797 smb = NewSMBPacket() 

3798 smb['Tid'] = tid 

3799 else: 

3800 smb = smb_packet 

3801 

3802 if cmd is None: 

3803 ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 

3804 ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 

3805 ntCreate['Data'] = SMBNtCreateAndX_Data(flags=self.__flags2) 

3806 ntCreate['Parameters']['FileNameLength'] = len(filename) 

3807 ntCreate['Parameters']['CreateFlags'] = 0x16 

3808 ntCreate['Parameters']['AccessMask'] = accessMask 

3809 ntCreate['Parameters']['CreateOptions'] = 0x40 

3810 ntCreate['Parameters']['ShareAccess'] = shareAccessMode 

3811 ntCreate['Parameters']['Disposition'] = disposition 

3812 ntCreate['Data']['FileName'] = filename 

3813 

3814 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3815 ntCreate['Data']['Pad'] = 0x0 

3816 else: 

3817 ntCreate = cmd 

3818 

3819 smb.addCommand(ntCreate) 

3820 

3821 self.sendSMB(smb) 

3822 

3823 while 1: 

3824 smb = self.recvSMB() 

3825 if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX): 3825 ↛ 3824line 3825 didn't jump to line 3824, because the condition on line 3825 was never false

3826 # XXX Here we are ignoring the rest of the response 

3827 ntCreateResponse = SMBCommand(smb['Data'][0]) 

3828 ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters']) 

3829 

3830 self.fid = ntCreateParameters['Fid'] 

3831 return ntCreateParameters['Fid'] 

3832 

3833 def logoff(self): 

3834 smb = NewSMBPacket() 

3835 

3836 logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX) 

3837 logOff['Parameters'] = SMBLogOffAndX() 

3838 smb.addCommand(logOff) 

3839 

3840 self.sendSMB(smb) 

3841 self.recvSMB() 

3842 # Let's clear some fields so you can login again under the same session 

3843 self._uid = 0 

3844 

3845 def list_path(self, service, path = '*', password = None): 

3846 path = path.replace('/', '\\') 

3847 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

3848 

3849 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3850 try: 

3851 findFirstParameter = SMBFindFirst2_Parameters(self.__flags2) 

3852 findFirstParameter['SearchAttributes'] = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \ 

3853 SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_READONLY | \ 

3854 SMB_FILE_ATTRIBUTE_ARCHIVE 

3855 findFirstParameter['SearchCount'] = 512 

3856 findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 

3857 findFirstParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 

3858 findFirstParameter['SearchStorageType'] = 0 

3859 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3860 findFirstParameter['FileName'] = path + b'\x00\x00' 

3861 else: 

3862 findFirstParameter['FileName'] = path + '\x00' 

3863 self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', findFirstParameter, '') 

3864 files = [ ] 

3865 

3866 totalDataCount = 1 

3867 findData = b'' 

3868 findFirst2ParameterBlock = b'' 

3869 while len(findData) < totalDataCount: 

3870 resp = self.recvSMB() 

3871 

3872 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3872 ↛ 3869line 3872 didn't jump to line 3869, because the condition on line 3872 was never false

3873 trans2Response = SMBCommand(resp['Data'][0]) 

3874 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3875 totalDataCount = trans2Parameters['TotalDataCount'] 

3876 findFirst2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 

3877 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 

3878 

3879 findParameterBlock = SMBFindFirst2Response_Parameters(findFirst2ParameterBlock) 

3880 # Save the SID for resume operations 

3881 sid = findParameterBlock['SID'] 

3882 

3883 while True: 

3884 record = SMBFindFileBothDirectoryInfo(data = findData) 

3885 

3886 shortname = record['ShortName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else \ 

3887 record['ShortName'].decode('cp437') 

3888 filename = record['FileName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else \ 

3889 record['FileName'].decode('cp437') 

3890 

3891 fileRecord = SharedFile(record['CreationTime'], record['LastAccessTime'], record['LastChangeTime'], 

3892 record['EndOfFile'], record['AllocationSize'], record['ExtFileAttributes'], 

3893 shortname, filename) 

3894 files.append(fileRecord) 

3895 if record['NextEntryOffset'] > 0 and len(findData[record['NextEntryOffset']:]) > 0: 

3896 findData = findData[record['NextEntryOffset']:] 

3897 else: 

3898 # More data to search? 

3899 if findParameterBlock['EndOfSearch'] == 0: 3899 ↛ 3900,   3899 ↛ 39262 missed branches: 1) line 3899 didn't jump to line 3900, because the condition on line 3899 was never true, 2) line 3899 didn't jump to line 3926, because the condition on line 3899 was never false

3900 resume_filename = record['FileName'] 

3901 findNextParameter = SMBFindNext2_Parameters() 

3902 findNextParameter['SID'] = sid 

3903 findNextParameter['SearchCount'] = 1024 

3904 findNextParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 

3905 findNextParameter['ResumeKey'] = 0 

3906 findNextParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 

3907 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3908 findNextParameter['FileName'] = resume_filename + b'\x00\x00' 

3909 else: 

3910 findNextParameter['FileName'] = resume_filename + b'\x00' 

3911 self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', findNextParameter, '') 

3912 findData = b'' 

3913 findNext2ParameterBlock = b'' 

3914 totalDataCount = 1 

3915 while len(findData) < totalDataCount: 

3916 resp = self.recvSMB() 

3917 

3918 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 

3919 trans2Response = SMBCommand(resp['Data'][0]) 

3920 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3921 totalDataCount = trans2Parameters['TotalDataCount'] 

3922 findNext2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 

3923 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 

3924 findParameterBlock = SMBFindNext2Response_Parameters(findNext2ParameterBlock) 

3925 else: 

3926 break 

3927 finally: 

3928 self.disconnect_tree(tid) 

3929 

3930 return files 

3931 

3932 def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset = 0, password = None, shareAccessMode = SMB_ACCESS_READ): 

3933 filename = filename.replace('/', '\\') 

3934 

3935 fid = -1 

3936 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3937 try: 

3938 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, accessMask = 0x20089) 

3939 

3940 res = self.query_file_info(tid, fid) 

3941 datasize = SMBQueryFileStandardInfo(res)['EndOfFile'] 

3942 

3943 self.__nonraw_retr_file(tid, fid, offset, datasize, callback) 

3944 finally: 

3945 if fid >= 0: 3945 ↛ 3947line 3945 didn't jump to line 3947, because the condition on line 3945 was never false

3946 self.close(tid, fid) 

3947 self.disconnect_tree(tid) 

3948 

3949 def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE): 

3950 filename = filename.replace('/', '\\') 

3951 

3952 fid = -1 

3953 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3954 try: 

3955 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode ) 

3956 

3957 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 

3958 finally: 

3959 if fid >= 0: 3959 ↛ 3961line 3959 didn't jump to line 3961, because the condition on line 3959 was never false

3960 self.close(tid, fid) 

3961 self.disconnect_tree(tid) 

3962 

3963 def stor_file_nonraw(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE ): 

3964 filename = filename.replace('/', '\\') 

3965 

3966 fid = -1 

3967 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3968 try: 

3969 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode) 

3970 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 

3971 finally: 

3972 if fid >= 0: 

3973 self.close(tid, fid) 

3974 self.disconnect_tree(tid) 

3975 

3976 def check_dir(self, service, path, password = None): 

3977 path = path.replace('/', '\\') 

3978 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3979 try: 

3980 smb = NewSMBPacket() 

3981 smb['Tid'] = tid 

3982 smb['Mid'] = 0 

3983 

3984 cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY) 

3985 cmd['Parameters'] = '' 

3986 cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2) 

3987 cmd['Data']['DirectoryName'] = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

3988 smb.addCommand(cmd) 

3989 

3990 self.sendSMB(smb) 

3991 

3992 while 1: 

3993 s = self.recvSMB() 

3994 if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY): 3994 ↛ 3993line 3994 didn't jump to line 3993, because the condition on line 3994 was never false

3995 return 

3996 finally: 

3997 self.disconnect_tree(tid) 

3998 

3999 def remove(self, service, path, password = None): 

4000 path = path.replace('/', '\\') 

4001 # Perform a list to ensure the path exists 

4002 self.list_path(service, path, password) 

4003 

4004 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4005 try: 

4006 smb = NewSMBPacket() 

4007 smb['Tid'] = tid 

4008 smb['Mid'] = 0 

4009 

4010 cmd = SMBCommand(SMB.SMB_COM_DELETE) 

4011 cmd['Parameters'] = SMBDelete_Parameters() 

4012 cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE 

4013 cmd['Data'] = SMBDelete_Data(flags = self.__flags2) 

4014 cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00') 

4015 smb.addCommand(cmd) 

4016 

4017 self.sendSMB(smb) 

4018 

4019 while 1: 

4020 s = self.recvSMB() 

4021 if s.isValidAnswer(SMB.SMB_COM_DELETE): 4021 ↛ 4020line 4021 didn't jump to line 4020, because the condition on line 4021 was never false

4022 return 

4023 finally: 

4024 self.disconnect_tree(tid) 

4025 

4026 def rmdir(self, service, path, password = None): 

4027 path = path.replace('/', '\\') 

4028 # Check that the directory exists 

4029 self.check_dir(service, path, password) 

4030 

4031 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4032 try: 

4033 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4034 

4035 smb = NewSMBPacket() 

4036 smb['Tid'] = tid 

4037 createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY) 

4038 createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2) 

4039 createDir['Data']['DirectoryName'] = path 

4040 smb.addCommand(createDir) 

4041 

4042 self.sendSMB(smb) 

4043 

4044 while 1: 

4045 s = self.recvSMB() 

4046 if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY): 4046 ↛ 4045line 4046 didn't jump to line 4045, because the condition on line 4046 was never false

4047 return 

4048 finally: 

4049 self.disconnect_tree(tid) 

4050 

4051 def mkdir(self, service, path, password = None): 

4052 path = path.replace('/', '\\') 

4053 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4054 try: 

4055 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4056 

4057 smb = NewSMBPacket() 

4058 smb['Tid'] = tid 

4059 smb['Mid'] = 0 

4060 

4061 createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY) 

4062 createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2) 

4063 createDir['Data']['DirectoryName'] = path 

4064 smb.addCommand(createDir) 

4065 

4066 self.sendSMB(smb) 

4067 

4068 smb = self.recvSMB() 

4069 if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY): 4069 ↛ 4071line 4069 didn't jump to line 4071, because the condition on line 4069 was never false

4070 return 1 

4071 return 0 

4072 finally: 

4073 self.disconnect_tree(tid) 4073 ↛ 4071line 4073 didn't jump to line 4071, because the return on line 4071 wasn't executed

4074 

4075 def rename(self, service, old_path, new_path, password = None): 

4076 old_path = old_path.replace('/', '\\') 

4077 new_path = new_path.replace('/', '\\') 

4078 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4079 try: 

4080 smb = NewSMBPacket() 

4081 smb['Tid'] = tid 

4082 smb['Mid'] = 0 

4083 

4084 renameCmd = SMBCommand(SMB.SMB_COM_RENAME) 

4085 renameCmd['Parameters'] = SMBRename_Parameters() 

4086 renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY 

4087 renameCmd['Data'] = SMBRename_Data(flags = self.__flags2) 

4088 renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else old_path 

4089 renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else new_path 

4090 smb.addCommand(renameCmd) 

4091 

4092 self.sendSMB(smb) 

4093 

4094 smb = self.recvSMB() 

4095 if smb.isValidAnswer(SMB.SMB_COM_RENAME): 4095 ↛ 4097line 4095 didn't jump to line 4097, because the condition on line 4095 was never false

4096 return 1 

4097 return 0 

4098 finally: 

4099 self.disconnect_tree(tid) 4099 ↛ 4097line 4099 didn't jump to line 4097, because the return on line 4097 wasn't executed

4100 

4101 def writeFile(self, treeId, fileId, data, offset = 0): 

4102 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 4102 ↛ 4103line 4102 didn't jump to line 4103, because the condition on line 4102 was never true

4103 max_buf_size = 65000 

4104 else: 

4105 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 

4106 

4107 write_offset = offset 

4108 while 1: 

4109 if len(data) == 0: 

4110 break 

4111 writeData = data[:max_buf_size] 

4112 data = data[max_buf_size:] 

4113 

4114 smb = self.write_andx(treeId,fileId,writeData, write_offset) 

4115 writeResponse = SMBCommand(smb['Data'][0]) 

4116 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 

4117 write_offset += writeResponseParameters['Count'] 

4118 

4119 def get_socket(self): 

4120 return self._sess.get_socket() 

4121 

4122 def send_nt_trans(self, tid, subcommand, max_param_count, setup='', param='', data=''): 

4123 """ 

4124 [MS-CIFS]: 2.2.4.62.1 SMB_COM_NT_TRANSACT request. 

4125 :param tid: 

4126 :param subcommand: The transaction subcommand code 

4127 :param max_param_count: This field MUST be set as specified in the subsections of Transaction subcommands. 

4128 :param setup: Transaction context to the server, depends on transaction subcommand. 

4129 :param param: Subcommand parameter bytes if any, depends on transaction subcommand. 

4130 :param data: Subcommand data bytes if any, depends on transaction subcommand. 

4131 :return: Buffer relative to requested subcommand. 

4132 """ 

4133 smb_packet = NewSMBPacket() 

4134 smb_packet['Tid'] = tid 

4135 # setup depends on NT_TRANSACT subcommands so it may be 0. 

4136 setup_bytes = pack('<H', setup) if setup != '' else '' 

4137 

4138 transCommand = SMBCommand(SMB.SMB_COM_NT_TRANSACT) 

4139 transCommand['Parameters'] = SMBNTTransaction_Parameters() 

4140 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 

4141 transCommand['Parameters']['Setup'] = setup_bytes 

4142 transCommand['Parameters']['Function'] = subcommand 

4143 transCommand['Parameters']['TotalParameterCount'] = len(param) 

4144 transCommand['Parameters']['TotalDataCount'] = len(data) 

4145 transCommand['Parameters']['MaxParameterCount'] = max_param_count 

4146 transCommand['Parameters']['MaxSetupCount'] = 0 

4147 

4148 transCommand['Data'] = SMBNTTransaction_Data() 

4149 

4150 # SMB header size + SMB_COM_NT_TRANSACT parameters size + length of setup bytes. 

4151 offset = 32 + 3 + 38 + len(setup_bytes) 

4152 transCommand['Data']['Pad1'] = '' 

4153 if offset % 4 != 0: 

4154 transCommand['Data']['Pad1'] = '\0' * (4 - offset % 4) 

4155 offset += (4 - offset % 4) # pad1 length 

4156 

4157 if len(param) > 0: 

4158 transCommand['Parameters']['ParameterOffset'] = offset 

4159 else: 

4160 transCommand['Parameters']['ParameterOffset'] = 0 

4161 

4162 offset += len(param) 

4163 transCommand['Data']['Pad2'] = '' 

4164 if offset % 4 != 0: 

4165 transCommand['Data']['Pad2'] = '\0' * (4 - offset % 4) 

4166 offset += (4 - offset % 4) 

4167 

4168 if len(data) > 0: 

4169 transCommand['Parameters']['DataOffset'] = offset 

4170 else: 

4171 transCommand['Parameters']['DataOffset'] = 0 

4172 

4173 transCommand['Parameters']['DataCount'] = len(data) 

4174 transCommand['Parameters']['ParameterCount'] = len(param) 

4175 transCommand['Data']['NT_Trans_Parameters'] = param 

4176 transCommand['Data']['NT_Trans_Data'] = data 

4177 smb_packet.addCommand(transCommand) 

4178 

4179 self.sendSMB(smb_packet) 

4180 

4181 def query_sec_info(self, tid, fid, additional_information=7): 

4182 """ 

4183 [MS-CIFS]: 2.2.7.6.1 

4184 NT_TRANSACT_QUERY_SECURITY_DESC 0x0006 

4185 :param tid: valid tree id. 

4186 :param fid: valid file handle. 

4187 :param additional_information: SecurityInfoFields. default = owner + group + dacl ie. 7 

4188 :return: security descriptor buffer 

4189 """ 

4190 self.send_nt_trans(tid, subcommand=0x0006, max_param_count=4, 

4191 param=pack('<HHL', fid, 0x0000, additional_information)) 

4192 resp = self.recvSMB() 

4193 if resp.isValidAnswer(SMB.SMB_COM_NT_TRANSACT): 

4194 nt_trans_response = SMBCommand(resp['Data'][0]) 

4195 nt_trans_parameters = SMBNTTransactionResponse_Parameters(nt_trans_response['Parameters']) 

4196 # Remove Potential Prefix Padding 

4197 return nt_trans_response['Data'][-nt_trans_parameters['TotalDataCount']:] 

4198 

4199 def echo(self, text = '', count = 1): 

4200 

4201 smb = NewSMBPacket() 

4202 comEcho = SMBCommand(SMB.SMB_COM_ECHO) 

4203 comEcho['Parameters'] = SMBEcho_Parameters() 

4204 comEcho['Data'] = SMBEcho_Data() 

4205 comEcho['Parameters']['EchoCount'] = count 

4206 comEcho['Data']['Data'] = text 

4207 smb.addCommand(comEcho) 

4208 

4209 self.sendSMB(smb) 

4210 

4211 for i in range(count): 

4212 resp = self.recvSMB() 

4213 resp.isValidAnswer(SMB.SMB_COM_ECHO) 

4214 return True 

4215 

4216ERRDOS = { 1: 'Invalid function', 

4217 2: 'File not found', 

4218 3: 'Invalid directory', 

4219 4: 'Too many open files', 

4220 5: 'Access denied', 

4221 6: 'Invalid file handle. Please file a bug report.', 

4222 7: 'Memory control blocks destroyed', 

4223 8: 'Out of memory', 

4224 9: 'Invalid memory block address', 

4225 10: 'Invalid environment', 

4226 11: 'Invalid format', 

4227 12: 'Invalid open mode', 

4228 13: 'Invalid data', 

4229 15: 'Invalid drive', 

4230 16: 'Attempt to remove server\'s current directory', 

4231 17: 'Not the same device', 

4232 18: 'No files found', 

4233 32: 'Sharing mode conflicts detected', 

4234 33: 'Lock request conflicts detected', 

4235 80: 'File already exists' 

4236 } 

4237 

4238ERRSRV = { 1: 'Non-specific error', 

4239 2: 'Bad password', 

4240 4: 'Access denied', 

4241 5: 'Invalid tid. Please file a bug report.', 

4242 6: 'Invalid network name', 

4243 7: 'Invalid device', 

4244 49: 'Print queue full', 

4245 50: 'Print queue full', 

4246 51: 'EOF on print queue dump', 

4247 52: 'Invalid print file handle', 

4248 64: 'Command not recognized. Please file a bug report.', 

4249 65: 'Internal server error', 

4250 67: 'Invalid path', 

4251 69: 'Invalid access permissions', 

4252 71: 'Invalid attribute mode', 

4253 81: 'Server is paused', 

4254 82: 'Not receiving messages', 

4255 83: 'No room to buffer messages', 

4256 87: 'Too many remote user names', 

4257 88: 'Operation timeout', 

4258 89: 'Out of resources', 

4259 91: 'Invalid user handle. Please file a bug report.', 

4260 250: 'Temporarily unable to support raw mode for transfer', 

4261 251: 'Temporarily unable to support raw mode for transfer', 

4262 252: 'Continue in MPX mode', 

4263 65535: 'Unsupported function' 

4264 } 

4265 

4266ERRHRD = { 19: 'Media is write-protected', 

4267 20: 'Unknown unit', 

4268 21: 'Drive not ready', 

4269 22: 'Unknown command', 

4270 23: 'CRC error', 

4271 24: 'Bad request', 

4272 25: 'Seek error', 

4273 26: 'Unknown media type', 

4274 27: 'Sector not found', 

4275 28: 'Printer out of paper', 

4276 29: 'Write fault', 

4277 30: 'Read fault', 

4278 31: 'General failure', 

4279 32: 'Open conflicts with an existing open', 

4280 33: 'Invalid lock request', 

4281 34: 'Wrong disk in drive', 

4282 35: 'FCBs not available', 

4283 36: 'Sharing buffer exceeded' 

4284 }