1# -*- coding: utf-8 -*- 2# Copyright: (c) 2020, Jordan Borean (@jborean93) <jborean93@gmail.com> 3# MIT License (see LICENSE or https://opensource.org/licenses/MIT) 4 5from collections import ( 6 OrderedDict, 7) 8 9from smbprotocol.structure import ( 10 BytesField, 11 EnumField, 12 FlagField, 13 IntField, 14 Structure, 15) 16 17try: 18 from queue import Queue 19except ImportError: # pragma: no cover 20 from Queue import Queue 21 22 23class Commands(object): 24 """ 25 [MS-SMB2] v53.0 2017-09-15 26 27 2.2.1.2 SMB2 Packet Header - SYNC Command 28 The command code of an SMB2 packet, it is used in the packet header. 29 """ 30 SMB2_NEGOTIATE = 0x0000 31 SMB2_SESSION_SETUP = 0x0001 32 SMB2_LOGOFF = 0x0002 33 SMB2_TREE_CONNECT = 0x0003 34 SMB2_TREE_DISCONNECT = 0x0004 35 SMB2_CREATE = 0x0005 36 SMB2_CLOSE = 0x0006 37 SMB2_FLUSH = 0x0007 38 SMB2_READ = 0x0008 39 SMB2_WRITE = 0x0009 40 SMB2_LOCK = 0x000A 41 SMB2_IOCTL = 0x000B 42 SMB2_CANCEL = 0x000C 43 SMB2_ECHO = 0x000D 44 SMB2_QUERY_DIRECTORY = 0x000E 45 SMB2_CHANGE_NOTIFY = 0x000F 46 SMB2_QUERY_INFO = 0x0010 47 SMB2_SET_INFO = 0x0011 48 SMB2_OPLOCK_BREAK = 0x0012 49 50 51class NtStatus(object): 52 """ 53 [MS-ERREF] https://msdn.microsoft.com/en-au/library/cc704588.aspx 54 55 2.3.1 NTSTATUS Values 56 These values are set in the status field of an SMB2Header response. This is 57 not an exhaustive list but common values that are returned. 58 """ 59 STATUS_SUCCESS = 0x00000000 60 STATUS_UNSUCCESSFUL = 0xC0000001 61 STATUS_NETWORK_NAME_DELETED = 0xC00000C9 62 STATUS_PENDING = 0x00000103 63 STATUS_NOTIFY_CLEANUP = 0x0000010B 64 STATUS_NOTIFY_ENUM_DIR = 0x0000010C 65 STATUS_BUFFER_OVERFLOW = 0x80000005 66 STATUS_NO_MORE_FILES = 0x80000006 67 STATUS_END_OF_FILE = 0xC0000011 68 STATUS_INVALID_EA_NAME = 0x80000013 69 STATUS_EA_LIST_INCONSISTENT = 0x80000014 70 STATUS_STOPPED_ON_SYMLINK = 0x8000002D 71 STATUS_INVALID_INFO_CLASS = 0xC0000003 72 STATUS_INFO_LENGTH_MISMATCH = 0xC0000004 73 STATUS_INVALID_PARAMETER = 0xC000000D 74 STATUS_NO_SUCH_FILE = 0xC000000F 75 STATUS_INVALID_DEVICE_REQUEST = 0xC0000010 76 STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016 77 STATUS_ACCESS_DENIED = 0xC0000022 78 STATUS_BUFFER_TOO_SMALL = 0xC0000023 79 STATUS_OBJECT_NAME_INVALID = 0xC0000033 80 STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034 81 STATUS_OBJECT_NAME_COLLISION = 0xC0000035 82 STATUS_OBJECT_PATH_INVALID = 0xC0000039 83 STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A 84 STATUS_OBJECT_PATH_SYNTAX_BAD = 0xC000003B 85 STATUS_SHARING_VIOLATION = 0xC0000043 86 STATUS_EAS_NOT_SUPPORTED = 0xC000004F 87 STATUS_EA_TOO_LARGE = 0xC0000050 88 STATUS_NONEXISTENT_EA_ENTRY = 0xC0000051 89 STATUS_NO_EAS_ON_FILE = 0xC0000052 90 STATUS_EA_CORRUPT_ERROR = 0xC0000053 91 STATUS_DELETE_PENDING = 0xC0000056 92 STATUS_PRIVILEGE_NOT_HELD = 0xC0000061 93 STATUS_WRONG_PASSWORD = 0xC000006A 94 STATUS_LOGON_FAILURE = 0xC000006D 95 STATUS_PASSWORD_EXPIRED = 0xC0000071 96 STATUS_NONE_MAPPED = 0xC0000073 97 STATUS_INSUFFICIENT_RESOURCES = 0xC000009A 98 STATUS_PIPE_NOT_AVAILABLE = 0xC00000AC 99 STATUS_PIPE_BUSY = 0xC00000AE 100 STATUS_PIPE_DISCONNECTED = 0xC00000B0 101 STATUS_PIPE_CLOSING = 0xC00000B1 102 STATUS_IO_TIMEOUT = 0xC00000B5 103 STATUS_FILE_IS_A_DIRECTORY = 0xC00000BA 104 STATUS_NOT_SUPPORTED = 0xC00000BB 105 STATUS_BAD_NETWORK_NAME = 0xC00000CC 106 STATUS_REQUEST_NOT_ACCEPTED = 0xC00000D0 107 STATUS_PIPE_EMPTY = 0xC00000D9 108 STATUS_INTERNAL_ERROR = 0xC00000E5 109 STATUS_DIRECTORY_NOT_EMPTY = 0xC0000101 110 STATUS_NOT_A_DIRECTORY = 0xC0000103 111 STATUS_CANCELLED = 0xC0000120 112 STATUS_CANNOT_DELETE = 0xC0000121 113 STATUS_FILE_CLOSED = 0xC0000128 114 STATUS_PIPE_BROKEN = 0xC000014B 115 STATUS_FS_DRIVER_REQUIRED = 0xC000019C 116 STATUS_USER_SESSION_DELETED = 0xC0000203 117 STATUS_INSUFF_SERVER_RESOURCES = 0xC0000205 118 STATUS_NOT_FOUND = 0xC0000225 119 STATUS_PATH_NOT_COVERED = 0xC0000257 120 STATUS_DFS_UNAVAILABLE = 0xC000026D 121 STATUS_NOT_A_REPARSE_POINT = 0xC0000275 122 STATUS_SERVER_UNAVAILABLE = 0xC0000466 123 124 125class Smb2Flags(object): 126 """ 127 [MS-SMB2] v53.0 2017-09-15 128 129 2.2.1.2 SMB2 Packet Header - SYNC Flags 130 Indicates various processing rules that need to be done on the SMB2 packet. 131 """ 132 SMB2_FLAGS_SERVER_TO_REDIR = 0x00000001 133 SMB2_FLAGS_ASYNC_COMMAND = 0x00000002 134 SMB2_FLAGS_RELATED_OPERATIONS = 0x00000004 135 SMB2_FLAGS_SIGNED = 0x00000008 136 SMB2_FLAGS_PRIORITY_MASK = 0x00000070 137 SMB2_FLAGS_DFS_OPERATIONS = 0x10000000 138 SMB2_FLAGS_REPLAY_OPERATIONS = 0x20000000 139 140 141class SMB2HeaderAsync(Structure): 142 """ 143 [MS-SMB2] 2.2.1.1 SMB2 Packer Header - ASYNC 144 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/ea4560b7-90da-4803-82b5-344754b92a79 145 146 The SMB2 Packet header for async commands. 147 """ 148 149 def __init__(self): 150 self.fields = OrderedDict([ 151 ('protocol_id', BytesField( 152 size=4, 153 default=b"\xfeSMB", 154 )), 155 ('structure_size', IntField( 156 size=2, 157 default=64, 158 )), 159 ('credit_charge', IntField(size=2)), 160 ('channel_sequence', IntField(size=2)), 161 ('reserved', IntField(size=2)), 162 ('command', EnumField( 163 size=2, 164 enum_type=Commands, 165 )), 166 ('credit_request', IntField(size=2)), 167 ('flags', FlagField( 168 size=4, 169 flag_type=Smb2Flags, 170 )), 171 ('next_command', IntField(size=4)), 172 ('message_id', IntField(size=8)), 173 ('async_id', IntField(size=8)), 174 ('session_id', IntField(size=8)), 175 ('signature', BytesField( 176 size=16, 177 default=b"\x00" * 16, 178 )), 179 ('data', BytesField()) 180 ]) 181 super(SMB2HeaderAsync, self).__init__() 182 183 184class SMB2HeaderRequest(Structure): 185 """ 186 [MS-SMB2] v53.0 2017-09-15 187 188 2.2.1.2 SMB2 Packet Header - SYNC 189 This is the header definition that contains the ChannelSequence/Reserved 190 instead of the Status field used for a Packet request. 191 """ 192 193 def __init__(self): 194 self.fields = OrderedDict([ 195 ('protocol_id', BytesField( 196 size=4, 197 default=b"\xfeSMB", 198 )), 199 ('structure_size', IntField( 200 size=2, 201 default=64, 202 )), 203 ('credit_charge', IntField(size=2)), 204 ('channel_sequence', IntField(size=2)), 205 ('reserved', IntField(size=2)), 206 ('command', EnumField( 207 size=2, 208 enum_type=Commands 209 )), 210 ('credit_request', IntField(size=2)), 211 ('flags', FlagField( 212 size=4, 213 flag_type=Smb2Flags, 214 )), 215 ('next_command', IntField(size=4)), 216 ('message_id', IntField(size=8)), 217 ('process_id', IntField(size=4)), 218 ('tree_id', IntField(size=4)), 219 ('session_id', IntField(size=8)), 220 ('signature', BytesField( 221 size=16, 222 default=b"\x00" * 16, 223 )), 224 ('data', BytesField()) 225 ]) 226 super(SMB2HeaderRequest, self).__init__() 227 228 229class SMB2HeaderResponse(Structure): 230 """ 231 [MS-SMB2] v53.0 2017-09-15 232 233 2.2.1.2 SMB2 Packet Header - SYNC 234 The header definition for an SMB Response that contains the Status field 235 instead of the ChannelSequence/Reserved used for a Packet response. 236 """ 237 238 def __init__(self): 239 self.fields = OrderedDict([ 240 ('protocol_id', BytesField( 241 size=4, 242 default=b'\xfeSMB', 243 )), 244 ('structure_size', IntField( 245 size=2, 246 default=64, 247 )), 248 ('credit_charge', IntField(size=2)), 249 ('status', EnumField( 250 size=4, 251 enum_type=NtStatus, 252 enum_strict=False 253 )), 254 ('command', EnumField( 255 size=2, 256 enum_type=Commands, 257 enum_strict=False, 258 )), 259 ('credit_response', IntField(size=2)), 260 ('flags', FlagField( 261 size=4, 262 flag_type=Smb2Flags, 263 )), 264 ('next_command', IntField(size=4)), 265 ('message_id', IntField(size=8)), 266 ('reserved', IntField(size=4)), 267 ('tree_id', IntField(size=4)), 268 ('session_id', IntField(size=8)), 269 ('signature', BytesField( 270 size=16, 271 default=b"\x00" * 16, 272 )), 273 ('data', BytesField()), 274 ]) 275 super(SMB2HeaderResponse, self).__init__() 276