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

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

1105 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 collections 

15import functools 

16import hashlib 

17import os 

18import re 

19import struct 

20 

21from scapy.automaton import select_objects 

22from scapy.config import conf, crypto_validator 

23from scapy.error import log_runtime 

24from scapy.packet import Packet, bind_layers, bind_top_down 

25from scapy.fields import ( 

26 ByteEnumField, 

27 ByteField, 

28 ConditionalField, 

29 FieldLenField, 

30 FieldListField, 

31 FlagValue, 

32 FlagsField, 

33 IP6Field, 

34 IPField, 

35 IntField, 

36 LEIntField, 

37 LEIntEnumField, 

38 LELongField, 

39 LenField, 

40 LEShortEnumField, 

41 LEShortField, 

42 MultipleTypeField, 

43 PadField, 

44 PacketField, 

45 PacketLenField, 

46 PacketListField, 

47 ReversePadField, 

48 ScalingField, 

49 ShortEnumField, 

50 ShortField, 

51 StrFieldUtf16, 

52 StrFixedLenField, 

53 StrLenField, 

54 StrLenFieldUtf16, 

55 StrNullFieldUtf16, 

56 ThreeBytesField, 

57 UTCTimeField, 

58 UUIDField, 

59 XLEIntField, 

60 XLELongField, 

61 XLEShortField, 

62 XStrLenField, 

63 XStrFixedLenField, 

64 YesNoByteField, 

65) 

66from scapy.sessions import DefaultSession 

67from scapy.supersocket import StreamSocket 

68 

69if conf.crypto_valid: 

70 from scapy.libs.rfc3961 import SP800108_KDFCTR 

71 

72from scapy.layers.gssapi import GSSAPI_BLOB 

73from scapy.layers.netbios import NBTSession 

74from scapy.layers.ntlm import ( 

75 _NTLMPayloadField, 

76 _NTLMPayloadPacket, 

77 _NTLM_ENUM, 

78 _NTLM_post_build, 

79) 

80 

81 

82# EnumField 

83SMB_DIALECTS = { 

84 0x0202: "SMB 2.002", 

85 0x0210: "SMB 2.1", 

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

87 0x0300: "SMB 3.0", 

88 0x0302: "SMB 3.0.2", 

89 0x0311: "SMB 3.1.1", 

90} 

91 

92# SMB2 sect 3.3.5.15 + [MS-ERREF] 

93STATUS_ERREF = { 

94 0x00000000: "STATUS_SUCCESS", 

95 0x00000002: "ERROR_FILE_NOT_FOUND", 

96 0x00000005: "ERROR_ACCESS_DENIED", 

97 0x00000103: "STATUS_PENDING", 

98 0x0000010B: "STATUS_NOTIFY_CLEANUP", 

99 0x0000010C: "STATUS_NOTIFY_ENUM_DIR", 

100 0x00000532: "ERROR_PASSWORD_EXPIRED", 

101 0x00000533: "ERROR_ACCOUNT_DISABLED", 

102 0x000006FE: "ERROR_TRUST_FAILURE", 

103 0x80000005: "STATUS_BUFFER_OVERFLOW", 

104 0x80000006: "STATUS_NO_MORE_FILES", 

105 0x8000002D: "STATUS_STOPPED_ON_SYMLINK", 

106 0x80070005: "E_ACCESSDENIED", 

107 0x8007000E: "E_OUTOFMEMORY", 

108 0x80090308: "SEC_E_INVALID_TOKEN", 

109 0x8009030C: "SEC_E_LOGON_DENIED", 

110 0x8009030F: "SEC_E_MESSAGE_ALTERED", 

111 0x80090310: "SEC_E_OUT_OF_SEQUENCE", 

112 0x80090346: "SEC_E_BAD_BINDINGS", 

113 0x80090351: "SEC_E_SMARTCARD_CERT_REVOKED", 

114 0xC0000003: "STATUS_INVALID_INFO_CLASS", 

115 0xC0000004: "STATUS_INFO_LENGTH_MISMATCH", 

116 0xC000000D: "STATUS_INVALID_PARAMETER", 

117 0xC000000F: "STATUS_NO_SUCH_FILE", 

118 0xC0000016: "STATUS_MORE_PROCESSING_REQUIRED", 

119 0xC0000022: "STATUS_ACCESS_DENIED", 

120 0xC0000033: "STATUS_OBJECT_NAME_INVALID", 

121 0xC0000034: "STATUS_OBJECT_NAME_NOT_FOUND", 

122 0xC0000043: "STATUS_SHARING_VIOLATION", 

123 0xC0000061: "STATUS_PRIVILEGE_NOT_HELD", 

124 0xC0000064: "STATUS_NO_SUCH_USER", 

125 0xC000006D: "STATUS_LOGON_FAILURE", 

126 0xC000006E: "STATUS_ACCOUNT_RESTRICTION", 

127 0xC0000070: "STATUS_INVALID_WORKSTATION", 

128 0xC0000071: "STATUS_PASSWORD_EXPIRED", 

129 0xC0000072: "STATUS_ACCOUNT_DISABLED", 

130 0xC000009A: "STATUS_INSUFFICIENT_RESOURCES", 

131 0xC00000BA: "STATUS_FILE_IS_A_DIRECTORY", 

132 0xC00000BB: "STATUS_NOT_SUPPORTED", 

133 0xC00000C9: "STATUS_NETWORK_NAME_DELETED", 

134 0xC00000CC: "STATUS_BAD_NETWORK_NAME", 

135 0xC0000120: "STATUS_CANCELLED", 

136 0xC0000122: "STATUS_INVALID_COMPUTER_NAME", 

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

138 0xC000015B: "STATUS_LOGON_TYPE_NOT_GRANTED", 

139 0xC000018B: "STATUS_NO_TRUST_SAM_ACCOUNT", 

140 0xC000019C: "STATUS_FS_DRIVER_REQUIRED", 

141 0xC0000203: "STATUS_USER_SESSION_DELETED", 

142 0xC000020C: "STATUS_CONNECTION_DISCONNECTED", 

143 0xC0000225: "STATUS_NOT_FOUND", 

144 0xC0000257: "STATUS_PATH_NOT_COVERED", 

145 0xC000035C: "STATUS_NETWORK_SESSION_EXPIRED", 

146} 

147 

148# SMB2 sect 2.1.2.1 

149REPARSE_TAGS = { 

150 0x00000000: "IO_REPARSE_TAG_RESERVED_ZERO", 

151 0x00000001: "IO_REPARSE_TAG_RESERVED_ONE", 

152 0x00000002: "IO_REPARSE_TAG_RESERVED_TWO", 

153 0xA0000003: "IO_REPARSE_TAG_MOUNT_POINT", 

154 0xC0000004: "IO_REPARSE_TAG_HSM", 

155 0x80000005: "IO_REPARSE_TAG_DRIVE_EXTENDER", 

156 0x80000006: "IO_REPARSE_TAG_HSM2", 

157 0x80000007: "IO_REPARSE_TAG_SIS", 

158 0x80000008: "IO_REPARSE_TAG_WIM", 

159 0x80000009: "IO_REPARSE_TAG_CSV", 

160 0x8000000A: "IO_REPARSE_TAG_DFS", 

161 0x8000000B: "IO_REPARSE_TAG_FILTER_MANAGER", 

162 0xA000000C: "IO_REPARSE_TAG_SYMLINK", 

163 0xA0000010: "IO_REPARSE_TAG_IIS_CACHE", 

164 0x80000012: "IO_REPARSE_TAG_DFSR", 

165 0x80000013: "IO_REPARSE_TAG_DEDUP", 

166 0xC0000014: "IO_REPARSE_TAG_APPXSTRM", 

167 0x80000014: "IO_REPARSE_TAG_NFS", 

168 0x80000015: "IO_REPARSE_TAG_FILE_PLACEHOLDER", 

169 0x80000016: "IO_REPARSE_TAG_DFM", 

170 0x80000017: "IO_REPARSE_TAG_WOF", 

171 0x80000018: "IO_REPARSE_TAG_WCI", 

172 0x90001018: "IO_REPARSE_TAG_WCI_1", 

173 0xA0000019: "IO_REPARSE_TAG_GLOBAL_REPARSE", 

174 0x9000001A: "IO_REPARSE_TAG_CLOUD", 

175 0x9000101A: "IO_REPARSE_TAG_CLOUD_1", 

176 0x9000201A: "IO_REPARSE_TAG_CLOUD_2", 

177 0x9000301A: "IO_REPARSE_TAG_CLOUD_3", 

178 0x9000401A: "IO_REPARSE_TAG_CLOUD_4", 

179 0x9000501A: "IO_REPARSE_TAG_CLOUD_5", 

180 0x9000601A: "IO_REPARSE_TAG_CLOUD_6", 

181 0x9000701A: "IO_REPARSE_TAG_CLOUD_7", 

182 0x9000801A: "IO_REPARSE_TAG_CLOUD_8", 

183 0x9000901A: "IO_REPARSE_TAG_CLOUD_9", 

184 0x9000A01A: "IO_REPARSE_TAG_CLOUD_A", 

185 0x9000B01A: "IO_REPARSE_TAG_CLOUD_B", 

186 0x9000C01A: "IO_REPARSE_TAG_CLOUD_C", 

187 0x9000D01A: "IO_REPARSE_TAG_CLOUD_D", 

188 0x9000E01A: "IO_REPARSE_TAG_CLOUD_E", 

189 0x9000F01A: "IO_REPARSE_TAG_CLOUD_F", 

190 0x8000001B: "IO_REPARSE_TAG_APPEXECLINK", 

191 0x9000001C: "IO_REPARSE_TAG_PROJFS", 

192 0xA000001D: "IO_REPARSE_TAG_LX_SYMLINK", 

193 0x8000001E: "IO_REPARSE_TAG_STORAGE_SYNC", 

194 0xA000001F: "IO_REPARSE_TAG_WCI_TOMBSTONE", 

195 0x80000020: "IO_REPARSE_TAG_UNHANDLED", 

196 0x80000021: "IO_REPARSE_TAG_ONEDRIVE", 

197 0xA0000022: "IO_REPARSE_TAG_PROJFS_TOMBSTONE", 

198 0x80000023: "IO_REPARSE_TAG_AF_UNIX", 

199 0x80000024: "IO_REPARSE_TAG_LX_FIFO", 

200 0x80000025: "IO_REPARSE_TAG_LX_CHR", 

201 0x80000026: "IO_REPARSE_TAG_LX_BLK", 

202 0xA0000027: "IO_REPARSE_TAG_WCI_LINK", 

203 0xA0001027: "IO_REPARSE_TAG_WCI_LINK_1", 

204} 

205 

206# SMB2 sect 2.2.1.1 

207SMB2_COM = { 

208 0x0000: "SMB2_NEGOTIATE", 

209 0x0001: "SMB2_SESSION_SETUP", 

210 0x0002: "SMB2_LOGOFF", 

211 0x0003: "SMB2_TREE_CONNECT", 

212 0x0004: "SMB2_TREE_DISCONNECT", 

213 0x0005: "SMB2_CREATE", 

214 0x0006: "SMB2_CLOSE", 

215 0x0007: "SMB2_FLUSH", 

216 0x0008: "SMB2_READ", 

217 0x0009: "SMB2_WRITE", 

218 0x000A: "SMB2_LOCK", 

219 0x000B: "SMB2_IOCTL", 

220 0x000C: "SMB2_CANCEL", 

221 0x000D: "SMB2_ECHO", 

222 0x000E: "SMB2_QUERY_DIRECTORY", 

223 0x000F: "SMB2_CHANGE_NOTIFY", 

224 0x0010: "SMB2_QUERY_INFO", 

225 0x0011: "SMB2_SET_INFO", 

226 0x0012: "SMB2_OPLOCK_BREAK", 

227} 

228 

229# EnumField 

230SMB2_NEGOTIATE_CONTEXT_TYPES = { 

231 0x0001: "SMB2_PREAUTH_INTEGRITY_CAPABILITIES", 

232 0x0002: "SMB2_ENCRYPTION_CAPABILITIES", 

233 0x0003: "SMB2_COMPRESSION_CAPABILITIES", 

234 0x0005: "SMB2_NETNAME_NEGOTIATE_CONTEXT_ID", 

235 0x0006: "SMB2_TRANSPORT_CAPABILITIES", 

236 0x0007: "SMB2_RDMA_TRANSFORM_CAPABILITIES", 

237 0x0008: "SMB2_SIGNING_CAPABILITIES", 

238} 

239 

240# FlagField 

241SMB2_CAPABILITIES = { 

242 0x00000001: "DFS", 

243 0x00000002: "LEASING", 

244 0x00000004: "LARGE_MTU", 

245 0x00000008: "MULTI_CHANNEL", 

246 0x00000010: "PERSISTENT_HANDLES", 

247 0x00000020: "DIRECTORY_LEASING", 

248 0x00000040: "ENCRYPTION", 

249} 

250SMB2_SECURITY_MODE = { 

251 0x01: "SIGNING_ENABLED", 

252 0x02: "SIGNING_REQUIRED", 

253} 

254 

255# [MS-SMB2] 2.2.3.1.3 

256SMB2_COMPRESSION_ALGORITHMS = { 

257 0x0000: "None", 

258 0x0001: "LZNT1", 

259 0x0002: "LZ77", 

260 0x0003: "LZ77 + Huffman", 

261 0x0004: "Pattern_V1", 

262} 

263 

264# [MS-SMB2] sect 2.2.3.1.2 

265SMB2_ENCRYPTION_CIPHERS = { 

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

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

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

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

270} 

271 

272# [MS-SMB2] sect 2.2.3.1.7 

273SMB2_SIGNING_ALGORITHMS = { 

274 0x0000: "HMAC-SHA256", 

275 0x0001: "AES-CMAC", 

276 0x0002: "AES-GMAC", 

277} 

278 

279# [MS-SMB2] sect 2.2.3.1.1 

280SMB2_HASH_ALGORITHMS = { 

281 0x0001: "SHA-512", 

282} 

283 

284# sect [MS-SMB2] 2.2.13.1.1 

285SMB2_ACCESS_FLAGS_FILE = { 

286 0x00000001: "FILE_READ_DATA", 

287 0x00000002: "FILE_WRITE_DATA", 

288 0x00000004: "FILE_APPEND_DATA", 

289 0x00000008: "FILE_READ_EA", 

290 0x00000010: "FILE_WRITE_EA", 

291 0x00000040: "FILE_DELETE_CHILD", 

292 0x00000020: "FILE_EXECUTE", 

293 0x00000080: "FILE_READ_ATTRIBUTES", 

294 0x00000100: "FILE_WRITE_ATTRIBUTES", 

295 0x00010000: "DELETE", 

296 0x00020000: "READ_CONTROL", 

297 0x00040000: "WRITE_DAC", 

298 0x00080000: "WRITE_OWNER", 

299 0x00100000: "SYNCHRONIZE", 

300 0x01000000: "ACCESS_SYSTEM_SECURITY", 

301 0x02000000: "MAXIMUM_ALLOWED", 

302 0x10000000: "GENERIC_ALL", 

303 0x20000000: "GENERIC_EXECUTE", 

304 0x40000000: "GENERIC_WRITE", 

305 0x80000000: "GENERIC_READ", 

306} 

307 

308# sect [MS-SMB2] 2.2.13.1.2 

309SMB2_ACCESS_FLAGS_DIRECTORY = { 

310 0x00000001: "FILE_LIST_DIRECTORY", 

311 0x00000002: "FILE_ADD_FILE", 

312 0x00000004: "FILE_ADD_SUBDIRECTORY", 

313 0x00000008: "FILE_READ_EA", 

314 0x00000010: "FILE_WRITE_EA", 

315 0x00000020: "FILE_TRAVERSE", 

316 0x00000040: "FILE_DELETE_CHILD", 

317 0x00000080: "FILE_READ_ATTRIBUTES", 

318 0x00000100: "FILE_WRITE_ATTRIBUTES", 

319 0x00010000: "DELETE", 

320 0x00020000: "READ_CONTROL", 

321 0x00040000: "WRITE_DAC", 

322 0x00080000: "WRITE_OWNER", 

323 0x00100000: "SYNCHRONIZE", 

324 0x01000000: "ACCESS_SYSTEM_SECURITY", 

325 0x02000000: "MAXIMUM_ALLOWED", 

326 0x10000000: "GENERIC_ALL", 

327 0x20000000: "GENERIC_EXECUTE", 

328 0x40000000: "GENERIC_WRITE", 

329 0x80000000: "GENERIC_READ", 

330} 

331 

332# [MS-SRVS] sec 2.2.2.4 

333SRVSVC_SHARE_TYPES = { 

334 0x00000000: "DISKTREE", 

335 0x00000001: "PRINTQ", 

336 0x00000002: "DEVICE", 

337 0x00000003: "IPC", 

338 0x02000000: "CLUSTER_FS", 

339 0x04000000: "CLUSTER_SOFS", 

340 0x08000000: "CLUSTER_DFS", 

341} 

342 

343 

344# [MS-FSCC] sec 2.6 

345FileAttributes = { 

346 0x00000001: "FILE_ATTRIBUTE_READONLY", 

347 0x00000002: "FILE_ATTRIBUTE_HIDDEN", 

348 0x00000004: "FILE_ATTRIBUTE_SYSTEM", 

349 0x00000010: "FILE_ATTRIBUTE_DIRECTORY", 

350 0x00000020: "FILE_ATTRIBUTE_ARCHIVE", 

351 0x00000080: "FILE_ATTRIBUTE_NORMAL", 

352 0x00000100: "FILE_ATTRIBUTE_TEMPORARY", 

353 0x00000200: "FILE_ATTRIBUTE_SPARSE_FILE", 

354 0x00000400: "FILE_ATTRIBUTE_REPARSE_POINT", 

355 0x00000800: "FILE_ATTRIBUTE_COMPRESSED", 

356 0x00001000: "FILE_ATTRIBUTE_OFFLINE", 

357 0x00002000: "FILE_ATTRIBUTE_NOT_CONTENT_INDEXED", 

358 0x00004000: "FILE_ATTRIBUTE_ENCRYPTED", 

359 0x00008000: "FILE_ATTRIBUTE_INTEGRITY_STREAM", 

360 0x00020000: "FILE_ATTRIBUTE_NO_SCRUB_DATA", 

361 0x00040000: "FILE_ATTRIBUTE_RECALL_ON_OPEN", 

362 0x00080000: "FILE_ATTRIBUTE_PINNED", 

363 0x00100000: "FILE_ATTRIBUTE_UNPINNED", 

364 0x00400000: "FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS", 

365} 

366 

367 

368# [MS-FSCC] sect 2.4 

369FileInformationClasses = { 

370 0x01: "FileDirectoryInformation", 

371 0x02: "FileFullDirectoryInformation", 

372 0x03: "FileBothDirectoryInformation", 

373 0x04: "FileBasicInformation", 

374 0x05: "FileStandardInformation", 

375 0x06: "FileInternalInformation", 

376 0x07: "FileEaInformation", 

377 0x08: "FileAccessInformation", 

378 0x0A: "FileRenameInformation", 

379 0x0E: "FilePositionInformation", 

380 0x10: "FileModeInformation", 

381 0x11: "FileAlignmentInformation", 

382 0x12: "FileAllInformation", 

383 0x22: "FileNetworkOpenInformation", 

384 0x25: "FileIdBothDirectoryInformation", 

385 0x26: "FileIdFullDirectoryInformation", 

386 0x0C: "FileNamesInformation", 

387 0x30: "FileNormalizedNameInformation", 

388 0x3C: "FileIdExtdDirectoryInformation", 

389} 

390_FileInformationClasses = {} 

391 

392 

393# [MS-FSCC] 2.1.7 FILE_NAME_INFORMATION 

394 

395 

396class FILE_NAME_INFORMATION(Packet): 

397 fields_desc = [ 

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

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

400 ] 

401 

402 def default_payload_class(self, s): 

403 return conf.padding_layer 

404 

405 

406# [MS-FSCC] 2.4.1 FileAccessInformation 

407 

408 

409class FileAccessInformation(Packet): 

410 fields_desc = [ 

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

412 ] 

413 

414 def default_payload_class(self, s): 

415 return conf.padding_layer 

416 

417 

418# [MS-FSCC] 2.4.3 FileAlignmentInformation 

419 

420 

421class FileAlignmentInformation(Packet): 

422 fields_desc = [ 

423 LEIntEnumField( 

424 "AccessFlags", 

425 0, 

426 { 

427 0x00000000: "FILE_BYTE_ALIGNMENT", 

428 0x00000001: "FILE_WORD_ALIGNMENT", 

429 0x00000003: "FILE_LONG_ALIGNMENT", 

430 0x00000007: "FILE_QUAD_ALIGNMENT", 

431 0x0000000F: "FILE_OCTA_ALIGNMENT", 

432 0x0000001F: "FILE_32_BYTE_ALIGNMENT", 

433 0x0000003F: "FILE_64_BYTE_ALIGNMENT", 

434 0x0000007F: "FILE_128_BYTE_ALIGNMENT", 

435 0x000000FF: "FILE_256_BYTE_ALIGNMENT", 

436 0x000001FF: "FILE_512_BYTE_ALIGNMENT", 

437 }, 

438 ), 

439 ] 

440 

441 def default_payload_class(self, s): 

442 return conf.padding_layer 

443 

444 

445# [MS-FSCC] 2.4.5 FileAlternateNameInformation 

446 

447 

448class FileAlternateNameInformation(Packet): 

449 fields_desc = [ 

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

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

452 ] 

453 

454 

455# [MS-FSCC] 2.4.7 FileBasicInformation 

456 

457 

458class FileBasicInformation(Packet): 

459 fields_desc = [ 

460 UTCTimeField( 

461 "CreationTime", 

462 None, 

463 fmt="<Q", 

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

465 custom_scaling=1e7, 

466 ), 

467 UTCTimeField( 

468 "LastAccessTime", 

469 None, 

470 fmt="<Q", 

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

472 custom_scaling=1e7, 

473 ), 

474 UTCTimeField( 

475 "LastWriteTime", 

476 None, 

477 fmt="<Q", 

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

479 custom_scaling=1e7, 

480 ), 

481 UTCTimeField( 

482 "ChangeTime", 

483 None, 

484 fmt="<Q", 

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

486 custom_scaling=1e7, 

487 ), 

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

489 IntField("Reserved", 0), 

490 ] 

491 

492 def default_payload_class(self, s): 

493 return conf.padding_layer 

494 

495 

496# [MS-FSCC] 2.4.12 FileEaInformation 

497 

498 

499class FileEaInformation(Packet): 

500 fields_desc = [ 

501 LEIntField("EaSize", 0), 

502 ] 

503 

504 def default_payload_class(self, s): 

505 return conf.padding_layer 

506 

507 

508# [MS-FSCC] 2.4.29 FileNetworkOpenInformation 

509 

510 

511class FileNetworkOpenInformation(Packet): 

512 fields_desc = [ 

513 UTCTimeField( 

514 "CreationTime", 

515 None, 

516 fmt="<Q", 

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

518 custom_scaling=1e7, 

519 ), 

520 UTCTimeField( 

521 "LastAccessTime", 

522 None, 

523 fmt="<Q", 

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

525 custom_scaling=1e7, 

526 ), 

527 UTCTimeField( 

528 "LastWriteTime", 

529 None, 

530 fmt="<Q", 

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

532 custom_scaling=1e7, 

533 ), 

534 UTCTimeField( 

535 "ChangeTime", 

536 None, 

537 fmt="<Q", 

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

539 custom_scaling=1e7, 

540 ), 

541 LELongField("AllocationSize", 4096), 

542 LELongField("EndOfFile", 0), 

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

544 IntField("Reserved2", 0), 

545 ] 

546 

547 def default_payload_class(self, s): 

548 return conf.padding_layer 

549 

550 

551# [MS-FSCC] 2.4.8 FileBothDirectoryInformation 

552 

553 

554class FILE_BOTH_DIR_INFORMATION(Packet): 

555 fields_desc = ( 

556 [ 

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

558 LEIntField("FileIndex", 0), 

559 ] 

560 + ( 

561 FileNetworkOpenInformation.fields_desc[:4] 

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

563 + [FileNetworkOpenInformation.fields_desc[6]] 

564 ) 

565 + [ 

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

567 MultipleTypeField( 

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

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

570 # 2.1.2.1." 

571 [ 

572 ( 

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

574 lambda pkt: pkt.FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT, 

575 ) 

576 ], 

577 LEIntField("EaSize", 0), 

578 ), 

579 ByteField("ShortNameLength", 0), 

580 ByteField("Reserved1", 0), 

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

582 PadField( 

583 StrLenFieldUtf16( 

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

585 ), 

586 align=8, 

587 ), 

588 ] 

589 ) 

590 

591 def default_payload_class(self, s): 

592 return conf.padding_layer 

593 

594 

595class _NextPacketListField(PacketListField): 

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

597 # we use this field to set NextEntryOffset 

598 res = b"" 

599 for i, v in enumerate(val): 

600 x = self.i2m(pkt, v) 

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

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

603 res += x 

604 return s + res 

605 

606 

607class FileBothDirectoryInformation(Packet): 

608 fields_desc = [ 

609 _NextPacketListField( 

610 "files", 

611 [], 

612 FILE_BOTH_DIR_INFORMATION, 

613 max_count=1000, 

614 ), 

615 ] 

616 

617 

618# [MS-FSCC] 2.4.14 FileFullDirectoryInformation 

619 

620 

621class FILE_FULL_DIR_INFORMATION(Packet): 

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

623 FILE_BOTH_DIR_INFORMATION.fields_desc[-1] 

624 ] 

625 

626 

627class FileFullDirectoryInformation(Packet): 

628 fields_desc = [ 

629 _NextPacketListField( 

630 "files", 

631 [], 

632 FILE_FULL_DIR_INFORMATION, 

633 max_count=1000, 

634 ), 

635 ] 

636 

637 

638# [MS-FSCC] 2.4.17 FileIdBothDirectoryInformation 

639 

640 

641class FILE_ID_BOTH_DIR_INFORMATION(Packet): 

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

643 LEShortField("Reserved2", 0), 

644 LELongField("FileId", 0), 

645 FILE_BOTH_DIR_INFORMATION.fields_desc[-1], 

646 ] 

647 

648 def default_payload_class(self, s): 

649 return conf.padding_layer 

650 

651 

652class FileIdBothDirectoryInformation(Packet): 

653 fields_desc = [ 

654 _NextPacketListField( 

655 "files", 

656 [], 

657 FILE_ID_BOTH_DIR_INFORMATION, 

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

659 ), 

660 ] 

661 

662 

663# [MS-FSCC] 2.4.22 FileInternalInformation 

664 

665 

666class FileInternalInformation(Packet): 

667 fields_desc = [ 

668 LELongField("IndexNumber", 0), 

669 ] 

670 

671 def default_payload_class(self, s): 

672 return conf.padding_layer 

673 

674 

675# [MS-FSCC] 2.4.26 FileModeInformation 

676 

677 

678class FileModeInformation(Packet): 

679 fields_desc = [ 

680 FlagsField( 

681 "Mode", 

682 0, 

683 -32, 

684 { 

685 0x00000002: "FILE_WRITE_TROUGH", 

686 0x00000004: "FILE_SEQUENTIAL_ONLY", 

687 0x00000008: "FILE_NO_INTERMEDIATE_BUFFERING", 

688 0x00000010: "FILE_SYNCHRONOUS_IO_ALERT", 

689 0x00000020: "FILE_SYNCHRONOUS_IO_NONALERT", 

690 0x00001000: "FILE_DELETE_ON_CLOSE", 

691 }, 

692 ) 

693 ] 

694 

695 def default_payload_class(self, s): 

696 return conf.padding_layer 

697 

698 

699# [MS-FSCC] 2.4.35 FilePositionInformation 

700 

701 

702class FilePositionInformation(Packet): 

703 fields_desc = [ 

704 LELongField("CurrentByteOffset", 0), 

705 ] 

706 

707 def default_payload_class(self, s): 

708 return conf.padding_layer 

709 

710 

711# [MS-FSCC] 2.4.37 FileRenameInformation 

712 

713 

714class FileRenameInformation(Packet): 

715 fields_desc = [ 

716 YesNoByteField("ReplaceIfExists", False), 

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

718 LELongField("RootDirectory", 0), 

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

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

721 ] 

722 

723 def post_build(self, pkt, pay): 

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

725 if len(pkt) < 24: 

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

727 # size of this structure at least 24.' 

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

729 return pkt + pay 

730 

731 def default_payload_class(self, s): 

732 return conf.padding_layer 

733 

734 

735_FileInformationClasses[0x0A] = FileRenameInformation 

736 

737 

738# [MS-FSCC] 2.4.41 FileStandardInformation 

739 

740 

741class FileStandardInformation(Packet): 

742 fields_desc = [ 

743 LELongField("AllocationSize", 4096), 

744 LELongField("EndOfFile", 0), 

745 LEIntField("NumberOfLinks", 1), 

746 ByteField("DeletePending", 0), 

747 ByteField("Directory", 0), 

748 ShortField("Reserved", 0), 

749 ] 

750 

751 def default_payload_class(self, s): 

752 return conf.padding_layer 

753 

754 

755# [MS-FSCC] 2.4.43 FileStreamInformation 

756 

757 

758class FileStreamInformation(Packet): 

759 fields_desc = [ 

760 LEIntField("Next", 0), 

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

762 LELongField("StreamSize", 0), 

763 LELongField("StreamAllocationSize", 4096), 

764 StrLenFieldUtf16( 

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

766 ), 

767 ] 

768 

769 

770# [MS-DTYP] sect 2.4.1 

771 

772 

773class WINNT_SID_IDENTIFIER_AUTHORITY(Packet): 

774 fields_desc = [ 

775 StrFixedLenField("Value", b"\x00\x00\x00\x00\x00\x01", length=6), 

776 ] 

777 

778 def default_payload_class(self, payload): 

779 return conf.padding_layer 

780 

781 

782# [MS-DTYP] sect 2.4.2 

783 

784 

785class WINNT_SID(Packet): 

786 fields_desc = [ 

787 ByteField("Revision", 1), 

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

789 PacketField( 

790 "IdentifierAuthority", 

791 WINNT_SID_IDENTIFIER_AUTHORITY(), 

792 WINNT_SID_IDENTIFIER_AUTHORITY, 

793 ), 

794 FieldListField( 

795 "SubAuthority", 

796 [0], 

797 LEIntField("", 0), 

798 count_from=lambda pkt: pkt.SubAuthorityCount, 

799 ), 

800 ] 

801 

802 def default_payload_class(self, payload): 

803 return conf.padding_layer 

804 

805 _SID_REG = re.compile(r"^S-(\d)-(\d+)((?:-\d+)*)$") 

806 

807 @staticmethod 

808 def fromstr(x): 

809 m = WINNT_SID._SID_REG.match(x) 

810 if not m: 

811 raise ValueError("Invalid SID format !") 

812 rev, authority, subauthority = m.groups() 

813 return WINNT_SID( 

814 Revision=int(rev), 

815 IdentifierAuthority=WINNT_SID_IDENTIFIER_AUTHORITY( 

816 Value=struct.pack(">Q", int(authority))[2:] 

817 ), 

818 SubAuthority=[int(x) for x in subauthority[1:].split("-")], 

819 ) 

820 

821 def summary(self): 

822 return "S-%s-%s%s" % ( 

823 self.Revision, 

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

825 ( 

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

827 if self.SubAuthority 

828 else "" 

829 ), 

830 ) 

831 

832 

833# https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers 

834 

835WELL_KNOWN_SIDS = { 

836 # Universal well-known SID 

837 "S-1-0-0": "Null SID", 

838 "S-1-1-0": "Everyone", 

839 "S-1-2-0": "Local", 

840 "S-1-2-1": "Console Logon", 

841 "S-1-3-0": "Creator Owner ID", 

842 "S-1-3-1": "Creator Group ID", 

843 "S-1-3-2": "Owner Server", 

844 "S-1-3-3": "Group Server", 

845 "S-1-3-4": "Owner Rights", 

846 "S-1-4": "Non-unique Authority", 

847 "S-1-5": "NT Authority", 

848 "S-1-5-80-0": "All Services", 

849 # NT well-known SIDs 

850 "S-1-5-1": "Dialup", 

851 "S-1-5-113": "Local account", 

852 "S-1-5-114": "Local account and member of Administrators group", 

853 "S-1-5-2": "Network", 

854 "S-1-5-3": "Batch", 

855 "S-1-5-4": "Interactive", 

856 "S-1-5-6": "Service", 

857 "S-1-5-7": "Anonymous Logon", 

858 "S-1-5-8": "Proxy", 

859 "S-1-5-9": "Enterprise Domain Controllers", 

860 "S-1-5-10": "Self", 

861 "S-1-5-11": "Authenticated Users", 

862 "S-1-5-12": "Restricted Code", 

863 "S-1-5-13": "Terminal Server User", 

864 "S-1-5-14": "Remote Interactive Logon", 

865 "S-1-5-15": "This Organization", 

866 "S-1-5-17": "IUSR", 

867 "S-1-5-18": "System (or LocalSystem)", 

868 "S-1-5-19": "NT Authority (LocalService)", 

869 "S-1-5-20": "Network Service", 

870 "S-1-5-32-544": "Administrators", 

871 "S-1-5-32-545": "Users", 

872 "S-1-5-32-546": "Guests", 

873 "S-1-5-32-547": "Power Users", 

874 "S-1-5-32-548": "Account Operators", 

875 "S-1-5-32-549": "Server Operators", 

876 "S-1-5-32-550": "Print Operators", 

877 "S-1-5-32-551": "Backup Operators", 

878 "S-1-5-32-552": "Replicators", 

879 "S-1-5-32-554": r"Builtin\Pre-Windows 2000 Compatible Access", 

880 "S-1-5-32-555": r"Builtin\Remote Desktop Users", 

881 "S-1-5-32-556": r"Builtin\Network Configuration Operators", 

882 "S-1-5-32-557": r"Builtin\Incoming Forest Trust Builders", 

883 "S-1-5-32-558": r"Builtin\Performance Monitor Users", 

884 "S-1-5-32-559": r"Builtin\Performance Log Users", 

885 "S-1-5-32-560": r"Builtin\Windows Authorization Access Group", 

886 "S-1-5-32-561": r"Builtin\Terminal Server License Servers", 

887 "S-1-5-32-562": r"Builtin\Distributed COM Users", 

888 "S-1-5-32-568": r"Builtin\IIS_IUSRS", 

889 "S-1-5-32-569": r"Builtin\Cryptographic Operators", 

890 "S-1-5-32-573": r"Builtin\Event Log Readers", 

891 "S-1-5-32-574": r"Builtin\Certificate Service DCOM Access", 

892 "S-1-5-32-575": r"Builtin\RDS Remote Access Servers", 

893 "S-1-5-32-576": r"Builtin\RDS Endpoint Servers", 

894 "S-1-5-32-577": r"Builtin\RDS Management Servers", 

895 "S-1-5-32-578": r"Builtin\Hyper-V Administrators", 

896 "S-1-5-32-579": r"Builtin\Access Control Assistance Operators", 

897 "S-1-5-32-580": r"Builtin\Remote Management Users", 

898 "S-1-5-32-581": r"Builtin\Default Account", 

899 "S-1-5-32-582": r"Builtin\Storage Replica Admins", 

900 "S-1-5-32-583": r"Builtin\Device Owners", 

901 "S-1-5-64-10": "NTLM Authentication", 

902 "S-1-5-64-14": "SChannel Authentication", 

903 "S-1-5-64-21": "Digest Authentication", 

904 "S-1-5-80": "NT Service", 

905 "S-1-5-80-0": "All Services", 

906 "S-1-5-83-0": r"NT VIRTUAL MACHINE\Virtual Machines", 

907} 

908 

909 

910# [MS-DTYP] sect 2.4.3 

911 

912_WINNT_ACCESS_MASK = { 

913 0x80000000: "GENERIC_READ", 

914 0x40000000: "GENERIC_WRITE", 

915 0x20000000: "GENERIC_EXECUTE", 

916 0x10000000: "GENERIC_ALL", 

917 0x02000000: "MAXIMUM_ALLOWED", 

918 0x01000000: "ACCESS_SYSTEM_SECURITY", 

919 0x00100000: "SYNCHRONIZE", 

920 0x00080000: "WRITE_OWNER", 

921 0x00040000: "WRITE_DACL", 

922 0x00020000: "READ_CONTROL", 

923 0x00010000: "DELETE", 

924} 

925 

926 

927# [MS-DTYP] sect 2.4.4.1 

928 

929 

930WINNT_ACE_FLAGS = { 

931 0x01: "OBJECT_INHERIT", 

932 0x02: "CONTAINER_INHERIT", 

933 0x04: "NO_PROPAGATE_INHERIT", 

934 0x08: "INHERIT_ONLY", 

935 0x10: "INHERITED_ACE", 

936 0x40: "SUCCESSFUL_ACCESS", 

937 0x80: "FAILED_ACCESS", 

938} 

939 

940 

941class WINNT_ACE_HEADER(Packet): 

942 fields_desc = [ 

943 ByteEnumField( 

944 "AceType", 

945 0, 

946 { 

947 0x00: "ACCESS_ALLOWED", 

948 0x01: "ACCESS_DENIED", 

949 0x02: "SYSTEM_AUDIT", 

950 0x03: "SYSTEM_ALARM", 

951 0x04: "ACCESS_ALLOWED_COMPOUND", 

952 0x05: "ACCESS_ALLOWED_OBJECT", 

953 0x06: "ACCESS_DENIED_OBJECT", 

954 0x07: "SYSTEM_AUDIT_OBJECT", 

955 0x08: "SYSTEM_ALARM_OBJECT", 

956 0x09: "ACCESS_ALLOWED_CALLBACK", 

957 0x0A: "ACCESS_DENIED_CALLBACK", 

958 0x0B: "ACCESS_ALLOWED_CALLBACK_OBJECT", 

959 0x0C: "ACCESS_DENIED_CALLBACK_OBJECT", 

960 0x0D: "SYSTEM_AUDIT_CALLBACK", 

961 0x0E: "SYSTEM_ALARM_CALLBACK", 

962 0x0F: "SYSTEM_AUDIT_CALLBACK_OBJECT", 

963 0x10: "SYSTEM_ALARM_CALLBACK_OBJECT", 

964 0x11: "SYSTEM_MANDATORY_LABEL", 

965 0x12: "SYSTEM_RESOURCE_ATTRIBUTE", 

966 0x13: "SYSTEM_SCOPED_POLICY_ID", 

967 }, 

968 ), 

969 FlagsField( 

970 "AceFlags", 

971 0, 

972 8, 

973 WINNT_ACE_FLAGS, 

974 ), 

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

976 ] 

977 

978 def extract_padding(self, p): 

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

980 

981 # fmt: off 

982 def extractData(self, accessMask=None): 

983 """ 

984 Return the ACE data as usable data. 

985 

986 :param accessMask: context-specific flags for the ACE Mask. 

987 """ 

988 sid_string = self.payload.Sid.summary() 

989 mask = self.payload.Mask 

990 if accessMask is not None: 

991 mask = FlagValue(mask, FlagsField("", 0, 32, accessMask).names) 

992 ace_flag_string = str( 

993 FlagValue(self.AceFlags, ["OI", "CI", "NP", "IO", "ID", "SA", "FA"]) 

994 ) 

995 object_guid = getattr(self.payload, "ObjectType", "") 

996 inherit_object_guid = getattr(self.payload, "InheritedObjectType", "") 

997 # ApplicationData -> conditional expression 

998 cond_expr = None 

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

1000 # Parse tokens 

1001 res = [] 

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

1003 if ct.TokenType in [ 

1004 # binary operators 

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

1006 0xa0, 0xa1 

1007 ]: 

1008 t1 = res.pop(-1) 

1009 t0 = res.pop(-1) 

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

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

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

1013 else: 

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

1015 elif ct.TokenType in [ 

1016 # unary operators 

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

1018 ]: 

1019 t0 = res.pop(-1) 

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

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

1022 elif ct.TokenType in [ 

1023 # values 

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

1025 0xfa, 0xfb 

1026 ]: 

1027 def lit(ct): 

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

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

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

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

1032 else: 

1033 return str(ct.value) 

1034 res.append(lit(ct)) 

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

1036 pass 

1037 else: 

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

1039 if len(res) != 1: 

1040 raise ValueError("Incomplete SDDL !") 

1041 cond_expr = "(%s)" % res[0] 

1042 return { 

1043 "ace-flags-string": ace_flag_string, 

1044 "sid-string": sid_string, 

1045 "mask": mask, 

1046 "object-guid": object_guid, 

1047 "inherited-object-guid": inherit_object_guid, 

1048 "cond-expr": cond_expr, 

1049 } 

1050 # fmt: on 

1051 

1052 def toSDDL(self, accessMask=None): 

1053 """ 

1054 Return SDDL 

1055 """ 

1056 data = self.extractData(accessMask=accessMask) 

1057 ace_rights = "" # TODO 

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

1059 conditional_ace_type = { 

1060 0x09: "XA", 

1061 0x0A: "XD", 

1062 0x0B: "XU", 

1063 0x0D: "ZA", 

1064 }[self.AceType] 

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

1066 ";".join( 

1067 x 

1068 for x in [ 

1069 conditional_ace_type, 

1070 data["ace-flags-string"], 

1071 ace_rights, 

1072 str(data["object-guid"]), 

1073 str(data["inherited-object-guid"]), 

1074 data["sid-string"], 

1075 data["cond-expr"], 

1076 ] 

1077 if x is not None 

1078 ) 

1079 ) 

1080 else: 

1081 ace_type = { 

1082 0x00: "A", 

1083 0x01: "D", 

1084 0x02: "AU", 

1085 0x05: "OA", 

1086 0x06: "OD", 

1087 0x07: "OU", 

1088 0x11: "ML", 

1089 0x13: "SP", 

1090 }[self.AceType] 

1091 return "(%s)" % ( 

1092 ";".join( 

1093 x 

1094 for x in [ 

1095 ace_type, 

1096 data["ace-flags-string"], 

1097 ace_rights, 

1098 str(data["object-guid"]), 

1099 str(data["inherited-object-guid"]), 

1100 data["sid-string"], 

1101 data["cond-expr"], 

1102 ] 

1103 if x is not None 

1104 ) 

1105 ) 

1106 

1107 

1108# [MS-DTYP] sect 2.4.4.2 

1109 

1110 

1111class WINNT_ACCESS_ALLOWED_ACE(Packet): 

1112 fields_desc = [ 

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

1114 PacketField("Sid", WINNT_SID(), WINNT_SID), 

1115 ] 

1116 

1117 

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

1119 

1120 

1121# [MS-DTYP] sect 2.4.4.3 

1122 

1123 

1124class WINNT_ACCESS_ALLOWED_OBJECT_ACE(Packet): 

1125 fields_desc = [ 

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

1127 FlagsField( 

1128 "Flags", 

1129 0, 

1130 -32, 

1131 { 

1132 0x00000001: "OBJECT_TYPE_PRESENT", 

1133 0x00000002: "INHERITED_OBJECT_TYPE_PRESENT", 

1134 }, 

1135 ), 

1136 ConditionalField( 

1137 UUIDField("ObjectType", None, uuid_fmt=UUIDField.FORMAT_LE), 

1138 lambda pkt: pkt.Flags.OBJECT_TYPE_PRESENT, 

1139 ), 

1140 ConditionalField( 

1141 UUIDField("InheritedObjectType", None, uuid_fmt=UUIDField.FORMAT_LE), 

1142 lambda pkt: pkt.Flags.INHERITED_OBJECT_TYPE_PRESENT, 

1143 ), 

1144 PacketField("Sid", WINNT_SID(), WINNT_SID), 

1145 ] 

1146 

1147 

1148bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_ALLOWED_OBJECT_ACE, AceType=0x05) 

1149 

1150 

1151# [MS-DTYP] sect 2.4.4.4 

1152 

1153 

1154class WINNT_ACCESS_DENIED_ACE(Packet): 

1155 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc 

1156 

1157 

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

1159 

1160 

1161# [MS-DTYP] sect 2.4.4.5 

1162 

1163 

1164class WINNT_ACCESS_DENIED_OBJECT_ACE(Packet): 

1165 fields_desc = WINNT_ACCESS_ALLOWED_OBJECT_ACE.fields_desc 

1166 

1167 

1168bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_DENIED_OBJECT_ACE, AceType=0x06) 

1169 

1170 

1171# [MS-DTYP] sect 2.4.4.17.4+ 

1172 

1173 

1174class WINNT_APPLICATION_DATA_LITERAL_TOKEN(Packet): 

1175 def default_payload_class(self, payload): 

1176 return conf.padding_layer 

1177 

1178 

1179# fmt: off 

1180WINNT_APPLICATION_DATA_LITERAL_TOKEN.fields_desc = [ 

1181 ByteEnumField( 

1182 "TokenType", 

1183 0, 

1184 { 

1185 # [MS-DTYP] sect 2.4.4.17.5 

1186 0x00: "Padding token", 

1187 0x01: "Signed int8", 

1188 0x02: "Signed int16", 

1189 0x03: "Signed int32", 

1190 0x04: "Signed int64", 

1191 0x10: "Unicode", 

1192 0x18: "Octet String", 

1193 0x50: "Composite", 

1194 0x51: "SID", 

1195 # [MS-DTYP] sect 2.4.4.17.6 

1196 0x80: "==", 

1197 0x81: "!=", 

1198 0x82: "<", 

1199 0x83: "<=", 

1200 0x84: ">", 

1201 0x85: ">=", 

1202 0x86: "Contains", 

1203 0x88: "Any_of", 

1204 0x8e: "Not_Contains", 

1205 0x8f: "Not_Any_of", 

1206 0x89: "Member_of", 

1207 0x8a: "Device_Member_of", 

1208 0x8b: "Member_of_Any", 

1209 0x8c: "Device_Member_of_Any", 

1210 0x90: "Not_Member_of", 

1211 0x91: "Not_Device_Member_of", 

1212 0x92: "Not_Member_of_Any", 

1213 0x93: "Not_Device_Member_of_Any", 

1214 # [MS-DTYP] sect 2.4.4.17.7 

1215 0x87: "Exists", 

1216 0x8d: "Not_Exists", 

1217 0xa0: "&&", 

1218 0xa1: "||", 

1219 0xa2: "!", 

1220 # [MS-DTYP] sect 2.4.4.17.8 

1221 0xf8: "Local attribute", 

1222 0xf9: "User Attribute", 

1223 0xfa: "Resource Attribute", 

1224 0xfb: "Device Attribute", 

1225 } 

1226 ), 

1227 ConditionalField( 

1228 # Strings 

1229 LEIntField("length", 0), 

1230 lambda pkt: pkt.TokenType in [ 

1231 0x10, # Unicode string 

1232 0x18, # Octet string 

1233 0xf8, 0xf9, 0xfa, 0xfb, # Attribute tokens 

1234 0x50, # Composite 

1235 ] 

1236 ), 

1237 ConditionalField( 

1238 MultipleTypeField( 

1239 [ 

1240 ( 

1241 LELongField("value", 0), 

1242 lambda pkt: pkt.TokenType in [ 

1243 0x01, # signed int8 

1244 0x02, # signed int16 

1245 0x03, # signed int32 

1246 0x04, # signed int64 

1247 ] 

1248 ), 

1249 ( 

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

1251 lambda pkt: pkt.TokenType in [ 

1252 0x10, # Unicode string 

1253 0xf8, 0xf9, 0xfa, 0xfb, # Attribute tokens 

1254 ] 

1255 ), 

1256 ( 

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

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

1259 ), 

1260 ( 

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

1262 length_from=lambda pkt: pkt.length), 

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

1264 ), 

1265 

1266 ], 

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

1268 ), 

1269 lambda pkt: pkt.TokenType in [ 

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

1271 ] 

1272 ), 

1273 ConditionalField( 

1274 # Literal 

1275 ByteEnumField("sign", 0, { 

1276 0x01: "+", 

1277 0x02: "-", 

1278 0x03: "None", 

1279 }), 

1280 lambda pkt: pkt.TokenType in [ 

1281 0x01, # signed int8 

1282 0x02, # signed int16 

1283 0x03, # signed int32 

1284 0x04, # signed int64 

1285 ] 

1286 ), 

1287 ConditionalField( 

1288 # Literal 

1289 ByteEnumField("base", 0, { 

1290 0x01: "Octal", 

1291 0x02: "Decimal", 

1292 0x03: "Hexadecimal", 

1293 }), 

1294 lambda pkt: pkt.TokenType in [ 

1295 0x01, # signed int8 

1296 0x02, # signed int16 

1297 0x03, # signed int32 

1298 0x04, # signed int64 

1299 ] 

1300 ), 

1301] 

1302# fmt: on 

1303 

1304 

1305class WINNT_APPLICATION_DATA(Packet): 

1306 fields_desc = [ 

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

1308 PacketListField( 

1309 "Tokens", 

1310 [], 

1311 WINNT_APPLICATION_DATA_LITERAL_TOKEN, 

1312 ), 

1313 ] 

1314 

1315 def default_payload_class(self, payload): 

1316 return conf.padding_layer 

1317 

1318 

1319# [MS-DTYP] sect 2.4.4.6 

1320 

1321 

1322class WINNT_ACCESS_ALLOWED_CALLBACK_ACE(Packet): 

1323 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc + [ 

1324 PacketField( 

1325 "ApplicationData", WINNT_APPLICATION_DATA(), WINNT_APPLICATION_DATA 

1326 ), 

1327 ] 

1328 

1329 

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

1331 

1332 

1333# [MS-DTYP] sect 2.4.4.7 

1334 

1335 

1336class WINNT_ACCESS_DENIED_CALLBACK_ACE(Packet): 

1337 fields_desc = WINNT_ACCESS_ALLOWED_CALLBACK_ACE.fields_desc 

1338 

1339 

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

1341 

1342 

1343# [MS-DTYP] sect 2.4.4.8 

1344 

1345 

1346class WINNT_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE(Packet): 

1347 fields_desc = WINNT_ACCESS_ALLOWED_OBJECT_ACE.fields_desc + [ 

1348 PacketField( 

1349 "ApplicationData", WINNT_APPLICATION_DATA(), WINNT_APPLICATION_DATA 

1350 ), 

1351 ] 

1352 

1353 

1354bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE, AceType=0x0B) 

1355 

1356 

1357# [MS-DTYP] sect 2.4.4.9 

1358 

1359 

1360class WINNT_ACCESS_DENIED_CALLBACK_OBJECT_ACE(Packet): 

1361 fields_desc = WINNT_ACCESS_DENIED_OBJECT_ACE.fields_desc + [ 

1362 PacketField( 

1363 "ApplicationData", WINNT_APPLICATION_DATA(), WINNT_APPLICATION_DATA 

1364 ), 

1365 ] 

1366 

1367 

1368bind_layers(WINNT_ACE_HEADER, WINNT_ACCESS_DENIED_CALLBACK_OBJECT_ACE, AceType=0x0C) 

1369 

1370 

1371# [MS-DTYP] sect 2.4.4.10 

1372 

1373 

1374class WINNT_SYSTEM_AUDIT_ACE(Packet): 

1375 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc 

1376 

1377 

1378bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_AUDIT_ACE, AceType=0x02) 

1379 

1380 

1381# [MS-DTYP] sect 2.4.4.11 

1382 

1383 

1384class WINNT_SYSTEM_AUDIT_OBJECT_ACE(Packet): 

1385 # doc is wrong. 

1386 fields_desc = WINNT_ACCESS_ALLOWED_OBJECT_ACE.fields_desc 

1387 

1388 

1389bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_AUDIT_OBJECT_ACE, AceType=0x07) 

1390 

1391 

1392# [MS-DTYP] sect 2.4.4.12 

1393 

1394 

1395class WINNT_SYSTEM_AUDIT_CALLBACK_ACE(Packet): 

1396 fields_desc = WINNT_SYSTEM_AUDIT_ACE.fields_desc + [ 

1397 PacketField( 

1398 "ApplicationData", WINNT_APPLICATION_DATA(), WINNT_APPLICATION_DATA 

1399 ), 

1400 ] 

1401 

1402 

1403bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_AUDIT_CALLBACK_ACE, AceType=0x0D) 

1404 

1405 

1406# [MS-DTYP] sect 2.4.4.13 

1407 

1408 

1409class WINNT_SYSTEM_MANDATORY_LABEL_ACE(Packet): 

1410 fields_desc = WINNT_SYSTEM_AUDIT_ACE.fields_desc 

1411 

1412 

1413bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_MANDATORY_LABEL_ACE, AceType=0x11) 

1414 

1415 

1416# [MS-DTYP] sect 2.4.4.14 

1417 

1418 

1419class WINNT_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE(Packet): 

1420 fields_desc = WINNT_SYSTEM_AUDIT_OBJECT_ACE.fields_desc 

1421 

1422 

1423bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE, AceType=0x0F) 

1424 

1425# [MS-DTYP] sect 2.4.10.1 

1426 

1427 

1428class CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1(_NTLMPayloadPacket): 

1429 _NTLM_PAYLOAD_FIELD_NAME = "Data" 

1430 fields_desc = [ 

1431 LEIntField("NameOffset", 0), 

1432 LEShortEnumField( 

1433 "ValueType", 

1434 0, 

1435 { 

1436 0x0001: "CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64", 

1437 0x0002: "CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64", 

1438 0x0003: "CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING", 

1439 0x0005: "CLAIM_SECURITY_ATTRIBUTE_TYPE_SID", 

1440 0x0006: "CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN", 

1441 0x0010: "CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING", 

1442 }, 

1443 ), 

1444 LEShortField("Reserved", 0), 

1445 FlagsField( 

1446 "Flags", 

1447 0, 

1448 -32, 

1449 { 

1450 0x0001: "CLAIM_SECURITY_ATTRIBUTE_NON_INHERITABLE", 

1451 0x0002: "CLAIM_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE", 

1452 0x0004: "CLAIM_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY", 

1453 0x0008: "CLAIM_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT", 

1454 0x0010: "CLAIM_SECURITY_ATTRIBUTE_DISABLED", 

1455 0x0020: "CLAIM_SECURITY_ATTRIBUTE_MANDATORY", 

1456 }, 

1457 ), 

1458 LEIntField("ValueCount", 0), 

1459 FieldListField( 

1460 "ValueOffsets", [], LEIntField("", 0), count_from=lambda pkt: pkt.ValueCount 

1461 ), 

1462 _NTLMPayloadField( 

1463 "Data", 

1464 lambda pkt: 16 + pkt.ValueCount * 4, 

1465 [ 

1466 ConditionalField( 

1467 StrFieldUtf16("Name", b""), 

1468 lambda pkt: pkt.NameOffset, 

1469 ), 

1470 # TODO: Values 

1471 ], 

1472 offset_name="Offset", 

1473 ), 

1474 ] 

1475 

1476 

1477# [MS-DTYP] sect 2.4.4.15 

1478 

1479 

1480class WINNT_SYSTEM_RESOURCE_ATTRIBUTE_ACE(Packet): 

1481 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc + [ 

1482 PacketField( 

1483 "AttributeData", 

1484 CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1(), 

1485 CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1, 

1486 ) 

1487 ] 

1488 

1489 

1490bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_RESOURCE_ATTRIBUTE_ACE, AceType=0x12) 

1491 

1492# [MS-DTYP] sect 2.4.4.16 

1493 

1494 

1495class WINNT_SYSTEM_SCOPED_POLICY_ID_ACE(Packet): 

1496 fields_desc = WINNT_ACCESS_ALLOWED_ACE.fields_desc 

1497 

1498 

1499bind_layers(WINNT_ACE_HEADER, WINNT_SYSTEM_SCOPED_POLICY_ID_ACE, AceType=0x13) 

1500 

1501# [MS-DTYP] sect 2.4.5 

1502 

1503 

1504class WINNT_ACL(Packet): 

1505 fields_desc = [ 

1506 ByteField("AclRevision", 2), 

1507 ByteField("Sbz1", 0x00), 

1508 # Total size including header: 

1509 # AclRevision(1) + Sbz1(1) + AclSize(2) + AceCount(2) + Sbz2(2) 

1510 FieldLenField( 

1511 "AclSize", 

1512 None, 

1513 length_of="Aces", 

1514 adjust=lambda _, x: x + 8, 

1515 fmt="<H", 

1516 ), 

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

1518 ShortField("Sbz2", 0), 

1519 PacketListField( 

1520 "Aces", 

1521 [], 

1522 WINNT_ACE_HEADER, 

1523 count_from=lambda pkt: pkt.AceCount, 

1524 ), 

1525 ] 

1526 

1527 def toSDDL(self): 

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

1529 

1530 

1531# [MS-DTYP] 2.4.6 SECURITY_DESCRIPTOR 

1532 

1533 

1534class SECURITY_DESCRIPTOR(_NTLMPayloadPacket): 

1535 OFFSET = 20 

1536 _NTLM_PAYLOAD_FIELD_NAME = "Data" 

1537 fields_desc = [ 

1538 ByteField("Revision", 0x01), 

1539 ByteField("Sbz1", 0x00), 

1540 FlagsField( 

1541 "Control", 

1542 0x00, 

1543 -16, 

1544 [ 

1545 "OWNER_DEFAULTED", 

1546 "GROUP_DEFAULTED", 

1547 "DACL_PRESENT", 

1548 "DACL_DEFAULTED", 

1549 "SACL_PRESENT", 

1550 "SACL_DEFAULTED", 

1551 "DACL_TRUSTED", 

1552 "SERVER_SECURITY", 

1553 "DACL_COMPUTED", 

1554 "SACL_COMPUTED", 

1555 "DACL_AUTO_INHERITED", 

1556 "SACL_AUTO_INHERITED", 

1557 "DACL_PROTECTED", 

1558 "SACL_PROTECTED", 

1559 "RM_CONTROL_VALID", 

1560 "SELF_RELATIVE", 

1561 ], 

1562 ), 

1563 LEIntField("OwnerSidOffset", None), 

1564 LEIntField("GroupSidOffset", None), 

1565 LEIntField("SACLOffset", None), 

1566 LEIntField("DACLOffset", None), 

1567 _NTLMPayloadField( 

1568 "Data", 

1569 OFFSET, 

1570 [ 

1571 ConditionalField( 

1572 PacketField("OwnerSid", WINNT_SID(), WINNT_SID), 

1573 lambda pkt: pkt.OwnerSidOffset != 0, 

1574 ), 

1575 ConditionalField( 

1576 PacketField("GroupSid", WINNT_SID(), WINNT_SID), 

1577 lambda pkt: pkt.GroupSidOffset != 0, 

1578 ), 

1579 ConditionalField( 

1580 PacketField("SACL", WINNT_ACL(), WINNT_ACL), 

1581 lambda pkt: pkt.Control.SACL_PRESENT, 

1582 ), 

1583 ConditionalField( 

1584 PacketField("DACL", WINNT_ACL(), WINNT_ACL), 

1585 lambda pkt: pkt.Control.DACL_PRESENT, 

1586 ), 

1587 ], 

1588 offset_name="Offset", 

1589 ), 

1590 ] 

1591 

1592 def post_build(self, pkt, pay): 

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

1594 return ( 

1595 _NTLM_post_build( 

1596 self, 

1597 pkt, 

1598 self.OFFSET, 

1599 { 

1600 "OwnerSid": 4, 

1601 "GroupSid": 8, 

1602 "SACL": 12, 

1603 "DACL": 16, 

1604 }, 

1605 config=[ 

1606 ("Offset", _NTLM_ENUM.OFFSET), 

1607 ], 

1608 ) 

1609 + pay 

1610 ) 

1611 

1612 

1613# [MS-FSCC] 2.4.2 FileAllInformation 

1614 

1615 

1616class FileAllInformation(Packet): 

1617 fields_desc = [ 

1618 PacketField("BasicInformation", FileBasicInformation(), FileBasicInformation), 

1619 PacketField( 

1620 "StandardInformation", FileStandardInformation(), FileStandardInformation 

1621 ), 

1622 PacketField( 

1623 "InternalInformation", FileInternalInformation(), FileInternalInformation 

1624 ), 

1625 PacketField("EaInformation", FileEaInformation(), FileEaInformation), 

1626 PacketField( 

1627 "AccessInformation", FileAccessInformation(), FileAccessInformation 

1628 ), 

1629 PacketField( 

1630 "PositionInformation", FilePositionInformation(), FilePositionInformation 

1631 ), 

1632 PacketField("ModeInformation", FileModeInformation(), FileModeInformation), 

1633 PacketField( 

1634 "AlignmentInformation", FileAlignmentInformation(), FileAlignmentInformation 

1635 ), 

1636 PacketField("NameInformation", FILE_NAME_INFORMATION(), FILE_NAME_INFORMATION), 

1637 ] 

1638 

1639 

1640# [MS-FSCC] 2.5.1 FileFsAttributeInformation 

1641 

1642 

1643class FileFsAttributeInformation(Packet): 

1644 fields_desc = [ 

1645 FlagsField( 

1646 "FileSystemAttributes", 

1647 0x00C706FF, 

1648 -32, 

1649 { 

1650 0x02000000: "FILE_SUPPORTS_USN_JOURNAL", 

1651 0x01000000: "FILE_SUPPORTS_OPEN_BY_FILE_ID", 

1652 0x00800000: "FILE_SUPPORTS_EXTENDED_ATTRIBUTES", 

1653 0x00400000: "FILE_SUPPORTS_HARD_LINKS", 

1654 0x00200000: "FILE_SUPPORTS_TRANSACTIONS", 

1655 0x00100000: "FILE_SEQUENTIAL_WRITE_ONCE", 

1656 0x00080000: "FILE_READ_ONLY_VOLUME", 

1657 0x00040000: "FILE_NAMED_STREAMS", 

1658 0x00020000: "FILE_SUPPORTS_ENCRYPTION", 

1659 0x00010000: "FILE_SUPPORTS_OBJECT_IDS", 

1660 0x00008000: "FILE_VOLUME_IS_COMPRESSED", 

1661 0x00000100: "FILE_SUPPORTS_REMOTE_STORAGE", 

1662 0x00000080: "FILE_SUPPORTS_REPARSE_POINTS", 

1663 0x00000040: "FILE_SUPPORTS_SPARSE_FILES", 

1664 0x00000020: "FILE_VOLUME_QUOTAS", 

1665 0x00000010: "FILE_FILE_COMPRESSION", 

1666 0x00000008: "FILE_PERSISTENT_ACLS", 

1667 0x00000004: "FILE_UNICODE_ON_DISK", 

1668 0x00000002: "FILE_CASE_PRESERVED_NAMES", 

1669 0x00000001: "FILE_CASE_SENSITIVE_SEARCH", 

1670 0x04000000: "FILE_SUPPORT_INTEGRITY_STREAMS", 

1671 0x08000000: "FILE_SUPPORTS_BLOCK_REFCOUNTING", 

1672 0x10000000: "FILE_SUPPORTS_SPARSE_VDL", 

1673 }, 

1674 ), 

1675 LEIntField("MaximumComponentNameLength", 255), 

1676 FieldLenField( 

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

1678 ), 

1679 StrLenFieldUtf16( 

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

1681 ), 

1682 ] 

1683 

1684 

1685# [MS-FSCC] 2.5.8 FileFsSizeInformation 

1686 

1687 

1688class FileFsSizeInformation(Packet): 

1689 fields_desc = [ 

1690 LELongField("TotalAllocationUnits", 10485760), 

1691 LELongField("AvailableAllocationUnits", 1048576), 

1692 LEIntField("SectorsPerAllocationUnit", 8), 

1693 LEIntField("BytesPerSector", 512), 

1694 ] 

1695 

1696 

1697# [MS-FSCC] 2.5.9 FileFsVolumeInformation 

1698 

1699 

1700class FileFsVolumeInformation(Packet): 

1701 fields_desc = [ 

1702 UTCTimeField( 

1703 "VolumeCreationTime", 

1704 None, 

1705 fmt="<Q", 

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

1707 custom_scaling=1e7, 

1708 ), 

1709 LEIntField("VolumeSerialNumber", 0), 

1710 LEIntField("VolumeLabelLength", 0), 

1711 ByteField("SupportsObjects", 1), 

1712 ByteField("Reserved", 0), 

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

1714 ] 

1715 

1716 

1717# [MS-FSCC] 2.7.1 FILE_NOTIFY_INFORMATION 

1718 

1719 

1720class FILE_NOTIFY_INFORMATION(Packet): 

1721 fields_desc = [ 

1722 IntField("NextEntryOffset", 0), 

1723 LEIntEnumField( 

1724 "Action", 

1725 0, 

1726 { 

1727 0x00000001: "FILE_ACTION_ADDED", 

1728 0x00000002: "FILE_ACTION_REMOVED", 

1729 0x00000003: "FILE_ACTION_MODIFIED", 

1730 0x00000004: "FILE_ACTION_RENAMED_OLD_NAME", 

1731 0x00000005: "FILE_ACTION_RENAMED_NEW_NAME", 

1732 0x00000006: "FILE_ACTION_ADDED_STREAM", 

1733 0x00000007: "FILE_ACTION_REMOVED_STREAM", 

1734 0x00000008: "FILE_ACTION_MODIFIED_STREAM", 

1735 0x00000009: "FILE_ACTION_REMOVED_BY_DELETE", 

1736 0x0000000A: "FILE_ACTION_ID_NOT_TUNNELLED", 

1737 0x0000000B: "FILE_ACTION_TUNNELLED_ID_COLLISION", 

1738 }, 

1739 ), 

1740 FieldLenField( 

1741 "FileNameLength", 

1742 None, 

1743 length_of="FileName", 

1744 fmt="<I", 

1745 ), 

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

1747 StrLenField( 

1748 "pad", 

1749 b"", 

1750 length_from=lambda x: ( 

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

1752 ), 

1753 ), 

1754 ] 

1755 

1756 def default_payload_class(self, s): 

1757 return conf.padding_layer 

1758 

1759 

1760_SMB2_CONFIG = [ 

1761 ("BufferOffset", _NTLM_ENUM.OFFSET), 

1762 ("Len", _NTLM_ENUM.LEN), 

1763] 

1764 

1765 

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

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

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

1769 

1770 

1771# SMB2 sect 2.1 

1772 

1773 

1774class DirectTCP(NBTSession): 

1775 name = "Direct TCP" 

1776 MAXLENGTH = 0xFFFFFF 

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

1778 

1779 

1780# SMB2 sect 2.2.1.1 

1781 

1782 

1783class SMB2_Header(Packet): 

1784 __slots__ = ["_decrypted"] 

1785 

1786 name = "SMB2 Header" 

1787 fields_desc = [ 

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

1789 LEShortField("StructureSize", 64), 

1790 LEShortField("CreditCharge", 0), 

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

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

1793 LEShortField("CreditRequest", 0), 

1794 FlagsField( 

1795 "Flags", 

1796 0, 

1797 -32, 

1798 { 

1799 0x00000001: "SMB2_FLAGS_SERVER_TO_REDIR", 

1800 0x00000002: "SMB2_FLAGS_ASYNC_COMMAND", 

1801 0x00000004: "SMB2_FLAGS_RELATED_OPERATIONS", 

1802 0x00000008: "SMB2_FLAGS_SIGNED", 

1803 0x10000000: "SMB2_FLAGS_DFS_OPERATIONS", 

1804 0x20000000: "SMB2_FLAGS_REPLAY_OPERATION", 

1805 }, 

1806 ), 

1807 XLEIntField("NextCommand", 0), 

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

1809 # ASYNC 

1810 ConditionalField( 

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

1812 ), 

1813 # SYNC 

1814 ConditionalField( 

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

1816 lambda pkt: not pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND, 

1817 ), 

1818 ConditionalField( 

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

1820 lambda pkt: not pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND, 

1821 ), 

1822 # COMMON 

1823 LELongField("SessionId", 0), 

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

1825 ] 

1826 

1827 _SMB2_OK_RETURNCODES = ( 

1828 # sect 3.3.4.4 

1829 (0xC0000016, 0x0001), # STATUS_MORE_PROCESSING_REQUIRED 

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

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

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

1833 (0xC000000D, 0x000B), # STATUS_INVALID_PARAMETER 

1834 (0x0000010C, 0x000F), # STATUS_NOTIFY_ENUM_DIR 

1835 ) 

1836 

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

1838 # The parent passes whether this packet was decrypted or not. 

1839 self._decrypted = kwargs.pop("_decrypted", False) 

1840 super(SMB2_Header, self).__init__(*args, **kwargs) 

1841 

1842 def guess_payload_class(self, payload): 

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

1844 # Check status for responses 

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

1846 return SMB2_Error_Response 

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

1848 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1849 return SMB2_Negotiate_Protocol_Response 

1850 return SMB2_Negotiate_Protocol_Request 

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

1852 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1853 return SMB2_Session_Setup_Response 

1854 return SMB2_Session_Setup_Request 

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

1856 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1857 return SMB2_Session_Logoff_Response 

1858 return SMB2_Session_Logoff_Request 

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

1860 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1861 return SMB2_Tree_Connect_Response 

1862 return SMB2_Tree_Connect_Request 

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

1864 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1865 return SMB2_Tree_Disconnect_Response 

1866 return SMB2_Tree_Disconnect_Request 

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

1868 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1869 return SMB2_Create_Response 

1870 return SMB2_Create_Request 

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

1872 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1873 return SMB2_Close_Response 

1874 return SMB2_Close_Request 

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

1876 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1877 return SMB2_Read_Response 

1878 return SMB2_Read_Request 

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

1880 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1881 return SMB2_Write_Response 

1882 return SMB2_Write_Request 

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

1884 return SMB2_Cancel_Request 

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

1886 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1887 return SMB2_Echo_Response 

1888 return SMB2_Echo_Request 

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

1890 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1891 return SMB2_Query_Directory_Response 

1892 return SMB2_Query_Directory_Request 

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

1894 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1895 return SMB2_Change_Notify_Response 

1896 return SMB2_Change_Notify_Request 

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

1898 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1899 return SMB2_Query_Info_Response 

1900 return SMB2_Query_Info_Request 

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

1902 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1903 return SMB2_Set_Info_Response 

1904 return SMB2_Set_Info_Request 

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

1906 if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: 

1907 return SMB2_IOCTL_Response 

1908 return SMB2_IOCTL_Request 

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

1910 

1911 def _calc_signature( 

1912 self, s, dialect, SigningSessionKey, SigningAlgorithmId=None, IsClient=None 

1913 ): 

1914 """ 

1915 This function calculates the signature of a SMB2 packet. 

1916 Detail is from [MS-SMB2] 3.1.4.1 

1917 """ 

1918 if len(s) <= 64: 

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

1920 return s 

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

1922 if dialect == 0x0311: # SMB 3.1.1 

1923 if IsClient is None: 

1924 raise Exception("SMB 3.1.1 needs a IsClient") 

1925 if SigningAlgorithmId is None: 

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

1927 else: 

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

1929 if "GMAC" in SigningAlgorithmId: 

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

1931 

1932 aesgcm = AESGCM(SigningSessionKey) 

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

1934 "<I", 

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

1936 ) 

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

1938 elif "CMAC" in SigningAlgorithmId: 

1939 from cryptography.hazmat.primitives import cmac 

1940 from cryptography.hazmat.primitives.ciphers import algorithms 

1941 

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

1943 c.update(s) 

1944 sig = c.finalize() 

1945 elif "HMAC" in SigningAlgorithmId: 

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

1947 

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

1949 sig = sig[:16] 

1950 else: 

1951 raise ValueError("Unknown SigningAlgorithmId") 

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

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

1954 

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

1956 sig = sig[:16] 

1957 else: 

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

1959 sig = b"\x00" * 16 

1960 return sig 

1961 

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

1963 """ 

1964 [MS-SMB2] 3.1.4.1 - Signing An Outgoing Message 

1965 """ 

1966 # Set the current signature to nul 

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

1968 # Calculate the signature 

1969 s = bytes(self) 

1970 self.SecuritySignature = self._calc_signature( 

1971 s, 

1972 dialect=dialect, 

1973 SigningSessionKey=SigningSessionKey, 

1974 SigningAlgorithmId=SigningAlgorithmId, 

1975 IsClient=IsClient, 

1976 ) 

1977 # we make sure the payload is static 

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

1979 

1980 def verify( 

1981 self, dialect, SigningSessionKey, SigningAlgorithmId=None, IsClient=None 

1982 ): 

1983 """ 

1984 [MS-SMB2] sect 3.2.5.1.3 - Verifying the signature 

1985 """ 

1986 s = bytes(self) 

1987 # Set SecuritySignature to nul 

1988 s = s[:48] + b"\x00" * 16 + s[64:] 

1989 # Calculate the signature 

1990 sig = self._calc_signature( 

1991 s, 

1992 dialect=dialect, 

1993 SigningSessionKey=SigningSessionKey, 

1994 SigningAlgorithmId=SigningAlgorithmId, 

1995 IsClient=IsClient, 

1996 ) 

1997 if self.SecuritySignature != sig: 

1998 log_runtime.error("SMB signature is invalid !") 

1999 raise Exception("ERROR: SMB signature is invalid !") 

2000 

2001 def encrypt(self, dialect, EncryptionKey, CipherId): 

2002 """ 

2003 [MS-SMB2] sect 3.1.4.3 - Encrypting the Message 

2004 """ 

2005 if dialect < 0x0300: 

2006 raise Exception("Encryption is not supported on this SMB dialect !") 

2007 elif dialect < 0x0311 and CipherId != "AES-128-CCM": 

2008 raise Exception("CipherId is not supported on this SMB dialect !") 

2009 

2010 data = bytes(self) 

2011 smbt = SMB2_Transform_Header( 

2012 OriginalMessageSize=len(self), 

2013 SessionId=self.SessionId, 

2014 Flags=0x0001, 

2015 ) 

2016 if "GCM" in CipherId: 

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

2018 

2019 nonce = os.urandom(12) 

2020 cipher = AESGCM(EncryptionKey) 

2021 elif "CCM" in CipherId: 

2022 from cryptography.hazmat.primitives.ciphers.aead import AESCCM 

2023 

2024 nonce = os.urandom(11) 

2025 cipher = AESCCM(EncryptionKey) 

2026 else: 

2027 raise Exception("Unknown CipherId !") 

2028 

2029 # Add nonce to header and build the auth data 

2030 smbt.Nonce = nonce 

2031 aad = bytes(smbt)[20:] 

2032 

2033 # Perform the actual encryption 

2034 data = cipher.encrypt(nonce, data, aad) 

2035 

2036 # Put the auth tag in the Signature field 

2037 smbt.Signature, data = data[-16:], data[:-16] 

2038 

2039 return smbt / data 

2040 

2041 

2042class _SMB2_Payload(Packet): 

2043 def do_dissect_payload(self, s): 

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

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

2046 if self.underlayer.NextCommand: 

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

2048 if padlen: 

2049 self.add_payload(s[:padlen]) 

2050 s = s[padlen:] 

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

2052 

2053 def answers(self, other): 

2054 return ( 

2055 isinstance(other, _SMB2_Payload) 

2056 and self.__class__ != other.__class__ 

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

2058 ) 

2059 

2060 def guess_payload_class(self, s): 

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

2062 if self.underlayer.NextCommand: 

2063 return SMB2_Header 

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

2065 

2066 

2067# sect 2.2.2 

2068 

2069 

2070class SMB2_Error_Response(_SMB2_Payload): 

2071 Command = -1 

2072 __slots__ = ["NTStatus"] # extra info 

2073 name = "SMB2 Error Response" 

2074 fields_desc = [ 

2075 XLEShortField("StructureSize", 0x09), 

2076 ByteField("ErrorContextCount", 0), 

2077 ByteField("Reserved", 0), 

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

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

2080 ] 

2081 

2082 

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

2084 

2085# sect 2.2.2.2.2 

2086 

2087 

2088class MOVE_DST_IPADDR(Packet): 

2089 fields_desc = [ 

2090 # Wireshark appears to get this wrong 

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

2092 IntField("Reserved", 0), 

2093 MultipleTypeField( 

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

2095 IPField("IPAddress", None), 

2096 ), 

2097 ConditionalField( 

2098 # For IPv4 

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

2100 lambda pkt: pkt.Type == 1, 

2101 ), 

2102 ] 

2103 

2104 def default_payload_class(self, payload): 

2105 return conf.padding_layer 

2106 

2107 

2108class SMB2_Error_Share_Redirect_Context_Response(_NTLMPayloadPacket): 

2109 name = "Share Redirect Error Context Response" 

2110 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2111 fields_desc = [ 

2112 XLEIntField("StructureSize", 0x30), 

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

2114 XLEIntField("ResourceNameBufferOffset", None), 

2115 LEIntField("ResourceNameLen", None), 

2116 ShortField("Reserved", 0), 

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

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

2119 PacketListField( 

2120 "IPAddrMoveList", 

2121 [], 

2122 MOVE_DST_IPADDR, 

2123 count_from=lambda pkt: pkt.IPAddrCount, 

2124 ), 

2125 _NTLMPayloadField( 

2126 "Buffer", 

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

2128 [ 

2129 StrLenFieldUtf16( 

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

2131 ), 

2132 ], 

2133 ), 

2134 ] 

2135 

2136 def post_build(self, pkt, pay): 

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

2138 return ( 

2139 _SMB2_post_build( 

2140 self, 

2141 pkt, 

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

2143 { 

2144 "ResourceName": 8, 

2145 }, 

2146 ) 

2147 + pay 

2148 ) 

2149 

2150 

2151# sect 2.2.2.1 

2152 

2153 

2154class SMB2_Error_ContextResponse(Packet): 

2155 fields_desc = [ 

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

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

2158 MultipleTypeField( 

2159 [ 

2160 ( 

2161 PacketField( 

2162 "ErrorContextData", 

2163 SMB2_Error_Share_Redirect_Context_Response(), 

2164 SMB2_Error_Share_Redirect_Context_Response, 

2165 ), 

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

2167 ) 

2168 ], 

2169 XStrLenField( 

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

2171 ), 

2172 ), 

2173 ] 

2174 

2175 

2176# sect 2.2.3 

2177 

2178 

2179class SMB2_Negotiate_Context(Packet): 

2180 name = "SMB2 Negotiate Context" 

2181 fields_desc = [ 

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

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

2184 IntField("Reserved", 0), 

2185 ] 

2186 

2187 def default_payload_class(self, payload): 

2188 return conf.padding_layer 

2189 

2190 

2191class SMB2_Negotiate_Protocol_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2192 name = "SMB2 Negotiate Protocol Request" 

2193 Command = 0x0000 

2194 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2195 fields_desc = [ 

2196 XLEShortField("StructureSize", 0x24), 

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

2198 # SecurityMode 

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

2200 LEShortField("Reserved", 0), 

2201 # Capabilities 

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

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

2204 XLEIntField("NegotiateContextsBufferOffset", None), 

2205 LEShortField("NegotiateContextsCount", None), 

2206 ShortField("Reserved2", 0), 

2207 FieldListField( 

2208 "Dialects", 

2209 [0x0202], 

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

2211 count_from=lambda pkt: pkt.DialectCount, 

2212 ), 

2213 _NTLMPayloadField( 

2214 "Buffer", 

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

2216 [ 

2217 # Field only exists if Dialects contains 0x0311 

2218 FieldListField( 

2219 "NegotiateContexts", 

2220 [], 

2221 ReversePadField( 

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

2223 8, 

2224 ), 

2225 count_from=lambda pkt: pkt.NegotiateContextsCount, 

2226 ), 

2227 ], 

2228 ), 

2229 ] 

2230 

2231 def post_build(self, pkt, pay): 

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

2233 return ( 

2234 _NTLM_post_build( 

2235 self, 

2236 pkt, 

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

2238 { 

2239 "NegotiateContexts": 28, 

2240 }, 

2241 config=[ 

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

2243 ("Count", _NTLM_ENUM.COUNT), 

2244 ], 

2245 ) 

2246 + pay 

2247 ) 

2248 

2249 

2250bind_top_down( 

2251 SMB2_Header, 

2252 SMB2_Negotiate_Protocol_Request, 

2253 Command=0x0000, 

2254) 

2255 

2256# sect 2.2.3.1.1 

2257 

2258 

2259class SMB2_Preauth_Integrity_Capabilities(Packet): 

2260 name = "SMB2 Preauth Integrity Capabilities" 

2261 fields_desc = [ 

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

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

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

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

2266 FieldListField( 

2267 "HashAlgorithms", 

2268 [0x0001], 

2269 LEShortEnumField( 

2270 "", 

2271 0x0, 

2272 SMB2_HASH_ALGORITHMS, 

2273 ), 

2274 count_from=lambda pkt: pkt.HashAlgorithmCount, 

2275 ), 

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

2277 ] 

2278 

2279 def default_payload_class(self, payload): 

2280 return conf.padding_layer 

2281 

2282 

2283bind_layers( 

2284 SMB2_Negotiate_Context, SMB2_Preauth_Integrity_Capabilities, ContextType=0x0001 

2285) 

2286 

2287# sect 2.2.3.1.2 

2288 

2289 

2290class SMB2_Encryption_Capabilities(Packet): 

2291 name = "SMB2 Encryption Capabilities" 

2292 fields_desc = [ 

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

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

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

2296 FieldListField( 

2297 "Ciphers", 

2298 [0x0001], 

2299 LEShortEnumField( 

2300 "", 

2301 0x0, 

2302 SMB2_ENCRYPTION_CIPHERS, 

2303 ), 

2304 count_from=lambda pkt: pkt.CipherCount, 

2305 ), 

2306 ] 

2307 

2308 def default_payload_class(self, payload): 

2309 return conf.padding_layer 

2310 

2311 

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

2313 

2314# sect 2.2.3.1.3 

2315 

2316 

2317class SMB2_Compression_Capabilities(Packet): 

2318 name = "SMB2 Compression Capabilities" 

2319 fields_desc = [ 

2320 FieldLenField( 

2321 "CompressionAlgorithmCount", 

2322 None, 

2323 fmt="<H", 

2324 count_of="CompressionAlgorithms", 

2325 ), 

2326 ShortField("Padding", 0x0), 

2327 LEIntEnumField( 

2328 "Flags", 

2329 0x0, 

2330 { 

2331 0x00000000: "SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE", 

2332 0x00000001: "SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED", 

2333 }, 

2334 ), 

2335 FieldListField( 

2336 "CompressionAlgorithms", 

2337 None, 

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

2339 count_from=lambda pkt: pkt.CompressionAlgorithmCount, 

2340 ), 

2341 ] 

2342 

2343 def default_payload_class(self, payload): 

2344 return conf.padding_layer 

2345 

2346 

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

2348 

2349# sect 2.2.3.1.4 

2350 

2351 

2352class SMB2_Netname_Negotiate_Context_ID(Packet): 

2353 name = "SMB2 Netname Negotiate Context ID" 

2354 fields_desc = [ 

2355 StrLenFieldUtf16( 

2356 "NetName", "", length_from=lambda pkt: pkt.underlayer.DataLength 

2357 ) 

2358 ] 

2359 

2360 def default_payload_class(self, payload): 

2361 return conf.padding_layer 

2362 

2363 

2364bind_layers( 

2365 SMB2_Negotiate_Context, SMB2_Netname_Negotiate_Context_ID, ContextType=0x0005 

2366) 

2367 

2368# sect 2.2.3.1.5 

2369 

2370 

2371class SMB2_Transport_Capabilities(Packet): 

2372 name = "SMB2 Transport Capabilities" 

2373 fields_desc = [ 

2374 FlagsField( 

2375 "Flags", 

2376 0x0, 

2377 -32, 

2378 { 

2379 0x00000001: "SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY", 

2380 }, 

2381 ), 

2382 ] 

2383 

2384 def default_payload_class(self, payload): 

2385 return conf.padding_layer 

2386 

2387 

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

2389 

2390# sect 2.2.3.1.6 

2391 

2392 

2393class SMB2_RDMA_Transform_Capabilities(Packet): 

2394 name = "SMB2 RDMA Transform Capabilities" 

2395 fields_desc = [ 

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

2397 LEShortField("Reserved1", 0), 

2398 LEIntField("Reserved2", 0), 

2399 FieldListField( 

2400 "RDMATransformIds", 

2401 None, 

2402 LEShortEnumField( 

2403 "", 

2404 0x0, 

2405 { 

2406 0x0000: "SMB2_RDMA_TRANSFORM_NONE", 

2407 0x0001: "SMB2_RDMA_TRANSFORM_ENCRYPTION", 

2408 0x0002: "SMB2_RDMA_TRANSFORM_SIGNING", 

2409 }, 

2410 ), 

2411 count_from=lambda pkt: pkt.TransformCount, 

2412 ), 

2413 ] 

2414 

2415 def default_payload_class(self, payload): 

2416 return conf.padding_layer 

2417 

2418 

2419bind_layers( 

2420 SMB2_Negotiate_Context, SMB2_RDMA_Transform_Capabilities, ContextType=0x0007 

2421) 

2422 

2423# sect 2.2.3.1.7 

2424 

2425 

2426class SMB2_Signing_Capabilities(Packet): 

2427 name = "SMB2 Signing Capabilities" 

2428 fields_desc = [ 

2429 FieldLenField( 

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

2431 ), 

2432 FieldListField( 

2433 "SigningAlgorithms", 

2434 None, 

2435 LEShortEnumField( 

2436 "", 

2437 0x0, 

2438 SMB2_SIGNING_ALGORITHMS, 

2439 ), 

2440 count_from=lambda pkt: pkt.SigningAlgorithmCount, 

2441 ), 

2442 ] 

2443 

2444 def default_payload_class(self, payload): 

2445 return conf.padding_layer 

2446 

2447 

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

2449 

2450# sect 2.2.4 

2451 

2452 

2453class SMB2_Negotiate_Protocol_Response(_SMB2_Payload, _NTLMPayloadPacket): 

2454 name = "SMB2 Negotiate Protocol Response" 

2455 Command = 0x0000 

2456 OFFSET = 64 + 64 

2457 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2458 fields_desc = [ 

2459 XLEShortField("StructureSize", 0x41), 

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

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

2462 LEShortField("NegotiateContextsCount", None), 

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

2464 # Capabilities 

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

2466 LEIntField("MaxTransactionSize", 65536), 

2467 LEIntField("MaxReadSize", 65536), 

2468 LEIntField("MaxWriteSize", 65536), 

2469 UTCTimeField( 

2470 "ServerTime", 

2471 None, 

2472 fmt="<Q", 

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

2474 custom_scaling=1e7, 

2475 ), 

2476 UTCTimeField( 

2477 "ServerStartTime", 

2478 None, 

2479 fmt="<Q", 

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

2481 custom_scaling=1e7, 

2482 ), 

2483 XLEShortField("SecurityBlobBufferOffset", None), 

2484 LEShortField("SecurityBlobLen", None), 

2485 XLEIntField("NegotiateContextsBufferOffset", None), 

2486 _NTLMPayloadField( 

2487 "Buffer", 

2488 OFFSET, 

2489 [ 

2490 PacketLenField( 

2491 "SecurityBlob", 

2492 None, 

2493 GSSAPI_BLOB, 

2494 length_from=lambda x: x.SecurityBlobLen, 

2495 ), 

2496 # Field only exists if Dialect is 0x0311 

2497 FieldListField( 

2498 "NegotiateContexts", 

2499 [], 

2500 ReversePadField( 

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

2502 8, 

2503 ), 

2504 count_from=lambda pkt: pkt.NegotiateContextsCount, 

2505 ), 

2506 ], 

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

2508 ), 

2509 ] 

2510 

2511 def post_build(self, pkt, pay): 

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

2513 pkt = _NTLM_post_build( 

2514 self, 

2515 pkt, 

2516 self.OFFSET, 

2517 { 

2518 "SecurityBlob": 56, 

2519 "NegotiateContexts": 60, 

2520 }, 

2521 config=[ 

2522 ( 

2523 "BufferOffset", 

2524 { 

2525 "SecurityBlob": _NTLM_ENUM.OFFSET, 

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

2527 }, 

2528 ), 

2529 ], 

2530 ) 

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

2532 if self.SecurityBlobLen is None: 

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

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

2535 if self.NegotiateContextsCount is None: 

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

2537 return pkt + pay 

2538 

2539 

2540bind_top_down( 

2541 SMB2_Header, 

2542 SMB2_Negotiate_Protocol_Response, 

2543 Command=0x0000, 

2544 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

2545) 

2546 

2547# sect 2.2.5 

2548 

2549 

2550class SMB2_Session_Setup_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2551 name = "SMB2 Session Setup Request" 

2552 Command = 0x0001 

2553 OFFSET = 24 + 64 

2554 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2555 fields_desc = [ 

2556 XLEShortField("StructureSize", 0x19), 

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

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

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

2560 LEIntField("Channel", 0), 

2561 XLEShortField("SecurityBlobBufferOffset", None), 

2562 LEShortField("SecurityBlobLen", None), 

2563 XLELongField("PreviousSessionId", 0), 

2564 _NTLMPayloadField( 

2565 "Buffer", 

2566 OFFSET, 

2567 [ 

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

2569 ], 

2570 ), 

2571 ] 

2572 

2573 def post_build(self, pkt, pay): 

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

2575 return ( 

2576 _SMB2_post_build( 

2577 self, 

2578 pkt, 

2579 self.OFFSET, 

2580 { 

2581 "SecurityBlob": 12, 

2582 }, 

2583 ) 

2584 + pay 

2585 ) 

2586 

2587 

2588bind_top_down( 

2589 SMB2_Header, 

2590 SMB2_Session_Setup_Request, 

2591 Command=0x0001, 

2592) 

2593 

2594# sect 2.2.6 

2595 

2596 

2597class SMB2_Session_Setup_Response(_SMB2_Payload, _NTLMPayloadPacket): 

2598 name = "SMB2 Session Setup Response" 

2599 Command = 0x0001 

2600 OFFSET = 8 + 64 

2601 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2602 fields_desc = [ 

2603 XLEShortField("StructureSize", 0x9), 

2604 FlagsField( 

2605 "SessionFlags", 

2606 0, 

2607 -16, 

2608 { 

2609 0x0001: "IS_GUEST", 

2610 0x0002: "IS_NULL", 

2611 0x0004: "ENCRYPT_DATA", 

2612 }, 

2613 ), 

2614 XLEShortField("SecurityBufferOffset", None), 

2615 LEShortField("SecurityLen", None), 

2616 _NTLMPayloadField( 

2617 "Buffer", 

2618 OFFSET, 

2619 [ 

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

2621 ], 

2622 ), 

2623 ] 

2624 

2625 def __getattr__(self, attr): 

2626 # Ease SMB1 backward compatibility 

2627 if attr == "SecurityBlob": 

2628 return ( 

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

2630 or [(None, None)] 

2631 )[0][1] 

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

2633 

2634 def setfieldval(self, attr, val): 

2635 if attr == "SecurityBlob": 

2636 return super(SMB2_Session_Setup_Response, self).setfieldval( 

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

2638 ) 

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

2640 

2641 def post_build(self, pkt, pay): 

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

2643 return ( 

2644 _SMB2_post_build( 

2645 self, 

2646 pkt, 

2647 self.OFFSET, 

2648 { 

2649 "Security": 4, 

2650 }, 

2651 ) 

2652 + pay 

2653 ) 

2654 

2655 

2656bind_top_down( 

2657 SMB2_Header, 

2658 SMB2_Session_Setup_Response, 

2659 Command=0x0001, 

2660 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

2661) 

2662 

2663# sect 2.2.7 

2664 

2665 

2666class SMB2_Session_Logoff_Request(_SMB2_Payload): 

2667 name = "SMB2 LOGOFF Request" 

2668 Command = 0x0002 

2669 fields_desc = [ 

2670 XLEShortField("StructureSize", 0x4), 

2671 ShortField("reserved", 0), 

2672 ] 

2673 

2674 

2675bind_top_down( 

2676 SMB2_Header, 

2677 SMB2_Session_Logoff_Request, 

2678 Command=0x0002, 

2679) 

2680 

2681# sect 2.2.8 

2682 

2683 

2684class SMB2_Session_Logoff_Response(_SMB2_Payload): 

2685 name = "SMB2 LOGOFF Request" 

2686 Command = 0x0002 

2687 fields_desc = [ 

2688 XLEShortField("StructureSize", 0x4), 

2689 ShortField("reserved", 0), 

2690 ] 

2691 

2692 

2693bind_top_down( 

2694 SMB2_Header, 

2695 SMB2_Session_Logoff_Response, 

2696 Command=0x0002, 

2697 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

2698) 

2699 

2700# sect 2.2.9 

2701 

2702 

2703class SMB2_Tree_Connect_Request(_SMB2_Payload, _NTLMPayloadPacket): 

2704 name = "SMB2 TREE_CONNECT Request" 

2705 Command = 0x0003 

2706 OFFSET = 8 + 64 

2707 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

2708 fields_desc = [ 

2709 XLEShortField("StructureSize", 0x9), 

2710 FlagsField( 

2711 "Flags", 

2712 0, 

2713 -16, 

2714 ["CLUSTER_RECONNECT", "REDIRECT_TO_OWNER", "EXTENSION_PRESENT"], 

2715 ), 

2716 XLEShortField("PathBufferOffset", None), 

2717 LEShortField("PathLen", None), 

2718 _NTLMPayloadField( 

2719 "Buffer", 

2720 OFFSET, 

2721 [ 

2722 StrFieldUtf16("Path", b""), 

2723 ], 

2724 ), 

2725 ] 

2726 

2727 def post_build(self, pkt, pay): 

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

2729 return ( 

2730 _SMB2_post_build( 

2731 self, 

2732 pkt, 

2733 self.OFFSET, 

2734 { 

2735 "Path": 4, 

2736 }, 

2737 ) 

2738 + pay 

2739 ) 

2740 

2741 

2742bind_top_down( 

2743 SMB2_Header, 

2744 SMB2_Tree_Connect_Request, 

2745 Command=0x0003, 

2746) 

2747 

2748# sect 2.2.10 

2749 

2750 

2751class SMB2_Tree_Connect_Response(_SMB2_Payload): 

2752 name = "SMB2 TREE_CONNECT Response" 

2753 Command = 0x0003 

2754 fields_desc = [ 

2755 XLEShortField("StructureSize", 0x10), 

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

2757 ByteField("Reserved", 0), 

2758 FlagsField( 

2759 "ShareFlags", 

2760 0x30, 

2761 -32, 

2762 { 

2763 0x00000010: "AUTO_CACHING", 

2764 0x00000020: "VDO_CACHING", 

2765 0x00000030: "NO_CACHING", 

2766 0x00000001: "DFS", 

2767 0x00000002: "DFS_ROOT", 

2768 0x00000100: "RESTRICT_EXCLUSIVE_OPENS", 

2769 0x00000200: "FORCE_SHARED_DELETE", 

2770 0x00000400: "ALLOW_NAMESPACE_CACHING", 

2771 0x00000800: "ACCESS_BASED_DIRECTORY_ENUM", 

2772 0x00001000: "FORCE_LEVELII_OPLOCK", 

2773 0x00002000: "ENABLE_HASH_V1", 

2774 0x00004000: "ENABLE_HASH_V2", 

2775 0x00008000: "ENCRYPT_DATA", 

2776 0x00040000: "IDENTITY_REMOTING", 

2777 0x00100000: "COMPRESS_DATA", 

2778 }, 

2779 ), 

2780 FlagsField( 

2781 "Capabilities", 

2782 0, 

2783 -32, 

2784 { 

2785 0x00000008: "DFS", 

2786 0x00000010: "CONTINUOUS_AVAILABILITY", 

2787 0x00000020: "SCALEOUT", 

2788 0x00000040: "CLUSTER", 

2789 0x00000080: "ASYMMETRIC", 

2790 0x00000100: "REDIRECT_TO_OWNER", 

2791 }, 

2792 ), 

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

2794 ] 

2795 

2796 

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

2798 

2799# sect 2.2.11 

2800 

2801 

2802class SMB2_Tree_Disconnect_Request(_SMB2_Payload): 

2803 name = "SMB2 TREE_DISCONNECT Request" 

2804 Command = 0x0004 

2805 fields_desc = [ 

2806 XLEShortField("StructureSize", 0x4), 

2807 XLEShortField("Reserved", 0), 

2808 ] 

2809 

2810 

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

2812 

2813# sect 2.2.12 

2814 

2815 

2816class SMB2_Tree_Disconnect_Response(_SMB2_Payload): 

2817 name = "SMB2 TREE_DISCONNECT Response" 

2818 Command = 0x0004 

2819 fields_desc = [ 

2820 XLEShortField("StructureSize", 0x4), 

2821 XLEShortField("Reserved", 0), 

2822 ] 

2823 

2824 

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

2826 

2827 

2828# sect 2.2.14.1 

2829 

2830 

2831class SMB2_FILEID(Packet): 

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

2833 

2834 def __hash__(self): 

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

2836 

2837 def default_payload_class(self, payload): 

2838 return conf.padding_layer 

2839 

2840 

2841# sect 2.2.14.2 

2842 

2843 

2844class SMB2_CREATE_DURABLE_HANDLE_RESPONSE(Packet): 

2845 fields_desc = [ 

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

2847 ] 

2848 

2849 

2850class SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE(Packet): 

2851 fields_desc = [ 

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

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

2854 ] 

2855 

2856 

2857class SMB2_CREATE_QUERY_ON_DISK_ID(Packet): 

2858 fields_desc = [ 

2859 XLELongField("DiskFileId", 0), 

2860 XLELongField("VolumeId", 0), 

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

2862 ] 

2863 

2864 

2865class SMB2_CREATE_RESPONSE_LEASE(Packet): 

2866 fields_desc = [ 

2867 UUIDField("LeaseKey", None), 

2868 FlagsField( 

2869 "LeaseState", 

2870 0x7, 

2871 -32, 

2872 { 

2873 0x01: "SMB2_LEASE_READ_CACHING", 

2874 0x02: "SMB2_LEASE_HANDLE_CACHING", 

2875 0x04: "SMB2_LEASE_WRITE_CACHING", 

2876 }, 

2877 ), 

2878 FlagsField( 

2879 "LeaseFlags", 

2880 0, 

2881 -32, 

2882 { 

2883 0x02: "SMB2_LEASE_FLAG_BREAK_IN_PROGRESS", 

2884 0x04: "SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET", 

2885 }, 

2886 ), 

2887 LELongField("LeaseDuration", 0), 

2888 ] 

2889 

2890 

2891class SMB2_CREATE_RESPONSE_LEASE_V2(Packet): 

2892 fields_desc = [ 

2893 SMB2_CREATE_RESPONSE_LEASE, 

2894 UUIDField("ParentLeaseKey", None), 

2895 LEShortField("Epoch", 0), 

2896 LEShortField("Reserved", 0), 

2897 ] 

2898 

2899 

2900class SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2(Packet): 

2901 fields_desc = [ 

2902 LEIntField("Timeout", 0), 

2903 FlagsField( 

2904 "Flags", 

2905 0, 

2906 -32, 

2907 { 

2908 0x02: "SMB2_DHANDLE_FLAG_PERSISTENT", 

2909 }, 

2910 ), 

2911 ] 

2912 

2913 

2914# sect 2.2.13 

2915 

2916 

2917class SMB2_CREATE_DURABLE_HANDLE_REQUEST(Packet): 

2918 fields_desc = [ 

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

2920 ] 

2921 

2922 

2923class SMB2_CREATE_DURABLE_HANDLE_RECONNECT(Packet): 

2924 fields_desc = [ 

2925 PacketField("Data", SMB2_FILEID(), SMB2_FILEID), 

2926 ] 

2927 

2928 

2929class SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST(Packet): 

2930 fields_desc = [ 

2931 LELongField("Timestamp", 0), 

2932 ] 

2933 

2934 

2935class SMB2_CREATE_ALLOCATION_SIZE(Packet): 

2936 fields_desc = [ 

2937 LELongField("AllocationSize", 0), 

2938 ] 

2939 

2940 

2941class SMB2_CREATE_TIMEWARP_TOKEN(Packet): 

2942 fields_desc = [ 

2943 LELongField("Timestamp", 0), 

2944 ] 

2945 

2946 

2947class SMB2_CREATE_REQUEST_LEASE(Packet): 

2948 fields_desc = [ 

2949 SMB2_CREATE_RESPONSE_LEASE, 

2950 ] 

2951 

2952 

2953class SMB2_CREATE_REQUEST_LEASE_V2(Packet): 

2954 fields_desc = [ 

2955 SMB2_CREATE_RESPONSE_LEASE_V2, 

2956 ] 

2957 

2958 

2959class SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2(Packet): 

2960 fields_desc = [ 

2961 SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2, 

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

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

2964 ] 

2965 

2966 

2967class SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2(Packet): 

2968 fields_desc = [ 

2969 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

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

2971 FlagsField( 

2972 "Flags", 

2973 0, 

2974 -32, 

2975 { 

2976 0x02: "SMB2_DHANDLE_FLAG_PERSISTENT", 

2977 }, 

2978 ), 

2979 ] 

2980 

2981 

2982class SMB2_CREATE_APP_INSTANCE_ID(Packet): 

2983 fields_desc = [ 

2984 XLEShortField("StructureSize", 0x14), 

2985 LEShortField("Reserved", 0), 

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

2987 ] 

2988 

2989 

2990class SMB2_CREATE_APP_INSTANCE_VERSION(Packet): 

2991 fields_desc = [ 

2992 XLEShortField("StructureSize", 0x18), 

2993 LEShortField("Reserved", 0), 

2994 LEIntField("Padding", 0), 

2995 LELongField("AppInstanceVersionHigh", 0), 

2996 LELongField("AppInstanceVersionLow", 0), 

2997 ] 

2998 

2999 

3000class SMB2_Create_Context(_NTLMPayloadPacket): 

3001 name = "SMB2 CREATE CONTEXT" 

3002 OFFSET = 16 

3003 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3004 fields_desc = [ 

3005 LEIntField("Next", None), 

3006 XLEShortField("NameBufferOffset", None), 

3007 LEShortField("NameLen", None), 

3008 ShortField("Reserved", 0), 

3009 XLEShortField("DataBufferOffset", None), 

3010 LEIntField("DataLen", None), 

3011 _NTLMPayloadField( 

3012 "Buffer", 

3013 OFFSET, 

3014 [ 

3015 PadField( 

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

3017 8, 

3018 ), 

3019 # Must be padded on 8-octet alignment 

3020 PacketLenField( 

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

3022 ), 

3023 ], 

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

3025 ), 

3026 StrLenField( 

3027 "pad", 

3028 b"", 

3029 length_from=lambda x: ( 

3030 ( 

3031 x.Next 

3032 - max( 

3033 x.DataBufferOffset + x.DataLen, x.NameBufferOffset + x.NameLen 

3034 ) 

3035 ) 

3036 if x.Next 

3037 else 0 

3038 ), 

3039 ), 

3040 ] 

3041 

3042 def post_dissect(self, s): 

3043 if not self.DataLen: 

3044 return s 

3045 try: 

3046 if isinstance(self.parent, SMB2_Create_Request): 

3047 data_cls = { 

3048 b"DHnQ": SMB2_CREATE_DURABLE_HANDLE_REQUEST, 

3049 b"DHnC": SMB2_CREATE_DURABLE_HANDLE_RECONNECT, 

3050 b"AISi": SMB2_CREATE_ALLOCATION_SIZE, 

3051 b"MxAc": SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 

3052 b"TWrp": SMB2_CREATE_TIMEWARP_TOKEN, 

3053 b"QFid": SMB2_CREATE_QUERY_ON_DISK_ID, 

3054 b"RqLs": SMB2_CREATE_REQUEST_LEASE, 

3055 b"DH2Q": SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, 

3056 b"DH2C": SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2, 

3057 # 3.1.1 only 

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

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

3060 }[self.Name] 

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

3062 data_cls = SMB2_CREATE_REQUEST_LEASE_V2 

3063 elif isinstance(self.parent, SMB2_Create_Response): 

3064 data_cls = { 

3065 b"DHnQ": SMB2_CREATE_DURABLE_HANDLE_RESPONSE, 

3066 b"MxAc": SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE, 

3067 b"QFid": SMB2_CREATE_QUERY_ON_DISK_ID, 

3068 b"RqLs": SMB2_CREATE_RESPONSE_LEASE, 

3069 b"DH2Q": SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2, 

3070 }[self.Name] 

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

3072 data_cls = SMB2_CREATE_RESPONSE_LEASE_V2 

3073 else: 

3074 return s 

3075 except KeyError: 

3076 return s 

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

3078 return s 

3079 

3080 def default_payload_class(self, _): 

3081 return conf.padding_layer 

3082 

3083 def post_build(self, pkt, pay): 

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

3085 return ( 

3086 _NTLM_post_build( 

3087 self, 

3088 pkt, 

3089 self.OFFSET, 

3090 { 

3091 "Name": 4, 

3092 "Data": 10, 

3093 }, 

3094 config=[ 

3095 ( 

3096 "BufferOffset", 

3097 { 

3098 "Name": _NTLM_ENUM.OFFSET, 

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

3100 }, 

3101 ), 

3102 ("Len", _NTLM_ENUM.LEN), 

3103 ], 

3104 ) 

3105 + pay 

3106 ) 

3107 

3108 

3109# sect 2.2.13 

3110 

3111SMB2_OPLOCK_LEVELS = { 

3112 0x00: "SMB2_OPLOCK_LEVEL_NONE", 

3113 0x01: "SMB2_OPLOCK_LEVEL_II", 

3114 0x08: "SMB2_OPLOCK_LEVEL_EXCLUSIVE", 

3115 0x09: "SMB2_OPLOCK_LEVEL_BATCH", 

3116 0xFF: "SMB2_OPLOCK_LEVEL_LEASE", 

3117} 

3118 

3119 

3120class SMB2_Create_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3121 name = "SMB2 CREATE Request" 

3122 Command = 0x0005 

3123 OFFSET = 56 + 64 

3124 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3125 fields_desc = [ 

3126 XLEShortField("StructureSize", 0x39), 

3127 ByteField("ShareType", 0), 

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

3129 LEIntEnumField( 

3130 "ImpersonationLevel", 

3131 0, 

3132 { 

3133 0x00000000: "Anonymous", 

3134 0x00000001: "Identification", 

3135 0x00000002: "Impersonation", 

3136 0x00000003: "Delegate", 

3137 }, 

3138 ), 

3139 LELongField("SmbCreateFlags", 0), 

3140 LELongField("Reserved", 0), 

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

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

3143 FlagsField( 

3144 "ShareAccess", 

3145 0, 

3146 -32, 

3147 { 

3148 0x00000001: "FILE_SHARE_READ", 

3149 0x00000002: "FILE_SHARE_WRITE", 

3150 0x00000004: "FILE_SHARE_DELETE", 

3151 }, 

3152 ), 

3153 LEIntEnumField( 

3154 "CreateDisposition", 

3155 1, 

3156 { 

3157 0x00000000: "FILE_SUPERSEDE", 

3158 0x00000001: "FILE_OPEN", 

3159 0x00000002: "FILE_CREATE", 

3160 0x00000003: "FILE_OPEN_IF", 

3161 0x00000004: "FILE_OVERWRITE", 

3162 0x00000005: "FILE_OVERWRITE_IF", 

3163 }, 

3164 ), 

3165 FlagsField( 

3166 "CreateOptions", 

3167 0, 

3168 -32, 

3169 { 

3170 0x00000001: "FILE_DIRECTORY_FILE", 

3171 0x00000002: "FILE_WRITE_THROUGH", 

3172 0x00000004: "FILE_SEQUENTIAL_ONLY", 

3173 0x00000008: "FILE_NO_INTERMEDIATE_BUFFERING", 

3174 0x00000010: "FILE_SYNCHRONOUS_IO_ALERT", 

3175 0x00000020: "FILE_SYNCHRONOUS_IO_NONALERT", 

3176 0x00000040: "FILE_NON_DIRECTORY_FILE", 

3177 0x00000100: "FILE_COMPLETE_IF_OPLOCKED", 

3178 0x00000200: "FILE_RANDOM_ACCESS", 

3179 0x00001000: "FILE_DELETE_ON_CLOSE", 

3180 0x00002000: "FILE_OPEN_BY_FILE_ID", 

3181 0x00004000: "FILE_OPEN_FOR_BACKUP_INTENT", 

3182 0x00008000: "FILE_NO_COMPRESSION", 

3183 0x00000400: "FILE_OPEN_REMOTE_INSTANCE", 

3184 0x00010000: "FILE_OPEN_REQUIRING_OPLOCK", 

3185 0x00020000: "FILE_DISALLOW_EXCLUSIVE", 

3186 0x00100000: "FILE_RESERVE_OPFILTER", 

3187 0x00200000: "FILE_OPEN_REPARSE_POINT", 

3188 0x00400000: "FILE_OPEN_NO_RECALL", 

3189 0x00800000: "FILE_OPEN_FOR_FREE_SPACE_QUERY", 

3190 }, 

3191 ), 

3192 XLEShortField("NameBufferOffset", None), 

3193 LEShortField("NameLen", None), 

3194 XLEIntField("CreateContextsBufferOffset", None), 

3195 LEIntField("CreateContextsLen", None), 

3196 _NTLMPayloadField( 

3197 "Buffer", 

3198 OFFSET, 

3199 [ 

3200 StrFieldUtf16("Name", b""), 

3201 _NextPacketListField( 

3202 "CreateContexts", 

3203 [], 

3204 SMB2_Create_Context, 

3205 length_from=lambda pkt: pkt.CreateContextsLen, 

3206 ), 

3207 ], 

3208 ), 

3209 ] 

3210 

3211 def post_build(self, pkt, pay): 

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

3213 if len(pkt) == 0x38: 

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

3215 pkt += b"\x00" 

3216 return ( 

3217 _SMB2_post_build( 

3218 self, 

3219 pkt, 

3220 self.OFFSET, 

3221 { 

3222 "Name": 44, 

3223 "CreateContexts": 48, 

3224 }, 

3225 ) 

3226 + pay 

3227 ) 

3228 

3229 

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

3231 

3232 

3233# sect 2.2.14 

3234 

3235 

3236class SMB2_Create_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3237 name = "SMB2 CREATE Response" 

3238 Command = 0x0005 

3239 OFFSET = 88 + 64 

3240 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3241 fields_desc = [ 

3242 XLEShortField("StructureSize", 0x59), 

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

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

3245 LEIntEnumField( 

3246 "CreateAction", 

3247 1, 

3248 { 

3249 0x00000000: "FILE_SUPERSEDED", 

3250 0x00000001: "FILE_OPENED", 

3251 0x00000002: "FILE_CREATED", 

3252 0x00000003: "FILE_OVERWRITEN", 

3253 }, 

3254 ), 

3255 FileNetworkOpenInformation, 

3256 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3257 XLEIntField("CreateContextsBufferOffset", None), 

3258 LEIntField("CreateContextsLen", None), 

3259 _NTLMPayloadField( 

3260 "Buffer", 

3261 OFFSET, 

3262 [ 

3263 _NextPacketListField( 

3264 "CreateContexts", 

3265 [], 

3266 SMB2_Create_Context, 

3267 length_from=lambda pkt: pkt.CreateContextsLen, 

3268 ), 

3269 ], 

3270 ), 

3271 ] 

3272 

3273 def post_build(self, pkt, pay): 

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

3275 return ( 

3276 _SMB2_post_build( 

3277 self, 

3278 pkt, 

3279 self.OFFSET, 

3280 { 

3281 "CreateContexts": 80, 

3282 }, 

3283 ) 

3284 + pay 

3285 ) 

3286 

3287 

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

3289 

3290# sect 2.2.15 

3291 

3292 

3293class SMB2_Close_Request(_SMB2_Payload): 

3294 name = "SMB2 CLOSE Request" 

3295 Command = 0x0006 

3296 fields_desc = [ 

3297 XLEShortField("StructureSize", 0x18), 

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

3299 LEIntField("Reserved", 0), 

3300 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3301 ] 

3302 

3303 

3304bind_top_down( 

3305 SMB2_Header, 

3306 SMB2_Close_Request, 

3307 Command=0x0006, 

3308) 

3309 

3310# sect 2.2.16 

3311 

3312 

3313class SMB2_Close_Response(_SMB2_Payload): 

3314 name = "SMB2 CLOSE Response" 

3315 Command = 0x0006 

3316 FileAttributes = 0 

3317 CreationTime = 0 

3318 LastAccessTime = 0 

3319 LastWriteTime = 0 

3320 ChangeTime = 0 

3321 fields_desc = [ 

3322 XLEShortField("StructureSize", 0x3C), 

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

3324 LEIntField("Reserved", 0), 

3325 ] + FileNetworkOpenInformation.fields_desc[:7] 

3326 

3327 

3328bind_top_down( 

3329 SMB2_Header, 

3330 SMB2_Close_Response, 

3331 Command=0x0006, 

3332 Flags=1, 

3333) 

3334 

3335# sect 2.2.19 

3336 

3337 

3338class SMB2_Read_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3339 name = "SMB2 READ Request" 

3340 Command = 0x0008 

3341 OFFSET = 48 + 64 

3342 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3343 fields_desc = [ 

3344 XLEShortField("StructureSize", 0x31), 

3345 ByteField("Padding", 0x00), 

3346 FlagsField( 

3347 "Flags", 

3348 0, 

3349 -8, 

3350 { 

3351 0x01: "SMB2_READFLAG_READ_UNBUFFERED", 

3352 0x02: "SMB2_READFLAG_REQUEST_COMPRESSED", 

3353 }, 

3354 ), 

3355 LEIntField("Length", 4280), 

3356 LELongField("Offset", 0), 

3357 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3358 LEIntField("MinimumCount", 0), 

3359 LEIntEnumField( 

3360 "Channel", 

3361 0, 

3362 { 

3363 0x00000000: "SMB2_CHANNEL_NONE", 

3364 0x00000001: "SMB2_CHANNEL_RDMA_V1", 

3365 0x00000002: "SMB2_CHANNEL_RDMA_V1_INVALIDATE", 

3366 0x00000003: "SMB2_CHANNEL_RDMA_TRANSFORM", 

3367 }, 

3368 ), 

3369 LEIntField("RemainingBytes", 0), 

3370 LEShortField("ReadChannelInfoBufferOffset", None), 

3371 LEShortField("ReadChannelInfoLen", None), 

3372 _NTLMPayloadField( 

3373 "Buffer", 

3374 OFFSET, 

3375 [ 

3376 StrLenField( 

3377 "ReadChannelInfo", 

3378 b"", 

3379 length_from=lambda pkt: pkt.ReadChannelInfoLen, 

3380 ) 

3381 ], 

3382 ), 

3383 ] 

3384 

3385 def post_build(self, pkt, pay): 

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

3387 if len(pkt) == 0x30: 

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

3389 pkt += b"\x00" 

3390 return ( 

3391 _SMB2_post_build( 

3392 self, 

3393 pkt, 

3394 self.OFFSET, 

3395 { 

3396 "ReadChannelInfo": 44, 

3397 }, 

3398 ) 

3399 + pay 

3400 ) 

3401 

3402 

3403bind_top_down( 

3404 SMB2_Header, 

3405 SMB2_Read_Request, 

3406 Command=0x0008, 

3407) 

3408 

3409# sect 2.2.20 

3410 

3411 

3412class SMB2_Read_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3413 name = "SMB2 READ Response" 

3414 Command = 0x0008 

3415 OFFSET = 16 + 64 

3416 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3417 fields_desc = [ 

3418 XLEShortField("StructureSize", 0x11), 

3419 LEShortField("DataBufferOffset", None), 

3420 LEIntField("DataLen", None), 

3421 LEIntField("DataRemaining", 0), 

3422 FlagsField( 

3423 "Flags", 

3424 0, 

3425 -32, 

3426 { 

3427 0x01: "SMB2_READFLAG_RESPONSE_RDMA_TRANSFORM", 

3428 }, 

3429 ), 

3430 _NTLMPayloadField( 

3431 "Buffer", 

3432 OFFSET, 

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

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 "Data": 2, 

3446 }, 

3447 ) 

3448 + pay 

3449 ) 

3450 

3451 

3452bind_top_down( 

3453 SMB2_Header, 

3454 SMB2_Read_Response, 

3455 Command=0x0008, 

3456 Flags=1, 

3457) 

3458 

3459 

3460# sect 2.2.21 

3461 

3462 

3463class SMB2_Write_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3464 name = "SMB2 WRITE Request" 

3465 Command = 0x0009 

3466 OFFSET = 48 + 64 

3467 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3468 fields_desc = [ 

3469 XLEShortField("StructureSize", 0x31), 

3470 LEShortField("DataBufferOffset", None), 

3471 LEIntField("DataLen", None), 

3472 LELongField("Offset", 0), 

3473 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3474 LEIntEnumField( 

3475 "Channel", 

3476 0, 

3477 { 

3478 0x00000000: "SMB2_CHANNEL_NONE", 

3479 0x00000001: "SMB2_CHANNEL_RDMA_V1", 

3480 0x00000002: "SMB2_CHANNEL_RDMA_V1_INVALIDATE", 

3481 0x00000003: "SMB2_CHANNEL_RDMA_TRANSFORM", 

3482 }, 

3483 ), 

3484 LEIntField("RemainingBytes", 0), 

3485 LEShortField("WriteChannelInfoBufferOffset", None), 

3486 LEShortField("WriteChannelInfoLen", None), 

3487 FlagsField( 

3488 "Flags", 

3489 0, 

3490 -32, 

3491 { 

3492 0x00000001: "SMB2_WRITEFLAG_WRITE_THROUGH", 

3493 0x00000002: "SMB2_WRITEFLAG_WRITE_UNBUFFERED", 

3494 }, 

3495 ), 

3496 _NTLMPayloadField( 

3497 "Buffer", 

3498 OFFSET, 

3499 [ 

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

3501 StrLenField( 

3502 "WriteChannelInfo", 

3503 b"", 

3504 length_from=lambda pkt: pkt.WriteChannelInfoLen, 

3505 ), 

3506 ], 

3507 ), 

3508 ] 

3509 

3510 def post_build(self, pkt, pay): 

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

3512 return ( 

3513 _SMB2_post_build( 

3514 self, 

3515 pkt, 

3516 self.OFFSET, 

3517 { 

3518 "Data": 2, 

3519 "WriteChannelInfo": 40, 

3520 }, 

3521 ) 

3522 + pay 

3523 ) 

3524 

3525 

3526bind_top_down( 

3527 SMB2_Header, 

3528 SMB2_Write_Request, 

3529 Command=0x0009, 

3530) 

3531 

3532# sect 2.2.22 

3533 

3534 

3535class SMB2_Write_Response(_SMB2_Payload): 

3536 name = "SMB2 WRITE Response" 

3537 Command = 0x0009 

3538 fields_desc = [ 

3539 XLEShortField("StructureSize", 0x11), 

3540 LEShortField("Reserved", 0), 

3541 LEIntField("Count", 0), 

3542 LEIntField("Remaining", 0), 

3543 LEShortField("WriteChannelInfoBufferOffset", 0), 

3544 LEShortField("WriteChannelInfoLen", 0), 

3545 ] 

3546 

3547 

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

3549 

3550# sect 2.2.28 

3551 

3552 

3553class SMB2_Echo_Request(_SMB2_Payload): 

3554 name = "SMB2 ECHO Request" 

3555 Command = 0x000D 

3556 fields_desc = [ 

3557 XLEShortField("StructureSize", 0x4), 

3558 LEShortField("Reserved", 0), 

3559 ] 

3560 

3561 

3562bind_top_down( 

3563 SMB2_Header, 

3564 SMB2_Echo_Request, 

3565 Command=0x000D, 

3566) 

3567 

3568# sect 2.2.29 

3569 

3570 

3571class SMB2_Echo_Response(_SMB2_Payload): 

3572 name = "SMB2 ECHO Response" 

3573 Command = 0x000D 

3574 fields_desc = [ 

3575 XLEShortField("StructureSize", 0x4), 

3576 LEShortField("Reserved", 0), 

3577 ] 

3578 

3579 

3580bind_top_down( 

3581 SMB2_Header, 

3582 SMB2_Echo_Response, 

3583 Command=0x000D, 

3584 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

3585) 

3586 

3587# sect 2.2.30 

3588 

3589 

3590class SMB2_Cancel_Request(_SMB2_Payload): 

3591 name = "SMB2 CANCEL Request" 

3592 fields_desc = [ 

3593 XLEShortField("StructureSize", 0x4), 

3594 LEShortField("Reserved", 0), 

3595 ] 

3596 

3597 

3598bind_top_down( 

3599 SMB2_Header, 

3600 SMB2_Cancel_Request, 

3601 Command=0x0009, 

3602) 

3603 

3604# sect 2.2.31.4 

3605 

3606 

3607class SMB2_IOCTL_Validate_Negotiate_Info_Request(Packet): 

3608 name = "SMB2 IOCTL Validate Negotiate Info" 

3609 fields_desc = ( 

3610 SMB2_Negotiate_Protocol_Request.fields_desc[4:6] 

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

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

3613 ) 

3614 

3615 

3616# sect 2.2.31 

3617 

3618 

3619class _SMB2_IOCTL_Request_PacketLenField(PacketLenField): 

3620 def m2i(self, pkt, m): 

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

3622 return SMB2_IOCTL_Validate_Negotiate_Info_Request(m) 

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

3624 return SMB2_IOCTL_REQ_GET_DFS_Referral(m) 

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

3626 return SMB2_IOCTL_OFFLOAD_READ_Request(m) 

3627 return conf.raw_layer(m) 

3628 

3629 

3630class SMB2_IOCTL_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3631 name = "SMB2 IOCTL Request" 

3632 Command = 0x000B 

3633 OFFSET = 56 + 64 

3634 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3635 deprecated_fields = { 

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

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

3638 } 

3639 fields_desc = [ 

3640 XLEShortField("StructureSize", 0x39), 

3641 LEShortField("Reserved", 0), 

3642 LEIntEnumField( 

3643 "CtlCode", 

3644 0, 

3645 { 

3646 0x00060194: "FSCTL_DFS_GET_REFERRALS", 

3647 0x0011400C: "FSCTL_PIPE_PEEK", 

3648 0x00110018: "FSCTL_PIPE_WAIT", 

3649 0x0011C017: "FSCTL_PIPE_TRANSCEIVE", 

3650 0x001440F2: "FSCTL_SRV_COPYCHUNK", 

3651 0x00144064: "FSCTL_SRV_ENUMERATE_SNAPSHOTS", 

3652 0x00140078: "FSCTL_SRV_REQUEST_RESUME_KEY", 

3653 0x001441BB: "FSCTL_SRV_READ_HASH", 

3654 0x001480F2: "FSCTL_SRV_COPYCHUNK_WRITE", 

3655 0x001401D4: "FSCTL_LMR_REQUEST_RESILIENCY", 

3656 0x001401FC: "FSCTL_QUERY_NETWORK_INTERFACE_INFO", 

3657 0x000900A4: "FSCTL_SET_REPARSE_POINT", 

3658 0x000601B0: "FSCTL_DFS_GET_REFERRALS_EX", 

3659 0x00098208: "FSCTL_FILE_LEVEL_TRIM", 

3660 0x00140204: "FSCTL_VALIDATE_NEGOTIATE_INFO", 

3661 0x00094264: "FSCTL_OFFLOAD_READ", 

3662 }, 

3663 ), 

3664 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3665 LEIntField("InputBufferOffset", None), 

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

3667 LEIntField("MaxInputResponse", 0), 

3668 LEIntField("OutputBufferOffset", None), 

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

3670 LEIntField("MaxOutputResponse", 65535), 

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

3672 LEIntField("Reserved2", 0), 

3673 _NTLMPayloadField( 

3674 "Buffer", 

3675 OFFSET, 

3676 [ 

3677 _SMB2_IOCTL_Request_PacketLenField( 

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

3679 ), 

3680 _SMB2_IOCTL_Request_PacketLenField( 

3681 "Output", 

3682 None, 

3683 conf.raw_layer, 

3684 length_from=lambda pkt: pkt.OutputLen, 

3685 ), 

3686 ], 

3687 ), 

3688 ] 

3689 

3690 def post_build(self, pkt, pay): 

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

3692 return ( 

3693 _SMB2_post_build( 

3694 self, 

3695 pkt, 

3696 self.OFFSET, 

3697 { 

3698 "Input": 24, 

3699 "Output": 36, 

3700 }, 

3701 ) 

3702 + pay 

3703 ) 

3704 

3705 

3706bind_top_down( 

3707 SMB2_Header, 

3708 SMB2_IOCTL_Request, 

3709 Command=0x000B, 

3710) 

3711 

3712# sect 2.2.32.5 

3713 

3714 

3715class SOCKADDR_STORAGE(Packet): 

3716 fields_desc = [ 

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

3718 ShortField("Port", 0), 

3719 # IPv4 

3720 ConditionalField( 

3721 IPField("IPv4Adddress", None), 

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

3723 ), 

3724 ConditionalField( 

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

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

3727 ), 

3728 # IPv6 

3729 ConditionalField( 

3730 LEIntField("FlowInfo", 0), 

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

3732 ), 

3733 ConditionalField( 

3734 IP6Field("IPv6Address", None), 

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

3736 ), 

3737 ConditionalField( 

3738 LEIntField("ScopeId", 0), 

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

3740 ), 

3741 ] 

3742 

3743 def default_payload_class(self, _): 

3744 return conf.padding_layer 

3745 

3746 

3747class NETWORK_INTERFACE_INFO(Packet): 

3748 fields_desc = [ 

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

3750 LEIntField("IfIndex", 1), 

3751 FlagsField( 

3752 "Capability", 

3753 1, 

3754 -32, 

3755 { 

3756 0x00000001: "RSS_CAPABLE", 

3757 0x00000002: "RDMA_CAPABLE", 

3758 }, 

3759 ), 

3760 LEIntField("Reserved", 0), 

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

3762 PacketField("SockAddr_Storage", SOCKADDR_STORAGE(), SOCKADDR_STORAGE), 

3763 ] 

3764 

3765 def default_payload_class(self, _): 

3766 return conf.padding_layer 

3767 

3768 

3769class SMB2_IOCTL_Network_Interface_Info(Packet): 

3770 name = "SMB2 IOCTL Network Interface Info response" 

3771 fields_desc = [ 

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

3773 ] 

3774 

3775 

3776# sect 2.2.32.6 

3777 

3778 

3779class SMB2_IOCTL_Validate_Negotiate_Info_Response(Packet): 

3780 name = "SMB2 IOCTL Validate Negotiate Info" 

3781 fields_desc = ( 

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

3783 + SMB2_Negotiate_Protocol_Response.fields_desc[ # Cap/GUID 

3784 1:3 

3785 ] # SecMod/DialectRevision 

3786 ) 

3787 

3788 

3789# [MS-FSCC] sect 2.3.42 

3790 

3791 

3792class SMB2_IOCTL_OFFLOAD_READ_Request(Packet): 

3793 name = "SMB2 IOCTL OFFLOAD_READ Request" 

3794 fields_desc = [ 

3795 LEIntField("StructureSize", 0x20), 

3796 LEIntField("Flags", 0), 

3797 LEIntField("TokenTimeToLive", 0), 

3798 LEIntField("Reserved", 0), 

3799 LELongField("FileOffset", 0), 

3800 LELongField("CopyLength", 0), 

3801 ] 

3802 

3803 

3804# [MS-FSCC] sect 2.1.11 

3805 

3806 

3807class STORAGE_OFFLOAD_TOKEN(Packet): 

3808 fields_desc = [ 

3809 LEIntEnumField( 

3810 "TokenType", 

3811 0xFFFF0001, 

3812 { 

3813 0xFFFF0001: "STORAGE_OFFLOAD_TOKEN_TYPE_ZERO_DATA", 

3814 }, 

3815 ), 

3816 LEShortField("Reserved", 0), 

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

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

3819 ] 

3820 

3821 

3822# [MS-FSCC] sect 2.3.42 

3823 

3824 

3825class SMB2_IOCTL_OFFLOAD_READ_Response(Packet): 

3826 name = "SMB2 IOCTL OFFLOAD_READ Response" 

3827 fields_desc = [ 

3828 LEIntField("StructureSize", 0x210), 

3829 FlagsField( 

3830 "Flags", 

3831 0, 

3832 -32, 

3833 { 

3834 0x00000001: "OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE", 

3835 }, 

3836 ), 

3837 LELongField("TransferLength", 0), 

3838 PacketField("Token", STORAGE_OFFLOAD_TOKEN(), STORAGE_OFFLOAD_TOKEN), 

3839 ] 

3840 

3841 

3842# sect 2.2.32 

3843 

3844 

3845class _SMB2_IOCTL_Response_PacketLenField(PacketLenField): 

3846 def m2i(self, pkt, m): 

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

3848 return SMB2_IOCTL_Validate_Negotiate_Info_Response(m) 

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

3850 return SMB2_IOCTL_Network_Interface_Info(m) 

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

3852 return SMB2_IOCTL_RESP_GET_DFS_Referral(m) 

3853 return conf.raw_layer(m) 

3854 

3855 

3856class SMB2_IOCTL_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3857 name = "SMB2 IOCTL Response" 

3858 Command = 0x000B 

3859 OFFSET = 48 + 64 

3860 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3861 StructureSize = 0x31 

3862 MaxOutputResponse = 0 

3863 fields_desc = ( 

3864 SMB2_IOCTL_Request.fields_desc[:6] 

3865 + SMB2_IOCTL_Request.fields_desc[7:9] 

3866 + SMB2_IOCTL_Request.fields_desc[10:12] 

3867 + [ 

3868 _NTLMPayloadField( 

3869 "Buffer", 

3870 OFFSET, 

3871 [ 

3872 _SMB2_IOCTL_Response_PacketLenField( 

3873 "Input", 

3874 None, 

3875 conf.raw_layer, 

3876 length_from=lambda pkt: pkt.InputLen, 

3877 ), 

3878 _SMB2_IOCTL_Response_PacketLenField( 

3879 "Output", 

3880 None, 

3881 conf.raw_layer, 

3882 length_from=lambda pkt: pkt.OutputLen, 

3883 ), 

3884 ], 

3885 ), 

3886 ] 

3887 ) 

3888 

3889 def post_build(self, pkt, pay): 

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

3891 return ( 

3892 _SMB2_post_build( 

3893 self, 

3894 pkt, 

3895 self.OFFSET, 

3896 { 

3897 "Input": 24, 

3898 "Output": 32, 

3899 }, 

3900 ) 

3901 + pay 

3902 ) 

3903 

3904 

3905bind_top_down( 

3906 SMB2_Header, 

3907 SMB2_IOCTL_Response, 

3908 Command=0x000B, 

3909 Flags=1, # SMB2_FLAGS_SERVER_TO_REDIR 

3910) 

3911 

3912# sect 2.2.33 

3913 

3914 

3915class SMB2_Query_Directory_Request(_SMB2_Payload, _NTLMPayloadPacket): 

3916 name = "SMB2 QUERY DIRECTORY Request" 

3917 Command = 0x000E 

3918 OFFSET = 32 + 64 

3919 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3920 fields_desc = [ 

3921 XLEShortField("StructureSize", 0x21), 

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

3923 FlagsField( 

3924 "Flags", 

3925 0, 

3926 -8, 

3927 { 

3928 0x01: "SMB2_RESTART_SCANS", 

3929 0x02: "SMB2_RETURN_SINGLE_ENTRY", 

3930 0x04: "SMB2_INDEX_SPECIFIED", 

3931 0x10: "SMB2_REOPEN", 

3932 }, 

3933 ), 

3934 LEIntField("FileIndex", 0), 

3935 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

3936 LEShortField("FileNameBufferOffset", None), 

3937 LEShortField("FileNameLen", None), 

3938 LEIntField("OutputBufferLength", 65535), 

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

3940 ] 

3941 

3942 def post_build(self, pkt, pay): 

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

3944 return ( 

3945 _SMB2_post_build( 

3946 self, 

3947 pkt, 

3948 self.OFFSET, 

3949 { 

3950 "FileName": 24, 

3951 }, 

3952 ) 

3953 + pay 

3954 ) 

3955 

3956 

3957bind_top_down( 

3958 SMB2_Header, 

3959 SMB2_Query_Directory_Request, 

3960 Command=0x000E, 

3961) 

3962 

3963# sect 2.2.34 

3964 

3965 

3966class SMB2_Query_Directory_Response(_SMB2_Payload, _NTLMPayloadPacket): 

3967 name = "SMB2 QUERY DIRECTORY Response" 

3968 Command = 0x000E 

3969 OFFSET = 8 + 64 

3970 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

3971 fields_desc = [ 

3972 XLEShortField("StructureSize", 0x9), 

3973 LEShortField("OutputBufferOffset", None), 

3974 LEIntField("OutputLen", None), 

3975 _NTLMPayloadField( 

3976 "Buffer", 

3977 OFFSET, 

3978 [ 

3979 # TODO 

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

3981 ], 

3982 ), 

3983 ] 

3984 

3985 def post_build(self, pkt, pay): 

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

3987 return ( 

3988 _SMB2_post_build( 

3989 self, 

3990 pkt, 

3991 self.OFFSET, 

3992 { 

3993 "Output": 2, 

3994 }, 

3995 ) 

3996 + pay 

3997 ) 

3998 

3999 

4000bind_top_down( 

4001 SMB2_Header, 

4002 SMB2_Query_Directory_Response, 

4003 Command=0x000E, 

4004 Flags=1, 

4005) 

4006 

4007# sect 2.2.35 

4008 

4009 

4010class SMB2_Change_Notify_Request(_SMB2_Payload): 

4011 name = "SMB2 CHANGE NOTIFY Request" 

4012 Command = 0x000F 

4013 fields_desc = [ 

4014 XLEShortField("StructureSize", 0x20), 

4015 FlagsField( 

4016 "Flags", 

4017 0, 

4018 -16, 

4019 { 

4020 0x0001: "SMB2_WATCH_TREE", 

4021 }, 

4022 ), 

4023 LEIntField("OutputBufferLength", 2048), 

4024 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

4025 FlagsField( 

4026 "CompletionFilter", 

4027 0, 

4028 -32, 

4029 { 

4030 0x00000001: "FILE_NOTIFY_CHANGE_FILE_NAME", 

4031 0x00000002: "FILE_NOTIFY_CHANGE_DIR_NAME", 

4032 0x00000004: "FILE_NOTIFY_CHANGE_ATTRIBUTES", 

4033 0x00000008: "FILE_NOTIFY_CHANGE_SIZE", 

4034 0x00000010: "FILE_NOTIFY_CHANGE_LAST_WRITE", 

4035 0x00000020: "FILE_NOTIFY_CHANGE_LAST_ACCESS", 

4036 0x00000040: "FILE_NOTIFY_CHANGE_CREATION", 

4037 0x00000080: "FILE_NOTIFY_CHANGE_EA", 

4038 0x00000100: "FILE_NOTIFY_CHANGE_SECURITY", 

4039 0x00000200: "FILE_NOTIFY_CHANGE_STREAM_NAME", 

4040 0x00000400: "FILE_NOTIFY_CHANGE_STREAM_SIZE", 

4041 0x00000800: "FILE_NOTIFY_CHANGE_STREAM_WRITE", 

4042 }, 

4043 ), 

4044 LEIntField("Reserved", 0), 

4045 ] 

4046 

4047 

4048bind_top_down( 

4049 SMB2_Header, 

4050 SMB2_Change_Notify_Request, 

4051 Command=0x000F, 

4052) 

4053 

4054# sect 2.2.36 

4055 

4056 

4057class SMB2_Change_Notify_Response(_SMB2_Payload, _NTLMPayloadPacket): 

4058 name = "SMB2 CHANGE NOTIFY Response" 

4059 Command = 0x000F 

4060 OFFSET = 8 + 64 

4061 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

4062 fields_desc = [ 

4063 XLEShortField("StructureSize", 0x9), 

4064 LEShortField("OutputBufferOffset", None), 

4065 LEIntField("OutputLen", None), 

4066 _NTLMPayloadField( 

4067 "Buffer", 

4068 OFFSET, 

4069 [ 

4070 _NextPacketListField( 

4071 "Output", 

4072 [], 

4073 FILE_NOTIFY_INFORMATION, 

4074 length_from=lambda pkt: pkt.OutputLen, 

4075 max_count=1000, 

4076 ) 

4077 ], 

4078 ), 

4079 ] 

4080 

4081 def post_build(self, pkt, pay): 

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

4083 return ( 

4084 _SMB2_post_build( 

4085 self, 

4086 pkt, 

4087 self.OFFSET, 

4088 { 

4089 "Output": 2, 

4090 }, 

4091 ) 

4092 + pay 

4093 ) 

4094 

4095 

4096bind_top_down( 

4097 SMB2_Header, 

4098 SMB2_Change_Notify_Response, 

4099 Command=0x000F, 

4100 Flags=1, 

4101) 

4102 

4103# sect 2.2.37 

4104 

4105 

4106class FILE_GET_QUOTA_INFORMATION(Packet): 

4107 fields_desc = [ 

4108 IntField("NextEntryOffset", 0), 

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

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

4111 StrLenField( 

4112 "pad", 

4113 b"", 

4114 length_from=lambda x: ( 

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

4116 ), 

4117 ), 

4118 ] 

4119 

4120 

4121class SMB2_Query_Quota_Info(Packet): 

4122 fields_desc = [ 

4123 ByteField("ReturnSingle", 0), 

4124 ByteField("ReturnBoolean", 0), 

4125 ShortField("Reserved", 0), 

4126 LEIntField("SidListLength", 0), 

4127 LEIntField("StartSidLength", 0), 

4128 LEIntField("StartSidOffset", 0), 

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

4130 MultipleTypeField( 

4131 [ 

4132 ( 

4133 PacketListField( 

4134 "SidBuffer", 

4135 [], 

4136 FILE_GET_QUOTA_INFORMATION, 

4137 length_from=lambda x: x.SidListLength, 

4138 ), 

4139 lambda x: x.SidListLength, 

4140 ), 

4141 ( 

4142 StrLenField( 

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

4144 ), 

4145 lambda x: x.StartSidLength, 

4146 ), 

4147 ], 

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

4149 ), 

4150 ] 

4151 

4152 

4153SMB2_INFO_TYPE = { 

4154 0x01: "SMB2_0_INFO_FILE", 

4155 0x02: "SMB2_0_INFO_FILESYSTEM", 

4156 0x03: "SMB2_0_INFO_SECURITY", 

4157 0x04: "SMB2_0_INFO_QUOTA", 

4158} 

4159 

4160SMB2_ADDITIONAL_INFORMATION = { 

4161 0x00000001: "OWNER_SECURITY_INFORMATION", 

4162 0x00000002: "GROUP_SECURITY_INFORMATION", 

4163 0x00000004: "DACL_SECURITY_INFORMATION", 

4164 0x00000008: "SACL_SECURITY_INFORMATION", 

4165 0x00000010: "LABEL_SECURITY_INFORMATION", 

4166 0x00000020: "ATTRIBUTE_SECURITY_INFORMATION", 

4167 0x00000040: "SCOPE_SECURITY_INFORMATION", 

4168 0x00010000: "BACKUP_SECURITY_INFORMATION", 

4169} 

4170 

4171 

4172class SMB2_Query_Info_Request(_SMB2_Payload, _NTLMPayloadPacket): 

4173 name = "SMB2 QUERY INFO Request" 

4174 Command = 0x0010 

4175 OFFSET = 40 + 64 

4176 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

4177 fields_desc = [ 

4178 XLEShortField("StructureSize", 0x29), 

4179 ByteEnumField( 

4180 "InfoType", 

4181 0, 

4182 SMB2_INFO_TYPE, 

4183 ), 

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

4185 LEIntField("OutputBufferLength", 0), 

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

4187 LEIntField("InputLen", None), 

4188 FlagsField( 

4189 "AdditionalInformation", 

4190 0, 

4191 -32, 

4192 SMB2_ADDITIONAL_INFORMATION, 

4193 ), 

4194 FlagsField( 

4195 "Flags", 

4196 0, 

4197 -32, 

4198 { 

4199 0x00000001: "SL_RESTART_SCAN", 

4200 0x00000002: "SL_RETURN_SINGLE_ENTRY", 

4201 0x00000004: "SL_INDEX_SPECIFIED", 

4202 }, 

4203 ), 

4204 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

4205 _NTLMPayloadField( 

4206 "Buffer", 

4207 OFFSET, 

4208 [ 

4209 MultipleTypeField( 

4210 [ 

4211 ( 

4212 # QUOTA 

4213 PacketListField( 

4214 "Input", 

4215 None, 

4216 SMB2_Query_Quota_Info, 

4217 length_from=lambda pkt: pkt.InputLen, 

4218 ), 

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

4220 ), 

4221 ], 

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

4223 ), 

4224 ], 

4225 ), 

4226 ] 

4227 

4228 def post_build(self, pkt, pay): 

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

4230 return ( 

4231 _SMB2_post_build( 

4232 self, 

4233 pkt, 

4234 self.OFFSET, 

4235 { 

4236 "Input": 4, 

4237 }, 

4238 ) 

4239 + pay 

4240 ) 

4241 

4242 

4243bind_top_down( 

4244 SMB2_Header, 

4245 SMB2_Query_Info_Request, 

4246 Command=0x00010, 

4247) 

4248 

4249 

4250class SMB2_Query_Info_Response(_SMB2_Payload, _NTLMPayloadPacket): 

4251 name = "SMB2 QUERY INFO Response" 

4252 Command = 0x0010 

4253 OFFSET = 8 + 64 

4254 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

4255 fields_desc = [ 

4256 XLEShortField("StructureSize", 0x9), 

4257 LEShortField("OutputBufferOffset", None), 

4258 LEIntField("OutputLen", None), 

4259 _NTLMPayloadField( 

4260 "Buffer", 

4261 OFFSET, 

4262 [ 

4263 # TODO 

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

4265 ], 

4266 ), 

4267 ] 

4268 

4269 def post_build(self, pkt, pay): 

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

4271 return ( 

4272 _SMB2_post_build( 

4273 self, 

4274 pkt, 

4275 self.OFFSET, 

4276 { 

4277 "Output": 2, 

4278 }, 

4279 ) 

4280 + pay 

4281 ) 

4282 

4283 

4284bind_top_down( 

4285 SMB2_Header, 

4286 SMB2_Query_Info_Response, 

4287 Command=0x00010, 

4288 Flags=1, 

4289) 

4290 

4291 

4292# sect 2.2.39 

4293 

4294 

4295class SMB2_Set_Info_Request(_SMB2_Payload, _NTLMPayloadPacket): 

4296 name = "SMB2 SET INFO Request" 

4297 Command = 0x0011 

4298 OFFSET = 32 + 64 

4299 _NTLM_PAYLOAD_FIELD_NAME = "Buffer" 

4300 fields_desc = [ 

4301 XLEShortField("StructureSize", 0x21), 

4302 ByteEnumField( 

4303 "InfoType", 

4304 0, 

4305 SMB2_INFO_TYPE, 

4306 ), 

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

4308 LEIntField("DataLen", None), 

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

4310 FlagsField( 

4311 "AdditionalInformation", 

4312 0, 

4313 -32, 

4314 SMB2_ADDITIONAL_INFORMATION, 

4315 ), 

4316 PacketField("FileId", SMB2_FILEID(), SMB2_FILEID), 

4317 _NTLMPayloadField( 

4318 "Buffer", 

4319 OFFSET, 

4320 [ 

4321 MultipleTypeField( 

4322 [ 

4323 ( 

4324 # FILE 

4325 PacketLenField( 

4326 "Data", 

4327 None, 

4328 lambda x, _parent: _FileInformationClasses.get( 

4329 _parent.FileInfoClass, conf.raw_layer 

4330 )(x), 

4331 length_from=lambda pkt: pkt.DataLen, 

4332 ), 

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

4334 ), 

4335 ( 

4336 # QUOTA 

4337 PacketListField( 

4338 "Data", 

4339 None, 

4340 SMB2_Query_Quota_Info, 

4341 length_from=lambda pkt: pkt.DataLen, 

4342 ), 

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

4344 ), 

4345 ], 

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

4347 ), 

4348 ], 

4349 ), 

4350 ] 

4351 

4352 def post_build(self, pkt, pay): 

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

4354 return ( 

4355 _SMB2_post_build( 

4356 self, 

4357 pkt, 

4358 self.OFFSET, 

4359 { 

4360 "Data": 4, 

4361 }, 

4362 ) 

4363 + pay 

4364 ) 

4365 

4366 

4367bind_top_down( 

4368 SMB2_Header, 

4369 SMB2_Set_Info_Request, 

4370 Command=0x00011, 

4371) 

4372 

4373 

4374class SMB2_Set_Info_Response(_SMB2_Payload): 

4375 name = "SMB2 SET INFO Request" 

4376 Command = 0x0011 

4377 fields_desc = [ 

4378 XLEShortField("StructureSize", 0x02), 

4379 ] 

4380 

4381 

4382bind_top_down( 

4383 SMB2_Header, 

4384 SMB2_Set_Info_Response, 

4385 Command=0x00011, 

4386 Flags=1, 

4387) 

4388 

4389 

4390# sect 2.2.41 

4391 

4392 

4393class SMB2_Transform_Header(Packet): 

4394 name = "SMB2 Transform Header" 

4395 fields_desc = [ 

4396 StrFixedLenField("Start", b"\xfdSMB", 4), 

4397 XStrFixedLenField("Signature", 0, length=16), 

4398 XStrFixedLenField("Nonce", b"", length=16), 

4399 LEIntField("OriginalMessageSize", 0x0), 

4400 LEShortField("Reserved", 0), 

4401 LEShortEnumField( 

4402 "Flags", 

4403 0x1, 

4404 { 

4405 0x0001: "ENCRYPTED", 

4406 }, 

4407 ), 

4408 LELongField("SessionId", 0), 

4409 ] 

4410 

4411 def decrypt(self, dialect, DecryptionKey, CipherId): 

4412 """ 

4413 [MS-SMB2] sect 3.2.5.1.1.1 - Decrypting the Message 

4414 """ 

4415 if not isinstance(self.payload, conf.raw_layer): 

4416 raise Exception("No payload to decrypt !") 

4417 

4418 if "GCM" in CipherId: 

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

4420 

4421 nonce = self.Nonce[:12] 

4422 cipher = AESGCM(DecryptionKey) 

4423 elif "CCM" in CipherId: 

4424 from cryptography.hazmat.primitives.ciphers.aead import AESCCM 

4425 

4426 nonce = self.Nonce[:11] 

4427 cipher = AESCCM(DecryptionKey) 

4428 else: 

4429 raise Exception("Unknown CipherId !") 

4430 

4431 # Decrypt the data 

4432 aad = self.self_build()[20:] 

4433 data = cipher.decrypt( 

4434 nonce, 

4435 self.payload.load + self.Signature, 

4436 aad, 

4437 ) 

4438 return SMB2_Header(data, _decrypted=True) 

4439 

4440 

4441bind_layers(SMB2_Transform_Header, conf.raw_layer) 

4442 

4443 

4444# sect 2.2.42.1 

4445 

4446 

4447class SMB2_Compression_Transform_Header(Packet): 

4448 name = "SMB2 Compression Transform Header" 

4449 fields_desc = [ 

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

4451 LEIntField("OriginalCompressedSegmentSize", 0x0), 

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

4453 LEShortEnumField( 

4454 "Flags", 

4455 0x0, 

4456 { 

4457 0x0000: "SMB2_COMPRESSION_FLAG_NONE", 

4458 0x0001: "SMB2_COMPRESSION_FLAG_CHAINED", 

4459 }, 

4460 ), 

4461 XLEIntField("Offset_or_Length", 0), 

4462 ] 

4463 

4464 

4465# [MS-DFSC] sect 2.2 

4466 

4467 

4468class SMB2_IOCTL_REQ_GET_DFS_Referral(Packet): 

4469 fields_desc = [ 

4470 LEShortField("MaxReferralLevel", 0), 

4471 StrNullFieldUtf16("RequestFileName", ""), 

4472 ] 

4473 

4474 

4475class DFS_REFERRAL(Packet): 

4476 fields_desc = [ 

4477 LEShortField("Version", 1), 

4478 FieldLenField( 

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

4480 ), 

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

4482 LEShortField("ReferralEntryFlags", 0), 

4483 StrNullFieldUtf16("ShareName", ""), 

4484 ] 

4485 

4486 @classmethod 

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

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

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

4490 if version == 1: 

4491 return DFS_REFERRAL 

4492 elif version == 3: 

4493 return DFS_REFERRAL_V3 

4494 elif version == 4: 

4495 return DFS_REFERRAL_V4 

4496 return cls 

4497 

4498 def default_payload_class(self, s): 

4499 return conf.padding_layer 

4500 

4501 

4502class DFS_REFERRAL_V3(DFS_REFERRAL): 

4503 fields_desc = [ 

4504 LEShortField("Version", 3), 

4505 LEShortField("Size", None), 

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

4507 FlagsField( 

4508 "ReferralEntryFlags", 

4509 0, 

4510 -16, 

4511 { 

4512 0x0002: "NameListReferral", 

4513 0x0004: "TargetSetBoundary", 

4514 }, 

4515 ), 

4516 LEIntField("TimeToLive", 300), 

4517 # NameListReferral is 0 

4518 ConditionalField( 

4519 LEShortField("DFSPathOffset", None), 

4520 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4521 ), 

4522 ConditionalField( 

4523 LEShortField("DFSAlternatePathOffset", None), 

4524 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4525 ), 

4526 ConditionalField( 

4527 LEShortField("NetworkAddressOffset", None), 

4528 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4529 ), 

4530 ConditionalField( 

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

4532 lambda pkt: not pkt.ReferralEntryFlags.NameListReferral, 

4533 ), 

4534 # NameListReferral is 1 

4535 ConditionalField( 

4536 LEShortField("SpecialNameOffset", None), 

4537 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4538 ), 

4539 ConditionalField( 

4540 LEShortField("NumberOfExpandedNames", None), 

4541 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4542 ), 

4543 ConditionalField( 

4544 LEShortField("ExpandedNameOffset", None), 

4545 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4546 ), 

4547 ConditionalField( 

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

4549 lambda pkt: pkt.ReferralEntryFlags.NameListReferral, 

4550 ), 

4551 ] 

4552 

4553 def post_build(self, pkt, pay): 

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

4555 if self.Size is None: 

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

4557 return pkt + pay 

4558 

4559 

4560class DFS_REFERRAL_V4(DFS_REFERRAL_V3): 

4561 Version = 4 

4562 

4563 

4564class DFS_REFERRAL_ENTRY0(Packet): 

4565 fields_desc = [ 

4566 StrNullFieldUtf16("DFSPath", ""), 

4567 StrNullFieldUtf16("DFSAlternatePath", ""), 

4568 StrNullFieldUtf16("NetworkAddress", ""), 

4569 ] 

4570 

4571 

4572class DFS_REFERRAL_ENTRY1(Packet): 

4573 fields_desc = [ 

4574 StrNullFieldUtf16("SpecialName", ""), 

4575 FieldListField( 

4576 "ExpandedName", 

4577 [], 

4578 StrNullFieldUtf16("", ""), 

4579 ), 

4580 ] 

4581 

4582 

4583class _DFS_Referrals_BufferField(PacketListField): 

4584 def getfield(self, pkt, s): 

4585 results = [] 

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

4587 for ref in pkt.ReferralEntries: 

4588 # For every ref 

4589 if not ref.ReferralEntryFlags.NameListReferral: 

4590 cls = DFS_REFERRAL_ENTRY0 

4591 else: 

4592 cls = DFS_REFERRAL_ENTRY1 

4593 # Build the fields manually 

4594 fld = _NTLMPayloadField( 

4595 "", 

4596 offset, 

4597 cls.fields_desc, 

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

4599 offset_name="Offset", 

4600 ) 

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

4602 vals = fld.i2h(ref, vals) 

4603 # Append the entry class 

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

4605 offset -= ref.Size 

4606 return b"", results 

4607 

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

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

4610 for i, val in enumerate(vals): 

4611 try: 

4612 ref = pkt.ReferralEntries[i] 

4613 except KeyError: 

4614 ref = None 

4615 fld = _NTLMPayloadField( 

4616 "", 

4617 offset, 

4618 val.fields_desc, 

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

4620 offset_name="Offset", 

4621 ) 

4622 # Append the bytes manually 

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

4624 values = fld.h2i(ref, values) 

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

4626 offset -= len(ref) 

4627 return s 

4628 

4629 

4630class SMB2_IOCTL_RESP_GET_DFS_Referral(Packet): 

4631 fields_desc = [ 

4632 LEShortField("PathConsumed", 0), 

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

4634 FlagsField( 

4635 "ReferralHeaderFlags", 

4636 0, 

4637 -32, 

4638 { 

4639 0x00000001: "ReferralServers", 

4640 0x00000002: "StorageServers", 

4641 0x00000004: "TargetFailback", 

4642 }, 

4643 ), 

4644 PacketListField( 

4645 "ReferralEntries", 

4646 [], 

4647 DFS_REFERRAL, 

4648 count_from=lambda pkt: pkt.NumberOfReferrals, 

4649 ), 

4650 _DFS_Referrals_BufferField("ReferralBuffer", []), 

4651 ] 

4652 

4653 def post_build(self, pkt, pay): 

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

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

4656 # that it reuses fields that are used several times across ReferralBuffer. 

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

4658 offsets = { 

4659 # DFS_REFERRAL_ENTRY0 

4660 "DFSPath": 12, 

4661 "DFSAlternatePath": 14, 

4662 "NetworkAddress": 16, 

4663 # DFS_REFERRAL_ENTRY1 

4664 "SpecialName": 12, 

4665 "ExpandedName": 16, 

4666 } 

4667 # dataoffset = pointer in the ReferralBuffer 

4668 # entryoffset = pointer in the ReferralEntries 

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

4670 entryoffset = 8 

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

4672 for fld in buf.fields_desc: 

4673 off = entryoffset + offsets[fld.name] 

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

4675 fld.name 

4676 ): 

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

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

4679 dataoffset -= len(ref) 

4680 entryoffset += len(ref) 

4681 return pkt + pay 

4682 

4683 

4684# [MS-SMB2] various usages 

4685 

4686 

4687def SMB2computePreauthIntegrityHashValue( 

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

4689): 

4690 """ 

4691 Update the PreauthIntegrityHashValue 

4692 """ 

4693 # get hasher 

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

4695 # compute the hash of concatenation of previous and bytes 

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

4697 

4698 

4699# SMB2 socket and session 

4700 

4701 

4702class SMBStreamSocket(StreamSocket): 

4703 """ 

4704 A modified StreamSocket to dissect SMB compounded requests 

4705 [MS-SMB2] 3.3.5.2.7 

4706 """ 

4707 

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

4709 self.queue = collections.deque() 

4710 self.session = SMBSession() 

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

4712 

4713 def recv(self, x=None): 

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

4715 # this takes care of splitting compounded requests 

4716 if self.queue: 

4717 pkt = self.queue.popleft() 

4718 else: 

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

4720 # If there are multiple SMB2_Header requests (aka. compounded), 

4721 # take the first and store the rest in a queue. 

4722 if pkt is not None and ( 

4723 SMB2_Header in pkt 

4724 or SMB2_Transform_Header in pkt 

4725 or SMB2_Compression_Transform_Header in pkt 

4726 ): 

4727 pkt = self.session.in_pkt(pkt) 

4728 pay = pkt[SMB2_Header].payload 

4729 while SMB2_Header in pay: 

4730 pay = pay[SMB2_Header] 

4731 pay.underlayer.remove_payload() 

4732 self.queue.append(pay) 

4733 if not pay.NextCommand: 

4734 break 

4735 pay = pay.payload 

4736 # Verify the signature if required. 

4737 # This happens here because we must have split compounded requests first. 

4738 smbh = pkt.getlayer(SMB2_Header) 

4739 if ( 

4740 smbh 

4741 and self.session.Dialect 

4742 and self.session.SigningKey 

4743 and self.session.SigningRequired 

4744 # [MS-SMB2] sect 3.2.5.1.3 Verifying the Signature 

4745 # "The client MUST skip the processing in this section if any of:" 

4746 # - [...] decryption in section 3.2.5.1.1.1 succeeds 

4747 and not smbh._decrypted 

4748 # - MessageId is 0xFFFFFFFFFFFFFFFF 

4749 and smbh.MID != 0xFFFFFFFFFFFFFFFF 

4750 # - Status in the SMB2 header is STATUS_PENDING 

4751 and smbh.Status != 0x00000103 

4752 ): 

4753 smbh.verify( 

4754 self.session.Dialect, 

4755 self.session.SigningKey, 

4756 # SMB 3.1.1 parameters: 

4757 SigningAlgorithmId=self.session.SigningAlgorithmId, 

4758 IsClient=False, 

4759 ) 

4760 return pkt 

4761 

4762 def send(self, x, Compounded=False, ForceSign=False, ForceEncrypt=False, **kwargs): 

4763 for pkt in self.session.out_pkt( 

4764 x, Compounded=Compounded, ForceSign=ForceSign, ForceEncrypt=ForceEncrypt 

4765 ): 

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

4767 

4768 @staticmethod 

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

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

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

4772 return select_objects(sockets, remain=remain) 

4773 

4774 

4775class SMBSession(DefaultSession): 

4776 """ 

4777 A SMB session within a TCP socket. 

4778 """ 

4779 

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

4781 self.smb_header = None 

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

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

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

4785 # SMB session parameters 

4786 self.CompoundQueue = [] 

4787 self.Dialect = 0x0202 # Updated by parent 

4788 self.Credits = 0 

4789 self.IsGuest = False 

4790 self.MaxTransactionSize = 0 

4791 self.MaxReadSize = 0 

4792 self.MaxWriteSize = 0 

4793 # Crypto parameters. Go read [MS-SMB2] to understand the names. 

4794 self.SigningRequired = True 

4795 self.SupportsEncryption = False 

4796 self.EncryptData = False 

4797 self.TreeEncryptData = False 

4798 self.SigningKey = None 

4799 self.EncryptionKey = None 

4800 self.DecryptionKey = None 

4801 self.PreauthIntegrityHashId = "SHA-512" 

4802 self.SupportedCipherIds = [ 

4803 "AES-128-CCM", 

4804 "AES-128-GCM", 

4805 "AES-256-CCM", 

4806 "AES-256-GCM", 

4807 ] 

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

4809 self.SupportedSigningAlgorithmIds = [ 

4810 "AES-CMAC", 

4811 "HMAC-SHA256", 

4812 ] 

4813 self.SigningAlgorithmId = None 

4814 self.Salt = os.urandom(32) 

4815 self.ConnectionPreauthIntegrityHashValue = None 

4816 self.SessionPreauthIntegrityHashValue = None 

4817 # SMB 3.1.1 

4818 self.SessionPreauthIntegrityHashValue = None 

4819 if conf.winssps_passive: 

4820 for ssp in conf.winssps_passive: 

4821 self.sniffsspcontexts[ssp] = None 

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

4823 

4824 # SMB crypto functions 

4825 

4826 @crypto_validator 

4827 def computeSMBSessionKeys(self, IsClient=None): 

4828 """ 

4829 Compute the SigningKey and EncryptionKey (for SMB 3+) 

4830 """ 

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

4832 # no signing key, no session key 

4833 return 

4834 # [MS-SMB2] sect 3.3.5.5.3 

4835 # SigningKey 

4836 if self.Dialect >= 0x0300: 

4837 if self.Dialect == 0x0311: 

4838 label = b"SMBSigningKey\x00" 

4839 context = self.SessionPreauthIntegrityHashValue 

4840 else: 

4841 label = b"SMB2AESCMAC\x00" 

4842 context = b"SmbSign\x00" 

4843 # [MS-SMB2] sect 3.1.4.2 

4844 if "256" in self.CipherId: 

4845 L = 256 

4846 elif "128" in self.CipherId: 

4847 L = 128 

4848 else: 

4849 raise ValueError 

4850 self.SigningKey = SP800108_KDFCTR( 

4851 self.sspcontext.SessionKey[:16], 

4852 label, 

4853 context, 

4854 L, 

4855 ) 

4856 # EncryptionKey / DecryptionKey 

4857 if self.Dialect == 0x0311: 

4858 if IsClient: 

4859 label_out = b"SMBC2SCipherKey\x00" 

4860 label_in = b"SMBS2CCipherKey\x00" 

4861 else: 

4862 label_out = b"SMBS2CCipherKey\x00" 

4863 label_in = b"SMBC2SCipherKey\x00" 

4864 context_out = context_in = self.SessionPreauthIntegrityHashValue 

4865 else: 

4866 label_out = label_in = b"SMB2AESCCM\x00" 

4867 if IsClient: 

4868 context_out = b"ServerIn \x00" # extra space per spec 

4869 context_in = b"ServerOut\x00" 

4870 else: 

4871 context_out = b"ServerOut\x00" 

4872 context_in = b"ServerIn \x00" 

4873 self.EncryptionKey = SP800108_KDFCTR( 

4874 self.sspcontext.SessionKey[: L // 8], 

4875 label_out, 

4876 context_out, 

4877 L, 

4878 ) 

4879 self.DecryptionKey = SP800108_KDFCTR( 

4880 self.sspcontext.SessionKey[: L // 8], 

4881 label_in, 

4882 context_in, 

4883 L, 

4884 ) 

4885 elif self.Dialect <= 0x0210: 

4886 self.SigningKey = self.sspcontext.SessionKey[:16] 

4887 else: 

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

4889 

4890 def computeSMBConnectionPreauth(self, *negopkts): 

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

4892 # [MS-SMB2] 3.3.5.4 

4893 # TODO: handle SMB2_SESSION_FLAG_BINDING 

4894 if self.ConnectionPreauthIntegrityHashValue is None: 

4895 # New auth or failure 

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

4897 # Calculate the *Connection* PreauthIntegrityHashValue 

4898 for negopkt in negopkts: 

4899 self.ConnectionPreauthIntegrityHashValue = ( 

4900 SMB2computePreauthIntegrityHashValue( 

4901 self.ConnectionPreauthIntegrityHashValue, 

4902 negopkt, 

4903 HashId=self.PreauthIntegrityHashId, 

4904 ) 

4905 ) 

4906 

4907 def computeSMBSessionPreauth(self, *sesspkts): 

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

4909 # [MS-SMB2] 3.3.5.5.3 

4910 if self.SessionPreauthIntegrityHashValue is None: 

4911 # New auth or failure 

4912 self.SessionPreauthIntegrityHashValue = ( 

4913 self.ConnectionPreauthIntegrityHashValue 

4914 ) 

4915 # Calculate the *Session* PreauthIntegrityHashValue 

4916 for sesspkt in sesspkts: 

4917 self.SessionPreauthIntegrityHashValue = ( 

4918 SMB2computePreauthIntegrityHashValue( 

4919 self.SessionPreauthIntegrityHashValue, 

4920 sesspkt, 

4921 HashId=self.PreauthIntegrityHashId, 

4922 ) 

4923 ) 

4924 

4925 # I/O 

4926 

4927 def in_pkt(self, pkt): 

4928 """ 

4929 Incoming SMB packet 

4930 """ 

4931 if SMB2_Transform_Header in pkt: 

4932 # Packet is encrypted 

4933 pkt = pkt[SMB2_Transform_Header].decrypt( 

4934 self.Dialect, 

4935 self.DecryptionKey, 

4936 CipherId=self.CipherId, 

4937 ) 

4938 # Signature is verified in SMBStreamSocket 

4939 return pkt 

4940 

4941 def out_pkt(self, pkt, Compounded=False, ForceSign=False, ForceEncrypt=False): 

4942 """ 

4943 Outgoing SMB packet 

4944 

4945 :param pkt: the packet to send 

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

4947 un-compounded packet 

4948 :param ForceSign: if True, force to sign the packet. 

4949 :param ForceEncrypt: if True, force to encrypt the packet. 

4950 

4951 Handles: 

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

4953 - handles signing and encryption (if required) 

4954 """ 

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

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

4957 if SMB2_Header in pkt: 

4958 if self.CompoundQueue: 

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

4960 pkt = pkt[SMB2_Header] 

4961 if Compounded: 

4962 # [MS-SMB2] 3.2.4.1.4 

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

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

4965 # an 8-byte boundary." 

4966 # [MS-SMB2] 3.1.4.1 

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

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

4969 # computation." 

4970 length = len(pkt[SMB2_Header]) 

4971 padlen = (-length) % 8 

4972 if padlen: 

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

4974 pkt[SMB2_Header].NextCommand = length + padlen 

4975 if ( 

4976 self.Dialect 

4977 and self.SigningKey 

4978 and (ForceSign or self.SigningRequired and not ForceEncrypt) 

4979 ): 

4980 # [MS-SMB2] sect 3.2.4.1.1 - Signing 

4981 smb = pkt[SMB2_Header] 

4982 smb.Flags += "SMB2_FLAGS_SIGNED" 

4983 smb.sign( 

4984 self.Dialect, 

4985 self.SigningKey, 

4986 # SMB 3.1.1 parameters: 

4987 SigningAlgorithmId=self.SigningAlgorithmId, 

4988 IsClient=False, 

4989 ) 

4990 if Compounded: 

4991 # There IS a next compound. Store in queue 

4992 self.CompoundQueue.append(pkt) 

4993 return [] 

4994 else: 

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

4996 if self.CompoundQueue: 

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

4998 self.CompoundQueue.clear() 

4999 if self.EncryptionKey and ( 

5000 ForceEncrypt or self.EncryptData or self.TreeEncryptData 

5001 ): 

5002 # [MS-SMB2] sect 3.1.4.3 - Encrypting the message 

5003 smb = pkt[SMB2_Header] 

5004 assert not smb.Flags.SMB2_FLAGS_SIGNED 

5005 smbt = smb.encrypt( 

5006 self.Dialect, 

5007 self.EncryptionKey, 

5008 CipherId=self.CipherId, 

5009 ) 

5010 if smb.underlayer: 

5011 # If there's an underlayer, replace current SMB header 

5012 smb.underlayer.payload = smbt 

5013 else: 

5014 smb = smbt 

5015 return [pkt] 

5016 

5017 def process(self, pkt: Packet): 

5018 # Called when passively sniffing 

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

5020 if pkt is not None and SMB2_Header in pkt: 

5021 return self.in_pkt(pkt) 

5022 return pkt