Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scapy/layers/smb2.py: 68%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

955 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Copyright (C) Gabriel Potter 

5 

6""" 

7SMB (Server Message Block), also known as CIFS - version 2 

8 

9.. note:: 

10 You will find more complete documentation for this layer over at 

11 `SMB <https://scapy.readthedocs.io/en/latest/layers/smb.html>`_ 

12""" 

13 

14import os 

15import collections 

16import functools 

17import hashlib 

18import struct 

19 

20from scapy.config import conf, crypto_validator 

21from scapy.error import log_runtime 

22from scapy.packet import Packet, bind_layers, bind_top_down 

23from scapy.fields import ( 

24 ByteEnumField, 

25 ByteField, 

26 ConditionalField, 

27 FieldLenField, 

28 FieldListField, 

29 FlagValue, 

30 FlagsField, 

31 IP6Field, 

32 IPField, 

33 IntEnumField, 

34 IntField, 

35 LEIntField, 

36 LEIntEnumField, 

37 LELongField, 

38 LenField, 

39 LEShortEnumField, 

40 LEShortField, 

41 MultipleTypeField, 

42 PadField, 

43 PacketField, 

44 PacketLenField, 

45 PacketListField, 

46 ReversePadField, 

47 ScalingField, 

48 ShortEnumField, 

49 ShortField, 

50 StrFieldUtf16, 

51 StrFixedLenField, 

52 StrLenField, 

53 StrLenFieldUtf16, 

54 StrNullFieldUtf16, 

55 ThreeBytesField, 

56 UTCTimeField, 

57 UUIDField, 

58 XLEIntField, 

59 XLELongField, 

60 XLEShortField, 

61 XStrLenField, 

62 XStrFixedLenField, 

63 YesNoByteField, 

64) 

65from scapy.sessions import DefaultSession 

66from scapy.supersocket import StreamSocket 

67 

68if conf.crypto_valid: 

69 from scapy.libs.rfc3961 import SP800108_KDFCTR 

70 

71from scapy.layers.gssapi import GSSAPI_BLOB 

72from scapy.layers.netbios import NBTSession 

73from scapy.layers.ntlm import ( 

74 _NTLMPayloadField, 

75 _NTLMPayloadPacket, 

76 _NTLM_ENUM, 

77 _NTLM_post_build, 

78) 

79 

80 

81# EnumField 

82SMB_DIALECTS = { 

83 0x0202: "SMB 2.002", 

84 0x0210: "SMB 2.1", 

85 0x02FF: "SMB 2.???", 

86 0x0300: "SMB 3.0", 

87 0x0302: "SMB 3.0.2", 

88 0x0311: "SMB 3.1.1", 

89} 

90 

91# SMB2 sect 3.3.5.15 + [MS-ERREF] 

92STATUS_ERREF = { 

93 0x00000000: "STATUS_SUCCESS", 

94 0x00000103: "STATUS_PENDING", 

95 0x0000010B: "STATUS_NOTIFY_CLEANUP", 

96 0x0000010C: "STATUS_NOTIFY_ENUM_DIR", 

97 0x00000532: "ERROR_PASSWORD_EXPIRED", 

98 0x00000533: "ERROR_ACCOUNT_DISABLED", 

99 0x80000005: "STATUS_BUFFER_OVERFLOW", 

100 0x80000006: "STATUS_NO_MORE_FILES", 

101 0x8000002D: "STATUS_STOPPED_ON_SYMLINK", 

102 0xC0000003: "STATUS_INVALID_INFO_CLASS", 

103 0xC0000004: "STATUS_INFO_LENGTH_MISMATCH", 

104 0xC000000D: "STATUS_INVALID_PARAMETER", 

105 0xC000000F: "STATUS_NO_SUCH_FILE", 

106 0xC0000016: "STATUS_MORE_PROCESSING_REQUIRED", 

107 0xC0000022: "STATUS_ACCESS_DENIED", 

108 0xC0000033: "STATUS_OBJECT_NAME_INVALID", 

109 0xC0000034: "STATUS_OBJECT_NAME_NOT_FOUND", 

110 0xC0000043: "STATUS_SHARING_VIOLATION", 

111 0xC000006D: "STATUS_LOGON_FAILURE", 

112 0xC000006E: "STATUS_ACCOUNT_RESTRICTION", 

113 0xC0000071: "STATUS_PASSWORD_EXPIRED", 

114 0xC0000072: "STATUS_ACCOUNT_DISABLED", 

115 0xC000009A: "STATUS_INSUFFICIENT_RESOURCES", 

116 0xC00000BA: "STATUS_FILE_IS_A_DIRECTORY", 

117 0xC00000BB: "STATUS_NOT_SUPPORTED", 

118 0xC00000C9: "STATUS_NETWORK_NAME_DELETED", 

119 0xC00000CC: "STATUS_BAD_NETWORK_NAME", 

120 0xC0000120: "STATUS_CANCELLED", 

121 0xC0000128: "STATUS_FILE_CLOSED", # backup error for older Win versions 

122 0xC000015B: "STATUS_LOGON_TYPE_NOT_GRANTED", 

123 0xC000019C: "STATUS_FS_DRIVER_REQUIRED", 

124 0xC0000203: "STATUS_USER_SESSION_DELETED", 

125 0xC000020C: "STATUS_CONNECTION_DISCONNECTED", 

126 0xC0000225: "STATUS_NOT_FOUND", 

127 0xC0000257: "STATUS_PATH_NOT_COVERED", 

128 0xC000035C: "STATUS_NETWORK_SESSION_EXPIRED", 

129} 

130 

131# SMB2 sect 2.1.2.1 

132REPARSE_TAGS = { 

133 0x00000000: "IO_REPARSE_TAG_RESERVED_ZERO", 

134 0x00000001: "IO_REPARSE_TAG_RESERVED_ONE", 

135 0x00000002: "IO_REPARSE_TAG_RESERVED_TWO", 

136 0xA0000003: "IO_REPARSE_TAG_MOUNT_POINT", 

137 0xC0000004: "IO_REPARSE_TAG_HSM", 

138 0x80000005: "IO_REPARSE_TAG_DRIVE_EXTENDER", 

139 0x80000006: "IO_REPARSE_TAG_HSM2", 

140 0x80000007: "IO_REPARSE_TAG_SIS", 

141 0x80000008: "IO_REPARSE_TAG_WIM", 

142 0x80000009: "IO_REPARSE_TAG_CSV", 

143 0x8000000A: "IO_REPARSE_TAG_DFS", 

144 0x8000000B: "IO_REPARSE_TAG_FILTER_MANAGER", 

145 0xA000000C: "IO_REPARSE_TAG_SYMLINK", 

146 0xA0000010: "IO_REPARSE_TAG_IIS_CACHE", 

147 0x80000012: "IO_REPARSE_TAG_DFSR", 

148 0x80000013: "IO_REPARSE_TAG_DEDUP", 

149 0xC0000014: "IO_REPARSE_TAG_APPXSTRM", 

150 0x80000014: "IO_REPARSE_TAG_NFS", 

151 0x80000015: "IO_REPARSE_TAG_FILE_PLACEHOLDER", 

152 0x80000016: "IO_REPARSE_TAG_DFM", 

153 0x80000017: "IO_REPARSE_TAG_WOF", 

154 0x80000018: "IO_REPARSE_TAG_WCI", 

155 0x90001018: "IO_REPARSE_TAG_WCI_1", 

156 0xA0000019: "IO_REPARSE_TAG_GLOBAL_REPARSE", 

157 0x9000001A: "IO_REPARSE_TAG_CLOUD", 

158 0x9000101A: "IO_REPARSE_TAG_CLOUD_1", 

159 0x9000201A: "IO_REPARSE_TAG_CLOUD_2", 

160 0x9000301A: "IO_REPARSE_TAG_CLOUD_3", 

161 0x9000401A: "IO_REPARSE_TAG_CLOUD_4", 

162 0x9000501A: "IO_REPARSE_TAG_CLOUD_5", 

163 0x9000601A: "IO_REPARSE_TAG_CLOUD_6", 

164 0x9000701A: "IO_REPARSE_TAG_CLOUD_7", 

165 0x9000801A: "IO_REPARSE_TAG_CLOUD_8", 

166 0x9000901A: "IO_REPARSE_TAG_CLOUD_9", 

167 0x9000A01A: "IO_REPARSE_TAG_CLOUD_A", 

168 0x9000B01A: "IO_REPARSE_TAG_CLOUD_B", 

169 0x9000C01A: "IO_REPARSE_TAG_CLOUD_C", 

170 0x9000D01A: "IO_REPARSE_TAG_CLOUD_D", 

171 0x9000E01A: "IO_REPARSE_TAG_CLOUD_E", 

172 0x9000F01A: "IO_REPARSE_TAG_CLOUD_F", 

173 0x8000001B: "IO_REPARSE_TAG_APPEXECLINK", 

174 0x9000001C: "IO_REPARSE_TAG_PROJFS", 

175 0xA000001D: "IO_REPARSE_TAG_LX_SYMLINK", 

176 0x8000001E: "IO_REPARSE_TAG_STORAGE_SYNC", 

177 0xA000001F: "IO_REPARSE_TAG_WCI_TOMBSTONE", 

178 0x80000020: "IO_REPARSE_TAG_UNHANDLED", 

179 0x80000021: "IO_REPARSE_TAG_ONEDRIVE", 

180 0xA0000022: "IO_REPARSE_TAG_PROJFS_TOMBSTONE", 

181 0x80000023: "IO_REPARSE_TAG_AF_UNIX", 

182 0x80000024: "IO_REPARSE_TAG_LX_FIFO", 

183 0x80000025: "IO_REPARSE_TAG_LX_CHR", 

184 0x80000026: "IO_REPARSE_TAG_LX_BLK", 

185 0xA0000027: "IO_REPARSE_TAG_WCI_LINK", 

186 0xA0001027: "IO_REPARSE_TAG_WCI_LINK_1", 

187} 

188 

189# SMB2 sect 2.2.1.1 

190SMB2_COM = { 

191 0x0000: "SMB2_NEGOTIATE", 

192 0x0001: "SMB2_SESSION_SETUP", 

193 0x0002: "SMB2_LOGOFF", 

194 0x0003: "SMB2_TREE_CONNECT", 

195 0x0004: "SMB2_TREE_DISCONNECT", 

196 0x0005: "SMB2_CREATE", 

197 0x0006: "SMB2_CLOSE", 

198 0x0007: "SMB2_FLUSH", 

199 0x0008: "SMB2_READ", 

200 0x0009: "SMB2_WRITE", 

201 0x000A: "SMB2_LOCK", 

202 0x000B: "SMB2_IOCTL", 

203 0x000C: "SMB2_CANCEL", 

204 0x000D: "SMB2_ECHO", 

205 0x000E: "SMB2_QUERY_DIRECTORY", 

206 0x000F: "SMB2_CHANGE_NOTIFY", 

207 0x0010: "SMB2_QUERY_INFO", 

208 0x0011: "SMB2_SET_INFO", 

209 0x0012: "SMB2_OPLOCK_BREAK", 

210} 

211 

212# EnumField 

213SMB2_NEGOTIATE_CONTEXT_TYPES = { 

214 0x0001: "SMB2_PREAUTH_INTEGRITY_CAPABILITIES", 

215 0x0002: "SMB2_ENCRYPTION_CAPABILITIES", 

216 0x0003: "SMB2_COMPRESSION_CAPABILITIES", 

217 0x0005: "SMB2_NETNAME_NEGOTIATE_CONTEXT_ID", 

218 0x0006: "SMB2_TRANSPORT_CAPABILITIES", 

219 0x0007: "SMB2_RDMA_TRANSFORM_CAPABILITIES", 

220 0x0008: "SMB2_SIGNING_CAPABILITIES", 

221} 

222 

223# FlagField 

224SMB2_CAPABILITIES = { 

225 0x00000001: "DFS", 

226 0x00000002: "LEASING", 

227 0x00000004: "LARGE_MTU", 

228 0x00000008: "MULTI_CHANNEL", 

229 0x00000010: "PERSISTENT_HANDLES", 

230 0x00000020: "DIRECTORY_LEASING", 

231 0x00000040: "ENCRYPTION", 

232} 

233SMB2_SECURITY_MODE = { 

234 0x01: "SIGNING_ENABLED", 

235 0x02: "SIGNING_REQUIRED", 

236} 

237 

238# [MS-SMB2] 2.2.3.1.3 

239SMB2_COMPRESSION_ALGORITHMS = { 

240 0x0000: "None", 

241 0x0001: "LZNT1", 

242 0x0002: "LZ77", 

243 0x0003: "LZ77 + Huffman", 

244 0x0004: "Pattern_V1", 

245} 

246 

247# [MS-SMB2] sect 2.2.3.1.2 

248SMB2_ENCRYPTION_CIPHERS = { 

249 0x0001: "AES-128-CCM", 

250 0x0002: "AES-128-GCM", 

251 0x0003: "AES-256-CCM", 

252 0x0004: "AES-256-GCM", 

253} 

254 

255# [MS-SMB2] sect 2.2.3.1.7 

256SMB2_SIGNING_ALGORITHMS = { 

257 0x0000: "HMAC-SHA256", 

258 0x0001: "AES-CMAC", 

259 0x0002: "AES-GMAC", 

260} 

261 

262# sect [MS-SMB2] 2.2.13.1.1 

263SMB2_ACCESS_FLAGS_FILE = { 

264 0x00000001: "FILE_READ_DATA", 

265 0x00000002: "FILE_WRITE_DATA", 

266 0x00000004: "FILE_APPEND_DATA", 

267 0x00000008: "FILE_READ_EA", 

268 0x00000010: "FILE_WRITE_EA", 

269 0x00000040: "FILE_DELETE_CHILD", 

270 0x00000020: "FILE_EXECUTE", 

271 0x00000080: "FILE_READ_ATTRIBUTES", 

272 0x00000100: "FILE_WRITE_ATTRIBUTES", 

273 0x00010000: "DELETE", 

274 0x00020000: "READ_CONTROL", 

275 0x00040000: "WRITE_DAC", 

276 0x00080000: "WRITE_OWNER", 

277 0x00100000: "SYNCHRONIZE", 

278 0x01000000: "ACCESS_SYSTEM_SECURITY", 

279 0x02000000: "MAXIMUM_ALLOWED", 

280 0x10000000: "GENERIC_ALL", 

281 0x20000000: "GENERIC_EXECUTE", 

282 0x40000000: "GENERIC_WRITE", 

283 0x80000000: "GENERIC_READ", 

284} 

285 

286# sect [MS-SMB2] 2.2.13.1.2 

287SMB2_ACCESS_FLAGS_DIRECTORY = { 

288 0x00000001: "FILE_LIST_DIRECTORY", 

289 0x00000002: "FILE_ADD_FILE", 

290 0x00000004: "FILE_ADD_SUBDIRECTORY", 

291 0x00000008: "FILE_READ_EA", 

292 0x00000010: "FILE_WRITE_EA", 

293 0x00000020: "FILE_TRAVERSE", 

294 0x00000040: "FILE_DELETE_CHILD", 

295 0x00000080: "FILE_READ_ATTRIBUTES", 

296 0x00000100: "FILE_WRITE_ATTRIBUTES", 

297 0x00010000: "DELETE", 

298 0x00020000: "READ_CONTROL", 

299 0x00040000: "WRITE_DAC", 

300 0x00080000: "WRITE_OWNER", 

301 0x00100000: "SYNCHRONIZE", 

302 0x01000000: "ACCESS_SYSTEM_SECURITY", 

303 0x02000000: "MAXIMUM_ALLOWED", 

304 0x10000000: "GENERIC_ALL", 

305 0x20000000: "GENERIC_EXECUTE", 

306 0x40000000: "GENERIC_WRITE", 

307 0x80000000: "GENERIC_READ", 

308} 

309 

310# [MS-SRVS] sec 2.2.2.4 

311SRVSVC_SHARE_TYPES = { 

312 0x00000000: "DISKTREE", 

313 0x00000001: "PRINTQ", 

314 0x00000002: "DEVICE", 

315 0x00000003: "IPC", 

316 0x02000000: "CLUSTER_FS", 

317 0x04000000: "CLUSTER_SOFS", 

318 0x08000000: "CLUSTER_DFS", 

319} 

320 

321 

322# [MS-FSCC] sec 2.6 

323FileAttributes = { 

324 0x00000001: "FILE_ATTRIBUTE_READONLY", 

325 0x00000002: "FILE_ATTRIBUTE_HIDDEN", 

326 0x00000004: "FILE_ATTRIBUTE_SYSTEM", 

327 0x00000010: "FILE_ATTRIBUTE_DIRECTORY", 

328 0x00000020: "FILE_ATTRIBUTE_ARCHIVE", 

329 0x00000080: "FILE_ATTRIBUTE_NORMAL", 

330 0x00000100: "FILE_ATTRIBUTE_TEMPORARY", 

331 0x00000200: "FILE_ATTRIBUTE_SPARSE_FILE", 

332 0x00000400: "FILE_ATTRIBUTE_REPARSE_POINT", 

333 0x00000800: "FILE_ATTRIBUTE_COMPRESSED", 

334 0x00001000: "FILE_ATTRIBUTE_OFFLINE", 

335 0x00002000: "FILE_ATTRIBUTE_NOT_CONTENT_INDEXED", 

336 0x00004000: "FILE_ATTRIBUTE_ENCRYPTED", 

337 0x00008000: "FILE_ATTRIBUTE_INTEGRITY_STREAM", 

338 0x00020000: "FILE_ATTRIBUTE_NO_SCRUB_DATA", 

339 0x00040000: "FILE_ATTRIBUTE_RECALL_ON_OPEN", 

340 0x00080000: "FILE_ATTRIBUTE_PINNED", 

341 0x00100000: "FILE_ATTRIBUTE_UNPINNED", 

342 0x00400000: "FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS", 

343} 

344 

345 

346# [MS-FSCC] sect 2.4 

347FileInformationClasses = { 

348 0x01: "FileDirectoryInformation", 

349 0x02: "FileFullDirectoryInformation", 

350 0x03: "FileBothDirectoryInformation", 

351 0x04: "FileBasicInformation", 

352 0x05: "FileStandardInformation", 

353 0x06: "FileInternalInformation", 

354 0x07: "FileEaInformation", 

355 0x08: "FileAccessInformation", 

356 0x0A: "FileRenameInformation", 

357 0x0E: "FilePositionInformation", 

358 0x10: "FileModeInformation", 

359 0x11: "FileAlignmentInformation", 

360 0x12: "FileAllInformation", 

361 0x22: "FileNetworkOpenInformation", 

362 0x25: "FileIdBothDirectoryInformation", 

363 0x26: "FileIdFullDirectoryInformation", 

364 0x0C: "FileNamesInformation", 

365 0x30: "FileNormalizedNameInformation", 

366 0x3C: "FileIdExtdDirectoryInformation", 

367} 

368_FileInformationClasses = {} 

369 

370 

371# [MS-FSCC] 2.1.7 FILE_NAME_INFORMATION 

372 

373 

374class FILE_NAME_INFORMATION(Packet): 

375 fields_desc = [ 

376 FieldLenField("FileNameLength", None, length_of="FileName", fmt="<I"), 

377 StrLenFieldUtf16("FileName", "", length_from=lambda pkt: pkt.FileNameLength), 

378 ] 

379 

380 def default_payload_class(self, s): 

381 return conf.padding_layer 

382 

383 

384# [MS-FSCC] 2.4.1 FileAccessInformation 

385 

386 

387class FileAccessInformation(Packet): 

388 fields_desc = [ 

389 FlagsField("AccessFlags", 0, -32, SMB2_ACCESS_FLAGS_FILE), 

390 ] 

391 

392 def default_payload_class(self, s): 

393 return conf.padding_layer 

394 

395 

396# [MS-FSCC] 2.4.3 FileAlignmentInformation 

397 

398 

399class FileAlignmentInformation(Packet): 

400 fields_desc = [ 

401 LEIntEnumField( 

402 "AccessFlags", 

403 0, 

404 { 

405 0x00000000: "FILE_BYTE_ALIGNMENT", 

406 0x00000001: "FILE_WORD_ALIGNMENT", 

407 0x00000003: "FILE_LONG_ALIGNMENT", 

408 0x00000007: "FILE_QUAD_ALIGNMENT", 

409 0x0000000F: "FILE_OCTA_ALIGNMENT", 

410 0x0000001F: "FILE_32_BYTE_ALIGNMENT", 

411 0x0000003F: "FILE_64_BYTE_ALIGNMENT", 

412 0x0000007F: "FILE_128_BYTE_ALIGNMENT", 

413 0x000000FF: "FILE_256_BYTE_ALIGNMENT", 

414 0x000001FF: "FILE_512_BYTE_ALIGNMENT", 

415 }, 

416 ), 

417 ] 

418 

419 def default_payload_class(self, s): 

420 return conf.padding_layer 

421 

422 

423# [MS-FSCC] 2.4.5 FileAlternateNameInformation 

424 

425 

426class FileAlternateNameInformation(Packet): 

427 fields_desc = [ 

428 FieldLenField("FileNameLength", None, length_of="FileName", fmt="<I"), 

429 StrLenFieldUtf16("FileName", b"", length_from=lambda pkt: pkt.FileNameLength), 

430 ] 

431 

432 

433# [MS-FSCC] 2.4.7 FileBasicInformation 

434 

435 

436class FileBasicInformation(Packet): 

437 fields_desc = [ 

438 UTCTimeField( 

439 "CreationTime", 

440 None, 

441 fmt="<Q", 

442 epoch=[1601, 1, 1, 0, 0, 0], 

443 custom_scaling=1e7, 

444 ), 

445 UTCTimeField( 

446 "LastAccessTime", 

447 None, 

448 fmt="<Q", 

449 epoch=[1601, 1, 1, 0, 0, 0], 

450 custom_scaling=1e7, 

451 ), 

452 UTCTimeField( 

453 "LastWriteTime", 

454 None, 

455 fmt="<Q", 

456 epoch=[1601, 1, 1, 0, 0, 0], 

457 custom_scaling=1e7, 

458 ), 

459 UTCTimeField( 

460 "ChangeTime", 

461 None, 

462 fmt="<Q", 

463 epoch=[1601, 1, 1, 0, 0, 0], 

464 custom_scaling=1e7, 

465 ), 

466 FlagsField("FileAttributes", 0x00000080, -32, FileAttributes), 

467 IntField("Reserved", 0), 

468 ] 

469 

470 def default_payload_class(self, s): 

471 return conf.padding_layer 

472 

473 

474# [MS-FSCC] 2.4.12 FileEaInformation 

475 

476 

477class FileEaInformation(Packet): 

478 fields_desc = [ 

479 LEIntField("EaSize", 0), 

480 ] 

481 

482 def default_payload_class(self, s): 

483 return conf.padding_layer 

484 

485 

486# [MS-FSCC] 2.4.29 FileNetworkOpenInformation 

487 

488 

489class FileNetworkOpenInformation(Packet): 

490 fields_desc = [ 

491 UTCTimeField( 

492 "CreationTime", 

493 None, 

494 fmt="<Q", 

495 epoch=[1601, 1, 1, 0, 0, 0], 

496 custom_scaling=1e7, 

497 ), 

498 UTCTimeField( 

499 "LastAccessTime", 

500 None, 

501 fmt="<Q", 

502 epoch=[1601, 1, 1, 0, 0, 0], 

503 custom_scaling=1e7, 

504 ), 

505 UTCTimeField( 

506 "LastWriteTime", 

507 None, 

508 fmt="<Q", 

509 epoch=[1601, 1, 1, 0, 0, 0], 

510 custom_scaling=1e7, 

511 ), 

512 UTCTimeField( 

513 "ChangeTime", 

514 None, 

515 fmt="<Q", 

516 epoch=[1601, 1, 1, 0, 0, 0], 

517 custom_scaling=1e7, 

518 ), 

519 LELongField("AllocationSize", 4096), 

520 LELongField("EndOfFile", 0), 

521 FlagsField("FileAttributes", 0x00000080, -32, FileAttributes), 

522 IntField("Reserved2", 0), 

523 ] 

524 

525 def default_payload_class(self, s): 

526 return conf.padding_layer 

527 

528 

529# [MS-FSCC] 2.4.8 FileBothDirectoryInformation 

530 

531 

532class FILE_BOTH_DIR_INFORMATION(Packet): 

533 fields_desc = ( 

534 [ 

535 LEIntField("Next", None), # 0 = no next entry 

536 LEIntField("FileIndex", 0), 

537 ] 

538 + ( 

539 FileNetworkOpenInformation.fields_desc[:4] 

540 + FileNetworkOpenInformation.fields_desc[4:6][::-1] 

541 + [FileNetworkOpenInformation.fields_desc[6]] 

542 ) 

543 + [ 

544 FieldLenField("FileNameLength", None, fmt="<I", length_of="FileName"), 

545 MultipleTypeField( 

546 # "If FILE_ATTRIBUTE_REPARSE_POINT is set in the FileAttributes field, 

547 # this field MUST contain a reparse tag as specified in section 

548 # 2.1.2.1." 

549 [ 

550 ( 

551 LEIntEnumField("EaSize", 0, REPARSE_TAGS), 

552 lambda pkt: pkt.FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT, 

553 ) 

554 ], 

555 LEIntField("EaSize", 0), 

556 ), 

557 ByteField("ShortNameLength", 0), 

558 ByteField("Reserved1", 0), 

559 StrFixedLenField("ShortName", b"", length=24), 

560 PadField( 

561 StrLenFieldUtf16( 

562 "FileName", b".", length_from=lambda pkt: pkt.FileNameLength 

563 ), 

564 align=8, 

565 ), 

566 ] 

567 ) 

568 

569 def default_payload_class(self, s): 

570 return conf.padding_layer 

571 

572 

573class _NextPacketListField(PacketListField): 

574 def addfield(self, pkt, s, val): 

575 # we use this field to set NextEntryOffset 

576 res = b"" 

577 for i, v in enumerate(val): 

578 x = self.i2m(pkt, v) 

579 if v.Next is None and i != len(val) - 1: 

580 x = struct.pack("<I", len(x)) + x[4:] 

581 res += x 

582 return s + res 

583 

584 

585class FileBothDirectoryInformation(Packet): 

586 fields_desc = [ 

587 _NextPacketListField( 

588 "files", 

589 [], 

590 FILE_BOTH_DIR_INFORMATION, 

591 max_count=1000, 

592 ), 

593 ] 

594 

595 

596# [MS-FSCC] 2.4.14 FileFullDirectoryInformation 

597 

598 

599class FILE_FULL_DIR_INFORMATION(Packet): 

600 fields_desc = FILE_BOTH_DIR_INFORMATION.fields_desc[:11] + [ 

601 FILE_BOTH_DIR_INFORMATION.fields_desc[-1] 

602 ] 

603 

604 

605class FileFullDirectoryInformation(Packet): 

606 fields_desc = [ 

607 _NextPacketListField( 

608 "files", 

609 [], 

610 FILE_FULL_DIR_INFORMATION, 

611 max_count=1000, 

612 ), 

613 ] 

614 

615 

616# [MS-FSCC] 2.4.17 FileIdBothDirectoryInformation 

617 

618 

619class FILE_ID_BOTH_DIR_INFORMATION(Packet): 

620 fields_desc = FILE_BOTH_DIR_INFORMATION.fields_desc[:14] + [ 

621 LEShortField("Reserved2", 0), 

622 LELongField("FileId", 0), 

623 FILE_BOTH_DIR_INFORMATION.fields_desc[-1], 

624 ] 

625 

626 def default_payload_class(self, s): 

627 return conf.padding_layer 

628 

629 

630class FileIdBothDirectoryInformation(Packet): 

631 fields_desc = [ 

632 _NextPacketListField( 

633 "files", 

634 [], 

635 FILE_ID_BOTH_DIR_INFORMATION, 

636 max_count=1000, # > 65535 / len(FILE_ID_BOTH_DIR_INFORMATION()) 

637 ), 

638 ] 

639 

640 

641# [MS-FSCC] 2.4.22 FileInternalInformation 

642 

643 

644class FileInternalInformation(Packet): 

645 fields_desc = [ 

646 LELongField("IndexNumber", 0), 

647 ] 

648 

649 def default_payload_class(self, s): 

650 return conf.padding_layer 

651 

652 

653# [MS-FSCC] 2.4.26 FileModeInformation 

654 

655 

656class FileModeInformation(Packet): 

657 fields_desc = [ 

658 FlagsField( 

659 "Mode", 

660 0, 

661 -32, 

662 { 

663 0x00000002: "FILE_WRITE_TROUGH", 

664 0x00000004: "FILE_SEQUENTIAL_ONLY", 

665 0x00000008: "FILE_NO_INTERMEDIATE_BUFFERING", 

666 0x00000010: "FILE_SYNCHRONOUS_IO_ALERT", 

667 0x00000020: "FILE_SYNCHRONOUS_IO_NONALERT", 

668 0x00001000: "FILE_DELETE_ON_CLOSE", 

669 }, 

670 ) 

671 ] 

672 

673 def default_payload_class(self, s): 

674 return conf.padding_layer 

675 

676 

677# [MS-FSCC] 2.4.35 FilePositionInformation 

678 

679 

680class FilePositionInformation(Packet): 

681 fields_desc = [ 

682 LELongField("CurrentByteOffset", 0), 

683 ] 

684 

685 def default_payload_class(self, s): 

686 return conf.padding_layer 

687 

688 

689# [MS-FSCC] 2.4.37 FileRenameInformation 

690 

691 

692class FileRenameInformation(Packet): 

693 fields_desc = [ 

694 YesNoByteField("ReplaceIfExists", False), 

695 XStrFixedLenField("Reserved", b"", length=7), 

696 LELongField("RootDirectory", 0), 

697 FieldLenField("FileNameLength", 0, length_of="FileName", fmt="<I"), 

698 StrLenFieldUtf16("FileName", b"", length_from=lambda pkt: pkt.FileNameLength), 

699 ] 

700 

701 def post_build(self, pkt, pay): 

702 # type: (bytes, bytes) -> bytes 

703 if len(pkt) < 24: 

704 # 'Length of this field MUST be the number of bytes required to make the 

705 # size of this structure at least 24.' 

706 pkt += (24 - len(pkt)) * b"\x00" 

707 return pkt + pay 

708 

709 def default_payload_class(self, s): 

710 return conf.padding_layer 

711 

712 

713_FileInformationClasses[0x0A] = FileRenameInformation 

714 

715 

716# [MS-FSCC] 2.4.41 FileStandardInformation 

717 

718 

719class FileStandardInformation(Packet): 

720 fields_desc = [ 

721 LELongField("AllocationSize", 4096), 

722 LELongField("EndOfFile", 0), 

723 LEIntField("NumberOfLinks", 1), 

724 ByteField("DeletePending", 0), 

725 ByteField("Directory", 0), 

726 ShortField("Reserved", 0), 

727 ] 

728 

729 def default_payload_class(self, s): 

730 return conf.padding_layer 

731 

732 

733# [MS-FSCC] 2.4.43 FileStreamInformation 

734 

735 

736class FileStreamInformation(Packet): 

737 fields_desc = [ 

738 LEIntField("Next", 0), 

739 FieldLenField("StreamNameLength", None, length_of="StreamName", fmt="<I"), 

740 LELongField("StreamSize", 0), 

741 LELongField("StreamAllocationSize", 4096), 

742 StrLenFieldUtf16( 

743 "StreamName", b"::$DATA", length_from=lambda pkt: pkt.StreamNameLength 

744 ), 

745 ] 

746 

747 

748# [MS-DTYP] sect 2.4.1 

749 

750 

751class WINNT_SID_IDENTIFIER_AUTHORITY(Packet): 

752 fields_desc = [ 

753 StrFixedLenField("Value", b"", length=6), 

754 ] 

755 

756 def default_payload_class(self, payload): 

757 return conf.padding_layer 

758 

759 

760# [MS-DTYP] sect 2.4.2 

761 

762 

763class WINNT_SID(Packet): 

764 fields_desc = [ 

765 ByteField("Revision", 1), 

766 FieldLenField("SubAuthorityCount", None, count_of="SubAuthority", fmt="B"), 

767 PacketField( 

768 "IdentifierAuthority", 

769 WINNT_SID_IDENTIFIER_AUTHORITY(), 

770 WINNT_SID_IDENTIFIER_AUTHORITY, 

771 ), 

772 FieldListField( 

773 "SubAuthority", 

774 [], 

775 LEIntField("", 0), 

776 count_from=lambda pkt: pkt.SubAuthorityCount, 

777 ), 

778 ] 

779 

780 def default_payload_class(self, payload): 

781 return conf.padding_layer 

782 

783 def summary(self): 

784 return "S-%s-%s%s" % ( 

785 self.Revision, 

786 struct.unpack(">Q", b"\x00\x00" + self.IdentifierAuthority.Value)[0], 

787 ("-%s" % "-".join(str(x) for x in self.SubAuthority)) 

788 if self.SubAuthority 

789 else "", 

790 ) 

791 

792 

793# [MS-DTYP] sect 2.4.3 

794 

795_WINNT_ACCESS_MASK = { 

796 0x80000000: "GENERIC_READ", 

797 0x40000000: "GENERIC_WRITE", 

798 0x20000000: "GENERIC_EXECUTE", 

799 0x10000000: "GENERIC_ALL", 

800 0x02000000: "MAXIMUM_ALLOWED", 

801 0x01000000: "ACCESS_SYSTEM_SECURITY", 

802 0x00100000: "SYNCHRONIZE", 

803 0x00080000: "WRITE_OWNER", 

804 0x00040000: "WRITE_DACL", 

805 0x00020000: "READ_CONTROL", 

806 0x00010000: "DELETE", 

807} 

808 

809 

810# [MS-DTYP] sect 2.4.4.1 

811 

812 

813class WINNT_ACE_HEADER(Packet): 

814 fields_desc = [ 

815 ByteEnumField( 

816 "AceType", 

817 0, 

818 { 

819 0x00: "ACCESS_ALLOWED", 

820 0x01: "ACCESS_DENIED", 

821 0x02: "SYSTEM_AUDIT", 

822 0x03: "SYSTEM_ALARM", 

823 0x04: "ACCESS_ALLOWED_COMPOUND", 

824 0x05: "ACCESS_ALLOWED_OBJECT", 

825 0x06: "ACCESS_DENIED_OBJECT", 

826 0x07: "SYSTEM_AUDIT_OBJECT", 

827 0x08: "SYSTEM_ALARM_OBJECT", 

828 0x09: "ACCESS_ALLOWED_CALLBACK", 

829 0x0A: "ACCESS_DENIED_CALLBACK", 

830 0x0B: "ACCESS_ALLOWED_CALLBACK_OBJECT", 

831 0x0C: "ACCESS_DENIED_CALLBACK_OBJECT", 

832 0x0D: "SYSTEM_AUDIT_CALLBACK", 

833 0x0E: "SYSTEM_ALARM_CALLBACK", 

834 0x0F: "SYSTEM_AUDIT_CALLBACK_OBJECT", 

835 0x10: "SYSTEM_ALARM_CALLBACK_OBJECT", 

836 0x11: "SYSTEM_MANDATORY_LABEL", 

837 0x12: "SYSTEM_RESOURCE_ATTRIBUTE", 

838 0x13: "SYSTEM_SCOPED_POLICY_ID", 

839 }, 

840 ), 

841 FlagsField( 

842 "AceFlags", 

843 0, 

844 8, 

845 { 

846 0x01: "OBJECT_INHERIT", 

847 0x02: "CONTAINER_INHERIT", 

848 0x04: "NO_PROPAGATE_INHERIT", 

849 0x08: "INHERIT_ONLY", 

850 0x10: "INHERITED_ACE", 

851 0x40: "SUCCESSFUL_ACCESS", 

852 0x80: "FAILED_ACCESS", 

853 }, 

854 ), 

855 LenField("AceSize", None, fmt="<H", adjust=lambda x: x + 4), 

856 ] 

857 

858 def extract_padding(self, p): 

859 return p[: self.AceSize - 4], p[self.AceSize - 4 :] 

860 

861 # fmt: off 

862 def toSDDL(self): 

863 """ 

864 Return SDDL 

865 """ 

866 sid = self.payload.Sid.summary() 

867 ace_flag_string = str( 

868 FlagValue( 

869 self.AceFlags, 

870 ["OI", "CI", "NP", "IO", "ID", "SA", "FA"] 

871 ) 

872 ) 

873 ace_rights = "" # TODO 

874 object_guid = "" # TODO 

875 inherit_object_guid = "" # TODO 

876 # ApplicationData -> conditional expression 

877 condexpr = "" 

878 if hasattr(self.payload, "ApplicationData"): 

879 # Parse tokens 

880 res = [] 

881 for ct in self.payload.ApplicationData.Tokens: 

882 if ct.TokenType in [ 

883 # binary operators 

884 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x88, 0x8e, 0x8f, 

885 0xa0, 0xa1 

886 ]: 

887 t1 = res.pop(-1) 

888 t0 = res.pop(-1) 

889 tt = ct.sprintf("%TokenType%") 

890 if ct.TokenType in [0xa0, 0xa1]: # && and || 

891 res.append(f"({t0}) {tt} ({t1})") 

892 else: 

893 res.append(f"{t0} {tt} {t1}") 

894 elif ct.TokenType in [ 

895 # unary operators 

896 0x87, 0x8d, 0xa2, 0x89, 0x8a, 0x8b, 0x8c, 0x91, 0x92, 0x93 

897 ]: 

898 t0 = res.pop(-1) 

899 tt = ct.sprintf("%TokenType%") 

900 res.append(f"{tt}{t0}") 

901 elif ct.TokenType in [ 

902 # values 

903 0x01, 0x02, 0x03, 0x04, 0x10, 0x18, 0x50, 0x51, 0xf8, 0xf9, 

904 0xfa, 0xfb 

905 ]: 

906 def lit(ct): 

907 if ct.TokenType in [0x10, 0x18]: # literal strings 

908 return '"%s"' % ct.value 

909 elif ct.TokenType == 0x50: # composite 

910 return "({%s})" % ",".join(lit(x) for x in ct.value) 

911 else: 

912 return str(ct.value) 

913 res.append(lit(ct)) 

914 elif ct.TokenType == 0x00: # padding 

915 pass 

916 else: 

917 raise ValueError("Unhandled token type %s" % ct.TokenType) 

918 if len(res) != 1: 

919 raise ValueError("Incomplete SDDL !") 

920 condexpr = ";(%s)" % res[0] 

921 if self.AceType in [0x9, 0xA, 0xB, 0xD]: # Conditional ACE 

922 conditional_ace_type = { 

923 0x09: "XA", 

924 0x0A: "XD", 

925 0x0B: "XU", 

926 0x0D: "ZA", 

927 }[self.AceType] 

928 return "D:(%s)" % ( 

929 ";".join([ 

930 conditional_ace_type, 

931 ace_flag_string, 

932 ace_rights, 

933 object_guid, 

934 inherit_object_guid, 

935 sid 

936 ]) + condexpr 

937 ) 

938 else: 

939 ace_type = { 

940 0x00: "A", 

941 0x01: "D", 

942 0x02: "AU", 

943 0x05: "OA", 

944 0x06: "OD", 

945 0x07: "OU", 

946 0x11: "ML", 

947 0x13: "SP", 

948 }[self.AceType] 

949 return "(%s)" % ( 

950 ";".join([ 

951 ace_type, 

952 ace_flag_string, 

953 ace_rights, 

954 object_guid, 

955 inherit_object_guid, 

956 sid 

957 ]) + condexpr 

958 ) 

959 

960 

961# fmt: on 

962 

963 

964# [MS-DTYP] sect 2.4.4.2 

965 

966 

967class WINNT_ACCESS_ALLOWED_ACE(Packet): 

968 fields_desc = [ 

969 FlagsField("Mask", 0, -32, _WINNT_ACCESS_MASK), 

970 PacketField("Sid", WINNT_SID(), WINNT_SID), 

971 ] 

972 

973 

974bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_ALLOWED_ACE, AceType=0x00) 

975 

976 

977# [MS-DTYP] sect 2.4.4.4 

978 

979 

980class WINNT_ACCESS_DENIED_ACE(Packet): 

981 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc 

982 

983 

984bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_DENIED_ACE, AceType=0x01) 

985 

986 

987# [MS-DTYP] sect 2.4.4.17.4+ 

988 

989 

990class WINNT_APPLICATION_DATA_LITERAL_TOKEN(Packet): 

991 def default_payload_class(self, payload): 

992 return conf.padding_layer 

993 

994 

995# fmt: off 

996WINNT_APPLICATION_DATA_LITERAL_TOKEN.fields_desc = [ 

997 ByteEnumField( 

998 "TokenType", 

999 0, 

1000 { 

1001 # [MS-DTYP] sect 2.4.4.17.5 

1002 0x00: "Padding token", 

1003 0x01: "Signed int8", 

1004 0x02: "Signed int16", 

1005 0x03: "Signed int32", 

1006 0x04: "Signed int64", 

1007 0x10: "Unicode", 

1008 0x18: "Octet String", 

1009 0x50: "Composite", 

1010 0x51: "SID", 

1011 # [MS-DTYP] sect 2.4.4.17.6 

1012 0x80: "==", 

1013 0x81: "!=", 

1014 0x82: "<", 

1015 0x83: "<=", 

1016 0x84: ">", 

1017 0x85: ">=", 

1018 0x86: "Contains", 

1019 0x88: "Any_of", 

1020 0x8e: "Not_Contains", 

1021 0x8f: "Not_Any_of", 

1022 0x89: "Member_of", 

1023 0x8a: "Device_Member_of", 

1024 0x8b: "Member_of_Any", 

1025 0x8c: "Device_Member_of_Any", 

1026 0x90: "Not_Member_of", 

1027 0x91: "Not_Device_Member_of", 

1028 0x92: "Not_Member_of_Any", 

1029 0x93: "Not_Device_Member_of_Any", 

1030 # [MS-DTYP] sect 2.4.4.17.7 

1031 0x87: "Exists", 

1032 0x8d: "Not_Exists", 

1033 0xa0: "&&", 

1034 0xa1: "||", 

1035 0xa2: "!", 

1036 # [MS-DTYP] sect 2.4.4.17.8 

1037 0xf8: "Local attribute", 

1038 0xf9: "User Attribute", 

1039 0xfa: "Resource Attribute", 

1040 0xfb: "Device Attribute", 

1041 } 

1042 ), 

1043 ConditionalField( 

1044 # Strings 

1045 LEIntField("length", 0), 

1046 lambda pkt: pkt.TokenType in [ 

1047 0x10, # Unicode string 

1048 0x18, # Octet string 

1049 0xf8, 0xf8, 0xfa, 0xfb, # Attribute tokens 

1050 0x50, # Composite 

1051 ] 

1052 ), 

1053 ConditionalField( 

1054 MultipleTypeField( 

1055 [ 

1056 ( 

1057 LELongField("value", 0), 

1058 lambda pkt: pkt.TokenType in [ 

1059 0x01, # signed int8 

1060 0x02, # signed int16 

1061 0x03, # signed int32 

1062 0x04, # signed int64 

1063 ] 

1064 ), 

1065 ( 

1066 StrLenFieldUtf16("value", b"", length_from=lambda pkt: pkt.length), 

1067 lambda pkt: pkt.TokenType in [ 

1068 0x10, # Unicode string 

1069 0xf8, 0xf8, 0xfa, 0xfb, # Attribute tokens 

1070 ] 

1071 ), 

1072 ( 

1073 StrLenField("value", b"", length_from=lambda pkt: pkt.length), 

1074 lambda pkt: pkt.TokenType == 0x18, # Octet string 

1075 ), 

1076 ( 

1077 PacketListField("value", [], WINNT_APPLICATION_DATA_LITERAL_TOKEN, 

1078 length_from=lambda pkt: pkt.length), 

1079 lambda pkt: pkt.TokenType == 0x50, # Composite 

1080 ), 

1081 

1082 ], 

1083 StrFixedLenField("value", b"", length=0), 

1084 ), 

1085 lambda pkt: pkt.TokenType in [ 

1086 0x01, 0x02, 0x03, 0x04, 0x10, 0x18, 0xf8, 0xf8, 0xfa, 0xfb, 0x50 

1087 ] 

1088 ), 

1089 ConditionalField( 

1090 # Literal 

1091 ByteEnumField("sign", 0, { 

1092 0x01: "+", 

1093 0x02: "-", 

1094 0x03: "None", 

1095 }), 

1096 lambda pkt: pkt.TokenType in [ 

1097 0x01, # signed int8 

1098 0x02, # signed int16 

1099 0x03, # signed int32 

1100 0x04, # signed int64 

1101 ] 

1102 ), 

1103 ConditionalField( 

1104 # Literal 

1105 ByteEnumField("base", 0, { 

1106 0x01: "Octal", 

1107 0x02: "Decimal", 

1108 0x03: "Hexadecimal", 

1109 }), 

1110 lambda pkt: pkt.TokenType in [ 

1111 0x01, # signed int8 

1112 0x02, # signed int16 

1113 0x03, # signed int32 

1114 0x04, # signed int64 

1115 ] 

1116 ), 

1117] 

1118# fmt: on 

1119 

1120 

1121class WINNT_APPLICATION_DATA(Packet): 

1122 fields_desc = [ 

1123 StrFixedLenField("Magic", b"\x61\x72\x74\x78", length=4), 

1124 PacketListField( 

1125 "Tokens", 

1126 [], 

1127 WINNT_APPLICATION_DATA_LITERAL_TOKEN, 

1128 ), 

1129 ] 

1130 

1131 def default_payload_class(self, payload): 

1132 return conf.padding_layer 

1133 

1134 

1135# [MS-DTYP] sect 2.4.4.6 

1136 

1137 

1138class WINNT_ACCESS_ALLOWED_CALLBACK_ACE(Packet): 

1139 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc + [ 

1140 PacketField( 

1141 "ApplicationData", WINNT_APPLICATION_DATA(), WINNT_APPLICATION_DATA 

1142 ), 

1143 ] 

1144 

1145 

1146bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_ALLOWED_CALLBACK_ACE, AceType=0x09) 

1147 

1148 

1149# [MS-DTYP] sect 2.4.4.6 

1150 

1151 

1152class WINNT_ACCESS_DENIED_CALLBACK_ACE(Packet): 

1153 fields_desc = WINNT_ACCESS_ALLOWED_CALLBACK_ACE.fields_desc 

1154 

1155 

1156bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_DENIED_CALLBACK_ACE, AceType=0x0A) 

1157 

1158 

1159# [MS-DTYP] sect 2.4.4.10 

1160 

1161 

1162class WINNT_AUDIT_ACE(Packet): 

1163 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc 

1164 

1165 

1166bind_layers(WINNT_ACE_HEADER, WINNT_AUDIT_ACE, AceType=0x02) 

1167 

1168 

1169# [MS-DTYP] sect 2.4.5 

1170 

1171 

1172class WINNT_ACL(Packet): 

1173 fields_desc = [ 

1174 ByteField("AclRevision", 2), 

1175 ByteField("Sbz1", 0x00), 

1176 FieldLenField( 

1177 "AclSize", None, length_of="Aces", adjust=lambda _, x: x + 14, fmt="<H" 

1178 ), 

1179 FieldLenField("AceCount", None, count_of="Aces", fmt="<H"), 

1180 ShortField("Sbz2", 0), 

1181 PacketListField( 

1182 "Aces", 

1183 [], 

1184 WINNT_ACE_HEADER, 

1185 count_from=lambda pkt: pkt.AceCount, 

1186 ), 

1187 ] 

1188 

1189 def toSDDL(self): 

1190 return [x.toSDDL() for x in self.Aces] 

1191 

1192 

1193# [MS-DTYP] 2.4.6 SECURITY_DESCRIPTOR 

1194 

1195 

1196class SECURITY_DESCRIPTOR(_NTLMPayloadPacket): 

1197 OFFSET = 20 

1198 _NTLM_PAYLOAD_FIELD_NAME = "Data" 

1199 fields_desc = [ 

1200 ByteField("Revision", 0x01), 

1201 ByteField("Sbz1", 0x00), 

1202 FlagsField( 

1203 "Control", 

1204 0x00, 

1205 -16, 

1206 [ 

1207 "OwnerDefaulted", 

1208 "GroupDefaulted", 

1209 "DACLPresent", 

1210 "DACLDefaulted", 

1211 "SACLPresent", 

1212 "SACLDefaulted", 

1213 "DACLTrusted", 

1214 "ServerSecurity", 

1215 "DACLComputer", 

1216 "SACLComputer", 

1217 "DACLAutoInheriter", 

1218 "SACLAutoInherited", 

1219 "DACLProtected", 

1220 "SACLProtected", 

1221 "RMControlValid", 

1222 "SelfRelative", 

1223 ], 

1224 ), 

1225 LEIntField("OwnerSidOffset", 0), 

1226 LEIntField("GroupSidOffset", 0), 

1227 LEIntField("SaclOffset", 0), 

1228 LEIntField("DaclOffset", 0), 

1229 _NTLMPayloadField( 

1230 "Data", 

1231 OFFSET, 

1232 [ 

1233 ConditionalField( 

1234 PacketField("OwnerSid", WINNT_SID(), WINNT_SID), 

1235 lambda pkt: pkt.OwnerSidOffset, 

1236 ), 

1237 ConditionalField( 

1238 PacketField("GroupSid", WINNT_SID(), WINNT_SID), 

1239 lambda pkt: pkt.GroupSidOffset, 

1240 ), 

1241 ConditionalField( 

1242 PacketField("Sacl", WINNT_ACL(), WINNT_ACL), 

1243 lambda pkt: pkt.Control.SACLPresent, 

1244 ), 

1245 ConditionalField( 

1246 PacketField("Dacl", WINNT_ACL(), WINNT_ACL), 

1247 lambda pkt: pkt.Control.DACLPresent, 

1248 ), 

1249 ], 

1250 offset_name="Offset", 

1251 ), 

1252 ] 

1253 

1254 

1255# [MS-FSCC] 2.4.2 FileAllInformation 

1256 

1257 

1258class FileAllInformation(Packet): 

1259 fields_desc = [ 

1260 PacketField("BasicInformation", FileBasicInformation(), FileBasicInformation), 

1261 PacketField( 

1262 "StandardInformation", FileStandardInformation(), FileStandardInformation 

1263 ), 

1264 PacketField( 

1265 "InternalInformation", FileInternalInformation(), FileInternalInformation 

1266 ), 

1267 PacketField("EaInformation", FileEaInformation(), FileEaInformation), 

1268 PacketField( 

1269 "AccessInformation", FileAccessInformation(), FileAccessInformation 

1270 ), 

1271 PacketField( 

1272 "PositionInformation", FilePositionInformation(), FilePositionInformation 

1273 ), 

1274 PacketField("ModeInformation", FileModeInformation(), FileModeInformation), 

1275 PacketField( 

1276 "AlignmentInformation", FileAlignmentInformation(), FileAlignmentInformation 

1277 ), 

1278 PacketField("NameInformation", FILE_NAME_INFORMATION(), FILE_NAME_INFORMATION), 

1279 ] 

1280 

1281 

1282# [MS-FSCC] 2.5.1 FileFsAttributeInformation 

1283 

1284 

1285class FileFsAttributeInformation(Packet): 

1286 fields_desc = [ 

1287 FlagsField( 

1288 "FileSystemAttributes", 

1289 0x00C706FF, 

1290 -32, 

1291 { 

1292 0x02000000: "FILE_SUPPORTS_USN_JOURNAL", 

1293 0x01000000: "FILE_SUPPORTS_OPEN_BY_FILE_ID", 

1294 0x00800000: "FILE_SUPPORTS_EXTENDED_ATTRIBUTES", 

1295 0x00400000: "FILE_SUPPORTS_HARD_LINKS", 

1296 0x00200000: "FILE_SUPPORTS_TRANSACTIONS", 

1297 0x00100000: "FILE_SEQUENTIAL_WRITE_ONCE", 

1298 0x00080000: "FILE_READ_ONLY_VOLUME", 

1299 0x00040000: "FILE_NAMED_STREAMS", 

1300 0x00020000: "FILE_SUPPORTS_ENCRYPTION", 

1301 0x00010000: "FILE_SUPPORTS_OBJECT_IDS", 

1302 0x00008000: "FILE_VOLUME_IS_COMPRESSED", 

1303 0x00000100: "FILE_SUPPORTS_REMOTE_STORAGE", 

1304 0x00000080: "FILE_SUPPORTS_REPARSE_POINTS", 

1305 0x00000040: "FILE_SUPPORTS_SPARSE_FILES", 

1306 0x00000020: "FILE_VOLUME_QUOTAS", 

1307 0x00000010: "FILE_FILE_COMPRESSION", 

1308 0x00000008: "FILE_PERSISTENT_ACLS", 

1309 0x00000004: "FILE_UNICODE_ON_DISK", 

1310 0x00000002: "FILE_CASE_PRESERVED_NAMES", 

1311 0x00000001: "FILE_CASE_SENSITIVE_SEARCH", 

1312 0x04000000: "FILE_SUPPORT_INTEGRITY_STREAMS", 

1313 0x08000000: "FILE_SUPPORTS_BLOCK_REFCOUNTING", 

1314 0x10000000: "FILE_SUPPORTS_SPARSE_VDL", 

1315 }, 

1316 ), 

1317 LEIntField("MaximumComponentNameLength", 255), 

1318 FieldLenField( 

1319 "FileSystemNameLength", None, length_of="FileSystemName", fmt="<I" 

1320 ), 

1321 StrLenFieldUtf16( 

1322 "FileSystemName", b"NTFS", length_from=lambda pkt: pkt.FileSystemNameLength 

1323 ), 

1324 ] 

1325 

1326 

1327# [MS-FSCC] 2.5.8 FileFsSizeInformation 

1328 

1329 

1330class FileFsSizeInformation(Packet): 

1331 fields_desc = [ 

1332 LELongField("TotalAllocationUnits", 10485760), 

1333 LELongField("AvailableAllocationUnits", 1048576), 

1334 LEIntField("SectorsPerAllocationUnit", 8), 

1335 LEIntField("BytesPerSector", 512), 

1336 ] 

1337 

1338 

1339# [MS-FSCC] 2.5.9 FileFsVolumeInformation 

1340 

1341 

1342class FileFsVolumeInformation(Packet): 

1343 fields_desc = [ 

1344 UTCTimeField( 

1345 "VolumeCreationTime", 

1346 None, 

1347 fmt="<Q", 

1348 epoch=[1601, 1, 1, 0, 0, 0], 

1349 custom_scaling=1e7, 

1350 ), 

1351 LEIntField("VolumeSerialNumber", 0), 

1352 LEIntField("VolumeLabelLength", 0), 

1353 ByteField("SupportsObjects", 1), 

1354 ByteField("Reserved", 0), 

1355 StrNullFieldUtf16("VolumeLabel", b"C"), 

1356 ] 

1357 

1358 

1359# [MS-FSCC] 2.7.1 FILE_NOTIFY_INFORMATION 

1360 

1361 

1362class FILE_NOTIFY_INFORMATION(Packet): 

1363 fields_desc = [ 

1364 IntField("NextEntryOffset", 0), 

1365 LEIntEnumField( 

1366 "Action", 

1367 0, 

1368 { 

1369 0x00000001: "FILE_ACTION_ADDED", 

1370 0x00000002: "FILE_ACTION_REMOVED", 

1371 0x00000003: "FILE_ACTION_MODIFIED", 

1372 0x00000004: "FILE_ACTION_RENAMED_OLD_NAME", 

1373 0x00000005: "FILE_ACTION_RENAMED_NEW_NAME", 

1374 0x00000006: "FILE_ACTION_ADDED_STREAM", 

1375 0x00000007: "FILE_ACTION_REMOVED_STREAM", 

1376 0x00000008: "FILE_ACTION_MODIFIED_STREAM", 

1377 0x00000009: "FILE_ACTION_REMOVED_BY_DELETE", 

1378 0x0000000A: "FILE_ACTION_ID_NOT_TUNNELLED", 

1379 0x0000000B: "FILE_ACTION_TUNNELLED_ID_COLLISION", 

1380 }, 

1381 ), 

1382 FieldLenField( 

1383 "FileNameLength", 

1384 None, 

1385 length_of="FileName", 

1386 fmt="<I", 

1387 ), 

1388 StrLenFieldUtf16("FileName", b"", length_from=lambda x: x.FileNameLength), 

1389 StrLenField( 

1390 "pad", 

1391 b"", 

1392 length_from=lambda x: ( 

1393 (x.NextEntryOffset - x.FileNameLength) if x.NextEntryOffset else 0 

1394 ), 

1395 ), 

1396 ] 

1397 

1398 def default_payload_class(self, s): 

1399 return conf.padding_layer 

1400 

1401 

1402_SMB2_CONFIG = [ 

1403 ("BufferOffset", _NTLM_ENUM.OFFSET), 

1404 ("Len", _NTLM_ENUM.LEN), 

1405] 

1406 

1407 

1408def _SMB2_post_build(self, p, pay_offset, fields): 

1409 """Util function to build the offset and populate the lengths""" 

1410 return _NTLM_post_build(self, p, pay_offset, fields, config=_SMB2_CONFIG) 

1411 

1412 

1413# SMB2 sect 2.1 

1414 

1415 

1416class DirectTCP(NBTSession): 

1417 name = "Direct TCP" 

1418 MAXLENGTH = 0xFFFFFF 

1419 fields_desc = [ByteField("zero", 0), ThreeBytesField("LENGTH", None)] 

1420 

1421 

1422# SMB2 sect 2.2.1.1 

1423 

1424 

1425class SMB2_Header(Packet): 

1426 name = "SMB2 Header" 

1427 fields_desc = [ 

1428 StrFixedLenField("Start", b"\xfeSMB", 4), 

1429 LEShortField("StructureSize", 64), 

1430 LEShortField("CreditCharge", 0), 

1431 LEIntEnumField("Status", 0, STATUS_ERREF), 

1432 LEShortEnumField("Command", 0, SMB2_COM), 

1433 LEShortField("CreditRequest", 0), 

1434 FlagsField( 

1435 "Flags", 

1436 0, 

1437 -32, 

1438 { 

1439 0x00000001: "SMB2_FLAGS_SERVER_TO_REDIR", 

1440 0x00000002: "SMB2_FLAGS_ASYNC_COMMAND", 

1441 0x00000004: "SMB2_FLAGS_RELATED_OPERATIONS", 

1442 0x00000008: "SMB2_FLAGS_SIGNED", 

1443 0x10000000: "SMB2_FLAGS_DFS_OPERATIONS", 

1444 0x20000000: "SMB2_FLAGS_REPLAY_OPERATION", 

1445 }, 

1446 ), 

1447 XLEIntField("NextCommand", 0), 

1448 LELongField("MID", 0), # MessageID 

1449 # ASYNC 

1450 ConditionalField( 

1451 LELongField("AsyncId", 0), lambda pkt: pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND 

1452 ), 

1453 # SYNC 

1454 ConditionalField( 

1455 LEIntField("PID", 0), # Reserved, but PID per wireshark 

1456 lambda pkt: not pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND, 

1457 ), 

1458 ConditionalField( 

1459 LEIntField("TID", 0), # TreeID 

1460 lambda pkt: not pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND, 

1461 ), 

1462 # COMMON 

1463 LELongField("SessionId", 0), 

1464 XStrFixedLenField("SecuritySignature", 0, length=16), 

1465 ] 

1466 

1467 _SMB2_OK_RETURNCODES = ( 

1468 # sect 3.3.4.4 

1469 (0xC0000016, 0x0001), # STATUS_MORE_PROCESSING_REQUIRED 

1470 (0x80000005, 0x0008), # STATUS_BUFFER_OVERFLOW (Read) 

1471 (0x80000005, 0x0010), # STATUS_BUFFER_OVERFLOW (QueryInfo) 

1472 (0x80000005, 0x000B), # STATUS_BUFFER_OVERFLOW (IOCTL) 

1473 (0xC000000D, 0x000B), # STATUS_INVALID_PARAMETER 

1474 (0x0000010C, 0x000F), # STATUS_NOTIFY_ENUM_DIR 

1475 ) 

1476 

1477 def guess_payload_class(self, payload): 

1478 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR and self.Status != 0x00000000: 

1479 # Check status for responses 

1480 if (self.Status, self.Command) not in SMB2_Header._SMB2_OK_RETURNCODES: 

1481 return SMB2_Error_Response 

1482 if self.Command == 0x0000: # Negotiate 

1483 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1484 return SMB2_Negotiate_Protocol_Response 

1485 return SMB2_Negotiate_Protocol_Request 

1486 elif self.Command == 0x0001: # Setup 

1487 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1488 return SMB2_Session_Setup_Response 

1489 return SMB2_Session_Setup_Request 

1490 elif self.Command == 0x0002: # Logoff 

1491 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1492 return SMB2_Session_Logoff_Response 

1493 return SMB2_Session_Logoff_Request 

1494 elif self.Command == 0x0003: # TREE connect 

1495 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1496 return SMB2_Tree_Connect_Response 

1497 return SMB2_Tree_Connect_Request 

1498 elif self.Command == 0x0004: # TREE disconnect 

1499 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1500 return SMB2_Tree_Disconnect_Response 

1501 return SMB2_Tree_Disconnect_Request 

1502 elif self.Command == 0x0005: # Create 

1503 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1504 return SMB2_Create_Response 

1505 return SMB2_Create_Request 

1506 elif self.Command == 0x0006: # Close 

1507 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1508 return SMB2_Close_Response 

1509 return SMB2_Close_Request 

1510 elif self.Command == 0x0008: # Read 

1511 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1512 return SMB2_Read_Response 

1513 return SMB2_Read_Request 

1514 elif self.Command == 0x0009: # Write 

1515 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1516 return SMB2_Write_Response 

1517 return SMB2_Write_Request 

1518 elif self.Command == 0x000C: # Cancel 

1519 return SMB2_Cancel_Request 

1520 elif self.Command == 0x000D: # Echo 

1521 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1522 return SMB2_Echo_Response 

1523 return SMB2_Echo_Request 

1524 elif self.Command == 0x000E: # Query directory 

1525 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1526 return SMB2_Query_Directory_Response 

1527 return SMB2_Query_Directory_Request 

1528 elif self.Command == 0x000F: # Change Notify 

1529 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1530 return SMB2_Change_Notify_Response 

1531 return SMB2_Change_Notify_Request 

1532 elif self.Command == 0x0010: # Query info 

1533 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1534 return SMB2_Query_Info_Response 

1535 return SMB2_Query_Info_Request 

1536 elif self.Command == 0x0011: # Set info 

1537 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1538 return SMB2_Set_Info_Response 

1539 return SMB2_Set_Info_Request 

1540 elif self.Command == 0x000B: # IOCTL 

1541 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1542 return SMB2_IOCTL_Response 

1543 return SMB2_IOCTL_Request 

1544 return super(SMB2_Header, self).guess_payload_class(payload) 

1545 

1546 def sign(self, dialect, SigningSessionKey, SigningAlgorithmId=None, IsClient=None): 

1547 # [MS-SMB2] 3.1.4.1 

1548 self.SecuritySignature = b"\x00" * 16 

1549 s = bytes(self) 

1550 if len(s) <= 64: 

1551 log_runtime.warning("Cannot sign invalid SMB packet !") 

1552 return s 

1553 if dialect in [0x0300, 0x0302, 0x0311]: # SMB 3 

1554 if dialect == 0x0311: # SMB 3.1.1 

1555 if SigningAlgorithmId is None or IsClient is None: 

1556 raise Exception("SMB 3.1.1 needs a SigningAlgorithmId and IsClient") 

1557 else: 

1558 SigningAlgorithmId = "AES-CMAC" # AES-128-CMAC 

1559 if "GMAC" in SigningAlgorithmId: 

1560 from cryptography.hazmat.primitives.ciphers.aead import AESGCM 

1561 

1562 aesgcm = AESGCM(SigningSessionKey) 

1563 nonce = struct.pack("<Q", self.MID) + struct.pack( 

1564 "<I", 

1565 (0 if IsClient else 1) | (0x8000000 if self.Command == 9 else 0), 

1566 ) 

1567 sig = aesgcm.encrypt(nonce, b"", s) 

1568 elif "CMAC" in SigningAlgorithmId: 

1569 from cryptography.hazmat.primitives import cmac 

1570 from cryptography.hazmat.primitives.ciphers import algorithms 

1571 

1572 c = cmac.CMAC(algorithms.AES(SigningSessionKey)) 

1573 c.update(s) 

1574 sig = c.finalize() 

1575 elif "HMAC" in SigningAlgorithmId: 

1576 from scapy.layers.tls.crypto.h_mac import Hmac_SHA256 

1577 

1578 sig = Hmac_SHA256(SigningSessionKey).digest(s) 

1579 sig = sig[:16] 

1580 else: 

1581 raise ValueError("Unknown SigningAlgorithmId") 

1582 elif dialect in [0x0210, 0x0202]: # SMB 2.1 or SMB 2.0.2 

1583 from scapy.layers.tls.crypto.h_mac import Hmac_SHA256 

1584 

1585 sig = Hmac_SHA256(SigningSessionKey).digest(s) 

1586 sig = sig[:16] 

1587 else: 

1588 log_runtime.warning("Unknown SMB Version %s ! Cannot sign." % dialect) 

1589 sig = s[:-16] + b"\x00" * 16 

1590 self.SecuritySignature = sig 

1591 # we make sure the payload is static 

1592 self.payload = conf.raw_layer(load=s[64:]) 

1593 

1594 

1595class _SMB2_Payload(Packet): 

1596 def do_dissect_payload(self, s): 

1597 # There can be padding between this layer and the next one 

1598 if self.underlayer and isinstance(self.underlayer, SMB2_Header): 

1599 if self.underlayer.NextCommand: 

1600 padlen = self.underlayer.NextCommand - (64 + len(self.raw_packet_cache)) 

1601 if padlen: 

1602 self.add_payload(s[:padlen]) 

1603 s = s[padlen:] 

1604 super(_SMB2_Payload, self).do_dissect_payload(s) 

1605 

1606 def answers(self, other): 

1607 return ( 

1608 isinstance(other, _SMB2_Payload) 

1609 and self.__class__ != other.__class__ 

1610 and (self.Command == other.Command or self.Command == -1) 

1611 ) 

1612 

1613 def guess_payload_class(self, s): 

1614 if self.underlayer and isinstance(self.underlayer, SMB2_Header): 

1615 if self.underlayer.NextCommand: 

1616 return SMB2_Header 

1617 return super(_SMB2_Payload, self).guess_payload_class(s) 

1618 

1619 

1620# sect 2.2.2 

1621 

1622 

1623class SMB2_Error_Response(_SMB2_Payload): 

1624 Command = -1 

1625 __slots__ = ["NTStatus"] # extra info 

1626 name = "SMB2 Error Response" 

1627 fields_desc = [ 

1628 XLEShortField("StructureSize", 0x09), 

1629 ByteField("ErrorContextCount", 0), 

1630 ByteField("Reserved", 0), 

1631 FieldLenField("ByteCount", None, fmt="<I", length_of="ErrorData"), 

1632 XStrLenField("ErrorData", b"", length_from=lambda pkt: pkt.ByteCount), 

1633 ] 

1634 

1635 

1636bind_top_down(SMB2_Header, SMB2_Error_Response, Flags=1) # SMB2_FLAGS_SERVER_TO_REDIR 

1637 

1638# sect 2.2.2.2.2 

1639 

1640 

1641class MOVE_DST_IPADDR(Packet): 

1642 fields_desc = [ 

1643 # Wireshark appears to get this wrong 

1644 LEIntEnumField("Type", 1, {1: "IPv4", 2: "IPv6"}), 

1645 IntField("Reserved", 0), 

1646 MultipleTypeField( 

1647 [(IP6Field("IPAddress", None), lambda pkt: pkt.Type == 2)], 

1648 IPField("IPAddress", None), 

1649 ), 

1650 ConditionalField( 

1651 # For IPv4 

1652 StrFixedLenField("Reserved2", b"", length=12), 

1653 lambda pkt: pkt.Type == 1, 

1654 ), 

1655 ] 

1656 

1657 def default_payload_class(self, payload): 

1658 return conf.padding_layer 

1659 

1660 

1661class SMB2_Error_Share_Redirect_Context_Response(_NTLMPayloadPacket): 

1662 name = "Share Redirect Error Context Response" 

1663 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

1664 fields_desc = [ 

1665 XLEIntField("StructureSize", 0x30), 

1666 LEIntEnumField("NotificationType", 3, {3: "SHARE_MOVE_NOTIFICATION"}), 

1667 XLEIntField("ResourceNameBufferOffset", None), 

1668 LEIntField("ResourceNameLen", None), 

1669 ShortField("Reserved", 0), 

1670 ShortEnumField("TargetType", 0, {0: "IP"}), 

1671 FieldLenField("IPAddrCount", None, fmt="<I", count_of="IPAddrMoveList"), 

1672 PacketListField( 

1673 "IPAddrMoveList", 

1674 [], 

1675 MOVE_DST_IPADDR, 

1676 count_from=lambda pkt: pkt.IPAddrCount, 

1677 ), 

1678 _NTLMPayloadField( 

1679 "Buffer", 

1680 lambda pkt: 24 + len(pkt.IPAddrMoveList) * 24, 

1681 [ 

1682 StrLenFieldUtf16( 

1683 "ResourceName", b"", length_from=lambda pkt: pkt.ResourceNameLen 

1684 ), 

1685 ], 

1686 ), 

1687 ] 

1688 

1689 def post_build(self, pkt, pay): 

1690 # type: (bytes, bytes) -> bytes 

1691 return ( 

1692 _SMB2_post_build( 

1693 self, 

1694 pkt, 

1695 24 + len(self.IPAddrMoveList) * 24, 

1696 { 

1697 "ResourceName": 8, 

1698 }, 

1699 ) 

1700 + pay 

1701 ) 

1702 

1703 

1704# sect 2.2.2.1 

1705 

1706 

1707class SMB2_Error_ContextResponse(Packet): 

1708 fields_desc = [ 

1709 FieldLenField("ErrorDatalength", None, fmt="<I", length_of="ErrorContextData"), 

1710 LEIntEnumField("ErrorId", 0, {0: "DEFAULT", 0x72645253: "SHARE_REDIRECT"}), 

1711 MultipleTypeField( 

1712 [ 

1713 ( 

1714 PacketField( 

1715 "ErrorContextData", 

1716 SMB2_Error_Share_Redirect_Context_Response(), 

1717 SMB2_Error_Share_Redirect_Context_Response, 

1718 ), 

1719 lambda pkt: pkt.ErrorId == 0x72645253, 

1720 ) 

1721 ], 

1722 XStrLenField( 

1723 "ErrorContextData", b"", length_from=lambda pkt: pkt.ErrorDatalength 

1724 ), 

1725 ), 

1726 ] 

1727 

1728 

1729# sect 2.2.3 

1730 

1731 

1732class SMB2_Negotiate_Context(Packet): 

1733 name = "SMB2 Negotiate Context" 

1734 fields_desc = [ 

1735 LEShortEnumField("ContextType", 0x0, SMB2_NEGOTIATE_CONTEXT_TYPES), 

1736 LenField("DataLength", None, fmt="<H"), 

1737 IntField("Reserved", 0), 

1738 ] 

1739 

1740 def default_payload_class(self, payload): 

1741 return conf.padding_layer 

1742 

1743 

1744class SMB2_Negotiate_Protocol_Request(_SMB2_Payload, _NTLMPayloadPacket): 

1745 name = "SMB2 Negotiate Protocol Request" 

1746 Command = 0x0000 

1747 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

1748 fields_desc = [ 

1749 XLEShortField("StructureSize", 0x24), 

1750 FieldLenField("DialectCount", None, fmt="<H", count_of="Dialects"), 

1751 # SecurityMode 

1752 FlagsField("SecurityMode", 0, -16, SMB2_SECURITY_MODE), 

1753 LEShortField("Reserved", 0), 

1754 # Capabilities 

1755 FlagsField("Capabilities", 0, -32, SMB2_CAPABILITIES), 

1756 UUIDField("ClientGUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), 

1757 XLEIntField("NegotiateContextsBufferOffset", None), 

1758 LEShortField("NegotiateContextsCount", None), 

1759 ShortField("Reserved2", 0), 

1760 FieldListField( 

1761 "Dialects", 

1762 [0x0202], 

1763 LEShortEnumField("", 0x0, SMB_DIALECTS), 

1764 count_from=lambda pkt: pkt.DialectCount, 

1765 ), 

1766 _NTLMPayloadField( 

1767 "Buffer", 

1768 lambda pkt: 64 + 36 + len(pkt.Dialects) * 2, 

1769 [ 

1770 # Field only exists if Dialects contains 0x0311 

1771 FieldListField( 

1772 "NegotiateContexts", 

1773 [], 

1774 ReversePadField( 

1775 PacketField("Context", None, SMB2_Negotiate_Context), 

1776 8, 

1777 ), 

1778 count_from=lambda pkt: pkt.NegotiateContextsCount, 

1779 ), 

1780 ], 

1781 ), 

1782 ] 

1783 

1784 def post_build(self, pkt, pay): 

1785 # type: (bytes, bytes) -> bytes 

1786 return ( 

1787 _NTLM_post_build( 

1788 self, 

1789 pkt, 

1790 64 + 36 + len(self.Dialects) * 2, 

1791 { 

1792 "NegotiateContexts": 28, 

1793 }, 

1794 config=[ 

1795 ("BufferOffset", _NTLM_ENUM.OFFSET | _NTLM_ENUM.PAD8), 

1796 ("Count", _NTLM_ENUM.COUNT), 

1797 ], 

1798 ) 

1799 + pay 

1800 ) 

1801 

1802 

1803bind_top_down( 

1804 SMB2_Header, 

1805 SMB2_Negotiate_Protocol_Request, 

1806 Command=0x0000, 

1807) 

1808 

1809# sect 2.2.3.1.1 

1810 

1811 

1812class SMB2_Preauth_Integrity_Capabilities(Packet): 

1813 name = "SMB2 Preauth Integrity Capabilities" 

1814 fields_desc = [ 

1815 # According to the spec, this field value must be greater than 0 

1816 # (cf Section 2.2.3.1.1 of MS-SMB2.pdf) 

1817 FieldLenField("HashAlgorithmCount", None, fmt="<H", count_of="HashAlgorithms"), 

1818 FieldLenField("SaltLength", None, fmt="<H", length_of="Salt"), 

1819 FieldListField( 

1820 "HashAlgorithms", 

1821 [0x0001], 

1822 LEShortEnumField( 

1823 "", 

1824 0x0, 

1825 { 

1826 # As for today, no other hash algorithm is described by the spec 

1827 0x0001: "SHA-512", 

1828 }, 

1829 ), 

1830 count_from=lambda pkt: pkt.HashAlgorithmCount, 

1831 ), 

1832 XStrLenField("Salt", "", length_from=lambda pkt: pkt.SaltLength), 

1833 ] 

1834 

1835 def default_payload_class(self, payload): 

1836 return conf.padding_layer 

1837 

1838 

1839bind_layers( 

1840 SMB2_Negotiate_Context, SMB2_Preauth_Integrity_Capabilities, ContextType=0x0001 

1841) 

1842 

1843# sect 2.2.3.1.2 

1844 

1845 

1846class SMB2_Encryption_Capabilities(Packet): 

1847 name = "SMB2 Encryption Capabilities" 

1848 fields_desc = [ 

1849 # According to the spec, this field value must be greater than 0 

1850 # (cf Section 2.2.3.1.2 of MS-SMB2.pdf) 

1851 FieldLenField("CipherCount", None, fmt="<H", count_of="Ciphers"), 

1852 FieldListField( 

1853 "Ciphers", 

1854 [0x0001], 

1855 LEShortEnumField( 

1856 "", 

1857 0x0, 

1858 SMB2_ENCRYPTION_CIPHERS, 

1859 ), 

1860 count_from=lambda pkt: pkt.CipherCount, 

1861 ), 

1862 ] 

1863 

1864 def default_payload_class(self, payload): 

1865 return conf.padding_layer 

1866 

1867 

1868bind_layers(SMB2_Negotiate_Context, SMB2_Encryption_Capabilities, ContextType=0x0002) 

1869 

1870# sect 2.2.3.1.3 

1871 

1872 

1873class SMB2_Compression_Capabilities(Packet): 

1874 name = "SMB2 Compression Capabilities" 

1875 fields_desc = [ 

1876 FieldLenField( 

1877 "CompressionAlgorithmCount", 

1878 None, 

1879 fmt="<H", 

1880 count_of="CompressionAlgorithms", 

1881 ), 

1882 ShortField("Padding", 0x0), 

1883 IntEnumField( 

1884 "Flags", 

1885 0x0, 

1886 { 

1887 0x00000000: "SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE", 

1888 0x00000001: "SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED", 

1889 }, 

1890 ), 

1891 FieldListField( 

1892 "CompressionAlgorithms", 

1893 None, 

1894 LEShortEnumField("", 0x0, SMB2_COMPRESSION_ALGORITHMS), 

1895 count_from=lambda pkt: pkt.CompressionAlgorithmCount, 

1896 ), 

1897 ] 

1898 

1899 def default_payload_class(self, payload): 

1900 return conf.padding_layer 

1901 

1902 

1903bind_layers(SMB2_Negotiate_Context, SMB2_Compression_Capabilities, ContextType=0x0003) 

1904 

1905# sect 2.2.3.1.4 

1906 

1907 

1908class SMB2_Netname_Negotiate_Context_ID(Packet): 

1909 name = "SMB2 Netname Negotiate Context ID" 

1910 fields_desc = [StrFieldUtf16("NetName", "")] 

1911 

1912 def default_payload_class(self, payload): 

1913 return conf.padding_layer 

1914 

1915 

1916bind_layers( 

1917 SMB2_Negotiate_Context, SMB2_Netname_Negotiate_Context_ID, ContextType=0x0005 

1918) 

1919 

1920# sect 2.2.3.1.5 

1921 

1922 

1923class SMB2_Transport_Capabilities(Packet): 

1924 name = "SMB2 Transport Capabilities" 

1925 fields_desc = [ 

1926 FlagsField( 

1927 "Flags", 

1928 0x0, 

1929 -32, 

1930 { 

1931 0x00000001: "SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY", 

1932 }, 

1933 ), 

1934 ] 

1935 

1936 def default_payload_class(self, payload): 

1937 return conf.padding_layer 

1938 

1939 

1940bind_layers(SMB2_Negotiate_Context, SMB2_Transport_Capabilities, ContextType=0x0006) 

1941 

1942# sect 2.2.3.1.6 

1943 

1944 

1945class SMB2_RDMA_Transform_Capabilities(Packet): 

1946 name = "SMB2 RDMA Transform Capabilities" 

1947 fields_desc = [ 

1948 FieldLenField("TransformCount", None, fmt="<H", count_of="RDMATransformIds"), 

1949 LEShortField("Reserved1", 0), 

1950 LEIntField("Reserved2", 0), 

1951 FieldListField( 

1952 "RDMATransformIds", 

1953 None, 

1954 LEShortEnumField( 

1955 "", 

1956 0x0, 

1957 { 

1958 0x0000: "SMB2_RDMA_TRANSFORM_NONE", 

1959 0x0001: "SMB2_RDMA_TRANSFORM_ENCRYPTION", 

1960 0x0002: "SMB2_RDMA_TRANSFORM_SIGNING", 

1961 }, 

1962 ), 

1963 count_from=lambda pkt: pkt.TransformCount, 

1964 ), 

1965 ] 

1966 

1967 def default_payload_class(self, payload): 

1968 return conf.padding_layer 

1969 

1970 

1971bind_layers( 

1972 SMB2_Negotiate_Context, SMB2_RDMA_Transform_Capabilities, ContextType=0x0007 

1973) 

1974 

1975# sect 2.2.3.1.7 

1976 

1977 

1978class SMB2_Signing_Capabilities(Packet): 

1979 name = "SMB2 Signing Capabilities" 

1980 fields_desc = [ 

1981 FieldLenField( 

1982 "SigningAlgorithmCount", None, fmt="<H", count_of="SigningAlgorithms" 

1983 ), 

1984 FieldListField( 

1985 "SigningAlgorithms", 

1986 None, 

1987 LEShortEnumField( 

1988 "", 

1989 0x0, 

1990 SMB2_SIGNING_ALGORITHMS, 

1991 ), 

1992 count_from=lambda pkt: pkt.SigningAlgorithmCount, 

1993 ), 

1994 ] 

1995 

1996 def default_payload_class(self, payload): 

1997 return conf.padding_layer 

1998 

1999 

2000bind_layers(SMB2_Negotiate_Context, SMB2_Signing_Capabilities, ContextType=0x0008) 

2001 

2002# sect 2.2.4 

2003 

2004 

2005class SMB2_Negotiate_Protocol_Response(_SMB2_Payload, _NTLMPayloadPacket): 

2006 name = "SMB2 Negotiate Protocol Response" 

2007 Command = 0x0000 

2008 OFFSET = 64 + 64 

2009 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2010 fields_desc = [ 

2011 XLEShortField("StructureSize", 0x41), 

2012 FlagsField("SecurityMode", 0, -16, SMB2_SECURITY_MODE), 

2013 LEShortEnumField("DialectRevision", 0x0, SMB_DIALECTS), 

2014 LEShortField("NegotiateContextsCount", None), 

2015 UUIDField("GUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), 

2016 # Capabilities 

2017 FlagsField("Capabilities", 0, -32, SMB2_CAPABILITIES), 

2018 LEIntField("MaxTransactionSize", 65536), 

2019 LEIntField("MaxReadSize", 65536), 

2020 LEIntField("MaxWriteSize", 65536), 

2021 UTCTimeField( 

2022 "ServerTime", 

2023 None, 

2024 fmt="<Q", 

2025 epoch=[1601, 1, 1, 0, 0, 0], 

2026 custom_scaling=1e7, 

2027 ), 

2028 UTCTimeField( 

2029 "ServerStartTime", 

2030 None, 

2031 fmt="<Q", 

2032 epoch=[1601, 1, 1, 0, 0, 0], 

2033 custom_scaling=1e7, 

2034 ), 

2035 XLEShortField("SecurityBlobBufferOffset", None), 

2036 LEShortField("SecurityBlobLen", None), 

2037 XLEIntField("NegotiateContextsBufferOffset", None), 

2038 _NTLMPayloadField( 

2039 "Buffer", 

2040 OFFSET, 

2041 [ 

2042 PacketLenField( 

2043 "SecurityBlob", 

2044 None, 

2045 GSSAPI_BLOB, 

2046 length_from=lambda x: x.SecurityBlobLen, 

2047 ), 

2048 # Field only exists if Dialect is 0x0311 

2049 FieldListField( 

2050 "NegotiateContexts", 

2051 [], 

2052 ReversePadField( 

2053 PacketField("Context", None, SMB2_Negotiate_Context), 

2054 8, 

2055 ), 

2056 count_from=lambda pkt: pkt.NegotiateContextsCount, 

2057 ), 

2058 ], 

2059 force_order=["SecurityBlob", "NegotiateContexts"], 

2060 ), 

2061 ] 

2062 

2063 def post_build(self, pkt, pay): 

2064 # type: (bytes, bytes) -> bytes 

2065 pkt = _NTLM_post_build( 

2066 self, 

2067 pkt, 

2068 self.OFFSET, 

2069 { 

2070 "SecurityBlob": 56, 

2071 "NegotiateContexts": 60, 

2072 }, 

2073 config=[ 

2074 ( 

2075 "BufferOffset", 

2076 { 

2077 "SecurityBlob": _NTLM_ENUM.OFFSET, 

2078 "NegotiateContexts": _NTLM_ENUM.OFFSET | _NTLM_ENUM.PAD8, 

2079 }, 

2080 ), 

2081 ], 

2082 ) 

2083 if getattr(self, "SecurityBlob", None): 

2084 if self.SecurityBlobLen is None: 

2085 pkt = pkt[:58] + struct.pack("<H", len(self.SecurityBlob)) + pkt[60:] 

2086 if getattr(self, "NegotiateContexts", None): 

2087 if self.NegotiateContextsCount is None: 

2088 pkt = pkt[:6] + struct.pack("<H", len(self.NegotiateContexts)) + pkt[8:] 

2089 return pkt + pay 

2090 

2091 

2092bind_top_down( 

2093 SMB2_Header, 

2094 SMB2_Negotiate_Protocol_Response, 

2095 Command=0x0000, 

2096 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

2097) 

2098 

2099# sect 2.2.5 

2100 

2101 

2102class SMB2_Session_Setup_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2103 name = "SMB2 Session Setup Request" 

2104 Command = 0x0001 

2105 OFFSET = 24 + 64 

2106 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2107 fields_desc = [ 

2108 XLEShortField("StructureSize", 0x19), 

2109 FlagsField("Flags", 0, -8, ["SMB2_SESSION_FLAG_BINDING"]), 

2110 FlagsField("SecurityMode", 0, -8, SMB2_SECURITY_MODE), 

2111 FlagsField("Capabilities", 0, -32, SMB2_CAPABILITIES), 

2112 LEIntField("Channel", 0), 

2113 XLEShortField("SecurityBlobBufferOffset", None), 

2114 LEShortField("SecurityBlobLen", None), 

2115 XLELongField("PreviousSessionId", 0), 

2116 _NTLMPayloadField( 

2117 "Buffer", 

2118 OFFSET, 

2119 [ 

2120 PacketField("SecurityBlob", None, GSSAPI_BLOB), 

2121 ], 

2122 ), 

2123 ] 

2124 

2125 def post_build(self, pkt, pay): 

2126 # type: (bytes, bytes) -> bytes 

2127 return ( 

2128 _SMB2_post_build( 

2129 self, 

2130 pkt, 

2131 self.OFFSET, 

2132 { 

2133 "SecurityBlob": 12, 

2134 }, 

2135 ) 

2136 + pay 

2137 ) 

2138 

2139 

2140bind_top_down( 

2141 SMB2_Header, 

2142 SMB2_Session_Setup_Request, 

2143 Command=0x0001, 

2144) 

2145 

2146# sect 2.2.6 

2147 

2148 

2149class SMB2_Session_Setup_Response(_SMB2_Payload, _NTLMPayloadPacket): 

2150 name = "SMB2 Session Setup Response" 

2151 Command = 0x0001 

2152 OFFSET = 8 + 64 

2153 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2154 fields_desc = [ 

2155 XLEShortField("StructureSize", 0x9), 

2156 FlagsField( 

2157 "SessionFlags", 

2158 0, 

2159 -16, 

2160 { 

2161 0x0001: "IS_GUEST", 

2162 0x0002: "IS_NULL", 

2163 0x0004: "ENCRYPT_DATE", 

2164 }, 

2165 ), 

2166 XLEShortField("SecurityBufferOffset", None), 

2167 LEShortField("SecurityLen", None), 

2168 _NTLMPayloadField( 

2169 "Buffer", 

2170 OFFSET, 

2171 [ 

2172 PacketField("Security", None, GSSAPI_BLOB), 

2173 ], 

2174 ), 

2175 ] 

2176 

2177 def __getattr__(self, attr): 

2178 # Ease SMB1 backward compatibility 

2179 if attr == "SecurityBlob": 

2180 return ( 

2181 super(SMB2_Session_Setup_Response, self).__getattr__("Buffer") 

2182 or [(None, None)] 

2183 )[0][1] 

2184 return super(SMB2_Session_Setup_Response, self).__getattr__(attr) 

2185 

2186 def setfieldval(self, attr, val): 

2187 if attr == "SecurityBlob": 

2188 return super(SMB2_Session_Setup_Response, self).setfieldval( 

2189 "Buffer", [("Security", val)] 

2190 ) 

2191 return super(SMB2_Session_Setup_Response, self).setfieldval(attr, val) 

2192 

2193 def post_build(self, pkt, pay): 

2194 # type: (bytes, bytes) -> bytes 

2195 return ( 

2196 _SMB2_post_build( 

2197 self, 

2198 pkt, 

2199 self.OFFSET, 

2200 { 

2201 "Security": 4, 

2202 }, 

2203 ) 

2204 + pay 

2205 ) 

2206 

2207 

2208bind_top_down( 

2209 SMB2_Header, 

2210 SMB2_Session_Setup_Response, 

2211 Command=0x0001, 

2212 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

2213) 

2214 

2215# sect 2.2.7 

2216 

2217 

2218class SMB2_Session_Logoff_Request(_SMB2_Payload): 

2219 name = "SMB2 LOGOFF Request" 

2220 Command = 0x0002 

2221 fields_desc = [ 

2222 XLEShortField("StructureSize", 0x4), 

2223 ShortField("reserved", 0), 

2224 ] 

2225 

2226 

2227bind_top_down( 

2228 SMB2_Header, 

2229 SMB2_Session_Logoff_Request, 

2230 Command=0x0002, 

2231) 

2232 

2233# sect 2.2.8 

2234 

2235 

2236class SMB2_Session_Logoff_Response(_SMB2_Payload): 

2237 name = "SMB2 LOGOFF Request" 

2238 Command = 0x0002 

2239 fields_desc = [ 

2240 XLEShortField("StructureSize", 0x4), 

2241 ShortField("reserved", 0), 

2242 ] 

2243 

2244 

2245bind_top_down( 

2246 SMB2_Header, 

2247 SMB2_Session_Logoff_Response, 

2248 Command=0x0002, 

2249 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

2250) 

2251 

2252# sect 2.2.9 

2253 

2254 

2255class SMB2_Tree_Connect_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2256 name = "SMB2 TREE_CONNECT Request" 

2257 Command = 0x0003 

2258 OFFSET = 8 + 64 

2259 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2260 fields_desc = [ 

2261 XLEShortField("StructureSize", 0x9), 

2262 FlagsField( 

2263 "Flags", 

2264 0, 

2265 -16, 

2266 ["CLUSTER_RECONNECT", "REDIRECT_TO_OWNER", "EXTENSION_PRESENT"], 

2267 ), 

2268 XLEShortField("PathBufferOffset", None), 

2269 LEShortField("PathLen", None), 

2270 _NTLMPayloadField( 

2271 "Buffer", 

2272 OFFSET, 

2273 [ 

2274 StrFieldUtf16("Path", b""), 

2275 ], 

2276 ), 

2277 ] 

2278 

2279 def post_build(self, pkt, pay): 

2280 # type: (bytes, bytes) -> bytes 

2281 return ( 

2282 _SMB2_post_build( 

2283 self, 

2284 pkt, 

2285 self.OFFSET, 

2286 { 

2287 "Path": 4, 

2288 }, 

2289 ) 

2290 + pay 

2291 ) 

2292 

2293 

2294bind_top_down( 

2295 SMB2_Header, 

2296 SMB2_Tree_Connect_Request, 

2297 Command=0x0003, 

2298) 

2299 

2300# sect 2.2.10 

2301 

2302 

2303class SMB2_Tree_Connect_Response(_SMB2_Payload): 

2304 name = "SMB2 TREE_CONNECT Response" 

2305 Command = 0x0003 

2306 fields_desc = [ 

2307 XLEShortField("StructureSize", 0x10), 

2308 ByteEnumField("ShareType", 0, {0x01: "DISK", 0x02: "PIPE", 0x03: "PRINT"}), 

2309 ByteField("Reserved", 0), 

2310 FlagsField( 

2311 "ShareFlags", 

2312 0x30, 

2313 -32, 

2314 { 

2315 0x00000010: "AUTO_CACHING", 

2316 0x00000020: "VDO_CACHING", 

2317 0x00000030: "NO_CACHING", 

2318 0x00000001: "DFS", 

2319 0x00000002: "DFS_ROOT", 

2320 0x00000100: "RESTRICT_EXCLUSIVE_OPENS", 

2321 0x00000200: "FORCE_SHARED_DELETE", 

2322 0x00000400: "ALLOW_NAMESPACE_CACHING", 

2323 0x00000800: "ACCESS_BASED_DIRECTORY_ENUM", 

2324 0x00001000: "FORCE_LEVELII_OPLOCK", 

2325 0x00002000: "ENABLE_HASH_V1", 

2326 0x00004000: "ENABLE_HASH_V2", 

2327 0x00008000: "ENCRYPT_DATA", 

2328 0x00040000: "IDENTITY_REMOTING", 

2329 0x00100000: "COMPRESS_DATA", 

2330 }, 

2331 ), 

2332 FlagsField( 

2333 "Capabilities", 

2334 0, 

2335 -32, 

2336 { 

2337 0x00000008: "DFS", 

2338 0x00000010: "CONTINUOUS_AVAILABILITY", 

2339 0x00000020: "SCALEOUT", 

2340 0x00000040: "CLUSTER", 

2341 0x00000080: "ASYMMETRIC", 

2342 0x00000100: "REDIRECT_TO_OWNER", 

2343 }, 

2344 ), 

2345 FlagsField("MaximalAccess", 0, -32, SMB2_ACCESS_FLAGS_FILE), 

2346 ] 

2347 

2348 

2349bind_top_down(SMB2_Header, SMB2_Tree_Connect_Response, Command=0x0003, Flags=1) 

2350 

2351# sect 2.2.11 

2352 

2353 

2354class SMB2_Tree_Disconnect_Request(_SMB2_Payload): 

2355 name = "SMB2 TREE_DISCONNECT Request" 

2356 Command = 0x0004 

2357 fields_desc = [ 

2358 XLEShortField("StructureSize", 0x4), 

2359 XLEShortField("Reserved", 0), 

2360 ] 

2361 

2362 

2363bind_top_down(SMB2_Header, SMB2_Tree_Disconnect_Request, Command=0x0004) 

2364 

2365# sect 2.2.12 

2366 

2367 

2368class SMB2_Tree_Disconnect_Response(_SMB2_Payload): 

2369 name = "SMB2 TREE_DISCONNECT Response" 

2370 Command = 0x0004 

2371 fields_desc = [ 

2372 XLEShortField("StructureSize", 0x4), 

2373 XLEShortField("Reserved", 0), 

2374 ] 

2375 

2376 

2377bind_top_down(SMB2_Header, SMB2_Tree_Disconnect_Response, Command=0x0004, Flags=1) 

2378 

2379 

2380# sect 2.2.14.1 

2381 

2382 

2383class SMB2_FILEID(Packet): 

2384 fields_desc = [XLELongField("Persistent", 0), XLELongField("Volatile", 0)] 

2385 

2386 def __hash__(self): 

2387 return self.Persistent + self.Volatile << 64 

2388 

2389 def default_payload_class(self, payload): 

2390 return conf.padding_layer 

2391 

2392 

2393# sect 2.2.14.2 

2394 

2395 

2396class SMB2_CREATE_DURABLE_HANDLE_RESPONSE(Packet): 

2397 fields_desc = [ 

2398 XStrFixedLenField("Reserved", b"\x00" * 8, length=8), 

2399 ] 

2400 

2401 

2402class SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE(Packet): 

2403 fields_desc = [ 

2404 LEIntEnumField("QueryStatus", 0, STATUS_ERREF), 

2405 FlagsField("MaximalAccess", 0, -32, SMB2_ACCESS_FLAGS_FILE), 

2406 ] 

2407 

2408 

2409class SMB2_CREATE_QUERY_ON_DISK_ID(Packet): 

2410 fields_desc = [ 

2411 XLELongField("DiskFileId", 0), 

2412 XLELongField("VolumeId", 0), 

2413 XStrFixedLenField("Reserved", b"", length=16), 

2414 ] 

2415 

2416 

2417class SMB2_CREATE_RESPONSE_LEASE(Packet): 

2418 fields_desc = [ 

2419 XStrFixedLenField("LeaseKey", b"", length=16), 

2420 FlagsField( 

2421 "LeaseState", 

2422 0x7, 

2423 -32, 

2424 { 

2425 0x01: "SMB2_LEASE_READ_CACHING", 

2426 0x02: "SMB2_LEASE_HANDLE_CACHING", 

2427 0x04: "SMB2_LEASE_WRITE_CACHING", 

2428 }, 

2429 ), 

2430 FlagsField( 

2431 "LeaseFlags", 

2432 0, 

2433 -32, 

2434 { 

2435 0x02: "SMB2_LEASE_FLAG_BREAK_IN_PROGRESS", 

2436 0x04: "SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET", 

2437 }, 

2438 ), 

2439 LELongField("LeaseDuration", 0), 

2440 ] 

2441 

2442 

2443class SMB2_CREATE_RESPONSE_LEASE_V2(Packet): 

2444 fields_desc = [ 

2445 SMB2_CREATE_RESPONSE_LEASE, 

2446 XStrFixedLenField("ParentLeaseKey", b"", length=16), 

2447 LEShortField("Epoch", 0), 

2448 LEShortField("Reserved", 0), 

2449 ] 

2450 

2451 

2452class SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2(Packet): 

2453 fields_desc = [ 

2454 LEIntField("Timeout", 0), 

2455 FlagsField( 

2456 "Flags", 

2457 0, 

2458 -32, 

2459 { 

2460 0x02: "SMB2_DHANDLE_FLAG_PERSISTENT", 

2461 }, 

2462 ), 

2463 ] 

2464 

2465 

2466# sect 2.2.13 

2467 

2468 

2469class SMB2_CREATE_DURABLE_HANDLE_REQUEST(Packet): 

2470 fields_desc = [ 

2471 XStrFixedLenField("DurableRequest", b"", length=16), 

2472 ] 

2473 

2474 

2475class SMB2_CREATE_DURABLE_HANDLE_RECONNECT(Packet): 

2476 fields_desc = [ 

2477 PacketField("Data", SMB2_FILEID(), SMB2_FILEID), 

2478 ] 

2479 

2480 

2481class SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST(Packet): 

2482 fields_desc = [ 

2483 LELongField("Timestamp", 0), 

2484 ] 

2485 

2486 

2487class SMB2_CREATE_ALLOCATION_SIZE(Packet): 

2488 fields_desc = [ 

2489 LELongField("AllocationSize", 0), 

2490 ] 

2491 

2492 

2493class SMB2_CREATE_TIMEWARP_TOKEN(Packet): 

2494 fields_desc = [ 

2495 LELongField("Timestamp", 0), 

2496 ] 

2497 

2498 

2499class SMB2_CREATE_REQUEST_LEASE(Packet): 

2500 fields_desc = [ 

2501 SMB2_CREATE_RESPONSE_LEASE, 

2502 ] 

2503 

2504 

2505class SMB2_CREATE_REQUEST_LEASE_V2(Packet): 

2506 fields_desc = [ 

2507 SMB2_CREATE_RESPONSE_LEASE_V2, 

2508 ] 

2509 

2510 

2511class SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2(Packet): 

2512 fields_desc = [ 

2513 SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2, 

2514 XStrFixedLenField("Reserved", b"", length=8), 

2515 UUIDField("CreateGuid", 0x0, uuid_fmt=UUIDField.FORMAT_LE), 

2516 ] 

2517 

2518 

2519class SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2(Packet): 

2520 fields_desc = [ 

2521 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

2522 UUIDField("CreateGuid", 0x0, uuid_fmt=UUIDField.FORMAT_LE), 

2523 FlagsField( 

2524 "Flags", 

2525 0, 

2526 -32, 

2527 { 

2528 0x02: "SMB2_DHANDLE_FLAG_PERSISTENT", 

2529 }, 

2530 ), 

2531 ] 

2532 

2533 

2534class SMB2_CREATE_APP_INSTANCE_ID(Packet): 

2535 fields_desc = [ 

2536 XLEShortField("StructureSize", 0x14), 

2537 LEShortField("Reserved", 0), 

2538 XStrFixedLenField("AppInstanceId", b"", length=16), 

2539 ] 

2540 

2541 

2542class SMB2_CREATE_APP_INSTANCE_VERSION(Packet): 

2543 fields_desc = [ 

2544 XLEShortField("StructureSize", 0x18), 

2545 LEShortField("Reserved", 0), 

2546 LEIntField("Padding", 0), 

2547 LELongField("AppInstanceVersionHigh", 0), 

2548 LELongField("AppInstanceVersionLow", 0), 

2549 ] 

2550 

2551 

2552class SMB2_Create_Context(_NTLMPayloadPacket): 

2553 name = "SMB2 CREATE CONTEXT" 

2554 OFFSET = 16 

2555 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2556 fields_desc = [ 

2557 LEIntField("Next", None), 

2558 XLEShortField("NameBufferOffset", None), 

2559 LEShortField("NameLen", None), 

2560 ShortField("Reserved", 0), 

2561 XLEShortField("DataBufferOffset", None), 

2562 LEIntField("DataLen", None), 

2563 _NTLMPayloadField( 

2564 "Buffer", 

2565 OFFSET, 

2566 [ 

2567 PadField( 

2568 StrLenField("Name", b"", length_from=lambda pkt: pkt.NameLen), 

2569 8, 

2570 ), 

2571 # Must be padded on 8-octet alignment 

2572 PacketLenField( 

2573 "Data", None, conf.raw_layer, length_from=lambda pkt: pkt.DataLen 

2574 ), 

2575 ], 

2576 force_order=["Name", "Data"], 

2577 ), 

2578 StrLenField( 

2579 "pad", 

2580 b"", 

2581 length_from=lambda x: ( 

2582 x.Next 

2583 - max(x.DataBufferOffset + x.DataLen, x.NameBufferOffset + x.NameLen) 

2584 ) 

2585 if x.Next 

2586 else 0, 

2587 ), 

2588 ] 

2589 

2590 def post_dissect(self, s): 

2591 if not self.DataLen: 

2592 return s 

2593 try: 

2594 if isinstance(self.parent, SMB2_Create_Request): 

2595 data_cls = { 

2596 b"DHnQ": SMB2_CREATE_DURABLE_HANDLE_REQUEST, 

2597 b"DHnC": SMB2_CREATE_DURABLE_HANDLE_RECONNECT, 

2598 b"AISi": SMB2_CREATE_ALLOCATION_SIZE, 

2599 b"MxAc": SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 

2600 b"TWrp": SMB2_CREATE_TIMEWARP_TOKEN, 

2601 b"QFid": SMB2_CREATE_QUERY_ON_DISK_ID, 

2602 b"RqLs": SMB2_CREATE_REQUEST_LEASE, 

2603 b"DH2Q": SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, 

2604 b"DH2C": SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2, 

2605 # 3.1.1 only 

2606 b"E\xbc\xa6j\xef\xa7\xf7J\x90\x08\xfaF.\x14Mt": SMB2_CREATE_APP_INSTANCE_ID, # noqa: E501 

2607 b"\xb9\x82\xd0\xb7;V\x07O\xa0{RJ\x81\x16\xa0\x10": SMB2_CREATE_APP_INSTANCE_VERSION, # noqa: E501 

2608 }[self.Name] 

2609 if self.Name == b"RqLs" and self.DataLen > 32: 

2610 data_cls = SMB2_CREATE_REQUEST_LEASE_V2 

2611 elif isinstance(self.parent, SMB2_Create_Response): 

2612 data_cls = { 

2613 b"DHnQ": SMB2_CREATE_DURABLE_HANDLE_RESPONSE, 

2614 b"MxAc": SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE, 

2615 b"QFid": SMB2_CREATE_QUERY_ON_DISK_ID, 

2616 b"RqLs": SMB2_CREATE_RESPONSE_LEASE, 

2617 b"DH2Q": SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2, 

2618 }[self.Name] 

2619 if self.Name == b"RqLs" and self.DataLen > 32: 

2620 data_cls = SMB2_CREATE_RESPONSE_LEASE_V2 

2621 else: 

2622 return s 

2623 except KeyError: 

2624 return s 

2625 self.Data = data_cls(self.Data.load) 

2626 return s 

2627 

2628 def default_payload_class(self, _): 

2629 return conf.padding_layer 

2630 

2631 def post_build(self, pkt, pay): 

2632 # type: (bytes, bytes) -> bytes 

2633 return ( 

2634 _NTLM_post_build( 

2635 self, 

2636 pkt, 

2637 self.OFFSET, 

2638 { 

2639 "Name": 4, 

2640 "Data": 10, 

2641 }, 

2642 config=[ 

2643 ( 

2644 "BufferOffset", 

2645 { 

2646 "Name": _NTLM_ENUM.OFFSET, 

2647 "Data": _NTLM_ENUM.OFFSET | _NTLM_ENUM.PAD8, 

2648 }, 

2649 ), 

2650 ("Len", _NTLM_ENUM.LEN), 

2651 ], 

2652 ) 

2653 + pay 

2654 ) 

2655 

2656 

2657# sect 2.2.13 

2658 

2659SMB2_OPLOCK_LEVELS = { 

2660 0x00: "SMB2_OPLOCK_LEVEL_NONE", 

2661 0x01: "SMB2_OPLOCK_LEVEL_II", 

2662 0x08: "SMB2_OPLOCK_LEVEL_EXCLUSIVE", 

2663 0x09: "SMB2_OPLOCK_LEVEL_BATCH", 

2664 0xFF: "SMB2_OPLOCK_LEVEL_LEASE", 

2665} 

2666 

2667 

2668class SMB2_Create_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2669 name = "SMB2 CREATE Request" 

2670 Command = 0x0005 

2671 OFFSET = 56 + 64 

2672 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2673 fields_desc = [ 

2674 XLEShortField("StructureSize", 0x39), 

2675 ByteField("ShareType", 0), 

2676 ByteEnumField("RequestedOplockLevel", 0, SMB2_OPLOCK_LEVELS), 

2677 LEIntEnumField( 

2678 "ImpersonationLevel", 

2679 0, 

2680 { 

2681 0x00000000: "Anonymous", 

2682 0x00000001: "Identification", 

2683 0x00000002: "Impersonation", 

2684 0x00000003: "Delegate", 

2685 }, 

2686 ), 

2687 LELongField("SmbCreateFlags", 0), 

2688 LELongField("Reserved", 0), 

2689 FlagsField("DesiredAccess", 0, -32, SMB2_ACCESS_FLAGS_FILE), 

2690 FlagsField("FileAttributes", 0x00000080, -32, FileAttributes), 

2691 FlagsField( 

2692 "ShareAccess", 

2693 0, 

2694 -32, 

2695 { 

2696 0x00000001: "FILE_SHARE_READ", 

2697 0x00000002: "FILE_SHARE_WRITE", 

2698 0x00000004: "FILE_SHARE_DELETE", 

2699 }, 

2700 ), 

2701 LEIntEnumField( 

2702 "CreateDisposition", 

2703 1, 

2704 { 

2705 0x00000000: "FILE_SUPERSEDE", 

2706 0x00000001: "FILE_OPEN", 

2707 0x00000002: "FILE_CREATE", 

2708 0x00000003: "FILE_OPEN_IF", 

2709 0x00000004: "FILE_OVERWRITE", 

2710 0x00000005: "FILE_OVERWRITE_IF", 

2711 }, 

2712 ), 

2713 FlagsField( 

2714 "CreateOptions", 

2715 0, 

2716 -32, 

2717 { 

2718 0x00000001: "FILE_DIRECTORY_FILE", 

2719 0x00000002: "FILE_WRITE_THROUGH", 

2720 0x00000004: "FILE_SEQUENTIAL_ONLY", 

2721 0x00000008: "FILE_NO_INTERMEDIATE_BUFFERING", 

2722 0x00000010: "FILE_SYNCHRONOUS_IO_ALERT", 

2723 0x00000020: "FILE_SYNCHRONOUS_IO_NONALERT", 

2724 0x00000040: "FILE_NON_DIRECTORY_FILE", 

2725 0x00000100: "FILE_COMPLETE_IF_OPLOCKED", 

2726 0x00000200: "FILE_RANDOM_ACCESS", 

2727 0x00001000: "FILE_DELETE_ON_CLOSE", 

2728 0x00002000: "FILE_OPEN_BY_FILE_ID", 

2729 0x00004000: "FILE_OPEN_FOR_BACKUP_INTENT", 

2730 0x00008000: "FILE_NO_COMPRESSION", 

2731 0x00000400: "FILE_OPEN_REMOTE_INSTANCE", 

2732 0x00010000: "FILE_OPEN_REQUIRING_OPLOCK", 

2733 0x00020000: "FILE_DISALLOW_EXCLUSIVE", 

2734 0x00100000: "FILE_RESERVE_OPFILTER", 

2735 0x00200000: "FILE_OPEN_REPARSE_POINT", 

2736 0x00400000: "FILE_OPEN_NO_RECALL", 

2737 0x00800000: "FILE_OPEN_FOR_FREE_SPACE_QUERY", 

2738 }, 

2739 ), 

2740 XLEShortField("NameBufferOffset", None), 

2741 LEShortField("NameLen", None), 

2742 XLEIntField("CreateContextsBufferOffset", None), 

2743 LEIntField("CreateContextsLen", None), 

2744 _NTLMPayloadField( 

2745 "Buffer", 

2746 OFFSET, 

2747 [ 

2748 StrFieldUtf16("Name", b""), 

2749 _NextPacketListField( 

2750 "CreateContexts", 

2751 [], 

2752 SMB2_Create_Context, 

2753 length_from=lambda pkt: pkt.CreateContextsLen, 

2754 ), 

2755 ], 

2756 ), 

2757 ] 

2758 

2759 def post_build(self, pkt, pay): 

2760 # type: (bytes, bytes) -> bytes 

2761 if len(pkt) == 0x38: 

2762 # 'In the request, the Buffer field MUST be at least one byte in length.' 

2763 pkt += b"\x00" 

2764 return ( 

2765 _SMB2_post_build( 

2766 self, 

2767 pkt, 

2768 self.OFFSET, 

2769 { 

2770 "Name": 44, 

2771 "CreateContexts": 48, 

2772 }, 

2773 ) 

2774 + pay 

2775 ) 

2776 

2777 

2778bind_top_down(SMB2_Header, SMB2_Create_Request, Command=0x0005) 

2779 

2780 

2781# sect 2.2.14 

2782 

2783 

2784class SMB2_Create_Response(_SMB2_Payload, _NTLMPayloadPacket): 

2785 name = "SMB2 CREATE Response" 

2786 Command = 0x0005 

2787 OFFSET = 88 + 64 

2788 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2789 fields_desc = [ 

2790 XLEShortField("StructureSize", 0x59), 

2791 ByteEnumField("OplockLevel", 0, SMB2_OPLOCK_LEVELS), 

2792 FlagsField("Flags", 0, -8, {0x01: "SMB2_CREATE_FLAG_REPARSEPOINT"}), 

2793 LEIntEnumField( 

2794 "CreateAction", 

2795 1, 

2796 { 

2797 0x00000000: "FILE_SUPERSEDED", 

2798 0x00000001: "FILE_OPENED", 

2799 0x00000002: "FILE_CREATED", 

2800 0x00000003: "FILE_OVERWRITEN", 

2801 }, 

2802 ), 

2803 FileNetworkOpenInformation, 

2804 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

2805 XLEIntField("CreateContextsBufferOffset", None), 

2806 LEIntField("CreateContextsLen", None), 

2807 _NTLMPayloadField( 

2808 "Buffer", 

2809 OFFSET, 

2810 [ 

2811 _NextPacketListField( 

2812 "CreateContexts", 

2813 [], 

2814 SMB2_Create_Context, 

2815 length_from=lambda pkt: pkt.CreateContextsLen, 

2816 ), 

2817 ], 

2818 ), 

2819 ] 

2820 

2821 def post_build(self, pkt, pay): 

2822 # type: (bytes, bytes) -> bytes 

2823 return ( 

2824 _SMB2_post_build( 

2825 self, 

2826 pkt, 

2827 self.OFFSET, 

2828 { 

2829 "CreateContexts": 80, 

2830 }, 

2831 ) 

2832 + pay 

2833 ) 

2834 

2835 

2836bind_top_down(SMB2_Header, SMB2_Create_Response, Command=0x0005, Flags=1) 

2837 

2838# sect 2.2.15 

2839 

2840 

2841class SMB2_Close_Request(_SMB2_Payload): 

2842 name = "SMB2 CLOSE Request" 

2843 Command = 0x0006 

2844 fields_desc = [ 

2845 XLEShortField("StructureSize", 0x18), 

2846 FlagsField("Flags", 0, -16, ["SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB"]), 

2847 LEIntField("Reserved", 0), 

2848 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

2849 ] 

2850 

2851 

2852bind_top_down( 

2853 SMB2_Header, 

2854 SMB2_Close_Request, 

2855 Command=0x0006, 

2856) 

2857 

2858# sect 2.2.16 

2859 

2860 

2861class SMB2_Close_Response(_SMB2_Payload): 

2862 name = "SMB2 CLOSE Response" 

2863 Command = 0x0006 

2864 FileAttributes = 0 

2865 CreationTime = 0 

2866 LastAccessTime = 0 

2867 LastWriteTime = 0 

2868 ChangeTime = 0 

2869 fields_desc = [ 

2870 XLEShortField("StructureSize", 0x3C), 

2871 FlagsField("Flags", 0, -16, ["SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB"]), 

2872 LEIntField("Reserved", 0), 

2873 ] + FileNetworkOpenInformation.fields_desc[:7] 

2874 

2875 

2876bind_top_down( 

2877 SMB2_Header, 

2878 SMB2_Close_Response, 

2879 Command=0x0006, 

2880 Flags=1, 

2881) 

2882 

2883# sect 2.2.19 

2884 

2885 

2886class SMB2_Read_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2887 name = "SMB2 READ Request" 

2888 Command = 0x0008 

2889 OFFSET = 48 + 64 

2890 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2891 fields_desc = [ 

2892 XLEShortField("StructureSize", 0x31), 

2893 ByteField("Padding", 0x00), 

2894 FlagsField( 

2895 "Flags", 

2896 0, 

2897 -8, 

2898 { 

2899 0x01: "SMB2_READFLAG_READ_UNBUFFERED", 

2900 0x02: "SMB2_READFLAG_REQUEST_COMPRESSED", 

2901 }, 

2902 ), 

2903 LEIntField("Length", 4280), 

2904 LELongField("Offset", 0), 

2905 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

2906 LEIntField("MinimumCount", 0), 

2907 LEIntEnumField( 

2908 "Channel", 

2909 0, 

2910 { 

2911 0x00000000: "SMB2_CHANNEL_NONE", 

2912 0x00000001: "SMB2_CHANNEL_RDMA_V1", 

2913 0x00000002: "SMB2_CHANNEL_RDMA_V1_INVALIDATE", 

2914 0x00000003: "SMB2_CHANNEL_RDMA_TRANSFORM", 

2915 }, 

2916 ), 

2917 LEIntField("RemainingBytes", 0), 

2918 LEShortField("ReadChannelInfoBufferOffset", None), 

2919 LEShortField("ReadChannelInfoLen", None), 

2920 _NTLMPayloadField( 

2921 "Buffer", 

2922 OFFSET, 

2923 [ 

2924 StrLenField( 

2925 "ReadChannelInfo", 

2926 b"", 

2927 length_from=lambda pkt: pkt.ReadChannelInfoLen, 

2928 ) 

2929 ], 

2930 ), 

2931 ] 

2932 

2933 def post_build(self, pkt, pay): 

2934 # type: (bytes, bytes) -> bytes 

2935 if len(pkt) == 0x30: 

2936 # 'The first byte of the Buffer field MUST be set to 0.' 

2937 pkt += b"\x00" 

2938 return ( 

2939 _SMB2_post_build( 

2940 self, 

2941 pkt, 

2942 self.OFFSET, 

2943 { 

2944 "ReadChannelInfo": 44, 

2945 }, 

2946 ) 

2947 + pay 

2948 ) 

2949 

2950 

2951bind_top_down( 

2952 SMB2_Header, 

2953 SMB2_Read_Request, 

2954 Command=0x0008, 

2955) 

2956 

2957# sect 2.2.20 

2958 

2959 

2960class SMB2_Read_Response(_SMB2_Payload, _NTLMPayloadPacket): 

2961 name = "SMB2 READ Response" 

2962 Command = 0x0008 

2963 OFFSET = 16 + 64 

2964 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2965 fields_desc = [ 

2966 XLEShortField("StructureSize", 0x11), 

2967 LEShortField("DataBufferOffset", None), 

2968 LEIntField("DataLen", None), 

2969 LEIntField("DataRemaining", 0), 

2970 FlagsField( 

2971 "Flags", 

2972 0, 

2973 -32, 

2974 { 

2975 0x01: "SMB2_READFLAG_RESPONSE_RDMA_TRANSFORM", 

2976 }, 

2977 ), 

2978 _NTLMPayloadField( 

2979 "Buffer", 

2980 OFFSET, 

2981 [StrLenField("Data", b"", length_from=lambda pkt: pkt.DataLen)], 

2982 ), 

2983 ] 

2984 

2985 def post_build(self, pkt, pay): 

2986 # type: (bytes, bytes) -> bytes 

2987 return ( 

2988 _SMB2_post_build( 

2989 self, 

2990 pkt, 

2991 self.OFFSET, 

2992 { 

2993 "Data": 2, 

2994 }, 

2995 ) 

2996 + pay 

2997 ) 

2998 

2999 

3000bind_top_down( 

3001 SMB2_Header, 

3002 SMB2_Read_Response, 

3003 Command=0x0008, 

3004 Flags=1, 

3005) 

3006 

3007 

3008# sect 2.2.21 

3009 

3010 

3011class SMB2_Write_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3012 name = "SMB2 WRITE Request" 

3013 Command = 0x0009 

3014 OFFSET = 48 + 64 

3015 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3016 fields_desc = [ 

3017 XLEShortField("StructureSize", 0x31), 

3018 LEShortField("DataBufferOffset", None), 

3019 LEIntField("DataLen", None), 

3020 LELongField("Offset", 0), 

3021 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3022 LEIntEnumField( 

3023 "Channel", 

3024 0, 

3025 { 

3026 0x00000000: "SMB2_CHANNEL_NONE", 

3027 0x00000001: "SMB2_CHANNEL_RDMA_V1", 

3028 0x00000002: "SMB2_CHANNEL_RDMA_V1_INVALIDATE", 

3029 0x00000003: "SMB2_CHANNEL_RDMA_TRANSFORM", 

3030 }, 

3031 ), 

3032 LEIntField("RemainingBytes", 0), 

3033 LEShortField("WriteChannelInfoBufferOffset", None), 

3034 LEShortField("WriteChannelInfoLen", None), 

3035 FlagsField( 

3036 "Flags", 

3037 0, 

3038 -32, 

3039 { 

3040 0x00000001: "SMB2_WRITEFLAG_WRITE_THROUGH", 

3041 0x00000002: "SMB2_WRITEFLAG_WRITE_UNBUFFERED", 

3042 }, 

3043 ), 

3044 _NTLMPayloadField( 

3045 "Buffer", 

3046 OFFSET, 

3047 [ 

3048 StrLenField("Data", b"", length_from=lambda pkt: pkt.DataLen), 

3049 StrLenField( 

3050 "WriteChannelInfo", 

3051 b"", 

3052 length_from=lambda pkt: pkt.WriteChannelInfoLen, 

3053 ), 

3054 ], 

3055 ), 

3056 ] 

3057 

3058 def post_build(self, pkt, pay): 

3059 # type: (bytes, bytes) -> bytes 

3060 return ( 

3061 _SMB2_post_build( 

3062 self, 

3063 pkt, 

3064 self.OFFSET, 

3065 { 

3066 "Data": 2, 

3067 "WriteChannelInfo": 40, 

3068 }, 

3069 ) 

3070 + pay 

3071 ) 

3072 

3073 

3074bind_top_down( 

3075 SMB2_Header, 

3076 SMB2_Write_Request, 

3077 Command=0x0009, 

3078) 

3079 

3080# sect 2.2.22 

3081 

3082 

3083class SMB2_Write_Response(_SMB2_Payload): 

3084 name = "SMB2 WRITE Response" 

3085 Command = 0x0009 

3086 fields_desc = [ 

3087 XLEShortField("StructureSize", 0x11), 

3088 LEShortField("Reserved", 0), 

3089 LEIntField("Count", 0), 

3090 LEIntField("Remaining", 0), 

3091 LEShortField("WriteChannelInfoBufferOffset", 0), 

3092 LEShortField("WriteChannelInfoLen", 0), 

3093 ] 

3094 

3095 

3096bind_top_down(SMB2_Header, SMB2_Write_Response, Command=0x0009, Flags=1) 

3097 

3098# sect 2.2.28 

3099 

3100 

3101class SMB2_Echo_Request(_SMB2_Payload): 

3102 name = "SMB2 ECHO Request" 

3103 Command = 0x000D 

3104 fields_desc = [ 

3105 XLEShortField("StructureSize", 0x4), 

3106 LEShortField("Reserved", 0), 

3107 ] 

3108 

3109 

3110bind_top_down( 

3111 SMB2_Header, 

3112 SMB2_Echo_Request, 

3113 Command=0x000D, 

3114) 

3115 

3116# sect 2.2.29 

3117 

3118 

3119class SMB2_Echo_Response(_SMB2_Payload): 

3120 name = "SMB2 ECHO Response" 

3121 Command = 0x000D 

3122 fields_desc = [ 

3123 XLEShortField("StructureSize", 0x4), 

3124 LEShortField("Reserved", 0), 

3125 ] 

3126 

3127 

3128bind_top_down( 

3129 SMB2_Header, 

3130 SMB2_Echo_Response, 

3131 Command=0x000D, 

3132 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

3133) 

3134 

3135# sect 2.2.30 

3136 

3137 

3138class SMB2_Cancel_Request(_SMB2_Payload): 

3139 name = "SMB2 CANCEL Request" 

3140 fields_desc = [ 

3141 XLEShortField("StructureSize", 0x4), 

3142 LEShortField("Reserved", 0), 

3143 ] 

3144 

3145 

3146bind_top_down( 

3147 SMB2_Header, 

3148 SMB2_Cancel_Request, 

3149 Command=0x0009, 

3150) 

3151 

3152# sect 2.2.31.4 

3153 

3154 

3155class SMB2_IOCTL_Validate_Negotiate_Info_Request(Packet): 

3156 name = "SMB2 IOCTL Validate Negotiate Info" 

3157 fields_desc = ( 

3158 SMB2_Negotiate_Protocol_Request.fields_desc[4:6] 

3159 + SMB2_Negotiate_Protocol_Request.fields_desc[1:3][::-1] # Cap/GUID 

3160 + [SMB2_Negotiate_Protocol_Request.fields_desc[9]] # SecMod/DC # Dialects 

3161 ) 

3162 

3163 

3164# sect 2.2.31 

3165 

3166 

3167class _SMB2_IOCTL_Request_PacketLenField(PacketLenField): 

3168 def m2i(self, pkt, m): 

3169 if pkt.CtlCode == 0x00140204: # FSCTL_VALIDATE_NEGOTIATE_INFO 

3170 return SMB2_IOCTL_Validate_Negotiate_Info_Request(m) 

3171 elif pkt.CtlCode == 0x00060194: # FSCTL_DFS_GET_REFERRALS 

3172 return SMB2_IOCTL_REQ_GET_DFS_Referral(m) 

3173 elif pkt.CtlCode == 0x00094264: # FSCTL_OFFLOAD_READ 

3174 return SMB2_IOCTL_OFFLOAD_READ_Request(m) 

3175 return conf.raw_layer(m) 

3176 

3177 

3178class SMB2_IOCTL_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3179 name = "SMB2 IOCTL Request" 

3180 Command = 0x000B 

3181 OFFSET = 56 + 64 

3182 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3183 deprecated_fields = { 

3184 "IntputCount": ("InputLen", "alias"), 

3185 "OutputCount": ("OutputLen", "alias"), 

3186 } 

3187 fields_desc = [ 

3188 XLEShortField("StructureSize", 0x39), 

3189 LEShortField("Reserved", 0), 

3190 LEIntEnumField( 

3191 "CtlCode", 

3192 0, 

3193 { 

3194 0x00060194: "FSCTL_DFS_GET_REFERRALS", 

3195 0x0011400C: "FSCTL_PIPE_PEEK", 

3196 0x00110018: "FSCTL_PIPE_WAIT", 

3197 0x0011C017: "FSCTL_PIPE_TRANSCEIVE", 

3198 0x001440F2: "FSCTL_SRV_COPYCHUNK", 

3199 0x00144064: "FSCTL_SRV_ENUMERATE_SNAPSHOTS", 

3200 0x00140078: "FSCTL_SRV_REQUEST_RESUME_KEY", 

3201 0x001441BB: "FSCTL_SRV_READ_HASH", 

3202 0x001480F2: "FSCTL_SRV_COPYCHUNK_WRITE", 

3203 0x001401D4: "FSCTL_LMR_REQUEST_RESILIENCY", 

3204 0x001401FC: "FSCTL_QUERY_NETWORK_INTERFACE_INFO", 

3205 0x000900A4: "FSCTL_SET_REPARSE_POINT", 

3206 0x000601B0: "FSCTL_DFS_GET_REFERRALS_EX", 

3207 0x00098208: "FSCTL_FILE_LEVEL_TRIM", 

3208 0x00140204: "FSCTL_VALIDATE_NEGOTIATE_INFO", 

3209 0x00094264: "FSCTL_OFFLOAD_READ", 

3210 }, 

3211 ), 

3212 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3213 LEIntField("InputBufferOffset", None), 

3214 LEIntField("InputLen", None), # Called InputCount but it's a length 

3215 LEIntField("MaxInputResponse", 0), 

3216 LEIntField("OutputBufferOffset", None), 

3217 LEIntField("OutputLen", None), # Called OutputCount. 

3218 LEIntField("MaxOutputResponse", 1024), 

3219 FlagsField("Flags", 0, -32, {0x00000001: "SMB2_0_IOCTL_IS_FSCTL"}), 

3220 LEIntField("Reserved2", 0), 

3221 _NTLMPayloadField( 

3222 "Buffer", 

3223 OFFSET, 

3224 [ 

3225 _SMB2_IOCTL_Request_PacketLenField( 

3226 "Input", None, conf.raw_layer, length_from=lambda pkt: pkt.InputLen 

3227 ), 

3228 _SMB2_IOCTL_Request_PacketLenField( 

3229 "Output", 

3230 None, 

3231 conf.raw_layer, 

3232 length_from=lambda pkt: pkt.OutputLen, 

3233 ), 

3234 ], 

3235 ), 

3236 ] 

3237 

3238 def post_build(self, pkt, pay): 

3239 # type: (bytes, bytes) -> bytes 

3240 return ( 

3241 _SMB2_post_build( 

3242 self, 

3243 pkt, 

3244 self.OFFSET, 

3245 { 

3246 "Input": 24, 

3247 "Output": 36, 

3248 }, 

3249 ) 

3250 + pay 

3251 ) 

3252 

3253 

3254bind_top_down( 

3255 SMB2_Header, 

3256 SMB2_IOCTL_Request, 

3257 Command=0x000B, 

3258) 

3259 

3260# sect 2.2.32.5 

3261 

3262 

3263class SOCKADDR_STORAGE(Packet): 

3264 fields_desc = [ 

3265 LEShortEnumField("Family", 0x0002, {0x0002: "IPv4", 0x0017: "IPv6"}), 

3266 ShortField("Port", 0), 

3267 # IPv4 

3268 ConditionalField( 

3269 IPField("IPv4Adddress", None), 

3270 lambda pkt: pkt.Family == 0x0002, 

3271 ), 

3272 ConditionalField( 

3273 StrFixedLenField("Reserved", b"", length=8), 

3274 lambda pkt: pkt.Family == 0x0002, 

3275 ), 

3276 # IPv6 

3277 ConditionalField( 

3278 LEIntField("FlowInfo", 0), 

3279 lambda pkt: pkt.Family == 0x00017, 

3280 ), 

3281 ConditionalField( 

3282 IP6Field("IPv6Address", None), 

3283 lambda pkt: pkt.Family == 0x00017, 

3284 ), 

3285 ConditionalField( 

3286 LEIntField("ScopeId", 0), 

3287 lambda pkt: pkt.Family == 0x00017, 

3288 ), 

3289 ] 

3290 

3291 def default_payload_class(self, _): 

3292 return conf.padding_layer 

3293 

3294 

3295class NETWORK_INTERFACE_INFO(Packet): 

3296 fields_desc = [ 

3297 LEIntField("Next", None), # 0 = no next entry 

3298 LEIntField("IfIndex", 1), 

3299 FlagsField( 

3300 "Capability", 

3301 1, 

3302 -32, 

3303 { 

3304 0x00000001: "RSS_CAPABLE", 

3305 0x00000002: "RDMA_CAPABLE", 

3306 }, 

3307 ), 

3308 LEIntField("Reserved", 0), 

3309 ScalingField("LinkSpeed", 10000000000, fmt="<Q", unit="bit/s"), 

3310 PacketField("SockAddr_Storage", SOCKADDR_STORAGE(), SOCKADDR_STORAGE), 

3311 ] 

3312 

3313 def default_payload_class(self, _): 

3314 return conf.padding_layer 

3315 

3316 

3317class SMB2_IOCTL_Network_Interface_Info(Packet): 

3318 name = "SMB2 IOCTL Network Interface Info response" 

3319 fields_desc = [ 

3320 _NextPacketListField("interfaces", [], NETWORK_INTERFACE_INFO), 

3321 ] 

3322 

3323 

3324# sect 2.2.32.6 

3325 

3326 

3327class SMB2_IOCTL_Validate_Negotiate_Info_Response(Packet): 

3328 name = "SMB2 IOCTL Validate Negotiate Info" 

3329 fields_desc = ( 

3330 SMB2_Negotiate_Protocol_Response.fields_desc[4:6][::-1] 

3331 + SMB2_Negotiate_Protocol_Response.fields_desc[ # Cap/GUID 

3332 1:3 

3333 ] # SecMod/DialectRevision 

3334 ) 

3335 

3336 

3337# [MS-FSCC] sect 2.3.42 

3338 

3339 

3340class SMB2_IOCTL_OFFLOAD_READ_Request(Packet): 

3341 name = "SMB2 IOCTL OFFLOAD_READ Request" 

3342 fields_desc = [ 

3343 LEIntField("StructureSize", 0x20), 

3344 LEIntField("Flags", 0), 

3345 LEIntField("TokenTimeToLive", 0), 

3346 LEIntField("Reserved", 0), 

3347 LELongField("FileOffset", 0), 

3348 LELongField("CopyLength", 0), 

3349 ] 

3350 

3351 

3352# [MS-FSCC] sect 2.1.11 

3353 

3354 

3355class STORAGE_OFFLOAD_TOKEN(Packet): 

3356 fields_desc = [ 

3357 LEIntEnumField( 

3358 "TokenType", 

3359 0xFFFF0001, 

3360 { 

3361 0xFFFF0001: "STORAGE_OFFLOAD_TOKEN_TYPE_ZERO_DATA", 

3362 }, 

3363 ), 

3364 LEShortField("Reserved", 0), 

3365 FieldLenField("TokenIdLength", None, fmt="<H", length_of="TokenId"), 

3366 StrFixedLenField("TokenId", b"", length=504), 

3367 ] 

3368 

3369 

3370# [MS-FSCC] sect 2.3.42 

3371 

3372 

3373class SMB2_IOCTL_OFFLOAD_READ_Response(Packet): 

3374 name = "SMB2 IOCTL OFFLOAD_READ Response" 

3375 fields_desc = [ 

3376 LEIntField("StructureSize", 0x210), 

3377 FlagsField( 

3378 "Flags", 

3379 0, 

3380 -32, 

3381 { 

3382 0x00000001: "OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE", 

3383 }, 

3384 ), 

3385 LELongField("TransferLength", 0), 

3386 PacketField("Token", STORAGE_OFFLOAD_TOKEN(), STORAGE_OFFLOAD_TOKEN), 

3387 ] 

3388 

3389 

3390# sect 2.2.32 

3391 

3392 

3393class _SMB2_IOCTL_Response_PacketLenField(PacketLenField): 

3394 def m2i(self, pkt, m): 

3395 if pkt.CtlCode == 0x00140204: # FSCTL_VALIDATE_NEGOTIATE_INFO 

3396 return SMB2_IOCTL_Validate_Negotiate_Info_Response(m) 

3397 elif pkt.CtlCode == 0x001401FC: # FSCTL_QUERY_NETWORK_INTERFACE_INFO 

3398 return SMB2_IOCTL_Network_Interface_Info(m) 

3399 elif pkt.CtlCode == 0x00060194: # FSCTL_DFS_GET_REFERRALS 

3400 return SMB2_IOCTL_RESP_GET_DFS_Referral(m) 

3401 return conf.raw_layer(m) 

3402 

3403 

3404class SMB2_IOCTL_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3405 name = "SMB2 IOCTL Response" 

3406 Command = 0x000B 

3407 OFFSET = 48 + 64 

3408 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3409 StructureSize = 0x31 

3410 MaxOutputResponse = 0 

3411 fields_desc = ( 

3412 SMB2_IOCTL_Request.fields_desc[:6] 

3413 + SMB2_IOCTL_Request.fields_desc[7:9] 

3414 + SMB2_IOCTL_Request.fields_desc[10:12] 

3415 + [ 

3416 _NTLMPayloadField( 

3417 "Buffer", 

3418 OFFSET, 

3419 [ 

3420 _SMB2_IOCTL_Response_PacketLenField( 

3421 "Input", 

3422 None, 

3423 conf.raw_layer, 

3424 length_from=lambda pkt: pkt.InputLen, 

3425 ), 

3426 _SMB2_IOCTL_Response_PacketLenField( 

3427 "Output", 

3428 None, 

3429 conf.raw_layer, 

3430 length_from=lambda pkt: pkt.OutputLen, 

3431 ), 

3432 ], 

3433 ), 

3434 ] 

3435 ) 

3436 

3437 def post_build(self, pkt, pay): 

3438 # type: (bytes, bytes) -> bytes 

3439 return ( 

3440 _SMB2_post_build( 

3441 self, 

3442 pkt, 

3443 self.OFFSET, 

3444 { 

3445 "Input": 24, 

3446 "Output": 32, 

3447 }, 

3448 ) 

3449 + pay 

3450 ) 

3451 

3452 

3453bind_top_down( 

3454 SMB2_Header, 

3455 SMB2_IOCTL_Response, 

3456 Command=0x000B, 

3457 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

3458) 

3459 

3460# sect 2.2.33 

3461 

3462 

3463class SMB2_Query_Directory_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3464 name = "SMB2 QUERY DIRECTORY Request" 

3465 Command = 0x000E 

3466 OFFSET = 32 + 64 

3467 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3468 fields_desc = [ 

3469 XLEShortField("StructureSize", 0x21), 

3470 ByteEnumField("FileInformationClass", 0x1, FileInformationClasses), 

3471 FlagsField( 

3472 "Flags", 

3473 0, 

3474 -8, 

3475 { 

3476 0x01: "SMB2_RESTART_SCANS", 

3477 0x02: "SMB2_RETURN_SINGLE_ENTRY", 

3478 0x04: "SMB2_INDEX_SPECIFIED", 

3479 0x10: "SMB2_REOPEN", 

3480 }, 

3481 ), 

3482 LEIntField("FileIndex", 0), 

3483 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3484 LEShortField("FileNameBufferOffset", None), 

3485 LEShortField("FileNameLen", None), 

3486 LEIntField("OutputBufferLength", 65535), 

3487 _NTLMPayloadField("Buffer", OFFSET, [StrFieldUtf16("FileName", b"")]), 

3488 ] 

3489 

3490 def post_build(self, pkt, pay): 

3491 # type: (bytes, bytes) -> bytes 

3492 return ( 

3493 _SMB2_post_build( 

3494 self, 

3495 pkt, 

3496 self.OFFSET, 

3497 { 

3498 "FileName": 24, 

3499 }, 

3500 ) 

3501 + pay 

3502 ) 

3503 

3504 

3505bind_top_down( 

3506 SMB2_Header, 

3507 SMB2_Query_Directory_Request, 

3508 Command=0x000E, 

3509) 

3510 

3511# sect 2.2.34 

3512 

3513 

3514class SMB2_Query_Directory_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3515 name = "SMB2 QUERY DIRECTORY Response" 

3516 Command = 0x000E 

3517 OFFSET = 8 + 64 

3518 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3519 fields_desc = [ 

3520 XLEShortField("StructureSize", 0x9), 

3521 LEShortField("OutputBufferOffset", None), 

3522 LEIntField("OutputLen", None), 

3523 _NTLMPayloadField( 

3524 "Buffer", 

3525 OFFSET, 

3526 [ 

3527 # TODO 

3528 StrFixedLenField("Output", b"", length_from=lambda pkt: pkt.OutputLen) 

3529 ], 

3530 ), 

3531 ] 

3532 

3533 def post_build(self, pkt, pay): 

3534 # type: (bytes, bytes) -> bytes 

3535 return ( 

3536 _SMB2_post_build( 

3537 self, 

3538 pkt, 

3539 self.OFFSET, 

3540 { 

3541 "Output": 2, 

3542 }, 

3543 ) 

3544 + pay 

3545 ) 

3546 

3547 

3548bind_top_down( 

3549 SMB2_Header, 

3550 SMB2_Query_Directory_Response, 

3551 Command=0x000E, 

3552 Flags=1, 

3553) 

3554 

3555# sect 2.2.35 

3556 

3557 

3558class SMB2_Change_Notify_Request(_SMB2_Payload): 

3559 name = "SMB2 CHANGE NOTIFY Request" 

3560 Command = 0x000F 

3561 fields_desc = [ 

3562 XLEShortField("StructureSize", 0x20), 

3563 FlagsField( 

3564 "Flags", 

3565 0, 

3566 -16, 

3567 { 

3568 0x0001: "SMB2_WATCH_TREE", 

3569 }, 

3570 ), 

3571 LEIntField("OutputBufferLength", 2048), 

3572 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3573 FlagsField( 

3574 "CompletionFilter", 

3575 0, 

3576 -32, 

3577 { 

3578 0x00000001: "FILE_NOTIFY_CHANGE_FILE_NAME", 

3579 0x00000002: "FILE_NOTIFY_CHANGE_DIR_NAME", 

3580 0x00000004: "FILE_NOTIFY_CHANGE_ATTRIBUTES", 

3581 0x00000008: "FILE_NOTIFY_CHANGE_SIZE", 

3582 0x00000010: "FILE_NOTIFY_CHANGE_LAST_WRITE", 

3583 0x00000020: "FILE_NOTIFY_CHANGE_LAST_ACCESS", 

3584 0x00000040: "FILE_NOTIFY_CHANGE_CREATION", 

3585 0x00000080: "FILE_NOTIFY_CHANGE_EA", 

3586 0x00000100: "FILE_NOTIFY_CHANGE_SECURITY", 

3587 0x00000200: "FILE_NOTIFY_CHANGE_STREAM_NAME", 

3588 0x00000400: "FILE_NOTIFY_CHANGE_STREAM_SIZE", 

3589 0x00000800: "FILE_NOTIFY_CHANGE_STREAM_WRITE", 

3590 }, 

3591 ), 

3592 LEIntField("Reserved", 0), 

3593 ] 

3594 

3595 

3596bind_top_down( 

3597 SMB2_Header, 

3598 SMB2_Change_Notify_Request, 

3599 Command=0x000F, 

3600) 

3601 

3602# sect 2.2.36 

3603 

3604 

3605class SMB2_Change_Notify_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3606 name = "SMB2 CHANGE NOTIFY Response" 

3607 Command = 0x000F 

3608 OFFSET = 8 + 64 

3609 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3610 fields_desc = [ 

3611 XLEShortField("StructureSize", 0x9), 

3612 LEShortField("OutputBufferOffset", None), 

3613 LEIntField("OutputLen", None), 

3614 _NTLMPayloadField( 

3615 "Buffer", 

3616 OFFSET, 

3617 [ 

3618 _NextPacketListField( 

3619 "Output", 

3620 [], 

3621 FILE_NOTIFY_INFORMATION, 

3622 length_from=lambda pkt: pkt.OutputLen, 

3623 max_count=1000, 

3624 ) 

3625 ], 

3626 ), 

3627 ] 

3628 

3629 def post_build(self, pkt, pay): 

3630 # type: (bytes, bytes) -> bytes 

3631 return ( 

3632 _SMB2_post_build( 

3633 self, 

3634 pkt, 

3635 self.OFFSET, 

3636 { 

3637 "Output": 2, 

3638 }, 

3639 ) 

3640 + pay 

3641 ) 

3642 

3643 

3644bind_top_down( 

3645 SMB2_Header, 

3646 SMB2_Change_Notify_Response, 

3647 Command=0x000F, 

3648 Flags=1, 

3649) 

3650 

3651# sect 2.2.37 

3652 

3653 

3654class FILE_GET_QUOTA_INFORMATION(Packet): 

3655 fields_desc = [ 

3656 IntField("NextEntryOffset", 0), 

3657 FieldLenField("SidLength", None, length_of="Sid"), 

3658 StrLenField("Sid", b"", length_from=lambda x: x.SidLength), 

3659 StrLenField( 

3660 "pad", 

3661 b"", 

3662 length_from=lambda x: ( 

3663 (x.NextEntryOffset - x.SidLength) if x.NextEntryOffset else 0 

3664 ), 

3665 ), 

3666 ] 

3667 

3668 

3669class SMB2_Query_Quota_Info(Packet): 

3670 fields_desc = [ 

3671 ByteField("ReturnSingle", 0), 

3672 ByteField("ReturnBoolean", 0), 

3673 ShortField("Reserved", 0), 

3674 LEIntField("SidListLength", 0), 

3675 LEIntField("StartSidLength", 0), 

3676 LEIntField("StartSidOffset", 0), 

3677 StrLenField("pad", b"", length_from=lambda x: x.StartSidOffset), 

3678 MultipleTypeField( 

3679 [ 

3680 ( 

3681 PacketListField( 

3682 "SidBuffer", 

3683 [], 

3684 FILE_GET_QUOTA_INFORMATION, 

3685 length_from=lambda x: x.SidListLength, 

3686 ), 

3687 lambda x: x.SidListLength, 

3688 ), 

3689 ( 

3690 StrLenField( 

3691 "SidBuffer", b"", length_from=lambda x: x.StartSidLength 

3692 ), 

3693 lambda x: x.StartSidLength, 

3694 ), 

3695 ], 

3696 StrFixedLenField("SidBuffer", b"", length=0), 

3697 ), 

3698 ] 

3699 

3700 

3701SMB2_INFO_TYPE = { 

3702 0x01: "SMB2_0_INFO_FILE", 

3703 0x02: "SMB2_0_INFO_FILESYSTEM", 

3704 0x03: "SMB2_0_INFO_SECURITY", 

3705 0x04: "SMB2_0_INFO_QUOTA", 

3706} 

3707 

3708SMB2_ADDITIONAL_INFORMATION = { 

3709 0x00000001: "OWNER_SECURITY_INFORMATION", 

3710 0x00000002: "GROUP_SECURITY_INFORMATION", 

3711 0x00000004: "DACL_SECURITY_INFORMATION", 

3712 0x00000008: "SACL_SECURITY_INFORMATION", 

3713 0x00000010: "LABEL_SECURITY_INFORMATION", 

3714 0x00000020: "ATTRIBUTE_SECURITY_INFORMATION", 

3715 0x00000040: "SCOPE_SECURITY_INFORMATION", 

3716 0x00010000: "BACKUP_SECURITY_INFORMATION", 

3717} 

3718 

3719 

3720class SMB2_Query_Info_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3721 name = "SMB2 QUERY INFO Request" 

3722 Command = 0x0010 

3723 OFFSET = 40 + 64 

3724 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3725 fields_desc = [ 

3726 XLEShortField("StructureSize", 0x29), 

3727 ByteEnumField( 

3728 "InfoType", 

3729 0, 

3730 SMB2_INFO_TYPE, 

3731 ), 

3732 ByteEnumField("FileInfoClass", 0, FileInformationClasses), 

3733 LEIntField("OutputBufferLength", 0), 

3734 XLEIntField("InputBufferOffset", None), # Short + Reserved = Int 

3735 LEIntField("InputLen", None), 

3736 FlagsField( 

3737 "AdditionalInformation", 

3738 0, 

3739 -32, 

3740 SMB2_ADDITIONAL_INFORMATION, 

3741 ), 

3742 FlagsField( 

3743 "Flags", 

3744 0, 

3745 -32, 

3746 { 

3747 0x00000001: "SL_RESTART_SCAN", 

3748 0x00000002: "SL_RETURN_SINGLE_ENTRY", 

3749 0x00000004: "SL_INDEX_SPECIFIED", 

3750 }, 

3751 ), 

3752 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3753 _NTLMPayloadField( 

3754 "Buffer", 

3755 OFFSET, 

3756 [ 

3757 MultipleTypeField( 

3758 [ 

3759 ( 

3760 # QUOTA 

3761 PacketListField( 

3762 "Input", 

3763 None, 

3764 SMB2_Query_Quota_Info, 

3765 length_from=lambda pkt: pkt.InputLen, 

3766 ), 

3767 lambda pkt: pkt.InfoType == 0x04, 

3768 ), 

3769 ], 

3770 StrLenField("Input", b"", length_from=lambda pkt: pkt.InputLen), 

3771 ), 

3772 ], 

3773 ), 

3774 ] 

3775 

3776 def post_build(self, pkt, pay): 

3777 # type: (bytes, bytes) -> bytes 

3778 return ( 

3779 _SMB2_post_build( 

3780 self, 

3781 pkt, 

3782 self.OFFSET, 

3783 { 

3784 "Input": 4, 

3785 }, 

3786 ) 

3787 + pay 

3788 ) 

3789 

3790 

3791bind_top_down( 

3792 SMB2_Header, 

3793 SMB2_Query_Info_Request, 

3794 Command=0x00010, 

3795) 

3796 

3797 

3798class SMB2_Query_Info_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3799 name = "SMB2 QUERY INFO Response" 

3800 Command = 0x0010 

3801 OFFSET = 8 + 64 

3802 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3803 fields_desc = [ 

3804 XLEShortField("StructureSize", 0x9), 

3805 LEShortField("OutputBufferOffset", None), 

3806 LEIntField("OutputLen", None), 

3807 _NTLMPayloadField( 

3808 "Buffer", 

3809 OFFSET, 

3810 [ 

3811 # TODO 

3812 StrFixedLenField("Output", b"", length_from=lambda pkt: pkt.OutputLen) 

3813 ], 

3814 ), 

3815 ] 

3816 

3817 def post_build(self, pkt, pay): 

3818 # type: (bytes, bytes) -> bytes 

3819 return ( 

3820 _SMB2_post_build( 

3821 self, 

3822 pkt, 

3823 self.OFFSET, 

3824 { 

3825 "Output": 2, 

3826 }, 

3827 ) 

3828 + pay 

3829 ) 

3830 

3831 

3832bind_top_down( 

3833 SMB2_Header, 

3834 SMB2_Query_Info_Response, 

3835 Command=0x00010, 

3836 Flags=1, 

3837) 

3838 

3839 

3840# sect 2.2.39 

3841 

3842 

3843class SMB2_Set_Info_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3844 name = "SMB2 SET INFO Request" 

3845 Command = 0x0011 

3846 OFFSET = 32 + 64 

3847 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3848 fields_desc = [ 

3849 XLEShortField("StructureSize", 0x21), 

3850 ByteEnumField( 

3851 "InfoType", 

3852 0, 

3853 SMB2_INFO_TYPE, 

3854 ), 

3855 ByteEnumField("FileInfoClass", 0, FileInformationClasses), 

3856 LEIntField("DataLen", None), 

3857 XLEIntField("DataBufferOffset", None), # Short + Reserved = Int 

3858 FlagsField( 

3859 "AdditionalInformation", 

3860 0, 

3861 -32, 

3862 SMB2_ADDITIONAL_INFORMATION, 

3863 ), 

3864 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3865 _NTLMPayloadField( 

3866 "Buffer", 

3867 OFFSET, 

3868 [ 

3869 MultipleTypeField( 

3870 [ 

3871 ( 

3872 # FILE 

3873 PacketLenField( 

3874 "Data", 

3875 None, 

3876 lambda x, _parent: _FileInformationClasses.get( 

3877 _parent.FileInfoClass, conf.raw_layer 

3878 )(x), 

3879 length_from=lambda pkt: pkt.DataLen, 

3880 ), 

3881 lambda pkt: pkt.InfoType == 0x01, 

3882 ), 

3883 ( 

3884 # QUOTA 

3885 PacketListField( 

3886 "Data", 

3887 None, 

3888 SMB2_Query_Quota_Info, 

3889 length_from=lambda pkt: pkt.DataLen, 

3890 ), 

3891 lambda pkt: pkt.InfoType == 0x04, 

3892 ), 

3893 ], 

3894 StrLenField("Data", b"", length_from=lambda pkt: pkt.DataLen), 

3895 ), 

3896 ], 

3897 ), 

3898 ] 

3899 

3900 def post_build(self, pkt, pay): 

3901 # type: (bytes, bytes) -> bytes 

3902 return ( 

3903 _SMB2_post_build( 

3904 self, 

3905 pkt, 

3906 self.OFFSET, 

3907 { 

3908 "Data": 4, 

3909 }, 

3910 ) 

3911 + pay 

3912 ) 

3913 

3914 

3915bind_top_down( 

3916 SMB2_Header, 

3917 SMB2_Set_Info_Request, 

3918 Command=0x00011, 

3919) 

3920 

3921 

3922class SMB2_Set_Info_Response(_SMB2_Payload): 

3923 name = "SMB2 SET INFO Request" 

3924 Command = 0x0011 

3925 fields_desc = [ 

3926 XLEShortField("StructureSize", 0x02), 

3927 ] 

3928 

3929 

3930bind_top_down( 

3931 SMB2_Header, 

3932 SMB2_Set_Info_Response, 

3933 Command=0x00011, 

3934 Flags=1, 

3935) 

3936 

3937 

3938# sect 2.2.42.1 

3939 

3940 

3941class SMB2_Compression_Transform_Header(Packet): 

3942 name = "SMB2 Compression Transform Header" 

3943 fields_desc = [ 

3944 StrFixedLenField("Start", b"\xfcSMB", 4), 

3945 LEIntField("OriginalCompressedSegmentSize", 0x0), 

3946 LEShortEnumField("CompressionAlgorithm", 0, SMB2_COMPRESSION_ALGORITHMS), 

3947 ShortEnumField( 

3948 "Flags", 

3949 0x0, 

3950 { 

3951 0x0000: "SMB2_COMPRESSION_FLAG_NONE", 

3952 0x0001: "SMB2_COMPRESSION_FLAG_CHAINED", 

3953 }, 

3954 ), 

3955 XLEIntField("Offset_or_Length", 0), 

3956 ] 

3957 

3958 

3959# [MS-DFSC] sect 2.2 

3960 

3961 

3962class SMB2_IOCTL_REQ_GET_DFS_Referral(Packet): 

3963 fields_desc = [ 

3964 LEShortField("MaxReferralLevel", 0), 

3965 StrNullFieldUtf16("RequestFileName", ""), 

3966 ] 

3967 

3968 

3969class DFS_REFERRAL(Packet): 

3970 fields_desc = [ 

3971 LEShortField("Version", 1), 

3972 FieldLenField( 

3973 "Size", None, fmt="<H", length_of="ShareName", adjust=lambda pkt, x: x + 9 

3974 ), 

3975 LEShortEnumField("ServerType", 0, {0: "non-root", 1: "root"}), 

3976 LEShortField("ReferralEntryFlags", 0), 

3977 StrNullFieldUtf16("ShareName", ""), 

3978 ] 

3979 

3980 @classmethod 

3981 def dispatch_hook(cls, _pkt=None, *args, **kargs): 

3982 if _pkt and len(_pkt) >= 2: 

3983 version = struct.unpack("<H", _pkt[:2])[0] 

3984 if version == 1: 

3985 return DFS_REFERRAL 

3986 elif version == 3: 

3987 return DFS_REFERRAL_V3 

3988 elif version == 4: 

3989 return DFS_REFERRAL_V4 

3990 return cls 

3991 

3992 def default_payload_class(self, s): 

3993 return conf.padding_layer 

3994 

3995 

3996class DFS_REFERRAL_V3(DFS_REFERRAL): 

3997 fields_desc = [ 

3998 LEShortField("Version", 3), 

3999 LEShortField("Size", None), 

4000 LEShortEnumField("ServerType", 0, {0: "non-root", 1: "root"}), 

4001 FlagsField( 

4002 "ReferralEntryFlags", 

4003 0, 

4004 -16, 

4005 { 

4006 0x0002: "NameListReferral", 

4007 0x0004: "TargetSetBoundary", 

4008 }, 

4009 ), 

4010 LEIntField("TimeToLive", 300), 

4011 # NameListReferral is 0 

4012 ConditionalField( 

4013 LEShortField("DFSPathOffset", None), 

4014 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4015 ), 

4016 ConditionalField( 

4017 LEShortField("DFSAlternatePathOffset", None), 

4018 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4019 ), 

4020 ConditionalField( 

4021 LEShortField("NetworkAddressOffset", None), 

4022 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4023 ), 

4024 ConditionalField( 

4025 StrFixedLenField("ServiceSiteGuid", 0, length=16), 

4026 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4027 ), 

4028 # NameListReferral is 1 

4029 ConditionalField( 

4030 LEShortField("SpecialNameOffset", None), 

4031 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4032 ), 

4033 ConditionalField( 

4034 LEShortField("NumberOfExpandedNames", None), 

4035 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4036 ), 

4037 ConditionalField( 

4038 LEShortField("ExpandedNameOffset", None), 

4039 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4040 ), 

4041 ConditionalField( 

4042 StrLenField("Padding", None, length_from=lambda pkt: pkt.Size - 18), 

4043 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4044 ), 

4045 ] 

4046 

4047 def post_build(self, pkt, pay): 

4048 # type: (bytes, bytes) -> bytes 

4049 if self.Size is None: 

4050 pkt = pkt[:2] + struct.pack("<H", len(pkt)) + pkt[4:] 

4051 return pkt + pay 

4052 

4053 

4054class DFS_REFERRAL_V4(DFS_REFERRAL_V3): 

4055 Version = 4 

4056 

4057 

4058class DFS_REFERRAL_ENTRY0(Packet): 

4059 fields_desc = [ 

4060 StrNullFieldUtf16("DFSPath", ""), 

4061 StrNullFieldUtf16("DFSAlternatePath", ""), 

4062 StrNullFieldUtf16("NetworkAddress", ""), 

4063 ] 

4064 

4065 

4066class DFS_REFERRAL_ENTRY1(Packet): 

4067 fields_desc = [ 

4068 StrNullFieldUtf16("SpecialName", ""), 

4069 FieldListField( 

4070 "ExpandedName", 

4071 [], 

4072 StrNullFieldUtf16("", ""), 

4073 ), 

4074 ] 

4075 

4076 

4077class _DFS_Referrals_BufferField(PacketListField): 

4078 def getfield(self, pkt, s): 

4079 results = [] 

4080 offset = sum(x.Size for x in pkt.ReferralEntries) 

4081 for ref in pkt.ReferralEntries: 

4082 # For every ref 

4083 if not ref.ReferralEntryFlags.NameListReferral: 

4084 cls = DFS_REFERRAL_ENTRY0 

4085 else: 

4086 cls = DFS_REFERRAL_ENTRY1 

4087 # Build the fields manually 

4088 fld = _NTLMPayloadField( 

4089 "", 

4090 offset, 

4091 cls.fields_desc, 

4092 force_order=[x.name for x in cls.fields_desc], 

4093 offset_name="Offset", 

4094 ) 

4095 remain, vals = fld.getfield(ref, s) 

4096 vals = fld.i2h(ref, vals) 

4097 # Append the entry class 

4098 results.append(cls(**{x[0]: x[1] for x in vals})) 

4099 offset -= ref.Size 

4100 return b"", results 

4101 

4102 def addfield(self, pkt, s, vals): 

4103 offset = sum(len(x) for x in pkt.ReferralEntries) 

4104 for i, val in enumerate(vals): 

4105 try: 

4106 ref = pkt.ReferralEntries[i] 

4107 except KeyError: 

4108 ref = None 

4109 fld = _NTLMPayloadField( 

4110 "", 

4111 offset, 

4112 val.fields_desc, 

4113 force_order=[x.name for x in val.fields_desc], 

4114 offset_name="Offset", 

4115 ) 

4116 # Append the bytes manually 

4117 values = [(fld.name, getattr(val, fld.name)) for fld in val.fields_desc] 

4118 values = fld.h2i(ref, values) 

4119 s += fld.addfield(ref, b"", values) 

4120 offset -= len(ref) 

4121 return s 

4122 

4123 

4124class SMB2_IOCTL_RESP_GET_DFS_Referral(Packet): 

4125 fields_desc = [ 

4126 LEShortField("PathConsumed", 0), 

4127 FieldLenField("NumberOfReferrals", None, fmt="<H", count_of="ReferralEntries"), 

4128 FlagsField( 

4129 "ReferralHeaderFlags", 

4130 0, 

4131 -32, 

4132 { 

4133 0x00000001: "ReferralServers", 

4134 0x00000002: "StorageServers", 

4135 0x00000004: "TargetFailback", 

4136 }, 

4137 ), 

4138 PacketListField( 

4139 "ReferralEntries", 

4140 [], 

4141 DFS_REFERRAL, 

4142 count_from=lambda pkt: pkt.NumberOfReferrals, 

4143 ), 

4144 _DFS_Referrals_BufferField("ReferralBuffer", []), 

4145 ] 

4146 

4147 def post_build(self, pkt, pay): 

4148 # type: (bytes, bytes) -> bytes 

4149 # Note: Windows is smart and uses some sort of compression in the sense 

4150 # that it re-uses fields that are used several times across ReferralBuffer. 

4151 # But we just do the dumb thing because it's 'easier', and do no compression. 

4152 offsets = { 

4153 # DFS_REFERRAL_ENTRY0 

4154 "DFSPath": 12, 

4155 "DFSAlternatePath": 14, 

4156 "NetworkAddress": 16, 

4157 # DFS_REFERRAL_ENTRY1 

4158 "SpecialName": 12, 

4159 "ExpandedName": 16, 

4160 } 

4161 # dataoffset = pointer in the ReferralBuffer 

4162 # entryoffset = pointer in the ReferralEntries 

4163 dataoffset = sum(len(x) for x in self.ReferralEntries) 

4164 entryoffset = 8 

4165 for ref, buf in zip(self.ReferralEntries, self.ReferralBuffer): 

4166 for fld in buf.fields_desc: 

4167 off = entryoffset + offsets[fld.name] 

4168 if ref.getfieldval(fld.name + "Offset") is None and buf.getfieldval( 

4169 fld.name 

4170 ): 

4171 pkt = pkt[:off] + struct.pack("<H", dataoffset) + pkt[off + 2 :] 

4172 dataoffset += len(fld.addfield(self, b"", buf.getfieldval(fld.name))) 

4173 dataoffset -= len(ref) 

4174 entryoffset += len(ref) 

4175 return pkt + pay 

4176 

4177 

4178# [MS-SMB2] various usages 

4179 

4180 

4181def SMB2computePreauthIntegrityHashValue( 

4182 PreauthIntegrityHashValue, s, HashId="SHA-512" 

4183): 

4184 """ 

4185 Update the PreauthIntegrityHashValue 

4186 """ 

4187 # get hasher 

4188 hasher = {"SHA-512": hashlib.sha512}[HashId] 

4189 # compute the hash of concatenation of previous and bytes 

4190 return hasher(PreauthIntegrityHashValue + s).digest() 

4191 

4192 

4193# SMB2 socket and session 

4194 

4195 

4196class SMBStreamSocket(StreamSocket): 

4197 """ 

4198 A modified StreamSocket to dissect SMB compounded requests 

4199 [MS-SMB2] 3.3.5.2.7 

4200 """ 

4201 

4202 def __init__(self, *args, **kwargs): 

4203 self.queue = collections.deque() 

4204 self.session = SMBSession() 

4205 super(SMBStreamSocket, self).__init__(*args, **kwargs) 

4206 

4207 def recv(self, x=None): 

4208 # note: normal StreamSocket takes care of NBTSession / DirectTCP fragments. 

4209 # this takes care of splitting compounded requests 

4210 if self.queue: 

4211 return self.queue.popleft() 

4212 pkt = super(SMBStreamSocket, self).recv(x) 

4213 if pkt is not None and SMB2_Header in pkt: 

4214 pay = pkt[SMB2_Header].payload 

4215 while SMB2_Header in pay: 

4216 pay = pay[SMB2_Header] 

4217 pay.underlayer.remove_payload() 

4218 self.queue.append(pay) 

4219 if not pay.NextCommand: 

4220 break 

4221 pay = pay.payload 

4222 return self.session.in_pkt(pkt) 

4223 

4224 def send(self, x, Compounded=False, **kwargs): 

4225 for pkt in self.session.out_pkt(x, Compounded=Compounded): 

4226 return super(SMBStreamSocket, self).send(pkt, **kwargs) 

4227 

4228 @staticmethod 

4229 def select(sockets, remain=conf.recv_poll_rate): 

4230 if any(getattr(x, "queue", None) for x in sockets): 

4231 return [x for x in sockets if isinstance(x, SMBStreamSocket) and x.queue] 

4232 return StreamSocket.select(sockets, remain=remain) 

4233 

4234 

4235class SMBSession(DefaultSession): 

4236 """ 

4237 A SMB session within a TCP socket. 

4238 """ 

4239 

4240 def __init__(self, *args, **kwargs): 

4241 self.smb_header = None 

4242 self.ssp = kwargs.pop("ssp", None) 

4243 self.sspcontext = kwargs.pop("sspcontext", None) 

4244 self.sniffsspcontexts = {} # Unfinished contexts for passive 

4245 # SMB session parameters 

4246 self.CompoundQueue = [] 

4247 self.Dialect = 0x0202 # Updated by parent 

4248 self.SecurityMode = 0 

4249 # Crypto parameters 

4250 self.SMBSessionKey = None 

4251 self.PreauthIntegrityHashId = "SHA-512" 

4252 self.CipherId = "AES-128-CCM" 

4253 self.SigningAlgorithmId = "AES-CMAC" 

4254 self.Salt = os.urandom(32) 

4255 self.ConnectionPreauthIntegrityHashValue = None 

4256 self.SessionPreauthIntegrityHashValue = None 

4257 # SMB 3.1.1 

4258 self.SessionPreauthIntegrityHashValue = None 

4259 if conf.winssps_passive: 

4260 for ssp in conf.winssps_passive: 

4261 self.sniffsspcontexts[ssp] = None 

4262 super(SMBSession, self).__init__(*args, **kwargs) 

4263 

4264 # SMB crypto functions 

4265 

4266 @crypto_validator 

4267 def computeSMBSessionKey(self): 

4268 if not getattr(self.sspcontext, "SessionKey", None): 

4269 # no signing key, no session key 

4270 return 

4271 # [MS-SMB2] sect 3.3.5.5.3 

4272 if self.Dialect >= 0x0300: 

4273 if self.Dialect == 0x0311: 

4274 label = b"SMBSigningKey\x00" 

4275 preauth_hash = self.SessionPreauthIntegrityHashValue 

4276 else: 

4277 label = b"SMB2AESCMAC\x00" 

4278 preauth_hash = b"SmbSign\x00" 

4279 # [MS-SMB2] sect 3.1.4.2 

4280 if "256" in self.CipherId: 

4281 L = 256 

4282 elif "128" in self.CipherId: 

4283 L = 128 

4284 else: 

4285 raise ValueError 

4286 self.SMBSessionKey = SP800108_KDFCTR( 

4287 self.sspcontext.SessionKey[:16], 

4288 label, # label 

4289 preauth_hash, # context 

4290 L, 

4291 ) 

4292 elif self.Dialect <= 0x0210: 

4293 self.SMBSessionKey = self.sspcontext.SessionKey[:16] 

4294 else: 

4295 raise ValueError("Hmmm ? >:(") 

4296 

4297 def computeSMBConnectionPreauth(self, *negopkts): 

4298 if self.Dialect and self.Dialect >= 0x0311: # SMB 3.1.1 only 

4299 # [MS-SMB2] 3.3.5.4 

4300 # TODO: handle SMB2_SESSION_FLAG_BINDING 

4301 if self.ConnectionPreauthIntegrityHashValue is None: 

4302 # New auth or failure 

4303 self.ConnectionPreauthIntegrityHashValue = b"\x00" * 64 

4304 # Calculate the *Connection* PreauthIntegrityHashValue 

4305 for negopkt in negopkts: 

4306 self.ConnectionPreauthIntegrityHashValue = ( 

4307 SMB2computePreauthIntegrityHashValue( 

4308 self.ConnectionPreauthIntegrityHashValue, 

4309 negopkt, 

4310 HashId=self.PreauthIntegrityHashId, 

4311 ) 

4312 ) 

4313 

4314 def computeSMBSessionPreauth(self, *sesspkts): 

4315 if self.Dialect and self.Dialect >= 0x0311: # SMB 3.1.1 only 

4316 # [MS-SMB2] 3.3.5.5.3 

4317 if self.SessionPreauthIntegrityHashValue is None: 

4318 # New auth or failure 

4319 self.SessionPreauthIntegrityHashValue = ( 

4320 self.ConnectionPreauthIntegrityHashValue 

4321 ) 

4322 # Calculate the *Session* PreauthIntegrityHashValue 

4323 for sesspkt in sesspkts: 

4324 self.SessionPreauthIntegrityHashValue = ( 

4325 SMB2computePreauthIntegrityHashValue( 

4326 self.SessionPreauthIntegrityHashValue, 

4327 sesspkt, 

4328 HashId=self.PreauthIntegrityHashId, 

4329 ) 

4330 ) 

4331 

4332 # I/O 

4333 

4334 def in_pkt(self, pkt): 

4335 """ 

4336 Incoming SMB packet 

4337 """ 

4338 return pkt 

4339 

4340 def out_pkt(self, pkt, Compounded=False): 

4341 """ 

4342 Outgoing SMB packet 

4343 

4344 :param pkt: the packet to send 

4345 :param Compound: if True, will be stack to be send with the next 

4346 un-compounded packet 

4347 

4348 Handles: 

4349 - handle compounded requests (if any): [MS-SMB2] 3.3.5.2.7 

4350 - handles signing (if required) 

4351 """ 

4352 # Note: impacket and wireshark get crazy on compounded+signature, but 

4353 # windows+samba tells we're right :D 

4354 if SMB2_Header in pkt: 

4355 if self.CompoundQueue: 

4356 # this is a subsequent compound: only keep the SMB2 

4357 pkt = pkt[SMB2_Header] 

4358 if Compounded: 

4359 # [MS-SMB2] 3.2.4.1.4 

4360 # "Compounded requests MUST be aligned on 8-byte boundaries; the 

4361 # last request of the compounded requests does not need to be padded to 

4362 # an 8-byte boundary." 

4363 # [MS-SMB2] 3.1.4.1 

4364 # "If the message is part of a compounded chain, any 

4365 # padding at the end of the message MUST be used in the hash 

4366 # computation." 

4367 length = len(pkt[SMB2_Header]) 

4368 padlen = (-length) % 8 

4369 if padlen: 

4370 pkt.add_payload(b"\x00" * padlen) 

4371 pkt[SMB2_Header].NextCommand = length + padlen 

4372 if self.Dialect and self.SMBSessionKey and self.SecurityMode != 0: 

4373 # Sign SMB2 ! 

4374 smb = pkt[SMB2_Header] 

4375 smb.Flags += "SMB2_FLAGS_SIGNED" 

4376 smb.sign( 

4377 self.Dialect, 

4378 self.SMBSessionKey, 

4379 # SMB 3.1.1 parameters: 

4380 SigningAlgorithmId=self.SigningAlgorithmId, 

4381 IsClient=False, 

4382 ) 

4383 if Compounded: 

4384 # There IS a next compound. Store in queue 

4385 self.CompoundQueue.append(pkt) 

4386 return [] 

4387 else: 

4388 # If there are any compounded responses in store, sum them 

4389 if self.CompoundQueue: 

4390 pkt = functools.reduce(lambda x, y: x / y, self.CompoundQueue) / pkt 

4391 self.CompoundQueue.clear() 

4392 return [pkt] 

4393 

4394 def process(self, pkt: Packet): 

4395 # Called when passively sniffing 

4396 pkt = super(SMBSession, self).process(pkt) 

4397 if pkt is not None and SMB2_Header in pkt: 

4398 return self.in_pkt(pkt) 

4399 return pkt