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

2# 

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

4# 

5# This software is provided under a slightly modified version 

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

7# for more information. 

8# 

9# Author: 

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

11# 

12# Copyright and license note from Pysmb: 

13# 

14# Copyright (C) 2001 Michael Teo <michaelteo@bigfoot.com> 

15# smb.py - SMB/CIFS library 

16# 

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

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

19# use of this software. 

20# 

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

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

23# freely, subject to the following restrictions: 

24# 

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

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

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

28# appreciated but is not required. 

29# 

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

31# misrepresented as being the original software. 

32# 

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

34# 

35# Todo: 

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

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

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

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

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

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

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

43# [x] Do chained AndX requests 

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

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

46# 

47from __future__ import division 

48from __future__ import print_function 

49import os 

50import socket 

51from binascii import a2b_hex 

52import datetime 

53from struct import pack, unpack 

54from contextlib import contextmanager 

55from pyasn1.type.univ import noValue 

56 

57from impacket import nmb, ntlm, nt_errors, LOG 

58from impacket.structure import Structure 

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

60from impacket.krb5.gssapi import KRB5_AP_REQ 

61 

62# For signing 

63import hashlib 

64 

65unicode_support = 0 

66unicode_convert = 1 

67 

68# Dialect for SMB1 

69SMB_DIALECT = 'NT LM 0.12' 

70 

71# Shared Device Type 

72SHARED_DISK = 0x00 

73SHARED_DISK_HIDDEN = 0x80000000 

74SHARED_PRINT_QUEUE = 0x01 

75SHARED_DEVICE = 0x02 

76SHARED_IPC = 0x03 

77 

78# Extended attributes mask 

79ATTR_ARCHIVE = 0x020 

80ATTR_COMPRESSED = 0x800 

81ATTR_NORMAL = 0x080 

82ATTR_HIDDEN = 0x002 

83ATTR_READONLY = 0x001 

84ATTR_TEMPORARY = 0x100 

85ATTR_DIRECTORY = 0x010 

86ATTR_SYSTEM = 0x004 

87 

88# Service Type 

89SERVICE_DISK = 'A:' 

90SERVICE_PRINTER = 'LPT1:' 

91SERVICE_IPC = 'IPC' 

92SERVICE_COMM = 'COMM' 

93SERVICE_ANY = '?????' 

94 

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

96SV_TYPE_WORKSTATION = 0x00000001 

97SV_TYPE_SERVER = 0x00000002 

98SV_TYPE_SQLSERVER = 0x00000004 

99SV_TYPE_DOMAIN_CTRL = 0x00000008 

100SV_TYPE_DOMAIN_BAKCTRL = 0x00000010 

101SV_TYPE_TIME_SOURCE = 0x00000020 

102SV_TYPE_AFP = 0x00000040 

103SV_TYPE_NOVELL = 0x00000080 

104SV_TYPE_DOMAIN_MEMBER = 0x00000100 

105SV_TYPE_PRINTQ_SERVER = 0x00000200 

106SV_TYPE_DIALIN_SERVER = 0x00000400 

107SV_TYPE_XENIX_SERVER = 0x00000800 

108SV_TYPE_NT = 0x00001000 

109SV_TYPE_WFW = 0x00002000 

110SV_TYPE_SERVER_NT = 0x00004000 

111SV_TYPE_POTENTIAL_BROWSER = 0x00010000 

112SV_TYPE_BACKUP_BROWSER = 0x00020000 

113SV_TYPE_MASTER_BROWSER = 0x00040000 

114SV_TYPE_DOMAIN_MASTER = 0x00080000 

115SV_TYPE_LOCAL_LIST_ONLY = 0x40000000 

116SV_TYPE_DOMAIN_ENUM = 0x80000000 

117 

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

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

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

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

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

123 

124# Share Access Mode 

125SMB_SHARE_COMPAT = 0x00 

126SMB_SHARE_DENY_EXCL = 0x10 

127SMB_SHARE_DENY_WRITE = 0x20 

128SMB_SHARE_DENY_READEXEC = 0x30 

129SMB_SHARE_DENY_NONE = 0x40 

130SMB_ACCESS_READ = 0x00 

131SMB_ACCESS_WRITE = 0x01 

132SMB_ACCESS_READWRITE = 0x02 

133SMB_ACCESS_EXEC = 0x03 

134 

135TRANS_DISCONNECT_TID = 1 

136TRANS_NO_RESPONSE = 2 

137 

138STATUS_SUCCESS = 0x00000000 

139STATUS_LOGON_FAILURE = 0xC000006D 

140STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B 

141MAX_TFRAG_SIZE = 5840 

142EVASION_NONE = 0 

143EVASION_LOW = 1 

144EVASION_HIGH = 2 

145EVASION_MAX = 3 

146RPC_X_BAD_STUB_DATA = 0x6F7 

147 

148# SMB_FILE_ATTRIBUTES 

149 

150SMB_FILE_ATTRIBUTE_NORMAL = 0x0000 

151SMB_FILE_ATTRIBUTE_READONLY = 0x0001 

152SMB_FILE_ATTRIBUTE_HIDDEN = 0x0002 

153SMB_FILE_ATTRIBUTE_SYSTEM = 0x0004 

154SMB_FILE_ATTRIBUTE_VOLUME = 0x0008 

155SMB_FILE_ATTRIBUTE_DIRECTORY = 0x0010 

156SMB_FILE_ATTRIBUTE_ARCHIVE = 0x0020 

157SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100 

158SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200 

159SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400 

160SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000 

161SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000 

162 

163# Session SetupAndX Action flags 

164SMB_SETUP_GUEST = 0x01 

165SMB_SETUP_USE_LANMAN_KEY = 0x02 

166 

167# QUERY_INFORMATION levels 

168SMB_INFO_ALLOCATION = 0x0001 

169SMB_INFO_VOLUME = 0x0002 

170FILE_FS_SIZE_INFORMATION = 0x0003 

171SMB_QUERY_FS_VOLUME_INFO = 0x0102 

172SMB_QUERY_FS_SIZE_INFO = 0x0103 

173SMB_QUERY_FILE_EA_INFO = 0x0103 

174SMB_QUERY_FS_DEVICE_INFO = 0x0104 

175SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105 

176SMB_QUERY_FILE_BASIC_INFO = 0x0101 

177SMB_QUERY_FILE_STANDARD_INFO = 0x0102 

178SMB_QUERY_FILE_ALL_INFO = 0x0107 

179FILE_FS_FULL_SIZE_INFORMATION = 0x03EF 

180 

181# SET_INFORMATION levels 

182SMB_SET_FILE_DISPOSITION_INFO = 0x0102 

183SMB_SET_FILE_BASIC_INFO = 0x0101 

184SMB_SET_FILE_END_OF_FILE_INFO = 0x0104 

185 

186# Device Type [MS-CIFS] 2.2.8.2.5 

187FILE_DEVICE_BEEP = 0x0001 

188FILE_DEVICE_CD_ROM = 0x0002 

189FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x0003 

190FILE_DEVICE_CONTROLLER = 0x0004 

191FILE_DEVICE_DATALINK = 0x0005 

192FILE_DEVICE_DFS = 0x0006 

193FILE_DEVICE_DISK = 0x0007 

194FILE_DEVICE_DISK_FILE_SYSTEM = 0x0008 

195FILE_DEVICE_FILE_SYSTEM = 0x0009 

196FILE_DEVICE_INPORT_PORT = 0x000a 

197FILE_DEVICE_KEYBOARD = 0x000b 

198FILE_DEVICE_MAILSLOT = 0x000c 

199FILE_DEVICE_MIDI_IN = 0x000d 

200FILE_DEVICE_MIDI_OUT = 0x000e 

201FILE_DEVICE_MOUSE = 0x000f 

202FILE_DEVICE_MULTI_UNC_PROVIDER = 0x0010 

203FILE_DEVICE_NAMED_PIPE = 0x0011 

204FILE_DEVICE_NETWORK = 0x0012 

205FILE_DEVICE_NETWORK_BROWSER = 0x0013 

206FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x0014 

207FILE_DEVICE_NULL = 0x0015 

208FILE_DEVICE_PARALLEL_PORT = 0x0016 

209FILE_DEVICE_PHYSICAL_NETCARD = 0x0017 

210FILE_DEVICE_PRINTER = 0x0018 

211FILE_DEVICE_SCANNER = 0x0019 

212FILE_DEVICE_SERIAL_MOUSE_PORT = 0x001a 

213FILE_DEVICE_SERIAL_PORT = 0x001b 

214FILE_DEVICE_SCREEN = 0x001c 

215FILE_DEVICE_SOUND = 0x001d 

216FILE_DEVICE_STREAMS = 0x001e 

217FILE_DEVICE_TAPE = 0x001f 

218FILE_DEVICE_TAPE_FILE_SYSTEM = 0x0020 

219FILE_DEVICE_TRANSPORT = 0x0021 

220FILE_DEVICE_UNKNOWN = 0x0022 

221FILE_DEVICE_VIDEO = 0x0023 

222FILE_DEVICE_VIRTUAL_DISK = 0x0024 

223FILE_DEVICE_WAVE_IN = 0x0025 

224FILE_DEVICE_WAVE_OUT = 0x0026 

225FILE_DEVICE_8042_PORT = 0x0027 

226FILE_DEVICE_NETWORK_REDIRECTOR = 0x0028 

227FILE_DEVICE_BATTERY = 0x0029 

228FILE_DEVICE_BUS_EXTENDER = 0x002a 

229FILE_DEVICE_MODEM = 0x002b 

230FILE_DEVICE_VDM = 0x002c 

231 

232# Device Characteristics [MS-CIFS] 2.2.8.2.5 

233FILE_REMOVABLE_MEDIA = 0x0001 

234FILE_READ_ONLY_DEVICE = 0x0002 

235FILE_FLOPPY_DISKETTE = 0x0004 

236FILE_WRITE_ONCE_MEDIA = 0x0008 

237FILE_REMOTE_DEVICE = 0x0010 

238FILE_DEVICE_IS_MOUNTED = 0x0020 

239FILE_VIRTUAL_VOLUME = 0x0040 

240 

241# File System Attributes 

242FILE_CASE_SENSITIVE_SEARCH = 0x00000001 

243FILE_CASE_PRESERVED_NAMES = 0x00000002 

244FILE_UNICODE_ON_DISK = 0x00000004 

245FILE_PERSISTENT_ACLS = 0x00000008 

246FILE_FILE_COMPRESSION = 0x00000010 

247FILE_VOLUME_IS_COMPRESSED = 0x00008000 

248 

249# FIND_FIRST2 flags and levels 

250SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001 

251SMB_FIND_CLOSE_AT_EOS = 0x0002 

252SMB_FIND_RETURN_RESUME_KEYS = 0x0004 

253SMB_FIND_CONTINUE_FROM_LAST = 0x0008 

254SMB_FIND_WITH_BACKUP_INTENT = 0x0010 

255 

256FILE_DIRECTORY_FILE = 0x00000001 

257FILE_DELETE_ON_CLOSE = 0x00001000 

258FILE_NON_DIRECTORY_FILE = 0x00000040 

259 

260SMB_FIND_INFO_STANDARD = 0x0001 

261SMB_FIND_FILE_DIRECTORY_INFO = 0x0101 

262SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102 

263SMB_FIND_FILE_NAMES_INFO = 0x0103 

264SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104 

265SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105 

266SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106 

267 

268 

269# DesiredAccess flags 

270FILE_READ_DATA = 0x00000001 

271FILE_WRITE_DATA = 0x00000002 

272FILE_APPEND_DATA = 0x00000004 

273FILE_EXECUTE = 0x00000020 

274MAXIMUM_ALLOWED = 0x02000000 

275GENERIC_ALL = 0x10000000 

276GENERIC_EXECUTE = 0x20000000 

277GENERIC_WRITE = 0x40000000 

278GENERIC_READ = 0x80000000 

279 

280# ShareAccess flags 

281FILE_SHARE_NONE = 0x00000000 

282FILE_SHARE_READ = 0x00000001 

283FILE_SHARE_WRITE = 0x00000002 

284FILE_SHARE_DELETE = 0x00000004 

285 

286# CreateDisposition flags 

287FILE_SUPERSEDE = 0x00000000 

288FILE_OPEN = 0x00000001 

289FILE_CREATE = 0x00000002 

290FILE_OPEN_IF = 0x00000003 

291FILE_OVERWRITE = 0x00000004 

292FILE_OVERWRITE_IF = 0x00000005 

293 

294def strerror(errclass, errcode): 

295 if errclass == 0x01: 

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

297 elif errclass == 0x02: 

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

299 elif errclass == 0x03: 

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

301 # This is not a standard error class for SMB 

302 #elif errclass == 0x80: 

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

304 elif errclass == 0xff: 

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

306 else: 

307 return 'Unknown error', 'Unknown error' 

308 

309# Raised when an error has occurred during a session 

310class SessionError(Exception): 

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

312 ERRsuccess = 0 

313 ERRbadfunc = 1 

314 ERRbadfile = 2 

315 ERRbadpath = 3 

316 ERRnofids = 4 

317 ERRnoaccess = 5 

318 ERRbadfid = 6 

319 ERRbadmcb = 7 

320 ERRnomem = 8 

321 ERRbadmem = 9 

322 ERRbadenv = 10 

323 ERRbadaccess = 12 

324 ERRbaddata = 13 

325 ERRres = 14 

326 ERRbaddrive = 15 

327 ERRremcd = 16 

328 ERRdiffdevice = 17 

329 ERRnofiles = 18 

330 ERRgeneral = 31 

331 ERRbadshare = 32 

332 ERRlock = 33 

333 ERRunsup = 50 

334 ERRnetnamedel = 64 

335 ERRnosuchshare = 67 

336 ERRfilexists = 80 

337 ERRinvalidparam = 87 

338 ERRcannotopen = 110 

339 ERRinsufficientbuffer = 122 

340 ERRinvalidname = 123 

341 ERRunknownlevel = 124 

342 ERRnotlocked = 158 

343 ERRrename = 183 

344 ERRbadpipe = 230 

345 ERRpipebusy = 231 

346 ERRpipeclosing = 232 

347 ERRnotconnected = 233 

348 ERRmoredata = 234 

349 ERRnomoreitems = 259 

350 ERRbaddirectory = 267 

351 ERReasnotsupported = 282 

352 ERRlogonfailure = 1326 

353 ERRbuftoosmall = 2123 

354 ERRunknownipc = 2142 

355 ERRnosuchprintjob = 2151 

356 ERRinvgroup = 2455 

357 

358 # here's a special one from observing NT 

359 ERRnoipc = 66 

360 

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

362 ERRdriveralreadyinstalled = 1795 

363 ERRunknownprinterport = 1796 

364 ERRunknownprinterdriver = 1797 

365 ERRunknownprintprocessor = 1798 

366 ERRinvalidseparatorfile = 1799 

367 ERRinvalidjobpriority = 1800 

368 ERRinvalidprintername = 1801 

369 ERRprinteralreadyexists = 1802 

370 ERRinvalidprintercommand = 1803 

371 ERRinvaliddatatype = 1804 

372 ERRinvalidenvironment = 1805 

373 

374 ERRunknownprintmonitor = 3000 

375 ERRprinterdriverinuse = 3001 

376 ERRspoolfilenotfound = 3002 

377 ERRnostartdoc = 3003 

378 ERRnoaddjob = 3004 

379 ERRprintprocessoralreadyinstalled = 3005 

380 ERRprintmonitoralreadyinstalled = 3006 

381 ERRinvalidprintmonitor = 3007 

382 ERRprintmonitorinuse = 3008 

383 ERRprinterhasjobsqueued = 3009 

384 

385 # Error codes for the ERRSRV class 

386 

387 ERRerror = 1 

388 ERRbadpw = 2 

389 ERRbadtype = 3 

390 ERRaccess = 4 

391 ERRinvnid = 5 

392 ERRinvnetname = 6 

393 ERRinvdevice = 7 

394 ERRqfull = 49 

395 ERRqtoobig = 50 

396 ERRinvpfid = 52 

397 ERRsmbcmd = 64 

398 ERRsrverror = 65 

399 ERRfilespecs = 67 

400 ERRbadlink = 68 

401 ERRbadpermits = 69 

402 ERRbadpid = 70 

403 ERRsetattrmode = 71 

404 ERRpaused = 81 

405 ERRmsgoff = 82 

406 ERRnoroom = 83 

407 ERRrmuns = 87 

408 ERRtimeout = 88 

409 ERRnoresource = 89 

410 ERRtoomanyuids = 90 

411 ERRbaduid = 91 

412 ERRuseMPX = 250 

413 ERRuseSTD = 251 

414 ERRcontMPX = 252 

415 ERRbadPW = None 

416 ERRnosupport = 0 

417 ERRunknownsmb = 22 

418 

419 # Error codes for the ERRHRD class 

420 

421 ERRnowrite = 19 

422 ERRbadunit = 20 

423 ERRnotready = 21 

424 ERRbadcmd = 22 

425 ERRdata = 23 

426 ERRbadreq = 24 

427 ERRseek = 25 

428 ERRbadmedia = 26 

429 ERRbadsector = 27 

430 ERRnopaper = 28 

431 ERRwrite = 29 

432 ERRread = 30 

433 ERRwrongdisk = 34 

434 ERRFCBunavail = 35 

435 ERRsharebufexc = 36 

436 ERRdiskfull = 39 

437 

438 

439 hard_msgs = { 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

454 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."), 

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

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

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

458 } 

459 

460 dos_msgs = { 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

480 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."), 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

495 } 

496 

497 server_msgs = { 

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

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

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

501 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."), 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

530 } 

531 # Error clases 

532 

533 ERRDOS = 0x1 

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

535 ERRDOS: ("ERRDOS", dos_msgs), 

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

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

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

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

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

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

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

543 

544 

545 

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

547 Exception.__init__(self, error_string) 

548 self.nt_status = nt_status 

549 self._args = error_string 

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

551 self.error_class = 0 

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

553 else: 

554 self.error_class = error_class 

555 self.error_code = error_code 

556 self.packet = packet 

557 

558 def get_error_class( self ): 

559 return self.error_class 

560 

561 def get_error_code( self ): 

562 return self.error_code 

563 

564 def get_error_packet(self): 

565 return self.packet 

566 

567 def __str__( self ): 

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

569 if not error_class: 

570 error_code_str = self.error_code 

571 error_class_str = self.error_class 

572 else: 

573 error_class_str = error_class[0] 

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

575 if not error_code: 

576 error_code_str = self.error_code 

577 else: 

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

579 

580 if self.nt_status: 

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

582 else: 

583 # Fall back to the old format 

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

585 

586 

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

588# currently supported by pysmb 

589class UnsupportedFeature(Exception): 

590 pass 

591 

592# Contains information about a SMB shared device/service 

593class SharedDevice: 

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

595 self.__name = name 

596 self.__type = share_type 

597 self.__comment = comment 

598 

599 def get_name(self): 

600 return self.__name 

601 

602 def get_type(self): 

603 return self.__type 

604 

605 def get_comment(self): 

606 return self.__comment 

607 

608 def __repr__(self): 

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

610 

611 

612# Contains information about the shared file/directory 

613class SharedFile: 

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

615 self.__ctime = ctime 

616 self.__atime = atime 

617 self.__mtime = mtime 

618 self.__filesize = filesize 

619 self.__allocsize = allocsize 

620 self.__attribs = attribs 

621 try: 

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

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

624 else: 

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

626 except (ValueError, TypeError): 

627 self.__shortname = shortname 

628 try: 

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

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

631 else: 

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

633 except (ValueError, TypeError): 

634 self.__longname = longname 

635 

636 def get_ctime(self): 

637 return self.__ctime 

638 

639 def get_ctime_epoch(self): 

640 return self.__convert_smbtime(self.__ctime) 

641 

642 def get_mtime(self): 

643 return self.__mtime 

644 

645 def get_mtime_epoch(self): 

646 return self.__convert_smbtime(self.__mtime) 

647 

648 def get_atime(self): 

649 return self.__atime 

650 

651 def get_atime_epoch(self): 

652 return self.__convert_smbtime(self.__atime) 

653 

654 def get_filesize(self): 

655 return self.__filesize 

656 

657 def get_allocsize(self): 

658 return self.__allocsize 

659 

660 def get_attributes(self): 

661 return self.__attribs 

662 

663 def is_archive(self): 

664 return self.__attribs & ATTR_ARCHIVE 

665 

666 def is_compressed(self): 

667 return self.__attribs & ATTR_COMPRESSED 

668 

669 def is_normal(self): 

670 return self.__attribs & ATTR_NORMAL 

671 

672 def is_hidden(self): 

673 return self.__attribs & ATTR_HIDDEN 

674 

675 def is_readonly(self): 

676 return self.__attribs & ATTR_READONLY 

677 

678 def is_temporary(self): 

679 return self.__attribs & ATTR_TEMPORARY 

680 

681 def is_directory(self): 

682 return self.__attribs & ATTR_DIRECTORY 

683 

684 def is_system(self): 

685 return self.__attribs & ATTR_SYSTEM 

686 

687 def get_shortname(self): 

688 return self.__shortname 

689 

690 def get_longname(self): 

691 return self.__longname 

692 

693 def __repr__(self): 

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

695 

696 @staticmethod 

697 def __convert_smbtime(t): 

698 x = t >> 32 

699 y = t & 0xffffffff 

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

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

702 

703 

704# Contain information about a SMB machine 

705class SMBMachine: 

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

707 self.__nbname = nbname 

708 self.__type = nbt_type 

709 self.__comment = comment 

710 

711 def __repr__(self): 

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

713 

714class SMBDomain: 

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

716 self.__nbgroup = nbgroup 

717 self.__type = domain_type 

718 self.__master_browser = master_browser 

719 

720 def __repr__(self): 

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

722 

723# Represents a SMB Packet 

724class NewSMBPacket(Structure): 

725 structure = ( 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

740 ('Data','*:'), 

741 ) 

742 

743 def __init__(self, **kargs): 

744 Structure.__init__(self, **kargs) 

745 

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

747 self['Flags2'] = 0 

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

749 self['Flags1'] = 0 

750 

751 if 'data' not in kargs: 

752 self['Data'] = [] 

753 

754 def addCommand(self, command): 

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

756 self['Command'] = command.command 

757 else: 

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

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

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

761 

762 def isMoreData(self): 

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

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

765 

766 def isMoreProcessingRequired(self): 

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

768 

769 def isValidAnswer(self, cmd): 

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

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

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

773 return 1 

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

775 return 1 

776 elif self.isMoreProcessingRequired(): 

777 return 1 

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

779 else: 

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

781 

782 

783class SMBCommand(Structure): 

784 structure = ( 

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

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

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

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

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

790 ) 

791 

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

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

794 self.command = commandOrData 

795 else: 

796 data = data or commandOrData 

797 

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

799 

800 if data is None: 

801 self['Parameters'] = '' 

802 self['Data'] = '' 

803 

804class AsciiOrUnicodeStructure(Structure): 

805 UnicodeStructure = () 

806 AsciiStructure = () 

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

808 if flags & SMB.FLAGS2_UNICODE: 

809 self.structure = self.UnicodeStructure 

810 else: 

811 self.structure = self.AsciiStructure 

812 Structure.__init__(self, **kargs) 

813 

814class SMBCommand_Parameters(Structure): 

815 pass 

816 

817class SMBAndXCommand_Parameters(Structure): 

818 commonHdr = ( 

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

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

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

822 ) 

823 structure = ( # default structure, overridden by subclasses 

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

825 ) 

826 

827############# TRANSACTIONS RELATED 

828# TRANS2_QUERY_FS_INFORMATION 

829# QUERY_FS Information Levels 

830# SMB_QUERY_FS_ATTRIBUTE_INFO 

831class SMBQueryFsAttributeInfo(Structure): 

832 structure = ( 

833 ('FileSystemAttributes','<L'), 

834 ('MaxFilenNameLengthInBytes','<L'), 

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

836 ('FileSystemName',':'), 

837 ) 

838 

839class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure): 

840 commonHdr = ( 

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

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

843 ) 

844 AsciiStructure = ( 

845 ('VolumeLabel','z'), 

846 ) 

847 UnicodeStructure = ( 

848 ('VolumeLabel','u'), 

849 ) 

850 

851# FILE_FS_SIZE_INFORMATION 

852class FileFsSizeInformation(Structure): 

853 structure = ( 

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

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

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

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

858 ) 

859 

860# SMB_QUERY_FS_SIZE_INFO 

861class SMBQueryFsSizeInfo(Structure): 

862 structure = ( 

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

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

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

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

867 ) 

868# FILE_FS_FULL_SIZE_INFORMATION 

869class SMBFileFsFullSizeInformation(Structure): 

870 structure = ( 

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

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

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

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

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

876 ) 

877# SMB_QUERY_FS_VOLUME_INFO 

878class SMBQueryFsVolumeInfo(Structure): 

879 structure = ( 

880 ('VolumeCreationTime','<q'), 

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

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

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

884 ('VolumeLabel',':') 

885 ) 

886 

887# SMB_QUERY_FS_DEVICE_INFO 

888class SMBQueryFsDeviceInfo(Structure): 

889 structure = ( 

890 ('DeviceType', '<L=0'), 

891 ('DeviceCharacteristics', '<L=0') 

892 ) 

893 

894 

895# SMB_FIND_FILE_BOTH_DIRECTORY_INFO level 

896class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure): 

897 commonHdr = ( 

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

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

900 ('CreationTime','<q'), 

901 ('LastAccessTime','<q'), 

902 ('LastWriteTime','<q'), 

903 ('LastChangeTime','<q'), 

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

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

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

907 ) 

908 AsciiStructure = ( 

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

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

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

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

913 ('ShortName','24s'), 

914 ('FileName',':'), 

915 ) 

916 UnicodeStructure = ( 

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

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

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

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

921 ('ShortName','24s'), 

922 ('FileName',':'), 

923 ) 

924 

925# SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level 

926class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure): 

927 commonHdr = ( 

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

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

930 ('CreationTime','<q'), 

931 ('LastAccessTime','<q'), 

932 ('LastWriteTime','<q'), 

933 ('LastChangeTime','<q'), 

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

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

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

937 ) 

938 AsciiStructure = ( 

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

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

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

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

943 ('FileName','z'), 

944 ) 

945 UnicodeStructure = ( 

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

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

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

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

950 ('FileName',':'), 

951 ) 

952 

953# SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level 

954class SMBFindFileIdBothDirectoryInfo(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=0'), 

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

965 ) 

966 AsciiStructure = ( 

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

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

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

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

971 ('ShortName','24s'), 

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

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

974 ('FileName','z'), 

975 ) 

976 UnicodeStructure = ( 

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

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

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

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

981 ('ShortName','24s'), 

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

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

984 ('FileName',':'), 

985 ) 

986 

987# SMB_FIND_FILE_DIRECTORY_INFO level 

988class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure): 

989 commonHdr = ( 

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

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

992 ('CreationTime','<q'), 

993 ('LastAccessTime','<q'), 

994 ('LastWriteTime','<q'), 

995 ('LastChangeTime','<q'), 

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

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

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

999 ) 

1000 AsciiStructure = ( 

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

1002 ('FileName','z'), 

1003 ) 

1004 UnicodeStructure = ( 

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

1006 ('FileName',':'), 

1007 ) 

1008 

1009# SMB_FIND_FILE_NAMES_INFO level 

1010class SMBFindFileNamesInfo(AsciiOrUnicodeStructure): 

1011 commonHdr = ( 

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

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

1014 ) 

1015 AsciiStructure = ( 

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

1017 ('FileName','z'), 

1018 ) 

1019 UnicodeStructure = ( 

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

1021 ('FileName',':'), 

1022 ) 

1023 

1024# SMB_FIND_FILE_FULL_DIRECTORY_INFO level 

1025class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure): 

1026 commonHdr = ( 

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

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

1029 ('CreationTime','<q'), 

1030 ('LastAccessTime','<q'), 

1031 ('LastWriteTime','<q'), 

1032 ('LastChangeTime','<q'), 

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

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

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

1036 ) 

1037 AsciiStructure = ( 

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

1039 ('EaSize','<L'), 

1040 ('FileName','z'), 

1041 ) 

1042 UnicodeStructure = ( 

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

1044 ('EaSize','<L'), 

1045 ('FileName',':'), 

1046 ) 

1047 

1048# SMB_FIND_INFO_STANDARD level 

1049class SMBFindInfoStandard(AsciiOrUnicodeStructure): 

1050 commonHdr = ( 

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

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

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

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

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

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

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

1058 ('EaSize','<L'), 

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

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

1061 ) 

1062 AsciiStructure = ( 

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

1064 ('FileName','z'), 

1065 ) 

1066 UnicodeStructure = ( 

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

1068 ('FileName',':'), 

1069 ) 

1070 

1071# SET_FILE_INFORMATION structures 

1072# SMB_SET_FILE_DISPOSITION_INFO 

1073class SMBSetFileDispositionInfo(Structure): 

1074 structure = ( 

1075 ('DeletePending','<B'), 

1076 ) 

1077 

1078# SMB_SET_FILE_BASIC_INFO 

1079class SMBSetFileBasicInfo(Structure): 

1080 structure = ( 

1081 ('CreationTime','<q'), 

1082 ('LastAccessTime','<q'), 

1083 ('LastWriteTime','<q'), 

1084 ('ChangeTime','<q'), 

1085 ('ExtFileAttributes','<H'), 

1086 ('Reserved','<L'), 

1087 ) 

1088 

1089# FILE_STREAM_INFORMATION 

1090class SMBFileStreamInformation(Structure): 

1091 commonHdr = ( 

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

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

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

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

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

1097 ) 

1098 

1099# FILE_NETWORK_OPEN_INFORMATION 

1100class SMBFileNetworkOpenInfo(Structure): 

1101 structure = ( 

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

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

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

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

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

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

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

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

1110 ) 

1111 

1112# SMB_SET_FILE_END_OF_FILE_INFO 

1113class SMBSetFileEndOfFileInfo(Structure): 

1114 structure = ( 

1115 ('EndOfFile','<q'), 

1116 ) 

1117 

1118# TRANS2_FIND_NEXT2 

1119class SMBFindNext2_Parameters(AsciiOrUnicodeStructure): 

1120 commonHdr = ( 

1121 ('SID','<H'), 

1122 ('SearchCount','<H'), 

1123 ('InformationLevel','<H'), 

1124 ('ResumeKey','<L'), 

1125 ('Flags','<H'), 

1126 ) 

1127 AsciiStructure = ( 

1128 ('FileName','z'), 

1129 ) 

1130 UnicodeStructure = ( 

1131 ('FileName','u'), 

1132 ) 

1133 

1134class SMBFindNext2Response_Parameters(Structure): 

1135 structure = ( 

1136 ('SearchCount','<H'), 

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

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

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

1140 ) 

1141 

1142class SMBFindNext2_Data(Structure): 

1143 structure = ( 

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

1145 ('GetExtendedAttributesList',':'), 

1146 ) 

1147 

1148 

1149# TRANS2_FIND_FIRST2 

1150class SMBFindFirst2Response_Parameters(Structure): 

1151 structure = ( 

1152 ('SID','<H'), 

1153 ('SearchCount','<H'), 

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

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

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

1157 ) 

1158 

1159class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure): 

1160 commonHdr = ( 

1161 ('SearchAttributes','<H'), 

1162 ('SearchCount','<H'), 

1163 ('Flags','<H'), 

1164 ('InformationLevel','<H'), 

1165 ('SearchStorageType','<L'), 

1166 ) 

1167 AsciiStructure = ( 

1168 ('FileName','z'), 

1169 ) 

1170 UnicodeStructure = ( 

1171 ('FileName','u'), 

1172 ) 

1173 

1174class SMBFindFirst2_Data(Structure): 

1175 structure = ( 

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

1177 ('GetExtendedAttributesList',':'), 

1178 ) 

1179 

1180# TRANS2_SET_PATH_INFORMATION 

1181class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure): 

1182 commonHdr = ( 

1183 ('InformationLevel','<H'), 

1184 ('Reserved','<L'), 

1185 ) 

1186 AsciiStructure = ( 

1187 ('FileName','z'), 

1188 ) 

1189 UnicodeStructure = ( 

1190 ('FileName','u'), 

1191 ) 

1192 

1193class SMBSetPathInformationResponse_Parameters(Structure): 

1194 structure = ( 

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

1196 ) 

1197 

1198# TRANS2_SET_FILE_INFORMATION 

1199class SMBSetFileInformation_Parameters(Structure): 

1200 structure = ( 

1201 ('FID','<H'), 

1202 ('InformationLevel','<H'), 

1203 ('Reserved','<H'), 

1204 ) 

1205 

1206class SMBSetFileInformationResponse_Parameters(Structure): 

1207 structure = ( 

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

1209 ) 

1210 

1211# TRANS2_QUERY_FILE_INFORMATION 

1212class SMBQueryFileInformation_Parameters(Structure): 

1213 structure = ( 

1214 ('FID','<H'), 

1215 ('InformationLevel','<H'), 

1216 ) 

1217 

1218class SMBQueryFileInformationResponse_Parameters(Structure): 

1219 structure = ( 

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

1221 ) 

1222 

1223class SMBQueryFileInformation_Data(Structure): 

1224 structure = ( 

1225 ('GetExtendedAttributeList',':'), 

1226 ) 

1227 

1228# TRANS2_QUERY_PATH_INFORMATION 

1229class SMBQueryPathInformationResponse_Parameters(Structure): 

1230 structure = ( 

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

1232 ) 

1233 

1234class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure): 

1235 commonHdr = ( 

1236 ('InformationLevel','<H'), 

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

1238 ) 

1239 AsciiStructure = ( 

1240 ('FileName','z'), 

1241 ) 

1242 UnicodeStructure = ( 

1243 ('FileName','u'), 

1244 ) 

1245 

1246class SMBQueryPathInformation_Data(Structure): 

1247 structure = ( 

1248 ('GetExtendedAttributeList',':'), 

1249 ) 

1250 

1251 

1252# SMB_QUERY_FILE_EA_INFO 

1253class SMBQueryFileEaInfo(Structure): 

1254 structure = ( 

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

1256 ) 

1257 

1258# SMB_QUERY_FILE_BASIC_INFO 

1259class SMBQueryFileBasicInfo(Structure): 

1260 structure = ( 

1261 ('CreationTime','<q'), 

1262 ('LastAccessTime','<q'), 

1263 ('LastWriteTime','<q'), 

1264 ('LastChangeTime','<q'), 

1265 ('ExtFileAttributes','<L'), 

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

1267 ) 

1268 

1269# SMB_QUERY_FILE_STANDARD_INFO 

1270class SMBQueryFileStandardInfo(Structure): 

1271 structure = ( 

1272 ('AllocationSize','<q'), 

1273 ('EndOfFile','<q'), 

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

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

1276 ('Directory','<B'), 

1277 ) 

1278 

1279# SMB_QUERY_FILE_ALL_INFO 

1280class SMBQueryFileAllInfo(Structure): 

1281 structure = ( 

1282 ('CreationTime','<q'), 

1283 ('LastAccessTime','<q'), 

1284 ('LastWriteTime','<q'), 

1285 ('LastChangeTime','<q'), 

1286 ('ExtFileAttributes','<L'), 

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

1288 ('AllocationSize','<q'), 

1289 ('EndOfFile','<q'), 

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

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

1292 ('Directory','<B'), 

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

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

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

1296 ('FileName',':'), 

1297 ) 

1298 

1299# \PIPE\LANMAN NetShareEnum 

1300class SMBNetShareEnum(Structure): 

1301 structure = ( 

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

1303 ('ParamDesc','z'), 

1304 ('DataDesc','z'), 

1305 ('InfoLevel','<H'), 

1306 ('ReceiveBufferSize','<H'), 

1307 ) 

1308 

1309class SMBNetShareEnumResponse(Structure): 

1310 structure = ( 

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

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

1313 ('EntriesReturned','<H'), 

1314 ('EntriesAvailable','<H'), 

1315 ) 

1316 

1317class NetShareInfo1(Structure): 

1318 structure = ( 

1319 ('NetworkName','13s'), 

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

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

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

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

1324 ) 

1325 

1326# \PIPE\LANMAN NetServerGetInfo 

1327class SMBNetServerGetInfoResponse(Structure): 

1328 structure = ( 

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

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

1331 ('TotalBytesAvailable','<H'), 

1332 ) 

1333 

1334class SMBNetServerInfo1(Structure): 

1335 # Level 1 Response 

1336 structure = ( 

1337 ('ServerName','16s'), 

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

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

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

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

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

1343 ) 

1344 

1345# \PIPE\LANMAN NetShareGetInfo 

1346class SMBNetShareGetInfo(Structure): 

1347 structure = ( 

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

1349 ('ParamDesc','z'), 

1350 ('DataDesc','z'), 

1351 ('ShareName','z'), 

1352 ('InfoLevel','<H'), 

1353 ('ReceiveBufferSize','<H'), 

1354 ) 

1355 

1356class SMBNetShareGetInfoResponse(Structure): 

1357 structure = ( 

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

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

1360 ('TotalBytesAvailable','<H'), 

1361 ) 

1362 

1363############# Security Features 

1364class SecurityFeatures(Structure): 

1365 structure = ( 

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

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

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

1369 ) 

1370 

1371############# SMB_COM_QUERY_INFORMATION2 (0x23) 

1372class SMBQueryInformation2_Parameters(Structure): 

1373 structure = ( 

1374 ('Fid','<H'), 

1375 ) 

1376 

1377class SMBQueryInformation2Response_Parameters(Structure): 

1378 structure = ( 

1379 ('CreateDate','<H'), 

1380 ('CreationTime','<H'), 

1381 ('LastAccessDate','<H'), 

1382 ('LastAccessTime','<H'), 

1383 ('LastWriteDate','<H'), 

1384 ('LastWriteTime','<H'), 

1385 ('FileDataSize','<L'), 

1386 ('FileAllocationSize','<L'), 

1387 ('FileAttributes','<L'), 

1388 ) 

1389 

1390 

1391 

1392############# SMB_COM_SESSION_SETUP_ANDX (0x73) 

1393class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters): 

1394 structure = ( 

1395 ('MaxBuffer','<H'), 

1396 ('MaxMpxCount','<H'), 

1397 ('VCNumber','<H'), 

1398 ('SessionKey','<L'), 

1399 ('AnsiPwdLength','<H'), 

1400 ('UnicodePwdLength','<H'), 

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

1402 ('Capabilities','<L'), 

1403 ) 

1404 

1405class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters): 

1406 structure = ( 

1407 ('MaxBufferSize','<H'), 

1408 ('MaxMpxCount','<H'), 

1409 ('VcNumber','<H'), 

1410 ('SessionKey','<L'), 

1411 ('SecurityBlobLength','<H'), 

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

1413 ('Capabilities','<L'), 

1414 ) 

1415 

1416class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure): 

1417 AsciiStructure = ( 

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

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

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

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

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

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

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

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

1426 ) 

1427 

1428 UnicodeStructure = ( 

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

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

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

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

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

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

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

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

1437 ) 

1438 

1439class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure): 

1440 AsciiStructure = ( 

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

1442 ('SecurityBlob',':'), 

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

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

1445 ) 

1446 

1447 UnicodeStructure = ( 

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

1449 ('SecurityBlob',':'), 

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

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

1452 ) 

1453 

1454class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1455 structure = ( 

1456 ('Action','<H'), 

1457 ) 

1458 

1459class SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters): 

1460 structure = ( 

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

1462 ('SecurityBlobLength','<H'), 

1463 ) 

1464 

1465class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure): 

1466 AsciiStructure = ( 

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

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

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

1470 ) 

1471 

1472 UnicodeStructure = ( 

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

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

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

1476 ) 

1477 

1478class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure): 

1479 AsciiStructure = ( 

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

1481 ('SecurityBlob',':'), 

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

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

1484 ) 

1485 

1486 UnicodeStructure = ( 

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

1488 ('SecurityBlob',':'), 

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

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

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

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

1493 ) 

1494 def getData(self): 

1495 if self.structure == self.UnicodeStructure: 

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

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

1498 return AsciiOrUnicodeStructure.getData(self) 

1499 

1500############# SMB_COM_TREE_CONNECT (0x70) 

1501class SMBTreeConnect_Parameters(SMBCommand_Parameters): 

1502 structure = ( 

1503 ) 

1504 

1505class SMBTreeConnect_Data(SMBCommand_Parameters): 

1506 structure = ( 

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

1508 ('Path','z'), 

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

1510 ('Password','z'), 

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

1512 ('Service','z'), 

1513 ) 

1514 

1515############# SMB_COM_TREE_CONNECT_ANDX (0x75) 

1516class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters): 

1517 structure = ( 

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

1519 ('PasswordLength','<H'), 

1520 ) 

1521 

1522class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1523 structure = ( 

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

1525 ) 

1526 

1527class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 

1528 structure = ( 

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

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

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

1532 ) 

1533 

1534class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure): 

1535 AsciiStructure = ( 

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

1537 ('Password',':'), 

1538 ('Path','z'), 

1539 ('Service','z'), 

1540 ) 

1541 

1542 UnicodeStructure = ( 

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

1544 ('Password',':'), 

1545 ('Path','u'), 

1546 ('Service','z'), 

1547 ) 

1548 

1549class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure): 

1550 AsciiStructure = ( 

1551 ('Service','z'), 

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

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

1554 ('NativeFileSystem','z'), 

1555 ) 

1556 UnicodeStructure = ( 

1557 ('Service','z'), 

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

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

1560 ('NativeFileSystem','u'), 

1561 ) 

1562 

1563############# SMB_COM_NT_CREATE_ANDX (0xA2) 

1564class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters): 

1565 structure = ( 

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

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

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

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

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

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

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

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

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

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

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

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

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

1579 ) 

1580 

1581class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1582 # 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? 

1583 structure = ( 

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

1585 ('Fid','<H'), 

1586 ('CreateAction','<L'), 

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

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

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

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

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

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

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

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

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

1596 ('IsDirectory','B'), 

1597 ) 

1598 

1599class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 

1600 # [MS-SMB] Extended response description 

1601 structure = ( 

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

1603 ('Fid','<H'), 

1604 ('CreateAction','<L'), 

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

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

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

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

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

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

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

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

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

1614 ('IsDirectory','B'), 

1615 ('VolumeGUID','16s'), 

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

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

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

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

1620 ) 

1621 

1622class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure): 

1623 AsciiStructure = ( 

1624 ('FileName','z'), 

1625 ) 

1626 UnicodeStructure = ( 

1627 ('Pad','B'), 

1628 ('FileName','u'), 

1629 ) 

1630 

1631############# SMB_COM_OPEN_ANDX (0xD2) 

1632class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters): 

1633 structure = ( 

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

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

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

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

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

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

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

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

1642 ) 

1643 

1644class SMBOpenAndX_Data(SMBNtCreateAndX_Data): 

1645 pass 

1646 

1647class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1648 structure = ( 

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

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

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

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

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

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

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

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

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

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

1659 ) 

1660 

1661############# SMB_COM_WRITE (0x0B) 

1662class SMBWrite_Parameters(SMBCommand_Parameters): 

1663 structure = ( 

1664 ('Fid','<H'), 

1665 ('Count','<H'), 

1666 ('Offset','<L'), 

1667 ('Remaining','<H'), 

1668 ) 

1669 

1670class SMBWriteResponse_Parameters(SMBCommand_Parameters): 

1671 structure = ( 

1672 ('Count','<H'), 

1673 ) 

1674 

1675class SMBWrite_Data(Structure): 

1676 structure = ( 

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

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

1679 ('Data',':'), 

1680 ) 

1681 

1682 

1683############# SMB_COM_WRITE_ANDX (0x2F) 

1684class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters): 

1685 structure = ( 

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

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

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

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

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

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

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

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

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

1695 ) 

1696 

1697class SMBWriteAndX_Data_Short(Structure): 

1698 structure = ( 

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

1700 ('Pad',':'), 

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

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

1703 ('Data',':'), 

1704 ) 

1705 

1706class SMBWriteAndX_Data(Structure): 

1707 structure = ( 

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

1709 ('Pad',':'), 

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

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

1712 ('Data',':'), 

1713 ) 

1714 

1715 

1716class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters): 

1717 structure = ( 

1718 ('Fid','<H'), 

1719 ('Offset','<L'), 

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

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

1722 ('Remaining','<H'), 

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

1724 ('DataLength','<H'), 

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

1726 ) 

1727 

1728class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1729 structure = ( 

1730 ('Count','<H'), 

1731 ('Available','<H'), 

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

1733 ) 

1734 

1735############# SMB_COM_WRITE_RAW (0x1D) 

1736class SMBWriteRaw_Parameters(SMBCommand_Parameters): 

1737 structure = ( 

1738 ('Fid','<H'), 

1739 ('Count','<H'), 

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

1741 ('Offset','<L'), 

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

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

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

1745 ('DataLength','<H'), 

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

1747 ) 

1748 

1749############# SMB_COM_READ (0x0A) 

1750class SMBRead_Parameters(SMBCommand_Parameters): 

1751 structure = ( 

1752 ('Fid','<H'), 

1753 ('Count','<H'), 

1754 ('Offset','<L'), 

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

1756 ) 

1757 

1758class SMBReadResponse_Parameters(Structure): 

1759 structure = ( 

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

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

1762 ) 

1763 

1764class SMBReadResponse_Data(Structure): 

1765 structure = ( 

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

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

1768 ('Data',':'), 

1769 ) 

1770 

1771############# SMB_COM_READ_RAW (0x1A) 

1772class SMBReadRaw_Parameters(SMBCommand_Parameters): 

1773 structure = ( 

1774 ('Fid','<H'), 

1775 ('Offset','<L'), 

1776 ('MaxCount','<H'), 

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

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

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

1780 ) 

1781 

1782############# SMB_COM_NT_TRANSACT (0xA0) 

1783class SMBNTTransaction_Parameters(SMBCommand_Parameters): 

1784 structure = ( 

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

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

1787 ('TotalParameterCount','<L'), 

1788 ('TotalDataCount','<L'), 

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

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

1791 ('ParameterCount','<L'), 

1792 ('ParameterOffset','<L'), 

1793 ('DataCount','<L'), 

1794 ('DataOffset','<L'), 

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

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

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

1798 ('Setup',':'), 

1799 ) 

1800 

1801class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters): 

1802 structure = ( 

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

1804 ('TotalParameterCount','<L'), 

1805 ('TotalDataCount','<L'), 

1806 ('ParameterCount','<L'), 

1807 ('ParameterOffset','<L'), 

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

1809 ('DataCount','<L'), 

1810 ('DataOffset','<L'), 

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

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

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

1814 ('Setup',':'), 

1815 ) 

1816 

1817class SMBNTTransaction_Data(Structure): 

1818 structure = ( 

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

1820 ('Pad1',':'), 

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

1822 ('NT_Trans_Parameters',':'), 

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

1824 ('Pad2',':'), 

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

1826 ('NT_Trans_Data',':'), 

1827 ) 

1828 

1829class SMBNTTransactionResponse_Data(Structure): 

1830 structure = ( 

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

1832 ('Pad1',':'), 

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

1834 ('Trans_Parameters',':'), 

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

1836 ('Pad2',':'), 

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

1838 ('Trans_Data',':'), 

1839 ) 

1840 

1841 

1842############# SMB_COM_TRANSACTION2_SECONDARY (0x33) 

1843class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters): 

1844 structure = ( 

1845 ('TotalParameterCount','<H'), 

1846 ('TotalDataCount','<H'), 

1847 ('ParameterCount','<H'), 

1848 ('ParameterOffset','<H'), 

1849 ('ParameterDisplacement','<H'), 

1850 ('DataCount','<H'), 

1851 ('DataOffset','<H'), 

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

1853 ('FID','<H'), 

1854 ) 

1855 

1856class SMBTransaction2Secondary_Data(Structure): 

1857 structure = ( 

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

1859 ('Pad1',':'), 

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

1861 ('Trans_Parameters',':'), 

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

1863 ('Pad2',':'), 

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

1865 ('Trans_Data',':'), 

1866 ) 

1867 

1868 

1869############# SMB_COM_TRANSACTION2 (0x32) 

1870 

1871class SMBTransaction2_Parameters(SMBCommand_Parameters): 

1872 structure = ( 

1873 ('TotalParameterCount','<H'), 

1874 ('TotalDataCount','<H'), 

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

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

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

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

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

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

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

1882 ('ParameterCount','<H'), 

1883 ('ParameterOffset','<H'), 

1884 ('DataCount','<H'), 

1885 ('DataOffset','<H'), 

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

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

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

1889 ('Setup',':'), 

1890 ) 

1891 

1892class SMBTransaction2Response_Parameters(SMBCommand_Parameters): 

1893 structure = ( 

1894 ('TotalParameterCount','<H'), 

1895 ('TotalDataCount','<H'), 

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

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

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

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

1900 ('DataCount','<H'), 

1901 ('DataOffset','<H'), 

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

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

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

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

1906 ('Setup',':'), 

1907 ) 

1908 

1909class SMBTransaction2_Data(Structure): 

1910 structure = ( 

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

1912# ('Name',':'), 

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

1914 ('Pad1',':'), 

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

1916 ('Trans_Parameters',':'), 

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

1918 ('Pad2',':'), 

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

1920 ('Trans_Data',':'), 

1921 ) 

1922 

1923class SMBTransaction2Response_Data(Structure): 

1924 structure = ( 

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

1926 ('Pad1',':'), 

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

1928 ('Trans_Parameters',':'), 

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

1930 ('Pad2',':'), 

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

1932 ('Trans_Data',':'), 

1933 ) 

1934 

1935############# SMB_COM_QUERY_INFORMATION (0x08) 

1936 

1937class SMBQueryInformation_Data(AsciiOrUnicodeStructure): 

1938 AsciiStructure = ( 

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

1940 ('FileName','z'), 

1941 ) 

1942 UnicodeStructure = ( 

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

1944 ('FileName','u'), 

1945 ) 

1946 

1947 

1948class SMBQueryInformationResponse_Parameters(Structure): 

1949 structure = ( 

1950 ('FileAttributes','<H'), 

1951 ('LastWriteTime','<L'), 

1952 ('FileSize','<L'), 

1953 ('Reserved','"0123456789'), 

1954 ) 

1955 

1956############# SMB_COM_TRANSACTION (0x25) 

1957class SMBTransaction_Parameters(SMBCommand_Parameters): 

1958 structure = ( 

1959 ('TotalParameterCount','<H'), 

1960 ('TotalDataCount','<H'), 

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

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

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

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

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

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

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

1968 ('ParameterCount','<H'), 

1969 ('ParameterOffset','<H'), 

1970 ('DataCount','<H'), 

1971 ('DataOffset','<H'), 

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

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

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

1975 ('Setup',':'), 

1976 ) 

1977 

1978class SMBTransactionResponse_Parameters(SMBCommand_Parameters): 

1979 structure = ( 

1980 ('TotalParameterCount','<H'), 

1981 ('TotalDataCount','<H'), 

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

1983 ('ParameterCount','<H'), 

1984 ('ParameterOffset','<H'), 

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

1986 ('DataCount','<H'), 

1987 ('DataOffset','<H'), 

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

1989 ('SetupCount','<B'), 

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

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

1992 ('Setup',':'), 

1993 ) 

1994 

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

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

1997class SMBTransaction_SData(AsciiOrUnicodeStructure): 

1998 AsciiStructure = ( 

1999 ('Name','z'), 

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

2001 ('Trans_Parameters',':'), 

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

2003 ('Trans_Data',':'), 

2004 ) 

2005 UnicodeStructure = ( 

2006 ('Pad','B'), 

2007 ('Name','u'), 

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

2009 ('Trans_Parameters',':'), 

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

2011 ('Trans_Data',':'), 

2012 ) 

2013 

2014class SMBTransaction_Data(Structure): 

2015 structure = ( 

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

2017 ('Name',':'), 

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

2019 ('Trans_Parameters',':'), 

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

2021 ('Trans_Data',':'), 

2022 ) 

2023 

2024class SMBTransactionResponse_Data(Structure): 

2025 structure = ( 

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

2027 ('Trans_Parameters',':'), 

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

2029 ('Trans_Data',':'), 

2030 ) 

2031 

2032############# SMB_COM_READ_ANDX (0x2E) 

2033class SMBReadAndX_Parameters(SMBAndXCommand_Parameters): 

2034 structure = ( 

2035 ('Fid','<H'), 

2036 ('Offset','<L'), 

2037 ('MaxCount','<H'), 

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

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

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

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

2042 ) 

2043 

2044class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters): 

2045 structure = ( 

2046 ('Fid','<H'), 

2047 ('Offset','<L'), 

2048 ('MaxCount','<H'), 

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

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

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

2052 ) 

2053 

2054class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters): 

2055 structure = ( 

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

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

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

2059 ('DataCount','<H'), 

2060 ('DataOffset','<H'), 

2061 ('DataCount_Hi','<L'), 

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

2063 ) 

2064 

2065############# SMB_COM_ECHO (0x2B) 

2066class SMBEcho_Data(Structure): 

2067 structure = ( 

2068 ('Data',':'), 

2069 ) 

2070 

2071class SMBEcho_Parameters(Structure): 

2072 structure = ( 

2073 ('EchoCount','<H'), 

2074 ) 

2075 

2076class SMBEchoResponse_Data(Structure): 

2077 structure = ( 

2078 ('Data',':'), 

2079 ) 

2080 

2081class SMBEchoResponse_Parameters(Structure): 

2082 structure = ( 

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

2084 ) 

2085 

2086############# SMB_COM_QUERY_INFORMATION_DISK (0x80) 

2087class SMBQueryInformationDiskResponse_Parameters(Structure): 

2088 structure = ( 

2089 ('TotalUnits','<H'), 

2090 ('BlocksPerUnit','<H'), 

2091 ('BlockSize','<H'), 

2092 ('FreeUnits','<H'), 

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

2094 ) 

2095 

2096 

2097############# SMB_COM_LOGOFF_ANDX (0x74) 

2098class SMBLogOffAndX(SMBAndXCommand_Parameters): 

2099 strucure = () 

2100 

2101############# SMB_COM_CLOSE (0x04) 

2102class SMBClose_Parameters(SMBCommand_Parameters): 

2103 structure = ( 

2104 ('FID','<H'), 

2105 ('Time','<L=0'), 

2106 ) 

2107 

2108############# SMB_COM_FLUSH (0x05) 

2109class SMBFlush_Parameters(SMBCommand_Parameters): 

2110 structure = ( 

2111 ('FID','<H'), 

2112 ) 

2113 

2114############# SMB_COM_CREATE_DIRECTORY (0x00) 

2115class SMBCreateDirectory_Data(AsciiOrUnicodeStructure): 

2116 AsciiStructure = ( 

2117 ('BufferFormat','<B=4'), 

2118 ('DirectoryName','z'), 

2119 ) 

2120 UnicodeStructure = ( 

2121 ('BufferFormat','<B=4'), 

2122 ('DirectoryName','u'), 

2123 ) 

2124 

2125############# SMB_COM_DELETE (0x06) 

2126class SMBDelete_Data(AsciiOrUnicodeStructure): 

2127 AsciiStructure = ( 

2128 ('BufferFormat','<B=4'), 

2129 ('FileName','z'), 

2130 ) 

2131 UnicodeStructure = ( 

2132 ('BufferFormat','<B=4'), 

2133 ('FileName','u'), 

2134 ) 

2135 

2136class SMBDelete_Parameters(Structure): 

2137 structure = ( 

2138 ('SearchAttributes','<H'), 

2139 ) 

2140 

2141############# SMB_COM_DELETE_DIRECTORY (0x01) 

2142class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure): 

2143 AsciiStructure = ( 

2144 ('BufferFormat','<B=4'), 

2145 ('DirectoryName','z'), 

2146 ) 

2147 UnicodeStructure = ( 

2148 ('BufferFormat','<B=4'), 

2149 ('DirectoryName','u'), 

2150 ) 

2151 

2152############# SMB_COM_CHECK_DIRECTORY (0x10) 

2153class SMBCheckDirectory_Data(AsciiOrUnicodeStructure): 

2154 AsciiStructure = ( 

2155 ('BufferFormat','<B=4'), 

2156 ('DirectoryName','z'), 

2157 ) 

2158 UnicodeStructure = ( 

2159 ('BufferFormat','<B=4'), 

2160 ('DirectoryName','u'), 

2161 ) 

2162 

2163############# SMB_COM_RENAME (0x07) 

2164class SMBRename_Parameters(SMBCommand_Parameters): 

2165 structure = ( 

2166 ('SearchAttributes','<H'), 

2167 ) 

2168 

2169class SMBRename_Data(AsciiOrUnicodeStructure): 

2170 AsciiStructure = ( 

2171 ('BufferFormat1','<B=4'), 

2172 ('OldFileName','z'), 

2173 ('BufferFormat2','<B=4'), 

2174 ('NewFileName','z'), 

2175 ) 

2176 UnicodeStructure = ( 

2177 ('BufferFormat1','<B=4'), 

2178 ('OldFileName','u'), 

2179 ('BufferFormat2','<B=4'), 

2180 ('Pad','B=0'), 

2181 ('NewFileName','u'), 

2182 ) 

2183 

2184 

2185############# SMB_COM_OPEN (0x02) 

2186class SMBOpen_Parameters(SMBCommand_Parameters): 

2187 structure = ( 

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

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

2190 ) 

2191 

2192class SMBOpen_Data(AsciiOrUnicodeStructure): 

2193 AsciiStructure = ( 

2194 ('FileNameFormat','"\x04'), 

2195 ('FileName','z'), 

2196 ) 

2197 UnicodeStructure = ( 

2198 ('FileNameFormat','"\x04'), 

2199 ('FileName','u'), 

2200 ) 

2201 

2202class SMBOpenResponse_Parameters(SMBCommand_Parameters): 

2203 structure = ( 

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

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

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

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

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

2209 ) 

2210 

2211############# EXTENDED SECURITY CLASSES 

2212class SMBExtended_Security_Parameters(Structure): 

2213 structure = ( 

2214 ('DialectIndex','<H'), 

2215 ('SecurityMode','<B'), 

2216 ('MaxMpxCount','<H'), 

2217 ('MaxNumberVcs','<H'), 

2218 ('MaxBufferSize','<L'), 

2219 ('MaxRawSize','<L'), 

2220 ('SessionKey','<L'), 

2221 ('Capabilities','<L'), 

2222 ('LowDateTime','<L'), 

2223 ('HighDateTime','<L'), 

2224 ('ServerTimeZone','<H'), 

2225 ('ChallengeLength','<B'), 

2226 ) 

2227 

2228class SMBExtended_Security_Data(Structure): 

2229 structure = ( 

2230 ('ServerGUID','16s'), 

2231 ('SecurityBlob',':'), 

2232 ) 

2233 

2234class SMBNTLMDialect_Parameters(Structure): 

2235 structure = ( 

2236 ('DialectIndex','<H'), 

2237 ('SecurityMode','<B'), 

2238 ('MaxMpxCount','<H'), 

2239 ('MaxNumberVcs','<H'), 

2240 ('MaxBufferSize','<L'), 

2241 ('MaxRawSize','<L'), 

2242 ('SessionKey','<L'), 

2243 ('Capabilities','<L'), 

2244 ('LowDateTime','<L'), 

2245 ('HighDateTime','<L'), 

2246 ('ServerTimeZone','<H'), 

2247 ('ChallengeLength','<B'), 

2248 ) 

2249 

2250class SMBNTLMDialect_Data(Structure): 

2251 structure = ( 

2252 ('ChallengeLength','_-Challenge','self["ChallengeLength"]'), 

2253 ('Challenge',':'), 

2254 ('Payload',':'), 

2255# 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. 

2256 ('DomainName','_'), 

2257 ('ServerName','_'), 

2258 ) 

2259 def __init__(self,data = None, alignment = 0): 

2260 Structure.__init__(self,data,alignment) 

2261 #self['ChallengeLength']=8 

2262 

2263 def fromString(self,data): 

2264 Structure.fromString(self,data) 

2265 self['DomainName'] = '' 

2266 self['ServerName'] = '' 

2267 

2268class SMB(object): 

2269 

2270 class HostnameValidationException(Exception): 

2271 pass 

2272 

2273 # SMB Command Codes 

2274 SMB_COM_CREATE_DIRECTORY = 0x00 

2275 SMB_COM_DELETE_DIRECTORY = 0x01 

2276 SMB_COM_OPEN = 0x02 

2277 SMB_COM_CREATE = 0x03 

2278 SMB_COM_CLOSE = 0x04 

2279 SMB_COM_FLUSH = 0x05 

2280 SMB_COM_DELETE = 0x06 

2281 SMB_COM_RENAME = 0x07 

2282 SMB_COM_QUERY_INFORMATION = 0x08 

2283 SMB_COM_SET_INFORMATION = 0x09 

2284 SMB_COM_READ = 0x0A 

2285 SMB_COM_WRITE = 0x0B 

2286 SMB_COM_LOCK_BYTE_RANGE = 0x0C 

2287 SMB_COM_UNLOCK_BYTE_RANGE = 0x0D 

2288 SMB_COM_CREATE_TEMPORARY = 0x0E 

2289 SMB_COM_CREATE_NEW = 0x0F 

2290 SMB_COM_CHECK_DIRECTORY = 0x10 

2291 SMB_COM_PROCESS_EXIT = 0x11 

2292 SMB_COM_SEEK = 0x12 

2293 SMB_COM_LOCK_AND_READ = 0x13 

2294 SMB_COM_WRITE_AND_UNLOCK = 0x14 

2295 SMB_COM_READ_RAW = 0x1A 

2296 SMB_COM_READ_MPX = 0x1B 

2297 SMB_COM_READ_MPX_SECONDARY = 0x1C 

2298 SMB_COM_WRITE_RAW = 0x1D 

2299 SMB_COM_WRITE_MPX = 0x1E 

2300 SMB_COM_WRITE_MPX_SECONDARY = 0x1F 

2301 SMB_COM_WRITE_COMPLETE = 0x20 

2302 SMB_COM_QUERY_SERVER = 0x21 

2303 SMB_COM_SET_INFORMATION2 = 0x22 

2304 SMB_COM_QUERY_INFORMATION2 = 0x23 

2305 SMB_COM_LOCKING_ANDX = 0x24 

2306 SMB_COM_TRANSACTION = 0x25 

2307 SMB_COM_TRANSACTION_SECONDARY = 0x26 

2308 SMB_COM_IOCTL = 0x27 

2309 SMB_COM_IOCTL_SECONDARY = 0x28 

2310 SMB_COM_COPY = 0x29 

2311 SMB_COM_MOVE = 0x2A 

2312 SMB_COM_ECHO = 0x2B 

2313 SMB_COM_WRITE_AND_CLOSE = 0x2C 

2314 SMB_COM_OPEN_ANDX = 0x2D 

2315 SMB_COM_READ_ANDX = 0x2E 

2316 SMB_COM_WRITE_ANDX = 0x2F 

2317 SMB_COM_NEW_FILE_SIZE = 0x30 

2318 SMB_COM_CLOSE_AND_TREE_DISC = 0x31 

2319 SMB_COM_TRANSACTION2 = 0x32 

2320 SMB_COM_TRANSACTION2_SECONDARY = 0x33 

2321 SMB_COM_FIND_CLOSE2 = 0x34 

2322 SMB_COM_FIND_NOTIFY_CLOSE = 0x35 

2323 # Used by Xenix/Unix 0x60 - 0x6E 

2324 SMB_COM_TREE_CONNECT = 0x70 

2325 SMB_COM_TREE_DISCONNECT = 0x71 

2326 SMB_COM_NEGOTIATE = 0x72 

2327 SMB_COM_SESSION_SETUP_ANDX = 0x73 

2328 SMB_COM_LOGOFF_ANDX = 0x74 

2329 SMB_COM_TREE_CONNECT_ANDX = 0x75 

2330 SMB_COM_QUERY_INFORMATION_DISK = 0x80 

2331 SMB_COM_SEARCH = 0x81 

2332 SMB_COM_FIND = 0x82 

2333 SMB_COM_FIND_UNIQUE = 0x83 

2334 SMB_COM_FIND_CLOSE = 0x84 

2335 SMB_COM_NT_TRANSACT = 0xA0 

2336 SMB_COM_NT_TRANSACT_SECONDARY = 0xA1 

2337 SMB_COM_NT_CREATE_ANDX = 0xA2 

2338 SMB_COM_NT_CANCEL = 0xA4 

2339 SMB_COM_NT_RENAME = 0xA5 

2340 SMB_COM_OPEN_PRINT_FILE = 0xC0 

2341 SMB_COM_WRITE_PRINT_FILE = 0xC1 

2342 SMB_COM_CLOSE_PRINT_FILE = 0xC2 

2343 SMB_COM_GET_PRINT_QUEUE = 0xC3 

2344 SMB_COM_READ_BULK = 0xD8 

2345 SMB_COM_WRITE_BULK = 0xD9 

2346 SMB_COM_WRITE_BULK_DATA = 0xDA 

2347 

2348 # TRANSACT codes 

2349 TRANS_TRANSACT_NMPIPE = 0x26 

2350 

2351 # TRANSACT2 codes 

2352 TRANS2_FIND_FIRST2 = 0x0001 

2353 TRANS2_FIND_NEXT2 = 0x0002 

2354 TRANS2_QUERY_FS_INFORMATION = 0x0003 

2355 TRANS2_QUERY_PATH_INFORMATION = 0x0005 

2356 TRANS2_QUERY_FILE_INFORMATION = 0x0007 

2357 TRANS2_SET_FILE_INFORMATION = 0x0008 

2358 TRANS2_SET_PATH_INFORMATION = 0x0006 

2359 

2360 # Security Share Mode (Used internally by SMB class) 

2361 SECURITY_SHARE_MASK = 0x01 

2362 SECURITY_SHARE_SHARE = 0x00 

2363 SECURITY_SHARE_USER = 0x01 

2364 SECURITY_SIGNATURES_ENABLED = 0X04 

2365 SECURITY_SIGNATURES_REQUIRED = 0X08 

2366 

2367 # Security Auth Mode (Used internally by SMB class) 

2368 SECURITY_AUTH_MASK = 0x02 

2369 SECURITY_AUTH_ENCRYPTED = 0x02 

2370 SECURITY_AUTH_PLAINTEXT = 0x00 

2371 

2372 # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and including LANMAN2.1) 

2373 RAW_READ_MASK = 0x01 

2374 RAW_WRITE_MASK = 0x02 

2375 

2376 # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 0.12) 

2377 CAP_RAW_MODE = 0x00000001 

2378 CAP_MPX_MODE = 0x0002 

2379 CAP_UNICODE = 0x0004 

2380 CAP_LARGE_FILES = 0x0008 

2381 CAP_EXTENDED_SECURITY = 0x80000000 

2382 CAP_USE_NT_ERRORS = 0x40 

2383 CAP_NT_SMBS = 0x10 

2384 CAP_LARGE_READX = 0x00004000 

2385 CAP_LARGE_WRITEX = 0x00008000 

2386 CAP_RPC_REMOTE_APIS = 0x20 

2387 

2388 # Flags1 Mask 

2389 FLAGS1_LOCK_AND_READ_OK = 0x01 

2390 FLAGS1_PATHCASELESS = 0x08 

2391 FLAGS1_CANONICALIZED_PATHS = 0x10 

2392 FLAGS1_REPLY = 0x80 

2393 

2394 # Flags2 Mask 

2395 FLAGS2_LONG_NAMES = 0x0001 

2396 FLAGS2_EAS = 0x0002 

2397 FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004 

2398 FLAGS2_IS_LONG_NAME = 0x0040 

2399 FLAGS2_DFS = 0x1000 

2400 FLAGS2_PAGING_IO = 0x2000 

2401 FLAGS2_NT_STATUS = 0x4000 

2402 FLAGS2_UNICODE = 0x8000 

2403 FLAGS2_COMPRESSED = 0x0008 

2404 FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED = 0x0010 

2405 FLAGS2_EXTENDED_SECURITY = 0x0800 

2406 

2407 # Dialect's Security Mode flags 

2408 NEGOTIATE_USER_SECURITY = 0x01 

2409 NEGOTIATE_ENCRYPT_PASSWORDS = 0x02 

2410 NEGOTIATE_SECURITY_SIGNATURE_ENABLE = 0x04 

2411 NEGOTIATE_SECURITY_SIGNATURE_REQUIRED = 0x08 

2412 

2413 # Tree Connect AndX Response optionalSuppor flags 

2414 SMB_SUPPORT_SEARCH_BITS = 0x01 

2415 SMB_SHARE_IS_IN_DFS = 0x02 

2416 

2417 def __init__(self, remote_name, remote_host, my_name=None, host_type=nmb.TYPE_SERVER, sess_port=445, timeout=None, 

2418 UDP=0, session=None, negPacket=None): 

2419 # The uid attribute will be set when the client calls the login() method 

2420 self._uid = 0 

2421 self.__server_name = '' 

2422 self.__client_name = '' 

2423 self.__server_os = '' 

2424 self.__server_os_major = None 

2425 self.__server_os_minor = None 

2426 self.__server_os_build = None 

2427 self.__server_lanman = '' 

2428 self.__server_domain = '' 

2429 self.__server_dns_domain_name = '' 

2430 self.__server_dns_host_name = '' 

2431 self.__remote_name = remote_name.upper() 

2432 self.__remote_host = remote_host 

2433 self.__isNTLMv2 = True 

2434 self._dialects_parameters = None 

2435 self._dialects_data = None 

2436 self._doKerberos = False 

2437 

2438 # Credentials 

2439 self.__userName = b'' 

2440 self.__password = b'' 

2441 self.__domain = b'' 

2442 self.__lmhash = b'' 

2443 self.__nthash = b'' 

2444 self.__aesKey = b'' 

2445 self.__kdc = b'' 

2446 self.__TGT = None 

2447 self.__TGS = None 

2448 

2449 # Negotiate Protocol Result, used everywhere 

2450 # Could be extended or not, flags should be checked before 

2451 self._dialect_data = 0 

2452 self._dialect_parameters = 0 

2453 self._action = 0 

2454 self._sess = None 

2455 self.encrypt_passwords = True 

2456 self.tid = 0 

2457 self.fid = 0 

2458 

2459 # Strict host validation - off by default 

2460 self._strict_hostname_validation = False 

2461 self._validation_allow_absent = True 

2462 self._accepted_hostname = '' 

2463 

2464 # Signing stuff 

2465 self._SignSequenceNumber = 0 

2466 self._SigningSessionKey = b'' 

2467 self._SigningChallengeResponse = b'' 

2468 self._SignatureEnabled = False 

2469 self._SignatureVerificationEnabled = False 

2470 self._SignatureRequired = False 

2471 

2472 # Base flags (default flags, can be overridden using set_flags()) 

2473 self.__flags1 = SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS 

2474 self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES 

2475 

2476 if timeout is None: 2476 ↛ 2477line 2476 didn't jump to line 2477, because the condition on line 2476 was never true

2477 self.__timeout = 60 

2478 else: 

2479 self.__timeout = timeout 

2480 

2481 # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP. 

2482 # This is to help some old applications still believing 

2483 # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better 

2484 # know about *SMBSERVER's limitations 

2485 if sess_port == 445 and remote_name == '*SMBSERVER': 2485 ↛ 2486line 2485 didn't jump to line 2486, because the condition on line 2485 was never true

2486 self.__remote_name = remote_host 

2487 

2488 # This is on purpose. I'm still not convinced to do a socket.gethostname() if not specified 

2489 if my_name is None: 2489 ↛ 2492line 2489 didn't jump to line 2492, because the condition on line 2489 was never false

2490 self.__client_name = b'' 

2491 else: 

2492 self.__client_name = my_name 

2493 

2494 if session is None: 2494 ↛ 2516line 2494 didn't jump to line 2516, because the condition on line 2494 was never false

2495 if not my_name: 2495 ↛ 2502line 2495 didn't jump to line 2502, because the condition on line 2495 was never false

2496 # If destination port is 139 yes, there's some client disclosure 

2497 my_name = socket.gethostname() 

2498 i = my_name.find('.') 

2499 if i > -1: 2499 ↛ 2500line 2499 didn't jump to line 2500, because the condition on line 2499 was never true

2500 my_name = my_name[:i] 

2501 

2502 if UDP: 2502 ↛ 2503line 2502 didn't jump to line 2503, because the condition on line 2502 was never true

2503 self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 

2504 else: 

2505 self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 

2506 

2507 # Initialize session values (_dialect_data and _dialect_parameters) 

2508 self.neg_session() 

2509 

2510 # Call login() without any authentication information to 

2511 # setup a session if the remote server 

2512 # is in share mode. 

2513 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 2513 ↛ 2514line 2513 didn't jump to line 2514, because the condition on line 2513 was never true

2514 self.login('', '') 

2515 else: 

2516 self._sess = session 

2517 self.neg_session(negPacket = negPacket) 

2518 # Call login() without any authentication information to 

2519 # setup a session if the remote server 

2520 # is in share mode. 

2521 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 

2522 self.login('', '') 

2523 

2524 @staticmethod 

2525 def ntlm_supported(): 

2526 return False 

2527 

2528 def getKerberos(self): 

2529 return self._doKerberos 

2530 

2531 def get_remote_name(self): 

2532 return self.__remote_name 

2533 

2534 def set_remote_name(self, name): 

2535 self.__remote_name = name 

2536 return True 

2537 

2538 def set_hostname_validation(self, validate, accept_empty, hostname): 

2539 self._strict_hostname_validation = validate 

2540 self._validation_allow_absent = accept_empty 

2541 self._accepted_hostname = hostname 

2542 

2543 def get_remote_host(self): 

2544 return self.__remote_host 

2545 

2546 def get_flags(self): 

2547 return self.__flags1, self.__flags2 

2548 

2549 def set_flags(self, flags1=None, flags2=None): 

2550 if flags1 is not None: 

2551 self.__flags1 = flags1 

2552 if flags2 is not None: 2552 ↛ exitline 2552 didn't return from function 'set_flags', because the condition on line 2552 was never false

2553 self.__flags2 = flags2 

2554 

2555 def set_timeout(self, timeout): 

2556 prev_timeout = self.__timeout 

2557 self.__timeout = timeout 

2558 return prev_timeout 

2559 

2560 def get_timeout(self): 

2561 return self.__timeout 

2562 

2563 @contextmanager 

2564 def use_timeout(self, timeout): 

2565 prev_timeout = self.set_timeout(timeout) 

2566 try: 

2567 yield 

2568 finally: 

2569 self.set_timeout(prev_timeout) 

2570 

2571 def get_session(self): 

2572 return self._sess 

2573 

2574 def get_tid(self): 

2575 return self.tid 

2576 

2577 def get_fid(self): 

2578 return self.fid 

2579 

2580 def isGuestSession(self): 

2581 return self._action & SMB_SETUP_GUEST 

2582 

2583 def doesSupportNTLMv2(self): 

2584 return self.__isNTLMv2 

2585 

2586 def close_session(self): 

2587 if self._sess: 2587 ↛ exitline 2587 didn't return from function 'close_session', because the condition on line 2587 was never false

2588 self._sess.close() 

2589 self._sess = None 

2590 

2591 def recvSMB(self): 

2592 r = self._sess.recv_packet(self.__timeout) 

2593 return NewSMBPacket(data = r.get_trailer()) 

2594 

2595 @staticmethod 

2596 def __decode_trans(params, data): 

2597 totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19]) 

2598 if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt: 

2599 has_more = 1 

2600 else: 

2601 has_more = 0 

2602 paramoffset = paramoffset - 55 - setupcnt * 2 

2603 dataoffset = dataoffset - 55 - setupcnt * 2 

2604 return has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt] 

2605 

2606 # TODO: Move this to NewSMBPacket, it belongs there 

2607 def signSMB(self, packet, signingSessionKey, signingChallengeResponse): 

2608 # This logic MUST be applied for messages sent in response to any of the higher-layer actions and in 

2609 # compliance with the message sequencing rules. 

2610 # * The client or server that sends the message MUST provide the 32-bit sequence number for this 

2611 # message, as specified in sections 3.2.4.1 and 3.3.4.1. 

2612 # * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be set. 

2613 # * To generate the signature, a 32-bit sequence number is copied into the 

2614 # least significant 32 bits of the SecuritySignature field and the remaining 

2615 # 4 bytes are set to 0x00. 

2616 # * The MD5 algorithm, as specified in [RFC1321], MUST be used to generate a hash of the SMB 

2617 # message from the start of the SMB Header, which is defined as follows. 

2618 # CALL MD5Init( md5context ) 

2619 # CALL MD5Update( md5context, Connection.SigningSessionKey ) 

2620 # CALL MD5Update( md5context, Connection.SigningChallengeResponse ) 

2621 # CALL MD5Update( md5context, SMB message ) 

2622 # CALL MD5Final( digest, md5context ) 

2623 # SET signature TO the first 8 bytes of the digest 

2624 # The resulting 8-byte signature MUST be copied into the SecuritySignature field of the SMB Header, 

2625 # after which the message can be transmitted. 

2626 

2627 #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % (self._SignSequenceNumber, signingSessionKey, signingChallengeResponse) 

2628 packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber) 

2629 # Sign with the sequence 

2630 m = hashlib.md5() 

2631 m.update( signingSessionKey ) 

2632 m.update( signingChallengeResponse ) 

2633 m.update( packet.getData() ) 

2634 # Replace sequence with acual hash 

2635 packet['SecurityFeatures'] = m.digest()[:8] 

2636 if self._SignatureVerificationEnabled: 2636 ↛ 2637line 2636 didn't jump to line 2637, because the condition on line 2636 was never true

2637 self._SignSequenceNumber +=1 

2638 else: 

2639 self._SignSequenceNumber +=2 

2640 

2641 def checkSignSMB(self, packet, signingSessionKey, signingChallengeResponse): 

2642 # Let's check 

2643 signature = packet['SecurityFeatures'] 

2644 #print "Signature received: %r " % signature 

2645 self.signSMB(packet, signingSessionKey, signingChallengeResponse) 

2646 #print "Signature calculated: %r" % packet['SecurityFeatures'] 

2647 if self._SignatureVerificationEnabled is not True: 

2648 self._SignSequenceNumber -= 1 

2649 return packet['SecurityFeatures'] == signature 

2650 

2651 def sendSMB(self,smb): 

2652 smb['Uid'] = self._uid 

2653 #At least on AIX, PIDs can exceed 16 bits, so we mask them out 

2654 smb['Pid'] = (os.getpid() & 0xFFFF) 

2655 # set flags 

2656 smb['Flags1'] |= self.__flags1 

2657 smb['Flags2'] |= self.__flags2 

2658 if self._SignatureEnabled: 

2659 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

2660 self.signSMB(smb, self._SigningSessionKey, self._SigningChallengeResponse) 

2661 

2662 self._sess.send_packet(smb.getData()) 

2663 

2664 @staticmethod 

2665 def isValidAnswer(s, cmd): 

2666 while 1: 

2667 if s.rawData(): 

2668 if s.get_command() == cmd: 

2669 if s.get_error_class() == 0x00 and s.get_error_code() == 0x00: 

2670 return 1 

2671 else: 

2672 raise SessionError( "SMB Library Error", s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , s.get_flags2() & SMB.FLAGS2_NT_STATUS) 

2673 else: 

2674 break 

2675 return 0 

2676 

2677 def neg_session(self, extended_security = True, negPacket = None): 

2678 def parsePacket(smb): 

2679 # If server speaks Unicode, let's set that flag from now on 

2680 if smb['Flags2'] & SMB.FLAGS2_UNICODE: 2680 ↛ 2681line 2680 didn't jump to line 2681, because the condition on line 2680 was never true

2681 self.__flags2 |= SMB.FLAGS2_UNICODE 

2682 

2683 if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE): 2683 ↛ 2712line 2683 didn't jump to line 2712, because the condition on line 2683 was never false

2684 sessionResponse = SMBCommand(smb['Data'][0]) 

2685 self._dialects_parameters = SMBNTLMDialect_Parameters(sessionResponse['Parameters']) 

2686 self._dialects_data = SMBNTLMDialect_Data() 

2687 self._dialects_data['ChallengeLength'] = self._dialects_parameters['ChallengeLength'] 

2688 self._dialects_data.fromString(sessionResponse['Data']) 

2689 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 2689 ↛ 2705line 2689 didn't jump to line 2705, because the condition on line 2689 was never false

2690 # Whether we choose it or it is enforced by the server, we go for extended security 

2691 self._dialects_parameters = SMBExtended_Security_Parameters(sessionResponse['Parameters']) 

2692 self._dialects_data = SMBExtended_Security_Data(sessionResponse['Data']) 

2693 # Let's setup some variable for later use 

2694 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 2694 ↛ 2701line 2694 didn't jump to line 2701, because the condition on line 2694 was never false

2695 self._SignatureRequired = True 

2696 

2697 # Interestingly, the security Blob might be missing sometimes. 

2698 #spnego = SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob']) 

2699 #for i in spnego['MechTypes']: 

2700 # print "Mech Found: %s" % MechTypes[i] 

2701 return 1 

2702 

2703 # If not, let's try the old way 

2704 else: 

2705 if self._dialects_data['ServerName'] is not None: 

2706 self.__server_name = self._dialects_data['ServerName'] 

2707 

2708 if self._dialects_parameters['DialectIndex'] == 0xffff: 

2709 raise UnsupportedFeature("Remote server does not know NT LM 0.12") 

2710 return 1 

2711 else: 

2712 return 0 

2713 

2714 if negPacket is None: 2714 ↛ 2732line 2714 didn't jump to line 2732, because the condition on line 2714 was never false

2715 smb = NewSMBPacket() 

2716 negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE) 

2717 flags2 = self.get_flags()[1] 

2718 if extended_security is True: 2718 ↛ 2721line 2718 didn't jump to line 2721, because the condition on line 2718 was never false

2719 self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY) 

2720 else: 

2721 self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY)) 

2722 

2723 negSession['Data'] = b'\x02NT LM 0.12\x00' 

2724 smb.addCommand(negSession) 

2725 self.sendSMB(smb) 

2726 

2727 while 1: 

2728 smb = self.recvSMB() 

2729 return parsePacket(smb) 

2730 else: 

2731 

2732 return parsePacket( NewSMBPacket( data = negPacket)) 

2733 

2734 def tree_connect(self, path, password = '', service = SERVICE_ANY): 

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

2736 

2737 # return 0x800 

2738 if password: 

2739 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 

2740 if self._dialects_parameters['ChallengeLength'] > 0: 

2741 # this code is untested 

2742 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 

2743 

2744 if not unicode_support: 

2745 if unicode_convert: 

2746 path = str(path) 

2747 else: 

2748 raise Exception('SMB: Can\t conver path from unicode!') 

2749 

2750 smb = NewSMBPacket() 

2751 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT) 

2752 treeConnect['Parameters'] = SMBTreeConnect_Parameters() 

2753 treeConnect['Data'] = SMBTreeConnect_Data() 

2754 treeConnect['Data']['Path'] = path.upper() 

2755 treeConnect['Data']['Password'] = password 

2756 treeConnect['Data']['Service'] = service 

2757 smb.addCommand(treeConnect) 

2758 self.sendSMB(smb) 

2759 

2760 while 1: 

2761 smb = self.recvSMB() 

2762 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT): 

2763 # XXX Here we are ignoring the rest of the response 

2764 return smb['Tid'] 

2765 return smb['Tid'] 

2766 

2767 def get_uid(self): 

2768 return self._uid 

2769 

2770 def set_uid(self, uid): 

2771 self._uid = uid 

2772 

2773 def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, smb_packet=None): 

2774 if password: 2774 ↛ 2776line 2774 didn't jump to line 2776, because the condition on line 2774 was never true

2775 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 

2776 if self._dialects_parameters['ChallengeLength'] > 0: 

2777 # this code is untested 

2778 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 

2779 else: 

2780 password = '\x00' 

2781 

2782 if not unicode_support: 2782 ↛ 2788line 2782 didn't jump to line 2788, because the condition on line 2782 was never false

2783 if unicode_convert: 2783 ↛ 2786line 2783 didn't jump to line 2786, because the condition on line 2783 was never false

2784 path = str(path) 

2785 else: 

2786 raise Exception('SMB: Can\t convert path from unicode!') 

2787 

2788 if smb_packet is None: 2788 ↛ 2791line 2788 didn't jump to line 2791, because the condition on line 2788 was never false

2789 smb = NewSMBPacket() 

2790 else: 

2791 smb = smb_packet 

2792 

2793 # Just in case this came with the full path ,let's just leave 

2794 # the sharename, we'll take care of the rest 

2795 

2796 share = path.split('\\')[-1] 

2797 try: 

2798 _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 80, 0, 0, socket.IPPROTO_TCP)[0] 

2799 remote_host = sockaddr[0] 

2800 except Exception: 

2801 remote_host = self.get_remote_host() 

2802 

2803 path = '\\\\' + remote_host + '\\' +share 

2804 path = path.upper().encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

2805 

2806 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX) 

2807 treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters() 

2808 treeConnect['Data'] = SMBTreeConnectAndX_Data(flags=self.__flags2) 

2809 treeConnect['Parameters']['PasswordLength'] = len(password) 

2810 treeConnect['Data']['Password'] = password 

2811 treeConnect['Data']['Path'] = path 

2812 treeConnect['Data']['Service'] = service 

2813 

2814 if self.__flags2 & SMB.FLAGS2_UNICODE: 

2815 treeConnect['Data']['Pad'] = 0x0 

2816 

2817 smb.addCommand(treeConnect) 

2818 

2819 # filename = "\PIPE\epmapper" 

2820 

2821 # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 

2822 # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 

2823 # ntCreate['Data'] = SMBNtCreateAndX_Data() 

2824 # ntCreate['Parameters']['FileNameLength'] = len(filename) 

2825 # ntCreate['Parameters']['CreateFlags'] = 0 

2826 # ntCreate['Parameters']['AccessMask'] = 0x3 

2827 # ntCreate['Parameters']['CreateOptions'] = 0x0 

2828 # ntCreate['Data']['FileName'] = filename 

2829 

2830 # smb.addCommand(ntCreate) 

2831 self.sendSMB(smb) 

2832 

2833 while 1: 

2834 smb = self.recvSMB() 

2835 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX): 2835 ↛ 2839line 2835 didn't jump to line 2839, because the condition on line 2835 was never false

2836 # XXX Here we are ignoring the rest of the response 

2837 self.tid = smb['Tid'] 

2838 return self.tid 

2839 self.tid = smb['Tid'] 

2840 return self.tid 

2841 

2842 # backwars compatibility 

2843 connect_tree = tree_connect_andx 

2844 

2845 @staticmethod 

2846 def getDialect(): 

2847 return SMB_DIALECT 

2848 

2849 def get_server_name(self): 

2850 #return self._dialects_data['ServerName'] 

2851 return self.__server_name 

2852 

2853 def get_client_name(self): 

2854 return self.__client_name 

2855 

2856 def get_session_key(self): 

2857 return self._SigningSessionKey 

2858 

2859 def set_session_key(self, key): 

2860 self._SignatureEnabled = True 

2861 self._SignSequenceNumber = 2 

2862 self._SigningSessionKey = key 

2863 

2864 def get_encryption_key(self): 

2865 if 'Challenge' in self._dialects_data.fields: 

2866 return self._dialects_data['Challenge'] 

2867 else: 

2868 return None 

2869 

2870 def get_server_time(self): 

2871 timestamp = self._dialects_parameters['HighDateTime'] 

2872 timestamp <<= 32 

2873 timestamp |= self._dialects_parameters['LowDateTime'] 

2874 timestamp -= 116444736000000000 

2875 timestamp //= 10000000 

2876 d = datetime.datetime.utcfromtimestamp(timestamp) 

2877 return d.strftime("%a, %d %b %Y %H:%M:%S GMT") 

2878 

2879 def disconnect_tree(self, tid): 

2880 smb = NewSMBPacket() 

2881 smb['Tid'] = tid 

2882 

2883 smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT)) 

2884 

2885 self.sendSMB(smb) 

2886 self.recvSMB() 

2887 

2888 def open(self, tid, filename, open_mode, desired_access): 

2889 filename = filename.replace('/', '\\') 

2890 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

2891 

2892 smb = NewSMBPacket() 

2893 smb['Tid'] = tid 

2894 

2895 openFile = SMBCommand(SMB.SMB_COM_OPEN) 

2896 openFile['Parameters'] = SMBOpen_Parameters() 

2897 openFile['Parameters']['DesiredAccess'] = desired_access 

2898 openFile['Parameters']['OpenMode'] = open_mode 

2899 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 

2900 openFile['Data'] = SMBOpen_Data(flags=self.__flags2) 

2901 openFile['Data']['FileName'] = filename 

2902 

2903 smb.addCommand(openFile) 

2904 

2905 self.sendSMB(smb) 

2906 

2907 smb = self.recvSMB() 

2908 if smb.isValidAnswer(SMB.SMB_COM_OPEN): 

2909 # XXX Here we are ignoring the rest of the response 

2910 openFileResponse = SMBCommand(smb['Data'][0]) 

2911 openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters']) 

2912 

2913 return ( 

2914 openFileParameters['Fid'], 

2915 openFileParameters['FileAttributes'], 

2916 openFileParameters['LastWriten'], 

2917 openFileParameters['FileSize'], 

2918 openFileParameters['GrantedAccess'], 

2919 ) 

2920 

2921 def open_andx(self, tid, filename, open_mode, desired_access): 

2922 filename = filename.replace('/', '\\') 

2923 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

2924 

2925 smb = NewSMBPacket() 

2926 smb['Tid'] = tid 

2927 

2928 openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX) 

2929 openFile['Parameters'] = SMBOpenAndX_Parameters() 

2930 openFile['Parameters']['DesiredAccess'] = desired_access 

2931 openFile['Parameters']['OpenMode'] = open_mode 

2932 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 

2933 openFile['Data'] = SMBOpenAndX_Data(flags=self.__flags2) 

2934 openFile['Data']['FileName'] = filename 

2935 

2936 if self.__flags2 & SMB.FLAGS2_UNICODE: 

2937 openFile['Data']['Pad'] = 0x0 

2938 

2939 smb.addCommand(openFile) 

2940 

2941 self.sendSMB(smb) 

2942 

2943 smb = self.recvSMB() 

2944 if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX): 

2945 # XXX Here we are ignoring the rest of the response 

2946 openFileResponse = SMBCommand(smb['Data'][0]) 

2947 openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters']) 

2948 

2949 return ( 

2950 openFileParameters['Fid'], 

2951 openFileParameters['FileAttributes'], 

2952 openFileParameters['LastWriten'], 

2953 openFileParameters['FileSize'], 

2954 openFileParameters['GrantedAccess'], 

2955 openFileParameters['FileType'], 

2956 openFileParameters['IPCState'], 

2957 openFileParameters['Action'], 

2958 openFileParameters['ServerFid'], 

2959 ) 

2960 

2961 def close(self, tid, fid): 

2962 smb = NewSMBPacket() 

2963 smb['Tid'] = tid 

2964 

2965 closeFile = SMBCommand(SMB.SMB_COM_CLOSE) 

2966 closeFile['Parameters'] = SMBClose_Parameters() 

2967 closeFile['Parameters']['FID'] = fid 

2968 smb.addCommand(closeFile) 

2969 

2970 self.sendSMB(smb) 

2971 smb = self.recvSMB() 

2972 if smb.isValidAnswer(SMB.SMB_COM_CLOSE): 2972 ↛ 2974line 2972 didn't jump to line 2974, because the condition on line 2972 was never false

2973 return 1 

2974 return 0 

2975 

2976 def send_trans(self, tid, setup, name, param, data, noAnswer = 0): 

2977 smb = NewSMBPacket() 

2978 smb['Tid'] = tid 

2979 

2980 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 

2981 transCommand['Parameters'] = SMBTransaction_Parameters() 

2982 transCommand['Data'] = SMBTransaction_Data() 

2983 

2984 transCommand['Parameters']['Setup'] = setup 

2985 transCommand['Parameters']['TotalParameterCount'] = len(param) 

2986 transCommand['Parameters']['TotalDataCount'] = len(data) 

2987 

2988 transCommand['Parameters']['ParameterCount'] = len(param) 

2989 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 

2990 

2991 transCommand['Parameters']['DataCount'] = len(data) 

2992 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) 

2993 

2994 transCommand['Data']['Name'] = name 

2995 transCommand['Data']['Trans_Parameters'] = param 

2996 transCommand['Data']['Trans_Data'] = data 

2997 

2998 if noAnswer: 

2999 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 

3000 

3001 smb.addCommand(transCommand) 

3002 

3003 self.sendSMB(smb) 

3004 

3005 def send_trans2(self, tid, setup, name, param, data): 

3006 smb = NewSMBPacket() 

3007 smb['Tid'] = tid 

3008 

3009 command = pack('<H', setup) 

3010 

3011 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2) 

3012 transCommand['Parameters'] = SMBTransaction2_Parameters() 

3013 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 

3014 transCommand['Data'] = SMBTransaction2_Data() 

3015 

3016 transCommand['Parameters']['Setup'] = command 

3017 transCommand['Parameters']['TotalParameterCount'] = len(param) 

3018 transCommand['Parameters']['TotalDataCount'] = len(data) 

3019 

3020 if len(param) > 0: 3020 ↛ 3025line 3020 didn't jump to line 3025, because the condition on line 3020 was never false

3021 padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4 

3022 padBytes = '\xFF' * padLen 

3023 transCommand['Data']['Pad1'] = padBytes 

3024 else: 

3025 transCommand['Data']['Pad1'] = '' 

3026 padLen = 0 

3027 

3028 transCommand['Parameters']['ParameterCount'] = len(param) 

3029 transCommand['Parameters']['ParameterOffset'] = 32+2+28+len(command)+len(name) + padLen 

3030 

3031 if len(data) > 0: 3031 ↛ 3032line 3031 didn't jump to line 3032, because the condition on line 3031 was never true

3032 pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) % 4 

3033 transCommand['Data']['Pad2'] = '\xFF' * pad2Len 

3034 else: 

3035 transCommand['Data']['Pad2'] = '' 

3036 pad2Len = 0 

3037 

3038 transCommand['Parameters']['DataCount'] = len(data) 

3039 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len 

3040 

3041 transCommand['Data']['Name'] = name 

3042 transCommand['Data']['Trans_Parameters'] = param 

3043 transCommand['Data']['Trans_Data'] = data 

3044 smb.addCommand(transCommand) 

3045 

3046 self.sendSMB(smb) 

3047 

3048 def query_file_info(self, tid, fid, fileInfoClass = SMB_QUERY_FILE_STANDARD_INFO): 

3049 self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', pack('<HH', fid, fileInfoClass), '') 

3050 

3051 resp = self.recvSMB() 

3052 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3052 ↛ exitline 3052 didn't return from function 'query_file_info', because the condition on line 3052 was never false

3053 trans2Response = SMBCommand(resp['Data'][0]) 

3054 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3055 # Remove Potential Prefix Padding 

3056 return trans2Response['Data'][-trans2Parameters['TotalDataCount']:] 

3057 

3058 def __nonraw_retr_file(self, tid, fid, offset, datasize, callback): 

3059 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3059 ↛ 3060line 3059 didn't jump to line 3060, because the condition on line 3059 was never true

3060 max_buf_size = 65000 

3061 else: 

3062 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Read in multiple KB blocks 

3063 

3064 read_offset = offset 

3065 while read_offset < datasize: 

3066 data = self.read_andx(tid, fid, read_offset, max_buf_size) 

3067 

3068 callback(data) 

3069 read_offset += len(data) 

3070 

3071 def __nonraw_stor_file(self, tid, fid, offset, datasize, callback): 

3072 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 3072 ↛ 3073line 3072 didn't jump to line 3073, because the condition on line 3072 was never true

3073 max_buf_size = 65000 

3074 else: 

3075 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 

3076 

3077 write_offset = offset 

3078 while 1: 

3079 data = callback(max_buf_size) 

3080 if not data: 

3081 break 

3082 

3083 smb = self.write_andx(tid,fid,data, write_offset) 

3084 writeResponse = SMBCommand(smb['Data'][0]) 

3085 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 

3086 write_offset += writeResponseParameters['Count'] 

3087 

3088 def get_server_domain(self): 

3089 return self.__server_domain 

3090 

3091 def get_server_dns_domain_name(self): 

3092 return self.__server_dns_domain_name 

3093 

3094 def get_server_dns_host_name(self): 

3095 return self.__server_dns_host_name 

3096 

3097 def get_server_os(self): 

3098 return self.__server_os 

3099 

3100 def get_server_os_major(self): 

3101 return self.__server_os_major 

3102 

3103 def get_server_os_minor(self): 

3104 return self.__server_os_minor 

3105 

3106 def get_server_os_build(self): 

3107 return self.__server_os_build 

3108 

3109 def set_server_os(self, os): 

3110 self.__server_os = os 

3111 

3112 def get_server_lanman(self): 

3113 return self.__server_lanman 

3114 

3115 def is_login_required(self): 

3116 # Login is required if share mode is user. 

3117 # Otherwise only public services or services in share mode 

3118 # are allowed. 

3119 return (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER 

3120 

3121 def is_signing_required(self): 

3122 return self._SignatureRequired 

3123 

3124 def get_ntlmv1_response(self, key): 

3125 challenge = self._dialects_data['Challenge'] 

3126 return ntlm.get_ntlmv1_response(key, challenge) 

3127 

3128 def perform_hostname_validation(self): 

3129 if self.__server_name == '': 

3130 if not self._validation_allow_absent: 

3131 raise self.HostnameValidationException('Hostname was not supplied by target host and absent validation is disallowed') 

3132 return 

3133 if self.__server_name.lower() != self._accepted_hostname.lower() and self.__server_dns_host_name.lower() != self._accepted_hostname.lower(): 

3134 raise self.HostnameValidationException('Supplied hostname %s does not match reported hostnames %s or %s' % 

3135 (self._accepted_hostname.lower(), self.__server_name.lower(), self.__server_dns_host_name.lower())) 

3136 

3137 

3138 def kerberos_login(self, user, password, domain = '', lmhash = '', nthash = '', aesKey = '', kdcHost = '', TGT=None, TGS=None): 

3139 # Importing down here so pyasn1 is not required if kerberos is not used. 

3140 from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set 

3141 from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS 

3142 from impacket.krb5 import constants 

3143 from impacket.krb5.types import Principal, KerberosTime, Ticket 

3144 from pyasn1.codec.der import decoder, encoder 

3145 import datetime 

3146 

3147 # login feature does not support unicode 

3148 # disable it if enabled 

3149 flags2 = self.__flags2 

3150 if flags2 & SMB.FLAGS2_UNICODE: 

3151 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3152 

3153 # If TGT or TGS are specified, they are in the form of: 

3154 # TGS['KDC_REP'] = the response from the server 

3155 # TGS['cipher'] = the cipher used 

3156 # TGS['sessionKey'] = the sessionKey 

3157 # If we have hashes, normalize them 

3158 if lmhash != '' or nthash != '': 

3159 if len(lmhash) % 2: 3159 ↛ 3160line 3159 didn't jump to line 3160, because the condition on line 3159 was never true

3160 lmhash = '0%s' % lmhash 

3161 if len(nthash) % 2: 3161 ↛ 3162line 3161 didn't jump to line 3162, because the condition on line 3161 was never true

3162 nthash = '0%s' % nthash 

3163 try: # just in case they were converted already 

3164 lmhash = a2b_hex(lmhash) 

3165 nthash = a2b_hex(nthash) 

3166 except: 

3167 pass 

3168 

3169 self.__userName = user 

3170 self.__password = password 

3171 self.__domain = domain 

3172 self.__lmhash = lmhash 

3173 self.__nthash = nthash 

3174 self.__aesKey = aesKey 

3175 self.__kdc = kdcHost 

3176 self.__TGT = TGT 

3177 self.__TGS = TGS 

3178 self._doKerberos= True 

3179 

3180 # First of all, we need to get a TGT for the user 

3181 userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) 

3182 if TGT is None: 3182 ↛ 3186line 3182 didn't jump to line 3186, because the condition on line 3182 was never false

3183 if TGS is None: 3183 ↛ 3192line 3183 didn't jump to line 3192, because the condition on line 3183 was never false

3184 tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost) 

3185 else: 

3186 tgt = TGT['KDC_REP'] 

3187 cipher = TGT['cipher'] 

3188 sessionKey = TGT['sessionKey'] 

3189 

3190 # Now that we have the TGT, we should ask for a TGS for cifs 

3191 

3192 if TGS is None: 3192 ↛ 3196line 3192 didn't jump to line 3196, because the condition on line 3192 was never false

3193 serverName = Principal('cifs/%s' % self.__remote_name, type=constants.PrincipalNameType.NT_SRV_INST.value) 

3194 tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey) 

3195 else: 

3196 tgs = TGS['KDC_REP'] 

3197 cipher = TGS['cipher'] 

3198 sessionKey = TGS['sessionKey'] 

3199 

3200 smb = NewSMBPacket() 

3201 

3202 # Are we required to sign SMB? If so we do it, if not we skip it 

3203 if self._SignatureRequired: 3203 ↛ 3207line 3203 didn't jump to line 3207, because the condition on line 3203 was never false

3204 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3205 

3206 

3207 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3208 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 

3209 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 

3210 

3211 sessionSetup['Parameters']['MaxBufferSize'] = 61440 

3212 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3213 sessionSetup['Parameters']['VcNumber'] = 1 

3214 sessionSetup['Parameters']['SessionKey'] = 0 

3215 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3216 

3217 

3218 # Let's build a NegTokenInit with the NTLMSSP 

3219 # TODO: In the future we should be able to choose different providers 

3220 

3221 blob = SPNEGO_NegTokenInit() 

3222 

3223 # Kerberos v5 mech 

3224 blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']] 

3225 

3226 # Let's extract the ticket from the TGS 

3227 tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0] 

3228 ticket = Ticket() 

3229 ticket.from_asn1(tgs['ticket']) 

3230 

3231 # Now let's build the AP_REQ 

3232 apReq = AP_REQ() 

3233 apReq['pvno'] = 5 

3234 apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value) 

3235 

3236 opts = list() 

3237 apReq['ap-options'] = constants.encodeFlags(opts) 

3238 seq_set(apReq,'ticket', ticket.to_asn1) 

3239 

3240 authenticator = Authenticator() 

3241 authenticator['authenticator-vno'] = 5 

3242 authenticator['crealm'] = domain 

3243 seq_set(authenticator, 'cname', userName.components_to_asn1) 

3244 now = datetime.datetime.utcnow() 

3245 

3246 authenticator['cusec'] = now.microsecond 

3247 authenticator['ctime'] = KerberosTime.to_asn1(now) 

3248 

3249 encodedAuthenticator = encoder.encode(authenticator) 

3250 

3251 # Key Usage 11 

3252 # AP-REQ Authenticator (includes application authenticator 

3253 # subkey), encrypted with the application session key 

3254 # (Section 5.5.1) 

3255 encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) 

3256 

3257 apReq['authenticator'] = noValue 

3258 apReq['authenticator']['etype'] = cipher.enctype 

3259 apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator 

3260 

3261 blob['MechToken'] = pack('B', ASN1_AID) + asn1encode(pack('B', ASN1_OID) + asn1encode( 

3262 TypesMech['KRB5 - Kerberos 5']) + KRB5_AP_REQ + encoder.encode(apReq)) 

3263 

3264 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 

3265 sessionSetup['Parameters'].getData() 

3266 sessionSetup['Data']['SecurityBlob'] = blob.getData() 

3267 

3268 # Fake Data here, don't want to get us fingerprinted 

3269 sessionSetup['Data']['NativeOS'] = 'Unix' 

3270 sessionSetup['Data']['NativeLanMan'] = 'Samba' 

3271 

3272 smb.addCommand(sessionSetup) 

3273 self.sendSMB(smb) 

3274 

3275 smb = self.recvSMB() 

3276 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3276 ↛ 3300line 3276 didn't jump to line 3300, because the condition on line 3276 was never false

3277 # We will need to use this uid field for all future requests/responses 

3278 self._uid = smb['Uid'] 

3279 

3280 # Now we have to extract the blob to continue the auth process 

3281 sessionResponse = SMBCommand(smb['Data'][0]) 

3282 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 

3283 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 

3284 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 

3285 sessionData.fromString(sessionResponse['Data']) 

3286 

3287 self._action = sessionParameters['Action'] 

3288 # If smb sign required, let's enable it for the rest of the connection 

3289 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3289 ↛ 3295line 3289 didn't jump to line 3295, because the condition on line 3289 was never false

3290 self._SigningSessionKey = sessionKey.contents 

3291 self._SignSequenceNumber = 2 

3292 self._SignatureEnabled = True 

3293 

3294 # restore unicode flag if needed 

3295 if flags2 & SMB.FLAGS2_UNICODE: 

3296 self.__flags2 |= SMB.FLAGS2_UNICODE 

3297 

3298 return 1 

3299 else: 

3300 raise Exception('Error: Could not login successfully') 

3301 

3302 def login_extended(self, user, password, domain = '', lmhash = '', nthash = '', use_ntlmv2 = True ): 

3303 

3304 # login feature does not support unicode 

3305 # disable it if enabled 

3306 flags2 = self.__flags2 

3307 if flags2 & SMB.FLAGS2_UNICODE: 

3308 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3309 

3310 # Once everything's working we should join login methods into a single one 

3311 smb = NewSMBPacket() 

3312 # Are we required to sign SMB? If so we do it, if not we skip it 

3313 if self._SignatureRequired: 3313 ↛ 3316line 3313 didn't jump to line 3316, because the condition on line 3313 was never false

3314 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3315 

3316 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3317 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 

3318 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 

3319 

3320 sessionSetup['Parameters']['MaxBufferSize'] = 61440 

3321 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3322 sessionSetup['Parameters']['VcNumber'] = 1 

3323 sessionSetup['Parameters']['SessionKey'] = 0 

3324 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3325 

3326 

3327 # Let's build a NegTokenInit with the NTLMSSP 

3328 # TODO: In the future we should be able to choose different providers 

3329 

3330 blob = SPNEGO_NegTokenInit() 

3331 

3332 # NTLMSSP 

3333 blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']] 

3334 auth = ntlm.getNTLMSSPType1(self.get_client_name(),domain,self._SignatureRequired, use_ntlmv2 = use_ntlmv2) 

3335 blob['MechToken'] = auth.getData() 

3336 

3337 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 

3338 sessionSetup['Parameters'].getData() 

3339 sessionSetup['Data']['SecurityBlob'] = blob.getData() 

3340 

3341 # Fake Data here, don't want to get us fingerprinted 

3342 sessionSetup['Data']['NativeOS'] = 'Unix' 

3343 sessionSetup['Data']['NativeLanMan'] = 'Samba' 

3344 

3345 smb.addCommand(sessionSetup) 

3346 self.sendSMB(smb) 

3347 

3348 smb = self.recvSMB() 

3349 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3349 ↛ 3446line 3349 didn't jump to line 3446, because the condition on line 3349 was never false

3350 # We will need to use this uid field for all future requests/responses 

3351 self._uid = smb['Uid'] 

3352 

3353 # Now we have to extract the blob to continue the auth process 

3354 sessionResponse = SMBCommand(smb['Data'][0]) 

3355 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 

3356 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 

3357 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 

3358 sessionData.fromString(sessionResponse['Data']) 

3359 respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob']) 

3360 

3361 # Let's parse some data and keep it to ourselves in case it is asked 

3362 ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken']) 

3363 if ntlmChallenge['TargetInfoFields_len'] > 0: 3363 ↛ 3392line 3363 didn't jump to line 3392, because the condition on line 3363 was never false

3364 av_pairs = ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']]) 

3365 if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None: 3365 ↛ 3371line 3365 didn't jump to line 3371, because the condition on line 3365 was never false

3366 try: 

3367 self.__server_name = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le') 

3368 except UnicodeDecodeError: 

3369 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3370 pass 

3371 if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None: 3371 ↛ 3378line 3371 didn't jump to line 3378, because the condition on line 3371 was never false

3372 try: 

3373 if self.__server_name != av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'): 3373 ↛ 3378line 3373 didn't jump to line 3378, because the condition on line 3373 was never false

3374 self.__server_domain = av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le') 

3375 except UnicodeDecodeError: 

3376 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3377 pass 

3378 if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None: 3378 ↛ 3385line 3378 didn't jump to line 3385, because the condition on line 3378 was never false

3379 try: 

3380 self.__server_dns_domain_name = av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le') 

3381 except UnicodeDecodeError: 

3382 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3383 pass 

3384 

3385 if av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME] is not None: 3385 ↛ 3392line 3385 didn't jump to line 3392, because the condition on line 3385 was never false

3386 try: 

3387 self.__server_dns_host_name = av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME][1].decode('utf-16le') 

3388 except UnicodeDecodeError: 

3389 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3390 pass 

3391 

3392 if self._strict_hostname_validation: 3392 ↛ 3393line 3392 didn't jump to line 3393, because the condition on line 3392 was never true

3393 self.perform_hostname_validation() 

3394 

3395 # Parse Version to know the target Operating system name. Not provided elsewhere anymore 

3396 if 'Version' in ntlmChallenge.fields: 3396 ↛ 3402line 3396 didn't jump to line 3402, because the condition on line 3396 was never false

3397 version = ntlmChallenge['Version'] 

3398 

3399 if len(version) >= 4: 3399 ↛ 3402line 3399 didn't jump to line 3402, because the condition on line 3399 was never false

3400 self.__server_os_major, self.__server_os_minor, self.__server_os_build = unpack('<BBH',version[:4]) 

3401 

3402 type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2) 

3403 

3404 if exportedSessionKey is not None: 3404 ↛ 3407line 3404 didn't jump to line 3407, because the condition on line 3404 was never false

3405 self._SigningSessionKey = exportedSessionKey 

3406 

3407 smb = NewSMBPacket() 

3408 

3409 # Are we required to sign SMB? If so we do it, if not we skip it 

3410 if self._SignatureRequired: 3410 ↛ 3413line 3410 didn't jump to line 3413, because the condition on line 3410 was never false

3411 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3412 

3413 respToken2 = SPNEGO_NegTokenResp() 

3414 respToken2['ResponseToken'] = type3.getData() 

3415 

3416 # Reusing the previous structure 

3417 sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2) 

3418 sessionSetup['Data']['SecurityBlob'] = respToken2.getData() 

3419 

3420 # Storing some info for later use 

3421 self.__server_os = sessionData['NativeOS'] 

3422 self.__server_lanman = sessionData['NativeLanMan'] 

3423 

3424 smb.addCommand(sessionSetup) 

3425 self.sendSMB(smb) 

3426 

3427 smb = self.recvSMB() 

3428 self._uid = 0 

3429 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3429 ↛ exitline 3429 didn't return from function 'login_extended', because the condition on line 3429 was never false

3430 self._uid = smb['Uid'] 

3431 sessionResponse = SMBCommand(smb['Data'][0]) 

3432 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 

3433 

3434 self._action = sessionParameters['Action'] 

3435 # If smb sign required, let's enable it for the rest of the connection 

3436 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3436 ↛ 3441line 3436 didn't jump to line 3441, because the condition on line 3436 was never false

3437 self._SignSequenceNumber = 2 

3438 self._SignatureEnabled = True 

3439 

3440 # restore unicode flag if needed 

3441 if flags2 & SMB.FLAGS2_UNICODE: 

3442 self.__flags2 |= SMB.FLAGS2_UNICODE 

3443 

3444 return 1 

3445 else: 

3446 raise Exception('Error: Could not login successfully') 

3447 

3448 def getCredentials(self): 

3449 return ( 

3450 self.__userName, 

3451 self.__password, 

3452 self.__domain, 

3453 self.__lmhash, 

3454 self.__nthash, 

3455 self.__aesKey, 

3456 self.__TGT, 

3457 self.__TGS) 

3458 

3459 def getIOCapabilities(self): 

3460 res = dict() 

3461 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3461 ↛ 3462line 3461 didn't jump to line 3462, because the condition on line 3461 was never true

3462 max_size = 65000 

3463 else: 

3464 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3465 res['MaxReadSize'] = max_size 

3466 res['MaxWriteSize'] = max_size 

3467 return res 

3468 

3469 def login(self, user, password, domain = '', lmhash = '', nthash = '', ntlm_fallback = True): 

3470 

3471 # If we have hashes, normalize them 

3472 if lmhash != '' or nthash != '': 

3473 if len(lmhash) % 2: 3473 ↛ 3474line 3473 didn't jump to line 3474, because the condition on line 3473 was never true

3474 lmhash = '0%s' % lmhash 

3475 if len(nthash) % 2: 3475 ↛ 3476line 3475 didn't jump to line 3476, because the condition on line 3475 was never true

3476 nthash = '0%s' % nthash 

3477 try: # just in case they were converted already 

3478 lmhash = a2b_hex(lmhash) 

3479 nthash = a2b_hex(nthash) 

3480 except: 

3481 pass 

3482 

3483 self.__userName = user 

3484 self.__password = password 

3485 self.__domain = domain 

3486 self.__lmhash = lmhash 

3487 self.__nthash = nthash 

3488 self.__aesKey = '' 

3489 self.__TGT = None 

3490 self.__TGS = None 

3491 

3492 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 3492 ↛ 3502line 3492 didn't jump to line 3502, because the condition on line 3492 was never false

3493 try: 

3494 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True) 

3495 except: 

3496 # If the target OS is Windows 5.0 or Samba, let's try using NTLMv1 

3497 if ntlm_fallback and ((self.get_server_lanman().find('Windows 2000') != -1) or (self.get_server_lanman().find('Samba') != -1)): 

3498 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = False) 

3499 self.__isNTLMv2 = False 

3500 else: 

3501 raise 

3502 elif ntlm_fallback: 

3503 self.login_standard(user, password, domain, lmhash, nthash) 

3504 self.__isNTLMv2 = False 

3505 else: 

3506 raise SessionError('Cannot authenticate against target, enable ntlm_fallback') 

3507 

3508 def login_standard(self, user, password, domain = '', lmhash = '', nthash = ''): 

3509 

3510 # login feature does not support unicode 

3511 # disable it if enabled 

3512 flags2 = self.__flags2 

3513 if flags2 & SMB.FLAGS2_UNICODE: 

3514 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3515 

3516 # Only supports NTLMv1 

3517 # Password is only encrypted if the server passed us an "encryption key" during protocol dialect negotiation 

3518 if self._dialects_parameters['ChallengeLength'] > 0: 

3519 if lmhash != '' or nthash != '': 

3520 pwd_ansi = self.get_ntlmv1_response(lmhash) 

3521 pwd_unicode = self.get_ntlmv1_response(nthash) 

3522 elif password: 

3523 lmhash = ntlm.compute_lmhash(password) 

3524 nthash = ntlm.compute_nthash(password) 

3525 pwd_ansi = self.get_ntlmv1_response(lmhash) 

3526 pwd_unicode = self.get_ntlmv1_response(nthash) 

3527 else: # NULL SESSION 

3528 pwd_ansi = '' 

3529 pwd_unicode = '' 

3530 else: 

3531 pwd_ansi = password 

3532 pwd_unicode = '' 

3533 

3534 smb = NewSMBPacket() 

3535 

3536 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3537 sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters() 

3538 sessionSetup['Data'] = SMBSessionSetupAndX_Data() 

3539 

3540 sessionSetup['Parameters']['MaxBuffer'] = 61440 

3541 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3542 sessionSetup['Parameters']['VCNumber'] = os.getpid() & 0xFFFF # Value has to be expressed in 2 bytes 

3543 sessionSetup['Parameters']['SessionKey'] = self._dialects_parameters['SessionKey'] 

3544 sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi) 

3545 sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode) 

3546 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE | SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3547 

3548 sessionSetup['Data']['AnsiPwd'] = pwd_ansi 

3549 sessionSetup['Data']['UnicodePwd'] = pwd_unicode 

3550 sessionSetup['Data']['Account'] = str(user) 

3551 sessionSetup['Data']['PrimaryDomain'] = str(domain) 

3552 sessionSetup['Data']['NativeOS'] = str(os.name) 

3553 sessionSetup['Data']['NativeLanMan'] = 'pysmb' 

3554 smb.addCommand(sessionSetup) 

3555 

3556 self.sendSMB(smb) 

3557 

3558 smb = self.recvSMB() 

3559 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 

3560 # We will need to use this uid field for all future requests/responses 

3561 self._uid = smb['Uid'] 

3562 sessionResponse = SMBCommand(smb['Data'][0]) 

3563 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 

3564 sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data']) 

3565 

3566 self._action = sessionParameters['Action'] 

3567 

3568 # Still gotta figure out how to do this with no EXTENDED_SECURITY 

3569 if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0: 

3570 self._SigningChallengeResponse = sessionSetup['Data']['UnicodePwd'] 

3571 self._SigningSessionKey = nthash 

3572 else: 

3573 self._SigningChallengeResponse = sessionSetup['Data']['AnsiPwd'] 

3574 self._SigningSessionKey = lmhash 

3575 

3576 #self._SignSequenceNumber = 1 

3577 #self.checkSignSMB(smb, self._SigningSessionKey ,self._SigningChallengeResponse) 

3578 #self._SignatureEnabled = True 

3579 self.__server_os = sessionData['NativeOS'] 

3580 self.__server_lanman = sessionData['NativeLanMan'] 

3581 self.__server_domain = sessionData['PrimaryDomain'] 

3582 

3583 # restore unicode flag if needed 

3584 if flags2 & SMB.FLAGS2_UNICODE: 

3585 self.__flags2 |= SMB.FLAGS2_UNICODE 

3586 

3587 return 1 

3588 else: 

3589 raise Exception('Error: Could not login successfully') 

3590 

3591 def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0): 

3592 smb = NewSMBPacket() 

3593 smb['Tid'] = tid 

3594 

3595 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 

3596 transCommand['Parameters'] = SMBTransaction_Parameters() 

3597 transCommand['Data'] = SMBTransaction_Data() 

3598 

3599 setup = '\x53\x00\x00\x00' 

3600 name = '\\PIPE%s\x00' % pipe 

3601 transCommand['Parameters']['Setup'] = setup 

3602 transCommand['Parameters']['TotalParameterCount'] = 0 

3603 transCommand['Parameters']['TotalDataCount'] = 0 

3604 transCommand['Parameters']['MaxParameterCount'] = 0 

3605 transCommand['Parameters']['MaxDataCount'] = 0 

3606 transCommand['Parameters']['Timeout'] = timeout * 1000 

3607 

3608 transCommand['Parameters']['ParameterCount'] = 0 

3609 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 

3610 

3611 transCommand['Parameters']['DataCount'] = 0 

3612 transCommand['Parameters']['DataOffset'] = 0 

3613 

3614 transCommand['Data']['Name'] = name 

3615 transCommand['Data']['Trans_Parameters'] = '' 

3616 transCommand['Data']['Trans_Data'] = '' 

3617 

3618 if noAnswer: 

3619 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 

3620 

3621 smb.addCommand(transCommand) 

3622 self.sendSMB(smb) 

3623 

3624 smb = self.recvSMB() 

3625 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3626 return 1 

3627 return 0 

3628 

3629 def read(self, tid, fid, offset=0, max_size = None, wait_answer=1): 

3630 if not max_size: 

3631 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3632 

3633 # max_size is not working, because although it would, the server returns an error (More data avail) 

3634 

3635 smb = NewSMBPacket() 

3636 smb['Tid'] = tid 

3637 

3638 read = SMBCommand(SMB.SMB_COM_READ) 

3639 read['Parameters'] = SMBRead_Parameters() 

3640 read['Parameters']['Fid'] = fid 

3641 read['Parameters']['Offset'] = offset 

3642 read['Parameters']['Count'] = max_size 

3643 smb.addCommand(read) 

3644 

3645 if wait_answer: 

3646 while 1: 

3647 self.sendSMB(smb) 

3648 ans = self.recvSMB() 

3649 

3650 if ans.isValidAnswer(SMB.SMB_COM_READ): 

3651 readResponse = SMBCommand(ans['Data'][0]) 

3652 readData = SMBReadResponse_Data(readResponse['Data']) 

3653 

3654 return readData['Data'] 

3655 

3656 return None 

3657 

3658 def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, smb_packet=None): 

3659 if not max_size: 3659 ↛ 3660line 3659 didn't jump to line 3660, because the condition on line 3659 was never true

3660 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 

3661 max_size = 65000 

3662 else: 

3663 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3664 

3665 # max_size is not working, because although it would, the server returns an error (More data avail) 

3666 

3667 if smb_packet is None: 3667 ↛ 3678line 3667 didn't jump to line 3678, because the condition on line 3667 was never false

3668 smb = NewSMBPacket() 

3669 smb['Tid'] = tid 

3670 

3671 readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX) 

3672 readAndX['Parameters'] = SMBReadAndX_Parameters() 

3673 readAndX['Parameters']['Fid'] = fid 

3674 readAndX['Parameters']['Offset'] = offset 

3675 readAndX['Parameters']['MaxCount'] = max_size 

3676 smb.addCommand(readAndX) 

3677 else: 

3678 smb = smb_packet 

3679 

3680 if wait_answer: 3680 ↛ 3699line 3680 didn't jump to line 3699, because the condition on line 3680 was never false

3681 answer = b'' 

3682 while 1: 

3683 self.sendSMB(smb) 

3684 ans = self.recvSMB() 

3685 

3686 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 3686 ↛ 3683line 3686 didn't jump to line 3683, because the condition on line 3686 was never false

3687 # XXX Here we are only using a few fields from the response 

3688 readAndXResponse = SMBCommand(ans['Data'][0]) 

3689 readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters']) 

3690 

3691 offset = readAndXParameters['DataOffset'] 

3692 count = readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi'] 

3693 answer += ans.getData()[offset:offset+count] 

3694 if not ans.isMoreData(): 3694 ↛ 3696line 3694 didn't jump to line 3696, because the condition on line 3694 was never false

3695 return answer 

3696 max_size = min(max_size, readAndXParameters['Remaining']) 

3697 readAndX['Parameters']['Offset'] += count # XXX Offset is not important (apparently) 

3698 else: 

3699 self.sendSMB(smb) 

3700 ans = self.recvSMB() 

3701 

3702 try: 

3703 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 

3704 return ans 

3705 else: 

3706 return None 

3707 except: 

3708 return ans 

3709 

3710 return None 

3711 

3712 def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1): 

3713 if not max_size: 

3714 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3715 

3716 # max_size is not working, because although it would, the server returns an error (More data avail) 

3717 smb = NewSMBPacket() 

3718 smb['Tid'] = tid 

3719 

3720 readRaw = SMBCommand(SMB.SMB_COM_READ_RAW) 

3721 readRaw['Parameters'] = SMBReadRaw_Parameters() 

3722 readRaw['Parameters']['Fid'] = fid 

3723 readRaw['Parameters']['Offset'] = offset 

3724 readRaw['Parameters']['MaxCount'] = max_size 

3725 smb.addCommand(readRaw) 

3726 

3727 self.sendSMB(smb) 

3728 if wait_answer: 

3729 data = self._sess.recv_packet(self.__timeout).get_trailer() 

3730 if not data: 

3731 # If there is no data it means there was an error 

3732 data = self.read_andx(tid, fid, offset, max_size) 

3733 return data 

3734 

3735 return None 

3736 

3737 def write(self,tid,fid,data, offset = 0, wait_answer=1): 

3738 smb = NewSMBPacket() 

3739 smb['Tid'] = tid 

3740 

3741 write = SMBCommand(SMB.SMB_COM_WRITE) 

3742 write['Parameters'] = SMBWrite_Parameters() 

3743 write['Data'] = SMBWrite_Data() 

3744 write['Parameters']['Fid'] = fid 

3745 write['Parameters']['Count'] = len(data) 

3746 write['Parameters']['Offset'] = offset 

3747 write['Parameters']['Remaining'] = len(data) 

3748 write['Data']['Data'] = data 

3749 smb.addCommand(write) 

3750 

3751 self.sendSMB(smb) 

3752 

3753 if wait_answer: 

3754 smb = self.recvSMB() 

3755 if smb.isValidAnswer(SMB.SMB_COM_WRITE): 

3756 return smb 

3757 return None 

3758 

3759 def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, write_pipe_mode = False, smb_packet=None): 

3760 if smb_packet is None: 3760 ↛ 3810line 3760 didn't jump to line 3810, because the condition on line 3760 was never false

3761 smb = NewSMBPacket() 

3762 smb['Tid'] = tid 

3763 

3764 writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX) 

3765 smb.addCommand(writeAndX) 

3766 

3767 writeAndX['Parameters'] = SMBWriteAndX_Parameters() 

3768 writeAndX['Parameters']['Fid'] = fid 

3769 writeAndX['Parameters']['Offset'] = offset 

3770 writeAndX['Parameters']['WriteMode'] = 8 

3771 writeAndX['Parameters']['Remaining'] = len(data) 

3772 writeAndX['Parameters']['DataLength'] = len(data) 

3773 writeAndX['Parameters']['DataOffset'] = len(smb) # this length already includes the parameter 

3774 writeAndX['Data'] = data 

3775 

3776 if write_pipe_mode is True: 3776 ↛ 3778line 3776 didn't jump to line 3778, because the condition on line 3776 was never true

3777 # First of all we gotta know what the MaxBuffSize is 

3778 maxBuffSize = self._dialects_parameters['MaxBufferSize'] 

3779 if len(data) > maxBuffSize: 

3780 chunks_size = maxBuffSize - 60 

3781 writeAndX['Parameters']['WriteMode'] = 0x0c 

3782 sendData = b'\xff\xff' + data 

3783 totalLen = len(sendData) 

3784 writeAndX['Parameters']['DataLength'] = chunks_size 

3785 writeAndX['Parameters']['Remaining'] = totalLen-2 

3786 writeAndX['Data'] = sendData[:chunks_size] 

3787 

3788 self.sendSMB(smb) 

3789 if wait_answer: 

3790 smbResp = self.recvSMB() 

3791 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 

3792 

3793 alreadySent = chunks_size 

3794 sendData = sendData[chunks_size:] 

3795 

3796 while alreadySent < totalLen: 

3797 writeAndX['Parameters']['WriteMode'] = 0x04 

3798 writeAndX['Parameters']['DataLength'] = len(sendData[:chunks_size]) 

3799 writeAndX['Data'] = sendData[:chunks_size] 

3800 self.sendSMB(smb) 

3801 if wait_answer: 

3802 smbResp = self.recvSMB() 

3803 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 

3804 alreadySent += writeAndX['Parameters']['DataLength'] 

3805 sendData = sendData[chunks_size:] 

3806 

3807 return smbResp 

3808 

3809 else: 

3810 smb = smb_packet 

3811 

3812 self.sendSMB(smb) 

3813 

3814 if wait_answer: 3814 ↛ 3818line 3814 didn't jump to line 3818, because the condition on line 3814 was never false

3815 smb = self.recvSMB() 

3816 if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX): 3816 ↛ 3818line 3816 didn't jump to line 3818, because the condition on line 3816 was never false

3817 return smb 

3818 return None 

3819 

3820 def write_raw(self,tid,fid,data, offset = 0, wait_answer=1): 

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

3822 smb = NewSMBPacket() 

3823 smb['Tid'] = tid 

3824 

3825 writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW) 

3826 writeRaw['Parameters'] = SMBWriteRaw_Parameters() 

3827 writeRaw['Parameters']['Fid'] = fid 

3828 writeRaw['Parameters']['Offset'] = offset 

3829 writeRaw['Parameters']['Count'] = len(data) 

3830 writeRaw['Parameters']['DataLength'] = 0 

3831 writeRaw['Parameters']['DataOffset'] = 0 

3832 smb.addCommand(writeRaw) 

3833 

3834 self.sendSMB(smb) 

3835 self._sess.send_packet(data) 

3836 

3837 if wait_answer: 

3838 smb = self.recvSMB() 

3839 if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW): 

3840 return smb 

3841 return None 

3842 

3843 def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0): 

3844 self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, noAnswer = noAnswer) 

3845 

3846 if noAnswer or not waitAnswer: 

3847 return 

3848 smb = self.recvSMB() 

3849 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3850 transResponse = SMBCommand(smb['Data'][0]) 

3851 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 

3852 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 

3853 return None 

3854 

3855 def TransactNamedPipeRecv(self): 

3856 s = self.recvSMB() 

3857 if s.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3858 transResponse = SMBCommand(s['Data'][0]) 

3859 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 

3860 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 

3861 return None 

3862 

3863 def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, accessMask = 0x2019f): 

3864 filename = filename.replace('/', '\\') 

3865 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

3866 

3867 if smb_packet is None: 3867 ↛ 3871line 3867 didn't jump to line 3871, because the condition on line 3867 was never false

3868 smb = NewSMBPacket() 

3869 smb['Tid'] = tid 

3870 else: 

3871 smb = smb_packet 

3872 

3873 if cmd is None: 

3874 ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 

3875 ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 

3876 ntCreate['Data'] = SMBNtCreateAndX_Data(flags=self.__flags2) 

3877 ntCreate['Parameters']['FileNameLength'] = len(filename) 

3878 ntCreate['Parameters']['CreateFlags'] = 0x16 

3879 ntCreate['Parameters']['AccessMask'] = accessMask 

3880 ntCreate['Parameters']['CreateOptions'] = 0x40 

3881 ntCreate['Parameters']['ShareAccess'] = shareAccessMode 

3882 ntCreate['Parameters']['Disposition'] = disposition 

3883 ntCreate['Data']['FileName'] = filename 

3884 

3885 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3886 ntCreate['Data']['Pad'] = 0x0 

3887 else: 

3888 ntCreate = cmd 

3889 

3890 smb.addCommand(ntCreate) 

3891 

3892 self.sendSMB(smb) 

3893 

3894 while 1: 

3895 smb = self.recvSMB() 

3896 if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX): 3896 ↛ 3895line 3896 didn't jump to line 3895, because the condition on line 3896 was never false

3897 # XXX Here we are ignoring the rest of the response 

3898 ntCreateResponse = SMBCommand(smb['Data'][0]) 

3899 ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters']) 

3900 

3901 self.fid = ntCreateParameters['Fid'] 

3902 return ntCreateParameters['Fid'] 

3903 

3904 def logoff(self): 

3905 smb = NewSMBPacket() 

3906 

3907 logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX) 

3908 logOff['Parameters'] = SMBLogOffAndX() 

3909 smb.addCommand(logOff) 

3910 

3911 self.sendSMB(smb) 

3912 self.recvSMB() 

3913 # Let's clear some fields so you can login again under the same session 

3914 self._uid = 0 

3915 

3916 def list_path(self, service, path = '*', password = None): 

3917 path = path.replace('/', '\\') 

3918 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

3919 

3920 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3921 try: 

3922 findFirstParameter = SMBFindFirst2_Parameters(self.__flags2) 

3923 findFirstParameter['SearchAttributes'] = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \ 

3924 SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_READONLY | \ 

3925 SMB_FILE_ATTRIBUTE_ARCHIVE 

3926 findFirstParameter['SearchCount'] = 512 

3927 findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 

3928 findFirstParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 

3929 findFirstParameter['SearchStorageType'] = 0 

3930 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3931 findFirstParameter['FileName'] = path + b'\x00\x00' 

3932 else: 

3933 findFirstParameter['FileName'] = path + '\x00' 

3934 self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', findFirstParameter, '') 

3935 files = [ ] 

3936 

3937 totalDataCount = 1 

3938 findData = b'' 

3939 findFirst2ParameterBlock = b'' 

3940 while len(findData) < totalDataCount: 

3941 resp = self.recvSMB() 

3942 

3943 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3943 ↛ 3940line 3943 didn't jump to line 3940, because the condition on line 3943 was never false

3944 trans2Response = SMBCommand(resp['Data'][0]) 

3945 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3946 totalDataCount = trans2Parameters['TotalDataCount'] 

3947 findFirst2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 

3948 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 

3949 

3950 findParameterBlock = SMBFindFirst2Response_Parameters(findFirst2ParameterBlock) 

3951 # Save the SID for resume operations 

3952 sid = findParameterBlock['SID'] 

3953 

3954 while findParameterBlock['SearchCount'] > 0: 3954 ↛ 3999line 3954 didn't jump to line 3999, because the condition on line 3954 was never false

3955 record = SMBFindFileBothDirectoryInfo(data = findData) 

3956 

3957 shortname = record['ShortName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else \ 

3958 record['ShortName'].decode('cp437') 

3959 filename = record['FileName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else \ 

3960 record['FileName'].decode('cp437') 

3961 

3962 fileRecord = SharedFile(record['CreationTime'], record['LastAccessTime'], record['LastChangeTime'], 

3963 record['EndOfFile'], record['AllocationSize'], record['ExtFileAttributes'], 

3964 shortname, filename) 

3965 files.append(fileRecord) 

3966 if record['NextEntryOffset'] > 0 and len(findData[record['NextEntryOffset']:]) > 0: 

3967 findData = findData[record['NextEntryOffset']:] 

3968 else: 

3969 # More data to search? 

3970 if findParameterBlock['EndOfSearch'] == 0: 3970 ↛ 3971,   3970 ↛ 39972 missed branches: 1) line 3970 didn't jump to line 3971, because the condition on line 3970 was never true, 2) line 3970 didn't jump to line 3997, because the condition on line 3970 was never false

3971 resume_filename = record['FileName'] 

3972 findNextParameter = SMBFindNext2_Parameters() 

3973 findNextParameter['SID'] = sid 

3974 findNextParameter['SearchCount'] = 1024 

3975 findNextParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 

3976 findNextParameter['ResumeKey'] = 0 

3977 findNextParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 

3978 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3979 findNextParameter['FileName'] = resume_filename + b'\x00\x00' 

3980 else: 

3981 findNextParameter['FileName'] = resume_filename + b'\x00' 

3982 self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', findNextParameter, '') 

3983 findData = b'' 

3984 findNext2ParameterBlock = b'' 

3985 totalDataCount = 1 

3986 while len(findData) < totalDataCount: 

3987 resp = self.recvSMB() 

3988 

3989 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 

3990 trans2Response = SMBCommand(resp['Data'][0]) 

3991 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3992 totalDataCount = trans2Parameters['TotalDataCount'] 

3993 findNext2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 

3994 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 

3995 findParameterBlock = SMBFindNext2Response_Parameters(findNext2ParameterBlock) 

3996 else: 

3997 break 

3998 finally: 

3999 self.disconnect_tree(tid) 

4000 

4001 return files 

4002 

4003 def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset = 0, password = None, shareAccessMode = SMB_ACCESS_READ): 

4004 filename = filename.replace('/', '\\') 

4005 

4006 fid = -1 

4007 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4008 try: 

4009 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, accessMask = 0x20089) 

4010 

4011 res = self.query_file_info(tid, fid) 

4012 datasize = SMBQueryFileStandardInfo(res)['EndOfFile'] 

4013 

4014 self.__nonraw_retr_file(tid, fid, offset, datasize, callback) 

4015 finally: 

4016 if fid >= 0: 4016 ↛ 4018line 4016 didn't jump to line 4018, because the condition on line 4016 was never false

4017 self.close(tid, fid) 

4018 self.disconnect_tree(tid) 

4019 

4020 def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE): 

4021 filename = filename.replace('/', '\\') 

4022 

4023 fid = -1 

4024 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4025 try: 

4026 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode ) 

4027 

4028 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 

4029 finally: 

4030 if fid >= 0: 4030 ↛ 4032line 4030 didn't jump to line 4032, because the condition on line 4030 was never false

4031 self.close(tid, fid) 

4032 self.disconnect_tree(tid) 

4033 

4034 def stor_file_nonraw(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE ): 

4035 filename = filename.replace('/', '\\') 

4036 

4037 fid = -1 

4038 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4039 try: 

4040 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode) 

4041 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 

4042 finally: 

4043 if fid >= 0: 

4044 self.close(tid, fid) 

4045 self.disconnect_tree(tid) 

4046 

4047 def check_dir(self, service, path, password = None): 

4048 path = path.replace('/', '\\') 

4049 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4050 try: 

4051 smb = NewSMBPacket() 

4052 smb['Tid'] = tid 

4053 smb['Mid'] = 0 

4054 

4055 cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY) 

4056 cmd['Parameters'] = '' 

4057 cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2) 

4058 cmd['Data']['DirectoryName'] = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4059 smb.addCommand(cmd) 

4060 

4061 self.sendSMB(smb) 

4062 

4063 while 1: 

4064 s = self.recvSMB() 

4065 if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY): 4065 ↛ 4064line 4065 didn't jump to line 4064, because the condition on line 4065 was never false

4066 return 

4067 finally: 

4068 self.disconnect_tree(tid) 

4069 

4070 def remove(self, service, path, password = None): 

4071 path = path.replace('/', '\\') 

4072 # Perform a list to ensure the path exists 

4073 self.list_path(service, path, password) 

4074 

4075 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4076 try: 

4077 smb = NewSMBPacket() 

4078 smb['Tid'] = tid 

4079 smb['Mid'] = 0 

4080 

4081 cmd = SMBCommand(SMB.SMB_COM_DELETE) 

4082 cmd['Parameters'] = SMBDelete_Parameters() 

4083 cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE 

4084 cmd['Data'] = SMBDelete_Data(flags = self.__flags2) 

4085 cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00') 

4086 smb.addCommand(cmd) 

4087 

4088 self.sendSMB(smb) 

4089 

4090 while 1: 

4091 s = self.recvSMB() 

4092 if s.isValidAnswer(SMB.SMB_COM_DELETE): 4092 ↛ 4091line 4092 didn't jump to line 4091, because the condition on line 4092 was never false

4093 return 

4094 finally: 

4095 self.disconnect_tree(tid) 

4096 

4097 def rmdir(self, service, path, password = None): 

4098 path = path.replace('/', '\\') 

4099 # Check that the directory exists 

4100 self.check_dir(service, path, password) 

4101 

4102 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4103 try: 

4104 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4105 

4106 smb = NewSMBPacket() 

4107 smb['Tid'] = tid 

4108 createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY) 

4109 createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2) 

4110 createDir['Data']['DirectoryName'] = path 

4111 smb.addCommand(createDir) 

4112 

4113 self.sendSMB(smb) 

4114 

4115 while 1: 

4116 s = self.recvSMB() 

4117 if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY): 4117 ↛ 4116line 4117 didn't jump to line 4116, because the condition on line 4117 was never false

4118 return 

4119 finally: 

4120 self.disconnect_tree(tid) 

4121 

4122 def mkdir(self, service, path, password = None): 

4123 path = path.replace('/', '\\') 

4124 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4125 try: 

4126 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4127 

4128 smb = NewSMBPacket() 

4129 smb['Tid'] = tid 

4130 smb['Mid'] = 0 

4131 

4132 createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY) 

4133 createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2) 

4134 createDir['Data']['DirectoryName'] = path 

4135 smb.addCommand(createDir) 

4136 

4137 self.sendSMB(smb) 

4138 

4139 smb = self.recvSMB() 

4140 if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY): 4140 ↛ 4142line 4140 didn't jump to line 4142, because the condition on line 4140 was never false

4141 return 1 

4142 return 0 

4143 finally: 

4144 self.disconnect_tree(tid) 4144 ↛ 4142line 4144 didn't jump to line 4142, because the return on line 4142 wasn't executed

4145 

4146 def rename(self, service, old_path, new_path, password = None): 

4147 old_path = old_path.replace('/', '\\') 

4148 new_path = new_path.replace('/', '\\') 

4149 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4150 try: 

4151 smb = NewSMBPacket() 

4152 smb['Tid'] = tid 

4153 smb['Mid'] = 0 

4154 

4155 renameCmd = SMBCommand(SMB.SMB_COM_RENAME) 

4156 renameCmd['Parameters'] = SMBRename_Parameters() 

4157 renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY 

4158 renameCmd['Data'] = SMBRename_Data(flags = self.__flags2) 

4159 renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else old_path 

4160 renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else new_path 

4161 smb.addCommand(renameCmd) 

4162 

4163 self.sendSMB(smb) 

4164 

4165 smb = self.recvSMB() 

4166 if smb.isValidAnswer(SMB.SMB_COM_RENAME): 4166 ↛ 4168line 4166 didn't jump to line 4168, because the condition on line 4166 was never false

4167 return 1 

4168 return 0 

4169 finally: 

4170 self.disconnect_tree(tid) 4170 ↛ 4168line 4170 didn't jump to line 4168, because the return on line 4168 wasn't executed

4171 

4172 def writeFile(self, treeId, fileId, data, offset = 0): 

4173 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 4173 ↛ 4174line 4173 didn't jump to line 4174, because the condition on line 4173 was never true

4174 max_buf_size = 65000 

4175 else: 

4176 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 

4177 

4178 write_offset = offset 

4179 while 1: 

4180 if len(data) == 0: 

4181 break 

4182 writeData = data[:max_buf_size] 

4183 data = data[max_buf_size:] 

4184 

4185 smb = self.write_andx(treeId,fileId,writeData, write_offset) 

4186 writeResponse = SMBCommand(smb['Data'][0]) 

4187 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 

4188 write_offset += writeResponseParameters['Count'] 

4189 

4190 def get_socket(self): 

4191 return self._sess.get_socket() 

4192 

4193 def send_nt_trans(self, tid, subcommand, max_param_count, setup='', param='', data=''): 

4194 """ 

4195 [MS-CIFS]: 2.2.4.62.1 SMB_COM_NT_TRANSACT request. 

4196 :param tid: 

4197 :param subcommand: The transaction subcommand code 

4198 :param max_param_count: This field MUST be set as specified in the subsections of Transaction subcommands. 

4199 :param setup: Transaction context to the server, depends on transaction subcommand. 

4200 :param param: Subcommand parameter bytes if any, depends on transaction subcommand. 

4201 :param data: Subcommand data bytes if any, depends on transaction subcommand. 

4202 :return: Buffer relative to requested subcommand. 

4203 """ 

4204 smb_packet = NewSMBPacket() 

4205 smb_packet['Tid'] = tid 

4206 # setup depends on NT_TRANSACT subcommands so it may be 0. 

4207 setup_bytes = pack('<H', setup) if setup != '' else '' 

4208 

4209 transCommand = SMBCommand(SMB.SMB_COM_NT_TRANSACT) 

4210 transCommand['Parameters'] = SMBNTTransaction_Parameters() 

4211 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 

4212 transCommand['Parameters']['Setup'] = setup_bytes 

4213 transCommand['Parameters']['Function'] = subcommand 

4214 transCommand['Parameters']['TotalParameterCount'] = len(param) 

4215 transCommand['Parameters']['TotalDataCount'] = len(data) 

4216 transCommand['Parameters']['MaxParameterCount'] = max_param_count 

4217 transCommand['Parameters']['MaxSetupCount'] = 0 

4218 

4219 transCommand['Data'] = SMBNTTransaction_Data() 

4220 

4221 # SMB header size + SMB_COM_NT_TRANSACT parameters size + length of setup bytes. 

4222 offset = 32 + 3 + 38 + len(setup_bytes) 

4223 transCommand['Data']['Pad1'] = '' 

4224 if offset % 4 != 0: 

4225 transCommand['Data']['Pad1'] = '\0' * (4 - offset % 4) 

4226 offset += (4 - offset % 4) # pad1 length 

4227 

4228 if len(param) > 0: 

4229 transCommand['Parameters']['ParameterOffset'] = offset 

4230 else: 

4231 transCommand['Parameters']['ParameterOffset'] = 0 

4232 

4233 offset += len(param) 

4234 transCommand['Data']['Pad2'] = '' 

4235 if offset % 4 != 0: 

4236 transCommand['Data']['Pad2'] = '\0' * (4 - offset % 4) 

4237 offset += (4 - offset % 4) 

4238 

4239 if len(data) > 0: 

4240 transCommand['Parameters']['DataOffset'] = offset 

4241 else: 

4242 transCommand['Parameters']['DataOffset'] = 0 

4243 

4244 transCommand['Parameters']['DataCount'] = len(data) 

4245 transCommand['Parameters']['ParameterCount'] = len(param) 

4246 transCommand['Data']['NT_Trans_Parameters'] = param 

4247 transCommand['Data']['NT_Trans_Data'] = data 

4248 smb_packet.addCommand(transCommand) 

4249 

4250 self.sendSMB(smb_packet) 

4251 

4252 def query_sec_info(self, tid, fid, additional_information=7): 

4253 """ 

4254 [MS-CIFS]: 2.2.7.6.1 

4255 NT_TRANSACT_QUERY_SECURITY_DESC 0x0006 

4256 :param tid: valid tree id. 

4257 :param fid: valid file handle. 

4258 :param additional_information: SecurityInfoFields. default = owner + group + dacl ie. 7 

4259 :return: security descriptor buffer 

4260 """ 

4261 self.send_nt_trans(tid, subcommand=0x0006, max_param_count=4, 

4262 param=pack('<HHL', fid, 0x0000, additional_information)) 

4263 resp = self.recvSMB() 

4264 if resp.isValidAnswer(SMB.SMB_COM_NT_TRANSACT): 

4265 nt_trans_response = SMBCommand(resp['Data'][0]) 

4266 nt_trans_parameters = SMBNTTransactionResponse_Parameters(nt_trans_response['Parameters']) 

4267 # Remove Potential Prefix Padding 

4268 return nt_trans_response['Data'][-nt_trans_parameters['TotalDataCount']:] 

4269 

4270 def echo(self, text = '', count = 1): 

4271 

4272 smb = NewSMBPacket() 

4273 comEcho = SMBCommand(SMB.SMB_COM_ECHO) 

4274 comEcho['Parameters'] = SMBEcho_Parameters() 

4275 comEcho['Data'] = SMBEcho_Data() 

4276 comEcho['Parameters']['EchoCount'] = count 

4277 comEcho['Data']['Data'] = text 

4278 smb.addCommand(comEcho) 

4279 

4280 self.sendSMB(smb) 

4281 

4282 for i in range(count): 

4283 resp = self.recvSMB() 

4284 resp.isValidAnswer(SMB.SMB_COM_ECHO) 

4285 return True 

4286 

4287ERRDOS = { 1: 'Invalid function', 

4288 2: 'File not found', 

4289 3: 'Invalid directory', 

4290 4: 'Too many open files', 

4291 5: 'Access denied', 

4292 6: 'Invalid file handle. Please file a bug report.', 

4293 7: 'Memory control blocks destroyed', 

4294 8: 'Out of memory', 

4295 9: 'Invalid memory block address', 

4296 10: 'Invalid environment', 

4297 11: 'Invalid format', 

4298 12: 'Invalid open mode', 

4299 13: 'Invalid data', 

4300 15: 'Invalid drive', 

4301 16: 'Attempt to remove server\'s current directory', 

4302 17: 'Not the same device', 

4303 18: 'No files found', 

4304 32: 'Sharing mode conflicts detected', 

4305 33: 'Lock request conflicts detected', 

4306 80: 'File already exists' 

4307 } 

4308 

4309ERRSRV = { 1: 'Non-specific error', 

4310 2: 'Bad password', 

4311 4: 'Access denied', 

4312 5: 'Invalid tid. Please file a bug report.', 

4313 6: 'Invalid network name', 

4314 7: 'Invalid device', 

4315 49: 'Print queue full', 

4316 50: 'Print queue full', 

4317 51: 'EOF on print queue dump', 

4318 52: 'Invalid print file handle', 

4319 64: 'Command not recognized. Please file a bug report.', 

4320 65: 'Internal server error', 

4321 67: 'Invalid path', 

4322 69: 'Invalid access permissions', 

4323 71: 'Invalid attribute mode', 

4324 81: 'Server is paused', 

4325 82: 'Not receiving messages', 

4326 83: 'No room to buffer messages', 

4327 87: 'Too many remote user names', 

4328 88: 'Operation timeout', 

4329 89: 'Out of resources', 

4330 91: 'Invalid user handle. Please file a bug report.', 

4331 250: 'Temporarily unable to support raw mode for transfer', 

4332 251: 'Temporarily unable to support raw mode for transfer', 

4333 252: 'Continue in MPX mode', 

4334 65535: 'Unsupported function' 

4335 } 

4336 

4337ERRHRD = { 19: 'Media is write-protected', 

4338 20: 'Unknown unit', 

4339 21: 'Drive not ready', 

4340 22: 'Unknown command', 

4341 23: 'CRC error', 

4342 24: 'Bad request', 

4343 25: 'Seek error', 

4344 26: 'Unknown media type', 

4345 27: 'Sector not found', 

4346 28: 'Printer out of paper', 

4347 29: 'Write fault', 

4348 30: 'Read fault', 

4349 31: 'General failure', 

4350 32: 'Open conflicts with an existing open', 

4351 33: 'Invalid lock request', 

4352 34: 'Wrong disk in drive', 

4353 35: 'FCBs not available', 

4354 36: 'Sharing buffer exceeded' 

4355 }