Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Impacket - Collection of Python classes for working with network protocols. 

2# 

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

4# 

5# This software is provided under a slightly modified version 

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

7# for more information. 

8# 

9# Description: 

10# Partial C706.pdf + [MS-RPCE] implementation 

11# 

12# Best way to learn how to use these calls is to grab the protocol standard 

13# so you understand what the call does, and then read the test case located 

14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC 

15# 

16# ToDo: 

17# [ ] Take out all the security provider stuff out of here (e.g. RPC_C_AUTHN_WINNT) 

18# and put it elsewhere. This will make the coder cleaner and easier to add 

19# more SSP (e.g. NETLOGON) 

20#  

21 

22import logging 

23import socket 

24import sys 

25from binascii import unhexlify 

26from Cryptodome.Cipher import ARC4 

27 

28from impacket import ntlm, LOG 

29from impacket.structure import Structure,pack,unpack 

30from impacket.krb5 import kerberosv5, gssapi 

31from impacket.uuid import uuidtup_to_bin, generate, stringver_to_bin, bin_to_uuidtup 

32from impacket.dcerpc.v5.dtypes import UCHAR, ULONG, USHORT 

33from impacket.dcerpc.v5.ndr import NDRSTRUCT 

34from impacket import hresult_errors 

35from threading import Thread 

36 

37# MS/RPC Constants 

38MSRPC_REQUEST = 0x00 

39MSRPC_PING = 0x01 

40MSRPC_RESPONSE = 0x02 

41MSRPC_FAULT = 0x03 

42MSRPC_WORKING = 0x04 

43MSRPC_NOCALL = 0x05 

44MSRPC_REJECT = 0x06 

45MSRPC_ACK = 0x07 

46MSRPC_CL_CANCEL = 0x08 

47MSRPC_FACK = 0x09 

48MSRPC_CANCELACK = 0x0A 

49MSRPC_BIND = 0x0B 

50MSRPC_BINDACK = 0x0C 

51MSRPC_BINDNAK = 0x0D 

52MSRPC_ALTERCTX = 0x0E 

53MSRPC_ALTERCTX_R= 0x0F 

54MSRPC_AUTH3 = 0x10 

55MSRPC_SHUTDOWN = 0x11 

56MSRPC_CO_CANCEL = 0x12 

57MSRPC_ORPHANED = 0x13 

58MSRPC_RTS = 0x14 

59 

60# MS/RPC Packet Flags 

61PFC_FIRST_FRAG = 0x01 

62PFC_LAST_FRAG = 0x02 

63 

64# For PDU types bind, bind_ack, alter_context, and 

65# alter_context_resp, this flag MUST be interpreted as PFC_SUPPORT_HEADER_SIGN 

66MSRPC_SUPPORT_SIGN = 0x04 

67 

68#For the 

69#remaining PDU types, this flag MUST be interpreted as PFC_PENDING_CANCEL. 

70MSRPC_PENDING_CANCEL= 0x04 

71 

72PFC_RESERVED_1 = 0x08 

73PFC_CONC_MPX = 0x10 

74PFC_DID_NOT_EXECUTE = 0x20 

75PFC_MAYBE = 0x40 

76PFC_OBJECT_UUID = 0x80 

77 

78# Auth Types - Security Providers 

79RPC_C_AUTHN_NONE = 0x00 

80RPC_C_AUTHN_GSS_NEGOTIATE = 0x09 

81RPC_C_AUTHN_WINNT = 0x0A 

82RPC_C_AUTHN_GSS_SCHANNEL = 0x0E 

83RPC_C_AUTHN_GSS_KERBEROS = 0x10 

84RPC_C_AUTHN_NETLOGON = 0x44 

85RPC_C_AUTHN_DEFAULT = 0xFF 

86 

87# Auth Levels 

88RPC_C_AUTHN_LEVEL_NONE = 1 

89RPC_C_AUTHN_LEVEL_CONNECT = 2 

90RPC_C_AUTHN_LEVEL_CALL = 3 

91RPC_C_AUTHN_LEVEL_PKT = 4 

92RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5 

93RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6 

94 

95#Reasons for rejection of a context element, included in bind_ack result reason 

96rpc_provider_reason = { 

97 0 : 'reason_not_specified', 

98 1 : 'abstract_syntax_not_supported', 

99 2 : 'proposed_transfer_syntaxes_not_supported', 

100 3 : 'local_limit_exceeded', 

101 4 : 'protocol_version_not_specified', 

102 8 : 'authentication_type_not_recognized', 

103 9 : 'invalid_checksum' 

104} 

105 

106MSRPC_CONT_RESULT_ACCEPT = 0 

107MSRPC_CONT_RESULT_USER_REJECT = 1 

108MSRPC_CONT_RESULT_PROV_REJECT = 2 

109 

110#Results of a presentation context negotiation 

111rpc_cont_def_result = { 

112 0 : 'acceptance', 

113 1 : 'user_rejection', 

114 2 : 'provider_rejection' 

115} 

116 

117#status codes, references: 

118#https://docs.microsoft.com/windows/desktop/Rpc/rpc-return-values 

119#https://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/common_return_values.asp 

120#winerror.h 

121#https://www.opengroup.org/onlinepubs/9629399/apdxn.htm 

122 

123rpc_status_codes = { 

124 0x00000005 : 'rpc_s_access_denied', 

125 0x00000008 : 'Authentication type not recognized', 

126 0x000006D8 : 'rpc_fault_cant_perform', 

127 0x000006C6 : 'rpc_x_invalid_bound', # the arrays bound are invalid 

128 0x000006E4 : 'rpc_s_cannot_support: The requested operation is not supported.', # some operation is not supported 

129 0x000006F7 : 'rpc_x_bad_stub_data', # the stub data is invalid, doesn't match with the IDL definition 

130 0x1C010001 : 'nca_s_comm_failure', # unable to get response from server: 

131 0x1C010002 : 'nca_s_op_rng_error', # bad operation number in call 

132 0x1C010003 : 'nca_s_unk_if', # unknown interface 

133 0x1C010006 : 'nca_s_wrong_boot_time', # client passed server wrong server boot time 

134 0x1C010009 : 'nca_s_you_crashed', # a restarted server called back a client 

135 0x1C01000B : 'nca_s_proto_error', # someone messed up the protocol 

136 0x1C010013 : 'nca_s_out_args_too_big ', # output args too big 

137 0x1C010014 : 'nca_s_server_too_busy', # server is too busy to handle call 

138 0x1C010015 : 'nca_s_fault_string_too_long', # string argument longer than declared max len 

139 0x1C010017 : 'nca_s_unsupported_type ', # no implementation of generic operation for object 

140 0x1C000001 : 'nca_s_fault_int_div_by_zero', 

141 0x1C000002 : 'nca_s_fault_addr_error ', 

142 0x1C000003 : 'nca_s_fault_fp_div_zero', 

143 0x1C000004 : 'nca_s_fault_fp_underflow', 

144 0x1C000005 : 'nca_s_fault_fp_overflow', 

145 0x1C000006 : 'nca_s_fault_invalid_tag', 

146 0x1C000007 : 'nca_s_fault_invalid_bound ', 

147 0x1C000008 : 'nca_s_rpc_version_mismatch', 

148 0x1C000009 : 'nca_s_unspec_reject ', 

149 0x1C00000A : 'nca_s_bad_actid', 

150 0x1C00000B : 'nca_s_who_are_you_failed', 

151 0x1C00000C : 'nca_s_manager_not_entered ', 

152 0x1C00000D : 'nca_s_fault_cancel', 

153 0x1C00000E : 'nca_s_fault_ill_inst', 

154 0x1C00000F : 'nca_s_fault_fp_error', 

155 0x1C000010 : 'nca_s_fault_int_overflow', 

156 0x1C000012 : 'nca_s_fault_unspec', 

157 0x1C000013 : 'nca_s_fault_remote_comm_failure ', 

158 0x1C000014 : 'nca_s_fault_pipe_empty ', 

159 0x1C000015 : 'nca_s_fault_pipe_closed', 

160 0x1C000016 : 'nca_s_fault_pipe_order ', 

161 0x1C000017 : 'nca_s_fault_pipe_discipline', 

162 0x1C000018 : 'nca_s_fault_pipe_comm_error', 

163 0x1C000019 : 'nca_s_fault_pipe_memory', 

164 0x1C00001A : 'nca_s_fault_context_mismatch ', 

165 0x1C00001B : 'nca_s_fault_remote_no_memory ', 

166 0x1C00001C : 'nca_s_invalid_pres_context_id', 

167 0x1C00001D : 'nca_s_unsupported_authn_level', 

168 0x1C00001F : 'nca_s_invalid_checksum ', 

169 0x1C000020 : 'nca_s_invalid_crc', 

170 0x1C000021 : 'nca_s_fault_user_defined', 

171 0x1C000022 : 'nca_s_fault_tx_open_failed', 

172 0x1C000023 : 'nca_s_fault_codeset_conv_error', 

173 0x1C000024 : 'nca_s_fault_object_not_found ', 

174 0x1C000025 : 'nca_s_fault_no_client_stub', 

175 0x16c9a000 : "rpc_s_mod", 

176 0x16c9a001 : "rpc_s_op_rng_error", 

177 0x16c9a002 : "rpc_s_cant_create_socket", 

178 0x16c9a003 : "rpc_s_cant_bind_socket", 

179 0x16c9a004 : "rpc_s_not_in_call", 

180 0x16c9a005 : "rpc_s_no_port", 

181 0x16c9a006 : "rpc_s_wrong_boot_time", 

182 0x16c9a007 : "rpc_s_too_many_sockets", 

183 0x16c9a008 : "rpc_s_illegal_register", 

184 0x16c9a009 : "rpc_s_cant_recv", 

185 0x16c9a00a : "rpc_s_bad_pkt", 

186 0x16c9a00b : "rpc_s_unbound_handle", 

187 0x16c9a00c : "rpc_s_addr_in_use", 

188 0x16c9a00d : "rpc_s_in_args_too_big", 

189 0x16c9a00e : "rpc_s_string_too_long", 

190 0x16c9a00f : "rpc_s_too_many_objects", 

191 0x16c9a010 : "rpc_s_binding_has_no_auth", 

192 0x16c9a011 : "rpc_s_unknown_authn_service", 

193 0x16c9a012 : "rpc_s_no_memory", 

194 0x16c9a013 : "rpc_s_cant_nmalloc", 

195 0x16c9a014 : "rpc_s_call_faulted", 

196 0x16c9a015 : "rpc_s_call_failed", 

197 0x16c9a016 : "rpc_s_comm_failure", 

198 0x16c9a017 : "rpc_s_rpcd_comm_failure", 

199 0x16c9a018 : "rpc_s_illegal_family_rebind", 

200 0x16c9a019 : "rpc_s_invalid_handle", 

201 0x16c9a01a : "rpc_s_coding_error", 

202 0x16c9a01b : "rpc_s_object_not_found", 

203 0x16c9a01c : "rpc_s_cthread_not_found", 

204 0x16c9a01d : "rpc_s_invalid_binding", 

205 0x16c9a01e : "rpc_s_already_registered", 

206 0x16c9a01f : "rpc_s_endpoint_not_found", 

207 0x16c9a020 : "rpc_s_invalid_rpc_protseq", 

208 0x16c9a021 : "rpc_s_desc_not_registered", 

209 0x16c9a022 : "rpc_s_already_listening", 

210 0x16c9a023 : "rpc_s_no_protseqs", 

211 0x16c9a024 : "rpc_s_no_protseqs_registered", 

212 0x16c9a025 : "rpc_s_no_bindings", 

213 0x16c9a026 : "rpc_s_max_descs_exceeded", 

214 0x16c9a027 : "rpc_s_no_interfaces", 

215 0x16c9a028 : "rpc_s_invalid_timeout", 

216 0x16c9a029 : "rpc_s_cant_inq_socket", 

217 0x16c9a02a : "rpc_s_invalid_naf_id", 

218 0x16c9a02b : "rpc_s_inval_net_addr", 

219 0x16c9a02c : "rpc_s_unknown_if", 

220 0x16c9a02d : "rpc_s_unsupported_type", 

221 0x16c9a02e : "rpc_s_invalid_call_opt", 

222 0x16c9a02f : "rpc_s_no_fault", 

223 0x16c9a030 : "rpc_s_cancel_timeout", 

224 0x16c9a031 : "rpc_s_call_cancelled", 

225 0x16c9a032 : "rpc_s_invalid_call_handle", 

226 0x16c9a033 : "rpc_s_cannot_alloc_assoc", 

227 0x16c9a034 : "rpc_s_cannot_connect", 

228 0x16c9a035 : "rpc_s_connection_aborted", 

229 0x16c9a036 : "rpc_s_connection_closed", 

230 0x16c9a037 : "rpc_s_cannot_accept", 

231 0x16c9a038 : "rpc_s_assoc_grp_not_found", 

232 0x16c9a039 : "rpc_s_stub_interface_error", 

233 0x16c9a03a : "rpc_s_invalid_object", 

234 0x16c9a03b : "rpc_s_invalid_type", 

235 0x16c9a03c : "rpc_s_invalid_if_opnum", 

236 0x16c9a03d : "rpc_s_different_server_instance", 

237 0x16c9a03e : "rpc_s_protocol_error", 

238 0x16c9a03f : "rpc_s_cant_recvmsg", 

239 0x16c9a040 : "rpc_s_invalid_string_binding", 

240 0x16c9a041 : "rpc_s_connect_timed_out", 

241 0x16c9a042 : "rpc_s_connect_rejected", 

242 0x16c9a043 : "rpc_s_network_unreachable", 

243 0x16c9a044 : "rpc_s_connect_no_resources", 

244 0x16c9a045 : "rpc_s_rem_network_shutdown", 

245 0x16c9a046 : "rpc_s_too_many_rem_connects", 

246 0x16c9a047 : "rpc_s_no_rem_endpoint", 

247 0x16c9a048 : "rpc_s_rem_host_down", 

248 0x16c9a049 : "rpc_s_host_unreachable", 

249 0x16c9a04a : "rpc_s_access_control_info_inv", 

250 0x16c9a04b : "rpc_s_loc_connect_aborted", 

251 0x16c9a04c : "rpc_s_connect_closed_by_rem", 

252 0x16c9a04d : "rpc_s_rem_host_crashed", 

253 0x16c9a04e : "rpc_s_invalid_endpoint_format", 

254 0x16c9a04f : "rpc_s_unknown_status_code", 

255 0x16c9a050 : "rpc_s_unknown_mgr_type", 

256 0x16c9a051 : "rpc_s_assoc_creation_failed", 

257 0x16c9a052 : "rpc_s_assoc_grp_max_exceeded", 

258 0x16c9a053 : "rpc_s_assoc_grp_alloc_failed", 

259 0x16c9a054 : "rpc_s_sm_invalid_state", 

260 0x16c9a055 : "rpc_s_assoc_req_rejected", 

261 0x16c9a056 : "rpc_s_assoc_shutdown", 

262 0x16c9a057 : "rpc_s_tsyntaxes_unsupported", 

263 0x16c9a058 : "rpc_s_context_id_not_found", 

264 0x16c9a059 : "rpc_s_cant_listen_socket", 

265 0x16c9a05a : "rpc_s_no_addrs", 

266 0x16c9a05b : "rpc_s_cant_getpeername", 

267 0x16c9a05c : "rpc_s_cant_get_if_id", 

268 0x16c9a05d : "rpc_s_protseq_not_supported", 

269 0x16c9a05e : "rpc_s_call_orphaned", 

270 0x16c9a05f : "rpc_s_who_are_you_failed", 

271 0x16c9a060 : "rpc_s_unknown_reject", 

272 0x16c9a061 : "rpc_s_type_already_registered", 

273 0x16c9a062 : "rpc_s_stop_listening_disabled", 

274 0x16c9a063 : "rpc_s_invalid_arg", 

275 0x16c9a064 : "rpc_s_not_supported", 

276 0x16c9a065 : "rpc_s_wrong_kind_of_binding", 

277 0x16c9a066 : "rpc_s_authn_authz_mismatch", 

278 0x16c9a067 : "rpc_s_call_queued", 

279 0x16c9a068 : "rpc_s_cannot_set_nodelay", 

280 0x16c9a069 : "rpc_s_not_rpc_tower", 

281 0x16c9a06a : "rpc_s_invalid_rpc_protid", 

282 0x16c9a06b : "rpc_s_invalid_rpc_floor", 

283 0x16c9a06c : "rpc_s_call_timeout", 

284 0x16c9a06d : "rpc_s_mgmt_op_disallowed", 

285 0x16c9a06e : "rpc_s_manager_not_entered", 

286 0x16c9a06f : "rpc_s_calls_too_large_for_wk_ep", 

287 0x16c9a070 : "rpc_s_server_too_busy", 

288 0x16c9a071 : "rpc_s_prot_version_mismatch", 

289 0x16c9a072 : "rpc_s_rpc_prot_version_mismatch", 

290 0x16c9a073 : "rpc_s_ss_no_import_cursor", 

291 0x16c9a074 : "rpc_s_fault_addr_error", 

292 0x16c9a075 : "rpc_s_fault_context_mismatch", 

293 0x16c9a076 : "rpc_s_fault_fp_div_by_zero", 

294 0x16c9a077 : "rpc_s_fault_fp_error", 

295 0x16c9a078 : "rpc_s_fault_fp_overflow", 

296 0x16c9a079 : "rpc_s_fault_fp_underflow", 

297 0x16c9a07a : "rpc_s_fault_ill_inst", 

298 0x16c9a07b : "rpc_s_fault_int_div_by_zero", 

299 0x16c9a07c : "rpc_s_fault_int_overflow", 

300 0x16c9a07d : "rpc_s_fault_invalid_bound", 

301 0x16c9a07e : "rpc_s_fault_invalid_tag", 

302 0x16c9a07f : "rpc_s_fault_pipe_closed", 

303 0x16c9a080 : "rpc_s_fault_pipe_comm_error", 

304 0x16c9a081 : "rpc_s_fault_pipe_discipline", 

305 0x16c9a082 : "rpc_s_fault_pipe_empty", 

306 0x16c9a083 : "rpc_s_fault_pipe_memory", 

307 0x16c9a084 : "rpc_s_fault_pipe_order", 

308 0x16c9a085 : "rpc_s_fault_remote_comm_failure", 

309 0x16c9a086 : "rpc_s_fault_remote_no_memory", 

310 0x16c9a087 : "rpc_s_fault_unspec", 

311 0x16c9a088 : "uuid_s_bad_version", 

312 0x16c9a089 : "uuid_s_socket_failure", 

313 0x16c9a08a : "uuid_s_getconf_failure", 

314 0x16c9a08b : "uuid_s_no_address", 

315 0x16c9a08c : "uuid_s_overrun", 

316 0x16c9a08d : "uuid_s_internal_error", 

317 0x16c9a08e : "uuid_s_coding_error", 

318 0x16c9a08f : "uuid_s_invalid_string_uuid", 

319 0x16c9a090 : "uuid_s_no_memory", 

320 0x16c9a091 : "rpc_s_no_more_entries", 

321 0x16c9a092 : "rpc_s_unknown_ns_error", 

322 0x16c9a093 : "rpc_s_name_service_unavailable", 

323 0x16c9a094 : "rpc_s_incomplete_name", 

324 0x16c9a095 : "rpc_s_group_not_found", 

325 0x16c9a096 : "rpc_s_invalid_name_syntax", 

326 0x16c9a097 : "rpc_s_no_more_members", 

327 0x16c9a098 : "rpc_s_no_more_interfaces", 

328 0x16c9a099 : "rpc_s_invalid_name_service", 

329 0x16c9a09a : "rpc_s_no_name_mapping", 

330 0x16c9a09b : "rpc_s_profile_not_found", 

331 0x16c9a09c : "rpc_s_not_found", 

332 0x16c9a09d : "rpc_s_no_updates", 

333 0x16c9a09e : "rpc_s_update_failed", 

334 0x16c9a09f : "rpc_s_no_match_exported", 

335 0x16c9a0a0 : "rpc_s_entry_not_found", 

336 0x16c9a0a1 : "rpc_s_invalid_inquiry_context", 

337 0x16c9a0a2 : "rpc_s_interface_not_found", 

338 0x16c9a0a3 : "rpc_s_group_member_not_found", 

339 0x16c9a0a4 : "rpc_s_entry_already_exists", 

340 0x16c9a0a5 : "rpc_s_nsinit_failure", 

341 0x16c9a0a6 : "rpc_s_unsupported_name_syntax", 

342 0x16c9a0a7 : "rpc_s_no_more_elements", 

343 0x16c9a0a8 : "rpc_s_no_ns_permission", 

344 0x16c9a0a9 : "rpc_s_invalid_inquiry_type", 

345 0x16c9a0aa : "rpc_s_profile_element_not_found", 

346 0x16c9a0ab : "rpc_s_profile_element_replaced", 

347 0x16c9a0ac : "rpc_s_import_already_done", 

348 0x16c9a0ad : "rpc_s_database_busy", 

349 0x16c9a0ae : "rpc_s_invalid_import_context", 

350 0x16c9a0af : "rpc_s_uuid_set_not_found", 

351 0x16c9a0b0 : "rpc_s_uuid_member_not_found", 

352 0x16c9a0b1 : "rpc_s_no_interfaces_exported", 

353 0x16c9a0b2 : "rpc_s_tower_set_not_found", 

354 0x16c9a0b3 : "rpc_s_tower_member_not_found", 

355 0x16c9a0b4 : "rpc_s_obj_uuid_not_found", 

356 0x16c9a0b5 : "rpc_s_no_more_bindings", 

357 0x16c9a0b6 : "rpc_s_invalid_priority", 

358 0x16c9a0b7 : "rpc_s_not_rpc_entry", 

359 0x16c9a0b8 : "rpc_s_invalid_lookup_context", 

360 0x16c9a0b9 : "rpc_s_binding_vector_full", 

361 0x16c9a0ba : "rpc_s_cycle_detected", 

362 0x16c9a0bb : "rpc_s_nothing_to_export", 

363 0x16c9a0bc : "rpc_s_nothing_to_unexport", 

364 0x16c9a0bd : "rpc_s_invalid_vers_option", 

365 0x16c9a0be : "rpc_s_no_rpc_data", 

366 0x16c9a0bf : "rpc_s_mbr_picked", 

367 0x16c9a0c0 : "rpc_s_not_all_objs_unexported", 

368 0x16c9a0c1 : "rpc_s_no_entry_name", 

369 0x16c9a0c2 : "rpc_s_priority_group_done", 

370 0x16c9a0c3 : "rpc_s_partial_results", 

371 0x16c9a0c4 : "rpc_s_no_env_setup", 

372 0x16c9a0c5 : "twr_s_unknown_sa", 

373 0x16c9a0c6 : "twr_s_unknown_tower", 

374 0x16c9a0c7 : "twr_s_not_implemented", 

375 0x16c9a0c8 : "rpc_s_max_calls_too_small", 

376 0x16c9a0c9 : "rpc_s_cthread_create_failed", 

377 0x16c9a0ca : "rpc_s_cthread_pool_exists", 

378 0x16c9a0cb : "rpc_s_cthread_no_such_pool", 

379 0x16c9a0cc : "rpc_s_cthread_invoke_disabled", 

380 0x16c9a0cd : "ept_s_cant_perform_op", 

381 0x16c9a0ce : "ept_s_no_memory", 

382 0x16c9a0cf : "ept_s_database_invalid", 

383 0x16c9a0d0 : "ept_s_cant_create", 

384 0x16c9a0d1 : "ept_s_cant_access", 

385 0x16c9a0d2 : "ept_s_database_already_open", 

386 0x16c9a0d3 : "ept_s_invalid_entry", 

387 0x16c9a0d4 : "ept_s_update_failed", 

388 0x16c9a0d5 : "ept_s_invalid_context", 

389 0x16c9a0d6 : "ept_s_not_registered", 

390 0x16c9a0d7 : "ept_s_server_unavailable", 

391 0x16c9a0d8 : "rpc_s_underspecified_name", 

392 0x16c9a0d9 : "rpc_s_invalid_ns_handle", 

393 0x16c9a0da : "rpc_s_unknown_error", 

394 0x16c9a0db : "rpc_s_ss_char_trans_open_fail", 

395 0x16c9a0dc : "rpc_s_ss_char_trans_short_file", 

396 0x16c9a0dd : "rpc_s_ss_context_damaged", 

397 0x16c9a0de : "rpc_s_ss_in_null_context", 

398 0x16c9a0df : "rpc_s_socket_failure", 

399 0x16c9a0e0 : "rpc_s_unsupported_protect_level", 

400 0x16c9a0e1 : "rpc_s_invalid_checksum", 

401 0x16c9a0e2 : "rpc_s_invalid_credentials", 

402 0x16c9a0e3 : "rpc_s_credentials_too_large", 

403 0x16c9a0e4 : "rpc_s_call_id_not_found", 

404 0x16c9a0e5 : "rpc_s_key_id_not_found", 

405 0x16c9a0e6 : "rpc_s_auth_bad_integrity", 

406 0x16c9a0e7 : "rpc_s_auth_tkt_expired", 

407 0x16c9a0e8 : "rpc_s_auth_tkt_nyv", 

408 0x16c9a0e9 : "rpc_s_auth_repeat", 

409 0x16c9a0ea : "rpc_s_auth_not_us", 

410 0x16c9a0eb : "rpc_s_auth_badmatch", 

411 0x16c9a0ec : "rpc_s_auth_skew", 

412 0x16c9a0ed : "rpc_s_auth_badaddr", 

413 0x16c9a0ee : "rpc_s_auth_badversion", 

414 0x16c9a0ef : "rpc_s_auth_msg_type", 

415 0x16c9a0f0 : "rpc_s_auth_modified", 

416 0x16c9a0f1 : "rpc_s_auth_badorder", 

417 0x16c9a0f2 : "rpc_s_auth_badkeyver", 

418 0x16c9a0f3 : "rpc_s_auth_nokey", 

419 0x16c9a0f4 : "rpc_s_auth_mut_fail", 

420 0x16c9a0f5 : "rpc_s_auth_baddirection", 

421 0x16c9a0f6 : "rpc_s_auth_method", 

422 0x16c9a0f7 : "rpc_s_auth_badseq", 

423 0x16c9a0f8 : "rpc_s_auth_inapp_cksum", 

424 0x16c9a0f9 : "rpc_s_auth_field_toolong", 

425 0x16c9a0fa : "rpc_s_invalid_crc", 

426 0x16c9a0fb : "rpc_s_binding_incomplete", 

427 0x16c9a0fc : "rpc_s_key_func_not_allowed", 

428 0x16c9a0fd : "rpc_s_unknown_stub_rtl_if_vers", 

429 0x16c9a0fe : "rpc_s_unknown_ifspec_vers", 

430 0x16c9a0ff : "rpc_s_proto_unsupp_by_auth", 

431 0x16c9a100 : "rpc_s_authn_challenge_malformed", 

432 0x16c9a101 : "rpc_s_protect_level_mismatch", 

433 0x16c9a102 : "rpc_s_no_mepv", 

434 0x16c9a103 : "rpc_s_stub_protocol_error", 

435 0x16c9a104 : "rpc_s_class_version_mismatch", 

436 0x16c9a105 : "rpc_s_helper_not_running", 

437 0x16c9a106 : "rpc_s_helper_short_read", 

438 0x16c9a107 : "rpc_s_helper_catatonic", 

439 0x16c9a108 : "rpc_s_helper_aborted", 

440 0x16c9a109 : "rpc_s_not_in_kernel", 

441 0x16c9a10a : "rpc_s_helper_wrong_user", 

442 0x16c9a10b : "rpc_s_helper_overflow", 

443 0x16c9a10c : "rpc_s_dg_need_way_auth", 

444 0x16c9a10d : "rpc_s_unsupported_auth_subtype", 

445 0x16c9a10e : "rpc_s_wrong_pickle_type", 

446 0x16c9a10f : "rpc_s_not_listening", 

447 0x16c9a110 : "rpc_s_ss_bad_buffer", 

448 0x16c9a111 : "rpc_s_ss_bad_es_action", 

449 0x16c9a112 : "rpc_s_ss_wrong_es_version", 

450 0x16c9a113 : "rpc_s_fault_user_defined", 

451 0x16c9a114 : "rpc_s_ss_incompatible_codesets", 

452 0x16c9a115 : "rpc_s_tx_not_in_transaction", 

453 0x16c9a116 : "rpc_s_tx_open_failed", 

454 0x16c9a117 : "rpc_s_partial_credentials", 

455 0x16c9a118 : "rpc_s_ss_invalid_codeset_tag", 

456 0x16c9a119 : "rpc_s_mgmt_bad_type", 

457 0x16c9a11a : "rpc_s_ss_invalid_char_input", 

458 0x16c9a11b : "rpc_s_ss_short_conv_buffer", 

459 0x16c9a11c : "rpc_s_ss_iconv_error", 

460 0x16c9a11d : "rpc_s_ss_no_compat_codeset", 

461 0x16c9a11e : "rpc_s_ss_no_compat_charsets", 

462 0x16c9a11f : "dce_cs_c_ok", 

463 0x16c9a120 : "dce_cs_c_unknown", 

464 0x16c9a121 : "dce_cs_c_notfound", 

465 0x16c9a122 : "dce_cs_c_cannot_open_file", 

466 0x16c9a123 : "dce_cs_c_cannot_read_file", 

467 0x16c9a124 : "dce_cs_c_cannot_allocate_memory", 

468 0x16c9a125 : "rpc_s_ss_cleanup_failed", 

469 0x16c9a126 : "rpc_svc_desc_general", 

470 0x16c9a127 : "rpc_svc_desc_mutex", 

471 0x16c9a128 : "rpc_svc_desc_xmit", 

472 0x16c9a129 : "rpc_svc_desc_recv", 

473 0x16c9a12a : "rpc_svc_desc_dg_state", 

474 0x16c9a12b : "rpc_svc_desc_cancel", 

475 0x16c9a12c : "rpc_svc_desc_orphan", 

476 0x16c9a12d : "rpc_svc_desc_cn_state", 

477 0x16c9a12e : "rpc_svc_desc_cn_pkt", 

478 0x16c9a12f : "rpc_svc_desc_pkt_quotas", 

479 0x16c9a130 : "rpc_svc_desc_auth", 

480 0x16c9a131 : "rpc_svc_desc_source", 

481 0x16c9a132 : "rpc_svc_desc_stats", 

482 0x16c9a133 : "rpc_svc_desc_mem", 

483 0x16c9a134 : "rpc_svc_desc_mem_type", 

484 0x16c9a135 : "rpc_svc_desc_dg_pktlog", 

485 0x16c9a136 : "rpc_svc_desc_thread_id", 

486 0x16c9a137 : "rpc_svc_desc_timestamp", 

487 0x16c9a138 : "rpc_svc_desc_cn_errors", 

488 0x16c9a139 : "rpc_svc_desc_conv_thread", 

489 0x16c9a13a : "rpc_svc_desc_pid", 

490 0x16c9a13b : "rpc_svc_desc_atfork", 

491 0x16c9a13c : "rpc_svc_desc_cma_thread", 

492 0x16c9a13d : "rpc_svc_desc_inherit", 

493 0x16c9a13e : "rpc_svc_desc_dg_sockets", 

494 0x16c9a13f : "rpc_svc_desc_timer", 

495 0x16c9a140 : "rpc_svc_desc_threads", 

496 0x16c9a141 : "rpc_svc_desc_server_call", 

497 0x16c9a142 : "rpc_svc_desc_nsi", 

498 0x16c9a143 : "rpc_svc_desc_dg_pkt", 

499 0x16c9a144 : "rpc_m_cn_ill_state_trans_sa", 

500 0x16c9a145 : "rpc_m_cn_ill_state_trans_ca", 

501 0x16c9a146 : "rpc_m_cn_ill_state_trans_sg", 

502 0x16c9a147 : "rpc_m_cn_ill_state_trans_cg", 

503 0x16c9a148 : "rpc_m_cn_ill_state_trans_sr", 

504 0x16c9a149 : "rpc_m_cn_ill_state_trans_cr", 

505 0x16c9a14a : "rpc_m_bad_pkt_type", 

506 0x16c9a14b : "rpc_m_prot_mismatch", 

507 0x16c9a14c : "rpc_m_frag_toobig", 

508 0x16c9a14d : "rpc_m_unsupp_stub_rtl_if", 

509 0x16c9a14e : "rpc_m_unhandled_callstate", 

510 0x16c9a14f : "rpc_m_call_failed", 

511 0x16c9a150 : "rpc_m_call_failed_no_status", 

512 0x16c9a151 : "rpc_m_call_failed_errno", 

513 0x16c9a152 : "rpc_m_call_failed_s", 

514 0x16c9a153 : "rpc_m_call_failed_c", 

515 0x16c9a154 : "rpc_m_errmsg_toobig", 

516 0x16c9a155 : "rpc_m_invalid_srchattr", 

517 0x16c9a156 : "rpc_m_nts_not_found", 

518 0x16c9a157 : "rpc_m_invalid_accbytcnt", 

519 0x16c9a158 : "rpc_m_pre_v2_ifspec", 

520 0x16c9a159 : "rpc_m_unk_ifspec", 

521 0x16c9a15a : "rpc_m_recvbuf_toosmall", 

522 0x16c9a15b : "rpc_m_unalign_authtrl", 

523 0x16c9a15c : "rpc_m_unexpected_exc", 

524 0x16c9a15d : "rpc_m_no_stub_data", 

525 0x16c9a15e : "rpc_m_eventlist_full", 

526 0x16c9a15f : "rpc_m_unk_sock_type", 

527 0x16c9a160 : "rpc_m_unimp_call", 

528 0x16c9a161 : "rpc_m_invalid_seqnum", 

529 0x16c9a162 : "rpc_m_cant_create_uuid", 

530 0x16c9a163 : "rpc_m_pre_v2_ss", 

531 0x16c9a164 : "rpc_m_dgpkt_pool_corrupt", 

532 0x16c9a165 : "rpc_m_dgpkt_bad_free", 

533 0x16c9a166 : "rpc_m_lookaside_corrupt", 

534 0x16c9a167 : "rpc_m_alloc_fail", 

535 0x16c9a168 : "rpc_m_realloc_fail", 

536 0x16c9a169 : "rpc_m_cant_open_file", 

537 0x16c9a16a : "rpc_m_cant_read_addr", 

538 0x16c9a16b : "rpc_svc_desc_libidl", 

539 0x16c9a16c : "rpc_m_ctxrundown_nomem", 

540 0x16c9a16d : "rpc_m_ctxrundown_exc", 

541 0x16c9a16e : "rpc_s_fault_codeset_conv_error", 

542 0x16c9a16f : "rpc_s_no_call_active", 

543 0x16c9a170 : "rpc_s_cannot_support", 

544 0x16c9a171 : "rpc_s_no_context_available", 

545} 

546 

547class DCERPCException(Exception): 

548 """ 

549 This is the exception every client should catch regardless of the underlying 

550 DCERPC Transport used. 

551 """ 

552 def __init__(self, error_string=None, error_code=None, packet=None): 

553 """ 

554 :param string error_string: A string you want to show explaining the exception. Otherwise the default ones will be used 

555 :param integer error_code: the error_code if we're using a dictionary with error's descriptions 

556 :param NDR packet: if successfully decoded, the NDR packet of the response call. This could probably have useful 

557 information 

558 """ 

559 Exception.__init__(self) 

560 self.packet = packet 

561 self.error_string = error_string 

562 if packet is not None: 

563 try: 

564 self.error_code = packet['ErrorCode'] 

565 except: 

566 self.error_code = error_code 

567 else: 

568 self.error_code = error_code 

569 

570 def get_error_code( self ): 

571 return self.error_code 

572 

573 def get_packet( self ): 

574 return self.packet 

575 

576 def __str__( self ): 

577 key = self.error_code 

578 if self.error_string is not None: 

579 return self.error_string 

580 if key in rpc_status_codes: 580 ↛ 584line 580 didn't jump to line 584, because the condition on line 580 was never false

581 error_msg_short = rpc_status_codes[key] 

582 return 'DCERPC Runtime Error: code: 0x%x - %s ' % (self.error_code, error_msg_short) 

583 else: 

584 return 'DCERPC Runtime Error: unknown error code: 0x%x' % self.error_code 

585 

586# Context Item 

587class CtxItem(Structure): 

588 structure = ( 

589 ('ContextID','<H=0'), 

590 ('TransItems','B=0'), 

591 ('Pad','B=0'), 

592 ('AbstractSyntax','20s=""'), 

593 ('TransferSyntax','20s=""'), 

594 ) 

595 

596class CtxItemResult(Structure): 

597 structure = ( 

598 ('Result','<H=0'), 

599 ('Reason','<H=0'), 

600 ('TransferSyntax','20s=""'), 

601 ) 

602 

603class SEC_TRAILER(Structure): 

604 commonHdr = ( 

605 ('auth_type', 'B=10'), 

606 ('auth_level','B=0'), 

607 ('auth_pad_len','B=0'), 

608 ('auth_rsvrd','B=0'), 

609 ('auth_ctx_id','<L=747920'), 

610 ) 

611 

612class MSRPCHeader(Structure): 

613 _SIZE = 16 

614 commonHdr = ( 

615 ('ver_major','B=5'), # 0 

616 ('ver_minor','B=0'), # 1 

617 ('type','B=0'), # 2 

618 ('flags','B=0'), # 3 

619 ('representation','<L=0x10'), # 4 

620 ('frag_len','<H=self._SIZE+len(auth_data)+(16 if (self["flags"] & 0x80) > 0 else 0)+len(pduData)+len(pad)+len(sec_trailer)'), # 8 

621 ('auth_len','<H=len(auth_data)'), # 10 

622 ('call_id','<L=1'), # 12 <-- Common up to here (including this) 

623 ) 

624 

625 structure = ( 

626 ('dataLen','_-pduData','self["frag_len"]-self["auth_len"]-self._SIZE-(8 if self["auth_len"] > 0 else 0)'), 

627 ('pduData',':'), 

628 ('_pad', '_-pad','(4 - ((self._SIZE + (16 if (self["flags"] & 0x80) > 0 else 0) + len(self["pduData"])) & 3) & 3)'), 

629 ('pad', ':'), 

630 ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'), 

631 ('sec_trailer',':'), 

632 ('auth_dataLen','_-auth_data','self["auth_len"]'), 

633 ('auth_data',':'), 

634 ) 

635 

636 def __init__(self, data = None, alignment = 0): 

637 Structure.__init__(self,data, alignment) 

638 if data is None: 

639 self['ver_major'] = 5 

640 self['ver_minor'] = 0 

641 self['flags'] = PFC_FIRST_FRAG | PFC_LAST_FRAG 

642 self['type'] = MSRPC_REQUEST 

643 self.__frag_len_set = 0 

644 self['auth_len'] = 0 

645 self['pduData'] = b'' 

646 self['auth_data'] = b'' 

647 self['sec_trailer'] = b'' 

648 self['pad'] = b'' 

649 

650 def get_header_size(self): 

651 return self._SIZE + (16 if (self["flags"] & PFC_OBJECT_UUID) > 0 else 0) 

652 

653 def get_packet(self): 

654 if self['auth_data'] != b'': 

655 self['auth_len'] = len(self['auth_data']) 

656 # The sec_trailer structure MUST be 4-byte aligned with respect to  

657 # the beginning of the PDU. Padding octets MUST be used to align the  

658 # sec_trailer structure if its natural beginning is not already 4-byte aligned 

659 ##self['pad'] = '\xAA' * (4 - ((self._SIZE + len(self['pduData'])) & 3) & 3) 

660 

661 return self.getData() 

662 

663class MSRPCRequestHeader(MSRPCHeader): 

664 _SIZE = 24 

665 commonHdr = MSRPCHeader.commonHdr + ( 

666 ('alloc_hint','<L=0'), # 16 

667 ('ctx_id','<H=0'), # 20 

668 ('op_num','<H=0'), # 22 

669 ('_uuid','_-uuid','16 if self["flags"] & 0x80 > 0 else 0' ), # 22 

670 ('uuid',':'), # 22 

671 ) 

672 

673 def __init__(self, data = None, alignment = 0): 

674 MSRPCHeader.__init__(self, data, alignment) 

675 if data is None: 675 ↛ exitline 675 didn't return from function '__init__', because the condition on line 675 was never false

676 self['type'] = MSRPC_REQUEST 

677 self['ctx_id'] = 0 

678 self['uuid'] = b'' 

679 

680class MSRPCRespHeader(MSRPCHeader): 

681 _SIZE = 24 

682 commonHdr = MSRPCHeader.commonHdr + ( 

683 ('alloc_hint','<L=0'), # 16  

684 ('ctx_id','<H=0'), # 20 

685 ('cancel_count','<B=0'), # 22 

686 ('padding','<B=0'), # 23 

687 ) 

688 

689 def __init__(self, aBuffer = None, alignment = 0): 

690 MSRPCHeader.__init__(self, aBuffer, alignment) 

691 if aBuffer is None: 691 ↛ 692line 691 didn't jump to line 692, because the condition on line 691 was never true

692 self['type'] = MSRPC_RESPONSE 

693 self['ctx_id'] = 0 

694 

695class MSRPCBind(Structure): 

696 _CTX_ITEM_LEN = len(CtxItem()) 

697 structure = ( 

698 ('max_tfrag','<H=4280'), 

699 ('max_rfrag','<H=4280'), 

700 ('assoc_group','<L=0'), 

701 ('ctx_num','B=0'), 

702 ('Reserved','B=0'), 

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

704 ('_ctx_items', '_-ctx_items', 'self["ctx_num"]*self._CTX_ITEM_LEN'), 

705 ('ctx_items',':'), 

706 ) 

707 

708 def __init__(self, data = None, alignment = 0): 

709 Structure.__init__(self, data, alignment) 

710 if data is None: 710 ↛ 716line 710 didn't jump to line 716, because the condition on line 710 was never false

711 self['max_tfrag'] = 4280 

712 self['max_rfrag'] = 4280 

713 self['assoc_group'] = 0 

714 self['ctx_num'] = 1 

715 self['ctx_items'] = b'' 

716 self.__ctx_items = [] 

717 

718 def addCtxItem(self, item): 

719 self.__ctx_items.append(item) 

720 

721 def getData(self): 

722 self['ctx_num'] = len(self.__ctx_items) 

723 for i in self.__ctx_items: 

724 self['ctx_items'] += i.getData() 

725 return Structure.getData(self) 

726 

727class MSRPCBindAck(MSRPCHeader): 

728 _SIZE = 26 # Up to SecondaryAddr 

729 _CTX_ITEM_LEN = len(CtxItemResult()) 

730 structure = ( 

731 ('max_tfrag','<H=0'), 

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

733 ('assoc_group','<L=0'), 

734 ('SecondaryAddrLen','<H&SecondaryAddr'), 

735 ('SecondaryAddr','z'), # Optional if SecondaryAddrLen == 0 

736 ('PadLen','_-Pad','(4-((self["SecondaryAddrLen"]+self._SIZE) % 4))%4'), 

737 ('Pad',':'), 

738 ('ctx_num','B=0'), 

739 ('Reserved','B=0'), 

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

741 ('_ctx_items','_-ctx_items','self["ctx_num"]*self._CTX_ITEM_LEN'), 

742 ('ctx_items',':'), 

743 ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'), 

744 ('sec_trailer',':'), 

745 ('auth_dataLen','_-auth_data','self["auth_len"]'), 

746 ('auth_data',':'), 

747 ) 

748 def __init__(self, data = None, alignment = 0): 

749 self.__ctx_items = [] 

750 MSRPCHeader.__init__(self,data,alignment) 

751 if data is None: 751 ↛ 752line 751 didn't jump to line 752, because the condition on line 751 was never true

752 self['Pad'] = b'' 

753 self['ctx_items'] = b'' 

754 self['sec_trailer'] = b'' 

755 self['auth_data'] = b'' 

756 

757 def getCtxItems(self): 

758 return self.__ctx_items 

759 

760 def getCtxItem(self,index): 

761 return self.__ctx_items[index-1] 

762 

763 def fromString(self, data): 

764 Structure.fromString(self,data) 

765 # Parse the ctx_items 

766 data = self['ctx_items'] 

767 for i in range(self['ctx_num']): 

768 item = CtxItemResult(data) 

769 self.__ctx_items.append(item) 

770 data = data[len(item):] 

771 

772class MSRPCBindNak(Structure): 

773 structure = ( 

774 ('RejectedReason','<H=0'), 

775 ('SupportedVersions',':'), 

776 ) 

777 def __init__(self, data = None, alignment = 0): 

778 Structure.__init__(self,data,alignment) 

779 if data is None: 

780 self['SupportedVersions'] = b'' 

781 

782class DCERPC: 

783 # Standard NDR Representation 

784 NDRSyntax = uuidtup_to_bin(('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')) 

785 # NDR 64 

786 NDR64Syntax = uuidtup_to_bin(('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0')) 

787 transfer_syntax = NDRSyntax 

788 

789 def __init__(self,transport): 

790 self._transport = transport 

791 self.set_ctx_id(0) 

792 self._max_user_frag = None 

793 self.set_default_max_fragment_size() 

794 self._ctx = None 

795 

796 def get_rpc_transport(self): 

797 return self._transport 

798 

799 def set_ctx_id(self, ctx_id): 

800 self._ctx = ctx_id 

801 

802 def connect(self): 

803 return self._transport.connect() 

804 

805 def disconnect(self): 

806 return self._transport.disconnect() 

807 

808 def set_max_fragment_size(self, fragment_size): 

809 # -1 is default fragment size: 0 for v5, 1300 y pico for v4 

810 # 0 is don't fragment 

811 # other values are max fragment size 

812 if fragment_size == -1: 812 ↛ 813line 812 didn't jump to line 813, because the condition on line 812 was never true

813 self.set_default_max_fragment_size() 

814 else: 

815 self._max_user_frag = fragment_size 

816 

817 def set_default_max_fragment_size(self): 

818 # default is 0: don'fragment. v4 will override this method 

819 self._max_user_frag = 0 

820 

821 def send(self, data): 

822 raise RuntimeError ('virtual method. Not implemented in subclass') 

823 

824 def recv(self): 

825 raise RuntimeError ('virtual method. Not implemented in subclass') 

826 

827 def alter_ctx(self, newUID, bogus_binds=''): 

828 raise RuntimeError ('virtual method. Not implemented in subclass') 

829 

830 def set_credentials(self, username, password, domain='', lmhash='', nthash='', aesKey='', TGT=None, TGS=None): 

831 pass 

832 

833 def set_auth_level(self, auth_level): 

834 pass 

835 

836 def set_auth_type(self, auth_type, callback=None): 

837 pass 

838 

839 def get_idempotent(self): 

840 return 0 

841 

842 def set_idempotent(self, flag): 

843 pass 

844 

845 def call(self, function, body, uuid=None): 

846 if hasattr(body, 'getData'): 846 ↛ 849line 846 didn't jump to line 849, because the condition on line 846 was never false

847 return self.send(DCERPC_RawCall(function, body.getData(), uuid)) 

848 else: 

849 return self.send(DCERPC_RawCall(function, body, uuid)) 

850 

851 def request(self, request, uuid=None, checkError=True): 

852 if self.transfer_syntax == self.NDR64Syntax: 

853 request.changeTransferSyntax(self.NDR64Syntax) 

854 isNDR64 = True 

855 else: 

856 isNDR64 = False 

857 

858 self.call(request.opnum, request, uuid) 

859 answer = self.recv() 

860 

861 __import__(request.__module__) 

862 module = sys.modules[request.__module__] 

863 respClass = getattr(module, request.__class__.__name__ + 'Response') 

864 

865 if answer[-4:] != b'\x00\x00\x00\x00' and checkError is True: 

866 error_code = unpack('<L', answer[-4:])[0] 

867 if error_code in rpc_status_codes: 

868 # This is an error we can handle 

869 exception = DCERPCException(error_code = error_code) 

870 else: 

871 sessionErrorClass = getattr(module, 'DCERPCSessionError') 

872 try: 

873 # Try to unpack the answer, even if it is an error, it works most of the times 

874 response = respClass(answer, isNDR64 = isNDR64) 

875 except: 

876 # No luck :( 

877 exception = sessionErrorClass(error_code = error_code) 

878 else: 

879 exception = sessionErrorClass(packet = response, error_code = error_code) 

880 raise exception 

881 else: 

882 response = respClass(answer, isNDR64 = isNDR64) 

883 return response 

884 

885class DCERPC_v4(DCERPC): 

886 pass 

887 

888class DCERPC_v5(DCERPC): 

889 def __init__(self, transport): 

890 DCERPC.__init__(self, transport) 

891 self.__auth_level = RPC_C_AUTHN_LEVEL_NONE 

892 self.__auth_type = RPC_C_AUTHN_WINNT 

893 self.__auth_type_callback = None 

894 # Flags of the authenticated session. We will need them throughout the connection 

895 self.__auth_flags = 0 

896 self.__username = None 

897 self.__password = None 

898 self.__domain = '' 

899 self.__lmhash = '' 

900 self.__nthash = '' 

901 self.__aesKey = '' 

902 self.__TGT = None 

903 self.__TGS = None 

904 

905 self.__clientSigningKey = b'' 

906 self.__serverSigningKey = b'' 

907 self.__clientSealingKey = b'' 

908 self.__clientSealingHandle = b'' 

909 self.__serverSealingKey = b'' 

910 self.__serverSealingHandle = b'' 

911 self.__sequence = 0 

912 

913 self.transfer_syntax = uuidtup_to_bin(('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')) 

914 self.__callid = 1 

915 self._ctx = 0 

916 self.__sessionKey = None 

917 self.__max_xmit_size = 0 

918 self.__flags = 0 

919 self.__cipher = None 

920 self.__confounder = b'' 

921 self.__gss = None 

922 

923 def set_session_key(self, session_key): 

924 self.__sessionKey = session_key 

925 

926 def get_session_key(self): 

927 return self.__sessionKey 

928 

929 def set_auth_level(self, auth_level): 

930 self.__auth_level = auth_level 

931 

932 def set_auth_type(self, auth_type, callback = None): 

933 self.__auth_type = auth_type 

934 self.__auth_type_callback = callback 

935 

936 def get_auth_type(self): 

937 return self.__auth_type 

938 

939 def set_max_tfrag(self, size): 

940 self.__max_xmit_size = size 

941 

942 def get_credentials(self): 

943 return self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS 

944 

945 def set_credentials(self, username, password, domain = '', lmhash = '', nthash = '', aesKey = '', TGT = None, TGS = None): 

946 self.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT) 

947 self.__username = username 

948 self.__password = password 

949 self.__domain = domain 

950 self.__aesKey = aesKey 

951 self.__TGT = TGT 

952 self.__TGS = TGS 

953 if lmhash != '' or nthash != '': 

954 if len(lmhash) % 2: 954 ↛ 955line 954 didn't jump to line 955, because the condition on line 954 was never true

955 lmhash = '0%s' % lmhash 

956 if len(nthash) % 2: 956 ↛ 957line 956 didn't jump to line 957, because the condition on line 956 was never true

957 nthash = '0%s' % nthash 

958 try: # just in case they were converted already 

959 self.__lmhash = unhexlify(lmhash) 

960 self.__nthash = unhexlify(nthash) 

961 except: 

962 self.__lmhash = lmhash 

963 self.__nthash = nthash 

964 pass 

965 

966 def bind(self, iface_uuid, alter = 0, bogus_binds = 0, transfer_syntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')): 

967 bind = MSRPCBind() 

968 #item['TransferSyntax']['Version'] = 1 

969 ctx = self._ctx 

970 for i in range(bogus_binds): 970 ↛ 971line 970 didn't jump to line 971, because the loop on line 970 never started

971 item = CtxItem() 

972 item['ContextID'] = ctx 

973 item['TransItems'] = 1 

974 item['ContextID'] = ctx 

975 # We generate random UUIDs for bogus binds 

976 item['AbstractSyntax'] = generate() + stringver_to_bin('2.0') 

977 item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax) 

978 bind.addCtxItem(item) 

979 self._ctx += 1 

980 ctx += 1 

981 

982 # The true one :) 

983 item = CtxItem() 

984 item['AbstractSyntax'] = iface_uuid 

985 item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax) 

986 item['ContextID'] = ctx 

987 item['TransItems'] = 1 

988 bind.addCtxItem(item) 

989 

990 packet = MSRPCHeader() 

991 packet['type'] = MSRPC_BIND 

992 packet['pduData'] = bind.getData() 

993 packet['call_id'] = self.__callid 

994 

995 if alter: 

996 packet['type'] = MSRPC_ALTERCTX 

997 

998 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE: 

999 if (self.__username is None) or (self.__password is None): 

1000 self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS = self._transport.get_credentials() 

1001 

1002 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1003 auth = ntlm.getNTLMSSPType1('', '', signingRequired=True, 

1004 use_ntlmv2=self._transport.doesSupportNTLMv2()) 

1005 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1005 ↛ 1006line 1005 didn't jump to line 1006, because the condition on line 1005 was never true

1006 from impacket.dcerpc.v5 import nrpc 

1007 auth = nrpc.getSSPType1(self.__username[:-1], self.__domain, signingRequired=True) 

1008 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1008 ↛ 1016line 1008 didn't jump to line 1016, because the condition on line 1008 was never false

1009 self.__cipher, self.__sessionKey, auth = kerberosv5.getKerberosType1(self.__username, self.__password, 

1010 self.__domain, self.__lmhash, 

1011 self.__nthash, self.__aesKey, 

1012 self.__TGT, self.__TGS, 

1013 self._transport.getRemoteName(), 

1014 self._transport.get_kdcHost()) 

1015 else: 

1016 raise DCERPCException('Unsupported auth_type 0x%x' % self.__auth_type) 

1017 

1018 sec_trailer = SEC_TRAILER() 

1019 sec_trailer['auth_type'] = self.__auth_type 

1020 sec_trailer['auth_level'] = self.__auth_level 

1021 sec_trailer['auth_ctx_id'] = self._ctx + 79231 

1022 

1023 pad = (4 - (len(packet.get_packet()) % 4)) % 4 

1024 if pad != 0: 1024 ↛ 1025line 1024 didn't jump to line 1025, because the condition on line 1024 was never true

1025 packet['pduData'] += b'\xFF'*pad 

1026 sec_trailer['auth_pad_len']=pad 

1027 

1028 packet['sec_trailer'] = sec_trailer 

1029 packet['auth_data'] = auth 

1030 

1031 self._transport.send(packet.get_packet()) 

1032 

1033 s = self._transport.recv() 

1034 

1035 if s != 0: 1035 ↛ 1038line 1035 didn't jump to line 1038, because the condition on line 1035 was never false

1036 resp = MSRPCHeader(s) 

1037 else: 

1038 return 0 #mmm why not None? 

1039 

1040 if resp['type'] == MSRPC_BINDACK or resp['type'] == MSRPC_ALTERCTX_R: 1040 ↛ 1042line 1040 didn't jump to line 1042, because the condition on line 1040 was never false

1041 bindResp = MSRPCBindAck(resp.getData()) 

1042 elif resp['type'] == MSRPC_BINDNAK or resp['type'] == MSRPC_FAULT: 

1043 if resp['type'] == MSRPC_FAULT: 

1044 resp = MSRPCRespHeader(resp.getData()) 

1045 status_code = unpack('<L', resp['pduData'][:4])[0] 

1046 else: 

1047 resp = MSRPCBindNak(resp['pduData']) 

1048 status_code = resp['RejectedReason'] 

1049 if status_code in rpc_status_codes: 

1050 raise DCERPCException(error_code = status_code) 

1051 elif status_code in rpc_provider_reason: 

1052 raise DCERPCException("Bind context rejected: %s" % rpc_provider_reason[status_code]) 

1053 else: 

1054 raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code) 

1055 else: 

1056 raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type']) 

1057 

1058 # check ack results for each context, except for the bogus ones 

1059 for ctx in range(bogus_binds+1,bindResp['ctx_num']+1): 

1060 ctxItems = bindResp.getCtxItem(ctx) 

1061 if ctxItems['Result'] != 0: 1061 ↛ 1062line 1061 didn't jump to line 1062, because the condition on line 1061 was never true

1062 msg = "Bind context %d rejected: " % ctx 

1063 msg += rpc_cont_def_result.get(ctxItems['Result'], 'Unknown DCE RPC context result code: %.4x' % ctxItems['Result']) 

1064 msg += "; " 

1065 reason = bindResp.getCtxItem(ctx)['Reason'] 

1066 msg += rpc_provider_reason.get(reason, 'Unknown reason code: %.4x' % reason) 

1067 if (ctxItems['Result'], reason) == (2, 1): # provider_rejection, abstract syntax not supported 

1068 msg += " (this usually means the interface isn't listening on the given endpoint)" 

1069 raise DCERPCException(msg) 

1070 

1071 # Save the transfer syntax for later use 

1072 self.transfer_syntax = ctxItems['TransferSyntax'] 

1073 

1074 # The received transmit size becomes the client's receive size, and the received receive size becomes the client's transmit size. 

1075 self.__max_xmit_size = bindResp['max_rfrag'] 

1076 

1077 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE: 

1078 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1079 response, self.__sessionKey = ntlm.getNTLMSSPType3(auth, bindResp['auth_data'], self.__username, 

1080 self.__password, self.__domain, self.__lmhash, 

1081 self.__nthash, 

1082 use_ntlmv2=self._transport.doesSupportNTLMv2()) 

1083 self.__flags = response['flags'] 

1084 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1084 ↛ 1085line 1084 didn't jump to line 1085, because the condition on line 1084 was never true

1085 response = None 

1086 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1086 ↛ 1091line 1086 didn't jump to line 1091, because the condition on line 1086 was never false

1087 self.__cipher, self.__sessionKey, response = kerberosv5.getKerberosType3(self.__cipher, 

1088 self.__sessionKey, 

1089 bindResp['auth_data']) 

1090 

1091 self.__sequence = 0 

1092 

1093 if self.__auth_level in (RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY): 1093 ↛ 1120line 1093 didn't jump to line 1120, because the condition on line 1093 was never false

1094 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1095 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1095 ↛ 1107line 1095 didn't jump to line 1107, because the condition on line 1095 was never false

1096 self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, self.__sessionKey) 

1097 self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, self.__sessionKey,b"Server") 

1098 self.__clientSealingKey = ntlm.SEALKEY(self.__flags, self.__sessionKey) 

1099 self.__serverSealingKey = ntlm.SEALKEY(self.__flags, self.__sessionKey,b"Server") 

1100 # Preparing the keys handle states 

1101 cipher3 = ARC4.new(self.__clientSealingKey) 

1102 self.__clientSealingHandle = cipher3.encrypt 

1103 cipher4 = ARC4.new(self.__serverSealingKey) 

1104 self.__serverSealingHandle = cipher4.encrypt 

1105 else: 

1106 # Same key for everything 

1107 self.__clientSigningKey = self.__sessionKey 

1108 self.__serverSigningKey = self.__sessionKey 

1109 self.__clientSealingKey = self.__sessionKey 

1110 self.__serverSealingKey = self.__sessionKey 

1111 cipher = ARC4.new(self.__clientSigningKey) 

1112 self.__clientSealingHandle = cipher.encrypt 

1113 self.__serverSealingHandle = cipher.encrypt 

1114 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1114 ↛ 1115line 1114 didn't jump to line 1115, because the condition on line 1114 was never true

1115 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 

1116 self.__confounder = b'' 

1117 else: 

1118 self.__confounder = b'12345678' 

1119 

1120 sec_trailer = SEC_TRAILER() 

1121 sec_trailer['auth_type'] = self.__auth_type 

1122 sec_trailer['auth_level'] = self.__auth_level 

1123 sec_trailer['auth_ctx_id'] = self._ctx + 79231 

1124 

1125 if response is not None: 1125 ↛ 1153line 1125 didn't jump to line 1153, because the condition on line 1125 was never false

1126 if self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 

1127 alter_ctx = MSRPCHeader() 

1128 alter_ctx['type'] = MSRPC_ALTERCTX 

1129 alter_ctx['pduData'] = bind.getData() 

1130 alter_ctx['sec_trailer'] = sec_trailer 

1131 alter_ctx['auth_data'] = response 

1132 self._transport.send(alter_ctx.get_packet(), forceWriteAndx = 1) 

1133 self.__gss = gssapi.GSSAPI(self.__cipher) 

1134 self.__sequence = 0 

1135 self.recv() 

1136 self.__sequence = 0 

1137 else: 

1138 auth3 = MSRPCHeader() 

1139 auth3['type'] = MSRPC_AUTH3 

1140 # pad (4 bytes): Can be set to any arbitrary value when set and MUST be  

1141 # ignored on receipt. The pad field MUST be immediately followed by a  

1142 # sec_trailer structure whose layout, location, and alignment are as  

1143 # specified in section 2.2.2.11 

1144 auth3['pduData'] = b' ' 

1145 auth3['sec_trailer'] = sec_trailer 

1146 auth3['auth_data'] = response.getData() 

1147 

1148 # Use the same call_id 

1149 self.__callid = resp['call_id'] 

1150 auth3['call_id'] = self.__callid 

1151 self._transport.send(auth3.get_packet(), forceWriteAndx = 1) 

1152 

1153 self.__callid += 1 

1154 

1155 return resp # means packet is signed, if verifier is wrong it fails 

1156 

1157 def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0): 

1158 rpc_packet['ctx_id'] = self._ctx 

1159 rpc_packet['sec_trailer'] = b'' 

1160 rpc_packet['auth_data'] = b'' 

1161 

1162 if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]: 

1163 # Dummy verifier, just for the calculations 

1164 sec_trailer = SEC_TRAILER() 

1165 sec_trailer['auth_type'] = self.__auth_type 

1166 sec_trailer['auth_level'] = self.__auth_level 

1167 sec_trailer['auth_pad_len'] = 0 

1168 sec_trailer['auth_ctx_id'] = self._ctx + 79231 

1169 

1170 pad = (4 - (len(rpc_packet.get_packet()) % 4)) % 4 

1171 if pad != 0: 

1172 rpc_packet['pduData'] += b'\xBB'*pad 

1173 sec_trailer['auth_pad_len']=pad 

1174 

1175 rpc_packet['sec_trailer'] = sec_trailer.getData() 

1176 rpc_packet['auth_data'] = b' '*16 

1177 

1178 plain_data = rpc_packet['pduData'] 

1179 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY: 

1180 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1181 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1181 ↛ 1192line 1181 didn't jump to line 1192, because the condition on line 1181 was never false

1182 # When NTLM2 is on, we sign the whole pdu, but encrypt just 

1183 # the data, not the dcerpc header. Weird.. 

1184 sealedMessage, signature = ntlm.SEAL(self.__flags, 

1185 self.__clientSigningKey, 

1186 self.__clientSealingKey, 

1187 rpc_packet.get_packet()[:-16], 

1188 plain_data, 

1189 self.__sequence, 

1190 self.__clientSealingHandle) 

1191 else: 

1192 sealedMessage, signature = ntlm.SEAL(self.__flags, 

1193 self.__clientSigningKey, 

1194 self.__clientSealingKey, 

1195 plain_data, 

1196 plain_data, 

1197 self.__sequence, 

1198 self.__clientSealingHandle) 

1199 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1199 ↛ 1200line 1199 didn't jump to line 1200, because the condition on line 1199 was never true

1200 from impacket.dcerpc.v5 import nrpc 

1201 sealedMessage, signature = nrpc.SEAL(plain_data, self.__confounder, self.__sequence, self.__sessionKey, False) 

1202 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1202 ↛ 1205line 1202 didn't jump to line 1205, because the condition on line 1202 was never false

1203 sealedMessage, signature = self.__gss.GSS_Wrap(self.__sessionKey, plain_data, self.__sequence) 

1204 

1205 rpc_packet['pduData'] = sealedMessage 

1206 elif self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 1206 ↛ 1232line 1206 didn't jump to line 1232, because the condition on line 1206 was never false

1207 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1208 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1208 ↛ 1217line 1208 didn't jump to line 1217, because the condition on line 1208 was never false

1209 # Interesting thing.. with NTLM2, what is is signed is the  

1210 # whole PDU, not just the data 

1211 signature = ntlm.SIGN(self.__flags, 

1212 self.__clientSigningKey, 

1213 rpc_packet.get_packet()[:-16], 

1214 self.__sequence, 

1215 self.__clientSealingHandle) 

1216 else: 

1217 signature = ntlm.SIGN(self.__flags, 

1218 self.__clientSigningKey, 

1219 plain_data, 

1220 self.__sequence, 

1221 self.__clientSealingHandle) 

1222 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1222 ↛ 1223line 1222 didn't jump to line 1223, because the condition on line 1222 was never true

1223 from impacket.dcerpc.v5 import nrpc 

1224 signature = nrpc.SIGN(plain_data, 

1225 self.__confounder, 

1226 self.__sequence, 

1227 self.__sessionKey, 

1228 False) 

1229 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1229 ↛ 1232line 1229 didn't jump to line 1232, because the condition on line 1229 was never false

1230 signature = self.__gss.GSS_GetMIC(self.__sessionKey, plain_data, self.__sequence) 

1231 

1232 rpc_packet['sec_trailer'] = sec_trailer.getData() 

1233 rpc_packet['auth_data'] = signature 

1234 

1235 self.__sequence += 1 

1236 

1237 self._transport.send(rpc_packet.get_packet(), forceWriteAndx = forceWriteAndx, forceRecv = forceRecv) 

1238 

1239 def send(self, data): 

1240 if isinstance(data, MSRPCHeader) is not True: 1240 ↛ 1242line 1240 didn't jump to line 1242, because the condition on line 1240 was never true

1241 # Must be an Impacket, transform to structure 

1242 data = DCERPC_RawCall(data.OP_NUM, data.get_packet()) 

1243 

1244 try: 

1245 if data['uuid'] != b'': 

1246 data['flags'] |= PFC_OBJECT_UUID 

1247 except: 

1248 # Structure doesn't have uuid 

1249 pass 

1250 data['ctx_id'] = self._ctx 

1251 data['call_id'] = self.__callid 

1252 data['alloc_hint'] = len(data['pduData']) 

1253 # We should fragment PDUs if: 

1254 # 1) Payload exceeds __max_xmit_size received during BIND response 

1255 # 2) We'e explicitly fragmenting packets with lower values 

1256 should_fragment = False 

1257 

1258 # Let's decide what will drive fragmentation for this request 

1259 if self._max_user_frag > 0: 

1260 # User set a frag size, let's compare it with the max transmit size agreed when binding the interface 

1261 fragment_size = min(self._max_user_frag, self.__max_xmit_size) 

1262 else: 

1263 fragment_size = self.__max_xmit_size 

1264 

1265 # Sanity check. Fragmentation can't be too low, otherwise sec_trailer won't fit 

1266 

1267 if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]: 

1268 if fragment_size <= 8: 

1269 # Minimum pdu fragment size is 8, important when doing PKT_INTEGRITY/PRIVACY. We need a minimum size of 8 

1270 # (Kerberos) 

1271 fragment_size = 8 

1272 

1273 # ToDo: Better calculate the size needed. Now I'm setting a number that surely is enough for Kerberos and NTLM 

1274 # ToDo: trailers, both for INTEGRITY and PRIVACY. This means we're not truly honoring the user's frag request. 

1275 if len(data['pduData']) + 128 > fragment_size: 

1276 should_fragment = True 

1277 if fragment_size+128 > self.__max_xmit_size: 

1278 fragment_size = self.__max_xmit_size - 128 

1279 

1280 if should_fragment: 

1281 packet = data['pduData'] 

1282 offset = 0 

1283 

1284 while 1: 

1285 toSend = packet[offset:offset+fragment_size] 

1286 if not toSend: 

1287 break 

1288 if offset == 0: 

1289 data['flags'] |= PFC_FIRST_FRAG 

1290 else: 

1291 data['flags'] &= (~PFC_FIRST_FRAG) 

1292 offset += len(toSend) 

1293 if offset >= len(packet): 

1294 data['flags'] |= PFC_LAST_FRAG 

1295 else: 

1296 data['flags'] &= (~PFC_LAST_FRAG) 

1297 data['pduData'] = toSend 

1298 self._transport_send(data, forceWriteAndx = 1, forceRecv =data['flags'] & PFC_LAST_FRAG) 

1299 else: 

1300 self._transport_send(data) 

1301 self.__callid += 1 

1302 

1303 def recv(self): 

1304 finished = False 

1305 forceRecv = 0 

1306 retAnswer = b'' 

1307 while not finished: 

1308 # At least give me the MSRPCRespHeader, especially important for  

1309 # TCP/UDP Transports 

1310 response_data = self._transport.recv(forceRecv, count=MSRPCRespHeader._SIZE) 

1311 response_header = MSRPCRespHeader(response_data) 

1312 # Ok, there might be situation, especially with large packets, that  

1313 # the transport layer didn't send us the full packet's contents 

1314 # So we gotta check we received it all 

1315 while len(response_data) < response_header['frag_len']: 

1316 response_data += self._transport.recv(forceRecv, count=(response_header['frag_len']-len(response_data))) 

1317 

1318 off = response_header.get_header_size() 

1319 

1320 if response_header['type'] == MSRPC_FAULT and response_header['frag_len'] >= off+4: 

1321 status_code = unpack("<L",response_data[off:off+4])[0] 

1322 if status_code in rpc_status_codes: 1322 ↛ 1324line 1322 didn't jump to line 1324, because the condition on line 1322 was never false

1323 raise DCERPCException(rpc_status_codes[status_code]) 

1324 elif status_code & 0xffff in rpc_status_codes: 

1325 raise DCERPCException(rpc_status_codes[status_code & 0xffff]) 

1326 else: 

1327 if status_code in hresult_errors.ERROR_MESSAGES: 

1328 error_msg_short = hresult_errors.ERROR_MESSAGES[status_code][0] 

1329 error_msg_verbose = hresult_errors.ERROR_MESSAGES[status_code][1] 

1330 raise DCERPCException('%s - %s' % (error_msg_short, error_msg_verbose)) 

1331 else: 

1332 raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code) 

1333 

1334 if response_header['flags'] & PFC_LAST_FRAG: 

1335 # No need to reassembly DCERPC 

1336 finished = True 

1337 else: 

1338 # Forcing Read Recv, we need more packets! 

1339 forceRecv = 1 

1340 

1341 answer = response_data[off:] 

1342 auth_len = response_header['auth_len'] 

1343 if auth_len: 

1344 auth_len += 8 

1345 auth_data = answer[-auth_len:] 

1346 sec_trailer = SEC_TRAILER(data = auth_data) 

1347 answer = answer[:-auth_len] 

1348 

1349 if sec_trailer['auth_level'] == RPC_C_AUTHN_LEVEL_PKT_PRIVACY: 

1350 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1351 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1351 ↛ 1362line 1351 didn't jump to line 1362, because the condition on line 1351 was never false

1352 # TODO: FIX THIS, it's not calculating the signature well 

1353 # Since I'm not testing it we don't care... yet 

1354 answer, signature = ntlm.SEAL(self.__flags, 

1355 self.__serverSigningKey, 

1356 self.__serverSealingKey, 

1357 answer, 

1358 answer, 

1359 self.__sequence, 

1360 self.__serverSealingHandle) 

1361 else: 

1362 answer, signature = ntlm.SEAL(self.__flags, 

1363 self.__serverSigningKey, 

1364 self.__serverSealingKey, 

1365 answer, 

1366 answer, 

1367 self.__sequence, 

1368 self.__serverSealingHandle) 

1369 self.__sequence += 1 

1370 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1370 ↛ 1371line 1370 didn't jump to line 1371, because the condition on line 1370 was never true

1371 from impacket.dcerpc.v5 import nrpc 

1372 answer, cfounder = nrpc.UNSEAL(answer, 

1373 auth_data[len(sec_trailer):], 

1374 self.__sessionKey, 

1375 False) 

1376 self.__sequence += 1 

1377 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1377 ↛ 1415line 1377 didn't jump to line 1415, because the condition on line 1377 was never false

1378 if self.__sequence > 0: 

1379 answer, cfounder = self.__gss.GSS_Unwrap(self.__sessionKey, answer, self.__sequence, 

1380 direction='init', authData=auth_data) 

1381 

1382 elif sec_trailer['auth_level'] == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 1382 ↛ 1415line 1382 didn't jump to line 1415, because the condition on line 1382 was never false

1383 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1384 ntlmssp = auth_data[12:] 

1385 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1385 ↛ 1392line 1385 didn't jump to line 1392, because the condition on line 1385 was never false

1386 signature = ntlm.SIGN(self.__flags, 

1387 self.__serverSigningKey, 

1388 answer, 

1389 self.__sequence, 

1390 self.__serverSealingHandle) 

1391 else: 

1392 signature = ntlm.SIGN(self.__flags, 

1393 self.__serverSigningKey, 

1394 ntlmssp, 

1395 self.__sequence, 

1396 self.__serverSealingHandle) 

1397 # Yes.. NTLM2 doesn't increment sequence when receiving 

1398 # the packet :P 

1399 self.__sequence += 1 

1400 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1400 ↛ 1401line 1400 didn't jump to line 1401, because the condition on line 1400 was never true

1401 from impacket.dcerpc.v5 import nrpc 

1402 ntlmssp = auth_data[12:] 

1403 signature = nrpc.SIGN(ntlmssp, 

1404 self.__confounder, 

1405 self.__sequence, 

1406 self.__sessionKey, 

1407 False) 

1408 self.__sequence += 1 

1409 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 

1410 # Do NOT increment the sequence number when Signing Kerberos 

1411 #self.__sequence += 1 

1412 pass 

1413 

1414 

1415 if sec_trailer['auth_pad_len']: 

1416 answer = answer[:-sec_trailer['auth_pad_len']] 

1417 

1418 retAnswer += answer 

1419 return retAnswer 

1420 

1421 def alter_ctx(self, newUID, bogus_binds = 0): 

1422 answer = self.__class__(self._transport) 

1423 

1424 answer.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, 

1425 self.__aesKey, self.__TGT, self.__TGS) 

1426 answer.set_auth_type(self.__auth_type) 

1427 answer.set_auth_level(self.__auth_level) 

1428 

1429 answer.set_ctx_id(self._ctx+1) 

1430 answer.__callid = self.__callid 

1431 answer.bind(newUID, alter = 1, bogus_binds = bogus_binds, transfer_syntax = bin_to_uuidtup(self.transfer_syntax)) 

1432 return answer 

1433 

1434class DCERPC_RawCall(MSRPCRequestHeader): 

1435 def __init__(self, op_num, data = b'', uuid=None): 

1436 MSRPCRequestHeader.__init__(self) 

1437 self['op_num'] = op_num 

1438 self['pduData'] = data 

1439 if uuid is not None: 

1440 self['flags'] |= PFC_OBJECT_UUID 

1441 self['uuid'] = uuid 

1442 

1443 def setData(self, data): 

1444 self['pduData'] = data 

1445 

1446# 2.2.6 Type Serialization Version 1 

1447class CommonHeader(NDRSTRUCT): 

1448 structure = ( 

1449 ('Version', UCHAR), 

1450 ('Endianness', UCHAR), 

1451 ('CommonHeaderLength', USHORT), 

1452 ('Filler', ULONG), 

1453 ) 

1454 def __init__(self, data = None,isNDR64 = False): 

1455 NDRSTRUCT.__init__(self, data, isNDR64) 

1456 if data is None: 1456 ↛ exitline 1456 didn't return from function '__init__', because the condition on line 1456 was never false

1457 self['Version'] = 1 

1458 self['Endianness'] = 0x10 

1459 self['CommonHeaderLength'] = 8 

1460 self['Filler'] = 0xcccccccc 

1461 

1462class PrivateHeader(NDRSTRUCT): 

1463 structure = ( 

1464 ('ObjectBufferLength', ULONG), 

1465 ('Filler', ULONG), 

1466 ) 

1467 def __init__(self, data = None,isNDR64 = False): 

1468 NDRSTRUCT.__init__(self, data, isNDR64) 

1469 if data is None: 1469 ↛ exitline 1469 didn't return from function '__init__', because the condition on line 1469 was never false

1470 self['Filler'] = 0xcccccccc 

1471 

1472class TypeSerialization1(NDRSTRUCT): 

1473 commonHdr = ( 

1474 ('CommonHeader', CommonHeader), 

1475 ('PrivateHeader', PrivateHeader), 

1476 ) 

1477 def getData(self, soFar = 0): 

1478 self['PrivateHeader']['ObjectBufferLength'] = len(NDRSTRUCT.getData(self, soFar)) + len( 

1479 NDRSTRUCT.getDataReferents(self, soFar)) - len(self['CommonHeader']) - len(self['PrivateHeader']) 

1480 return NDRSTRUCT.getData(self, soFar) 

1481 

1482class DCERPCServer(Thread): 

1483 """ 

1484 A minimalistic DCERPC Server, mainly used by the smbserver, for now. Might be useful 

1485 for other purposes in the future, but we should do it way stronger. 

1486 If you want to implement a DCE Interface Server, use this class as the base class 

1487 """ 

1488 def __init__(self): 

1489 Thread.__init__(self) 

1490 self._listenPort = 0 

1491 self._listenAddress = '127.0.0.1' 

1492 self._listenUUIDS = {} 

1493 self._boundUUID = b'' 

1494 self._sock = None 

1495 self._clientSock = None 

1496 self._callid = 1 

1497 self._max_frag = None 

1498 self._max_xmit_size = 4280 

1499 self.__log = LOG 

1500 self._sock = socket.socket() 

1501 self._sock.bind((self._listenAddress,self._listenPort)) 

1502 

1503 def log(self, msg, level=logging.INFO): 

1504 self.__log.log(level,msg) 

1505 

1506 def addCallbacks(self, ifaceUUID, secondaryAddr, callbacks): 

1507 """ 

1508 adds a call back to a UUID/opnum call 

1509  

1510 :param uuid ifaceUUID: the interface UUID 

1511 :param string secondaryAddr: the secondary address to answer as part of the bind request (e.g. \\\\PIPE\\\\srvsvc) 

1512 :param dict callbacks: the callbacks for each opnum. Format is [opnum] = callback 

1513 """ 

1514 self._listenUUIDS[uuidtup_to_bin(ifaceUUID)] = {} 

1515 self._listenUUIDS[uuidtup_to_bin(ifaceUUID)]['SecondaryAddr'] = secondaryAddr 

1516 self._listenUUIDS[uuidtup_to_bin(ifaceUUID)]['CallBacks'] = callbacks 

1517 self.log("Callback added for UUID %s V:%s" % ifaceUUID) 

1518 

1519 def setListenPort(self, portNum): 

1520 self._listenPort = portNum 

1521 self._sock = socket.socket() 

1522 self._sock.bind((self._listenAddress,self._listenPort)) 

1523 

1524 def getListenPort(self): 

1525 return self._sock.getsockname()[1] 

1526 

1527 def recv(self): 

1528 finished = False 

1529 retAnswer = b'' 

1530 response_data = b'' 

1531 while not finished: 

1532 # At least give me the MSRPCRespHeader, especially important for TCP/UDP Transports 

1533 response_data = self._clientSock.recv(MSRPCRespHeader._SIZE) 

1534 # No data?, connection might have closed 

1535 if response_data == b'': 

1536 return None 

1537 response_header = MSRPCRespHeader(response_data) 

1538 # Ok, there might be situation, especially with large packets,  

1539 # that the transport layer didn't send us the full packet's contents 

1540 # So we gotta check we received it all 

1541 while len(response_data) < response_header['frag_len']: 

1542 response_data += self._clientSock.recv(response_header['frag_len']-len(response_data)) 

1543 response_header = MSRPCRespHeader(response_data) 

1544 if response_header['flags'] & PFC_LAST_FRAG: 

1545 # No need to reassembly DCERPC 

1546 finished = True 

1547 answer = response_header['pduData'] 

1548 auth_len = response_header['auth_len'] 

1549 if auth_len: 

1550 auth_len += 8 

1551 auth_data = answer[-auth_len:] 

1552 sec_trailer = SEC_TRAILER(data = auth_data) 

1553 answer = answer[:-auth_len] 

1554 if sec_trailer['auth_pad_len']: 

1555 answer = answer[:-sec_trailer['auth_pad_len']] 

1556 

1557 retAnswer += answer 

1558 return response_data 

1559 

1560 def run(self): 

1561 self._sock.listen(10) 

1562 while True: 

1563 self._clientSock, address = self._sock.accept() 

1564 try: 

1565 while True: 

1566 data = self.recv() 

1567 if data is None: 

1568 # No data.. connection closed 

1569 break 

1570 answer = self.processRequest(data) 

1571 if answer is not None: 

1572 self.send(answer) 

1573 except Exception: 

1574 #import traceback 

1575 #traceback.print_exc() 

1576 pass 

1577 self._clientSock.close() 

1578 

1579 def send(self, data): 

1580 max_frag = self._max_frag 

1581 if len(data['pduData']) > self._max_xmit_size - 32: 

1582 max_frag = self._max_xmit_size - 32 # XXX: 32 is a safe margin for auth data 

1583 

1584 if self._max_frag: 

1585 max_frag = min(max_frag, self._max_frag) 

1586 if max_frag and len(data['pduData']) > 0: 

1587 packet = data['pduData'] 

1588 offset = 0 

1589 while 1: 

1590 toSend = packet[offset:offset+max_frag] 

1591 if not toSend: 

1592 break 

1593 flags = 0 

1594 if offset == 0: 

1595 flags |= PFC_FIRST_FRAG 

1596 offset += len(toSend) 

1597 if offset == len(packet): 

1598 flags |= PFC_LAST_FRAG 

1599 data['flags'] = flags 

1600 data['pduData'] = toSend 

1601 self._clientSock.send(data.get_packet()) 

1602 else: 

1603 self._clientSock.send(data.get_packet()) 

1604 self._callid += 1 

1605 

1606 def bind(self,packet, bind): 

1607 # Standard NDR Representation 

1608 NDRSyntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0') 

1609 resp = MSRPCBindAck() 

1610 

1611 resp['type'] = MSRPC_BINDACK 

1612 resp['flags'] = packet['flags'] 

1613 resp['frag_len'] = 0 

1614 resp['auth_len'] = 0 

1615 resp['auth_data'] = b'' 

1616 resp['call_id'] = packet['call_id'] 

1617 resp['max_tfrag'] = bind['max_tfrag'] 

1618 resp['max_rfrag'] = bind['max_rfrag'] 

1619 resp['assoc_group'] = 0x1234 

1620 resp['ctx_num'] = 0 

1621 

1622 data = bind['ctx_items'] 

1623 ctx_items = b'' 

1624 resp['SecondaryAddrLen'] = 0 

1625 for i in range(bind['ctx_num']): 

1626 result = MSRPC_CONT_RESULT_USER_REJECT 

1627 item = CtxItem(data) 

1628 data = data[len(item):] 

1629 

1630 # First we check the Transfer Syntax is NDR32, what we support 

1631 if item['TransferSyntax'] == uuidtup_to_bin(NDRSyntax): 

1632 # Now Check if the interface is what we listen 

1633 reason = 1 # Default, Abstract Syntax not supported 

1634 for j in self._listenUUIDS: 

1635 if item['AbstractSyntax'] == j: 

1636 # Match, we accept the bind request 

1637 resp['SecondaryAddr'] = self._listenUUIDS[item['AbstractSyntax']]['SecondaryAddr'] 

1638 resp['SecondaryAddrLen'] = len(resp['SecondaryAddr'])+1 

1639 reason = 0 

1640 self._boundUUID = j 

1641 else: 

1642 # Fail the bind request for this context 

1643 reason = 2 # Transfer Syntax not supported 

1644 if reason == 0: 

1645 result = MSRPC_CONT_RESULT_ACCEPT 

1646 if reason == 1: 

1647 LOG.error('Bind request for an unsupported interface %s' % bin_to_uuidtup(item['AbstractSyntax'])) 

1648 

1649 resp['ctx_num'] += 1 

1650 itemResult = CtxItemResult() 

1651 itemResult['Result'] = result 

1652 itemResult['Reason'] = reason 

1653 itemResult['TransferSyntax'] = uuidtup_to_bin(NDRSyntax) 

1654 ctx_items += itemResult.getData() 

1655 

1656 resp['Pad'] ='A'*((4-((resp["SecondaryAddrLen"]+MSRPCBindAck._SIZE) % 4))%4) 

1657 resp['ctx_items'] = ctx_items 

1658 resp['frag_len'] = len(resp.getData()) 

1659 

1660 self._clientSock.send(resp.getData()) 

1661 return None 

1662 

1663 def processRequest(self,data): 

1664 packet = MSRPCHeader(data) 

1665 if packet['type'] == MSRPC_BIND: 

1666 bind = MSRPCBind(packet['pduData']) 

1667 self.bind(packet, bind) 

1668 packet = None 

1669 elif packet['type'] == MSRPC_REQUEST: 

1670 request = MSRPCRequestHeader(data) 

1671 response = MSRPCRespHeader(data) 

1672 response['type'] = MSRPC_RESPONSE 

1673 # Serve the opnum requested, if not, fails 

1674 if request['op_num'] in self._listenUUIDS[self._boundUUID]['CallBacks']: 

1675 # Call the function  

1676 returnData = self._listenUUIDS[self._boundUUID]['CallBacks'][request['op_num']](request['pduData']) 

1677 response['pduData'] = returnData 

1678 else: 

1679 LOG.error('Unsupported DCERPC opnum %d called for interface %s' % (request['op_num'], bin_to_uuidtup(self._boundUUID))) 

1680 response['type'] = MSRPC_FAULT 

1681 response['pduData'] = pack('<L',0x000006E4) 

1682 response['frag_len'] = len(response) 

1683 return response 

1684 else: 

1685 # Defaults to a fault 

1686 packet = MSRPCRespHeader(data) 

1687 packet['type'] = MSRPC_FAULT 

1688 

1689 return packet