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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under under a slightly modified version 

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

5# for more information. 

6# 

7# Description: 

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

9# 

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

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

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

13# 

14# ToDo:  

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

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

17# more SSP (e.g. NETLOGON) 

18#  

19 

20import logging 

21import socket 

22import sys 

23from binascii import unhexlify 

24from Cryptodome.Cipher import ARC4 

25 

26from impacket import ntlm, LOG 

27from impacket.structure import Structure,pack,unpack 

28from impacket.krb5 import kerberosv5, gssapi 

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

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

31from impacket.dcerpc.v5.ndr import NDRSTRUCT 

32from impacket import hresult_errors 

33from threading import Thread 

34 

35# MS/RPC Constants 

36MSRPC_REQUEST = 0x00 

37MSRPC_PING = 0x01 

38MSRPC_RESPONSE = 0x02 

39MSRPC_FAULT = 0x03 

40MSRPC_WORKING = 0x04 

41MSRPC_NOCALL = 0x05 

42MSRPC_REJECT = 0x06 

43MSRPC_ACK = 0x07 

44MSRPC_CL_CANCEL = 0x08 

45MSRPC_FACK = 0x09 

46MSRPC_CANCELACK = 0x0A 

47MSRPC_BIND = 0x0B 

48MSRPC_BINDACK = 0x0C 

49MSRPC_BINDNAK = 0x0D 

50MSRPC_ALTERCTX = 0x0E 

51MSRPC_ALTERCTX_R= 0x0F 

52MSRPC_AUTH3 = 0x10 

53MSRPC_SHUTDOWN = 0x11 

54MSRPC_CO_CANCEL = 0x12 

55MSRPC_ORPHANED = 0x13 

56MSRPC_RTS = 0x14 

57 

58# MS/RPC Packet Flags 

59PFC_FIRST_FRAG = 0x01 

60PFC_LAST_FRAG = 0x02 

61 

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

63# alter_context_resp, this flag MUST be interpreted as PFC_SUPPORT_HEADER_SIGN 

64MSRPC_SUPPORT_SIGN = 0x04 

65 

66#For the 

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

68MSRPC_PENDING_CANCEL= 0x04 

69 

70PFC_RESERVED_1 = 0x08 

71PFC_CONC_MPX = 0x10 

72PFC_DID_NOT_EXECUTE = 0x20 

73PFC_MAYBE = 0x40 

74PFC_OBJECT_UUID = 0x80 

75 

76# Auth Types - Security Providers 

77RPC_C_AUTHN_NONE = 0x00 

78RPC_C_AUTHN_GSS_NEGOTIATE = 0x09 

79RPC_C_AUTHN_WINNT = 0x0A 

80RPC_C_AUTHN_GSS_SCHANNEL = 0x0E 

81RPC_C_AUTHN_GSS_KERBEROS = 0x10 

82RPC_C_AUTHN_NETLOGON = 0x44 

83RPC_C_AUTHN_DEFAULT = 0xFF 

84 

85# Auth Levels 

86RPC_C_AUTHN_LEVEL_NONE = 1 

87RPC_C_AUTHN_LEVEL_CONNECT = 2 

88RPC_C_AUTHN_LEVEL_CALL = 3 

89RPC_C_AUTHN_LEVEL_PKT = 4 

90RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5 

91RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6 

92 

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

94rpc_provider_reason = { 

95 0 : 'reason_not_specified', 

96 1 : 'abstract_syntax_not_supported', 

97 2 : 'proposed_transfer_syntaxes_not_supported', 

98 3 : 'local_limit_exceeded', 

99 4 : 'protocol_version_not_specified', 

100 8 : 'authentication_type_not_recognized', 

101 9 : 'invalid_checksum' 

102} 

103 

104MSRPC_CONT_RESULT_ACCEPT = 0 

105MSRPC_CONT_RESULT_USER_REJECT = 1 

106MSRPC_CONT_RESULT_PROV_REJECT = 2 

107 

108#Results of a presentation context negotiation 

109rpc_cont_def_result = { 

110 0 : 'acceptance', 

111 1 : 'user_rejection', 

112 2 : 'provider_rejection' 

113} 

114 

115#status codes, references: 

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

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

118#winerror.h 

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

120 

121rpc_status_codes = { 

122 0x00000005 : 'rpc_s_access_denied', 

123 0x00000008 : 'Authentication type not recognized', 

124 0x000006D8 : 'rpc_fault_cant_perform', 

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

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

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

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

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

130 0x1C010003 : 'nca_s_unk_if', # unknown interface 

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

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

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

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

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

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

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

138 0x1C000001 : 'nca_s_fault_int_div_by_zero', 

139 0x1C000002 : 'nca_s_fault_addr_error ', 

140 0x1C000003 : 'nca_s_fault_fp_div_zero', 

141 0x1C000004 : 'nca_s_fault_fp_underflow', 

142 0x1C000005 : 'nca_s_fault_fp_overflow', 

143 0x1C000006 : 'nca_s_fault_invalid_tag', 

144 0x1C000007 : 'nca_s_fault_invalid_bound ', 

145 0x1C000008 : 'nca_s_rpc_version_mismatch', 

146 0x1C000009 : 'nca_s_unspec_reject ', 

147 0x1C00000A : 'nca_s_bad_actid', 

148 0x1C00000B : 'nca_s_who_are_you_failed', 

149 0x1C00000C : 'nca_s_manager_not_entered ', 

150 0x1C00000D : 'nca_s_fault_cancel', 

151 0x1C00000E : 'nca_s_fault_ill_inst', 

152 0x1C00000F : 'nca_s_fault_fp_error', 

153 0x1C000010 : 'nca_s_fault_int_overflow', 

154 0x1C000012 : 'nca_s_fault_unspec', 

155 0x1C000013 : 'nca_s_fault_remote_comm_failure ', 

156 0x1C000014 : 'nca_s_fault_pipe_empty ', 

157 0x1C000015 : 'nca_s_fault_pipe_closed', 

158 0x1C000016 : 'nca_s_fault_pipe_order ', 

159 0x1C000017 : 'nca_s_fault_pipe_discipline', 

160 0x1C000018 : 'nca_s_fault_pipe_comm_error', 

161 0x1C000019 : 'nca_s_fault_pipe_memory', 

162 0x1C00001A : 'nca_s_fault_context_mismatch ', 

163 0x1C00001B : 'nca_s_fault_remote_no_memory ', 

164 0x1C00001C : 'nca_s_invalid_pres_context_id', 

165 0x1C00001D : 'nca_s_unsupported_authn_level', 

166 0x1C00001F : 'nca_s_invalid_checksum ', 

167 0x1C000020 : 'nca_s_invalid_crc', 

168 0x1C000021 : 'nca_s_fault_user_defined', 

169 0x1C000022 : 'nca_s_fault_tx_open_failed', 

170 0x1C000023 : 'nca_s_fault_codeset_conv_error', 

171 0x1C000024 : 'nca_s_fault_object_not_found ', 

172 0x1C000025 : 'nca_s_fault_no_client_stub', 

173 0x16c9a000 : "rpc_s_mod", 

174 0x16c9a001 : "rpc_s_op_rng_error", 

175 0x16c9a002 : "rpc_s_cant_create_socket", 

176 0x16c9a003 : "rpc_s_cant_bind_socket", 

177 0x16c9a004 : "rpc_s_not_in_call", 

178 0x16c9a005 : "rpc_s_no_port", 

179 0x16c9a006 : "rpc_s_wrong_boot_time", 

180 0x16c9a007 : "rpc_s_too_many_sockets", 

181 0x16c9a008 : "rpc_s_illegal_register", 

182 0x16c9a009 : "rpc_s_cant_recv", 

183 0x16c9a00a : "rpc_s_bad_pkt", 

184 0x16c9a00b : "rpc_s_unbound_handle", 

185 0x16c9a00c : "rpc_s_addr_in_use", 

186 0x16c9a00d : "rpc_s_in_args_too_big", 

187 0x16c9a00e : "rpc_s_string_too_long", 

188 0x16c9a00f : "rpc_s_too_many_objects", 

189 0x16c9a010 : "rpc_s_binding_has_no_auth", 

190 0x16c9a011 : "rpc_s_unknown_authn_service", 

191 0x16c9a012 : "rpc_s_no_memory", 

192 0x16c9a013 : "rpc_s_cant_nmalloc", 

193 0x16c9a014 : "rpc_s_call_faulted", 

194 0x16c9a015 : "rpc_s_call_failed", 

195 0x16c9a016 : "rpc_s_comm_failure", 

196 0x16c9a017 : "rpc_s_rpcd_comm_failure", 

197 0x16c9a018 : "rpc_s_illegal_family_rebind", 

198 0x16c9a019 : "rpc_s_invalid_handle", 

199 0x16c9a01a : "rpc_s_coding_error", 

200 0x16c9a01b : "rpc_s_object_not_found", 

201 0x16c9a01c : "rpc_s_cthread_not_found", 

202 0x16c9a01d : "rpc_s_invalid_binding", 

203 0x16c9a01e : "rpc_s_already_registered", 

204 0x16c9a01f : "rpc_s_endpoint_not_found", 

205 0x16c9a020 : "rpc_s_invalid_rpc_protseq", 

206 0x16c9a021 : "rpc_s_desc_not_registered", 

207 0x16c9a022 : "rpc_s_already_listening", 

208 0x16c9a023 : "rpc_s_no_protseqs", 

209 0x16c9a024 : "rpc_s_no_protseqs_registered", 

210 0x16c9a025 : "rpc_s_no_bindings", 

211 0x16c9a026 : "rpc_s_max_descs_exceeded", 

212 0x16c9a027 : "rpc_s_no_interfaces", 

213 0x16c9a028 : "rpc_s_invalid_timeout", 

214 0x16c9a029 : "rpc_s_cant_inq_socket", 

215 0x16c9a02a : "rpc_s_invalid_naf_id", 

216 0x16c9a02b : "rpc_s_inval_net_addr", 

217 0x16c9a02c : "rpc_s_unknown_if", 

218 0x16c9a02d : "rpc_s_unsupported_type", 

219 0x16c9a02e : "rpc_s_invalid_call_opt", 

220 0x16c9a02f : "rpc_s_no_fault", 

221 0x16c9a030 : "rpc_s_cancel_timeout", 

222 0x16c9a031 : "rpc_s_call_cancelled", 

223 0x16c9a032 : "rpc_s_invalid_call_handle", 

224 0x16c9a033 : "rpc_s_cannot_alloc_assoc", 

225 0x16c9a034 : "rpc_s_cannot_connect", 

226 0x16c9a035 : "rpc_s_connection_aborted", 

227 0x16c9a036 : "rpc_s_connection_closed", 

228 0x16c9a037 : "rpc_s_cannot_accept", 

229 0x16c9a038 : "rpc_s_assoc_grp_not_found", 

230 0x16c9a039 : "rpc_s_stub_interface_error", 

231 0x16c9a03a : "rpc_s_invalid_object", 

232 0x16c9a03b : "rpc_s_invalid_type", 

233 0x16c9a03c : "rpc_s_invalid_if_opnum", 

234 0x16c9a03d : "rpc_s_different_server_instance", 

235 0x16c9a03e : "rpc_s_protocol_error", 

236 0x16c9a03f : "rpc_s_cant_recvmsg", 

237 0x16c9a040 : "rpc_s_invalid_string_binding", 

238 0x16c9a041 : "rpc_s_connect_timed_out", 

239 0x16c9a042 : "rpc_s_connect_rejected", 

240 0x16c9a043 : "rpc_s_network_unreachable", 

241 0x16c9a044 : "rpc_s_connect_no_resources", 

242 0x16c9a045 : "rpc_s_rem_network_shutdown", 

243 0x16c9a046 : "rpc_s_too_many_rem_connects", 

244 0x16c9a047 : "rpc_s_no_rem_endpoint", 

245 0x16c9a048 : "rpc_s_rem_host_down", 

246 0x16c9a049 : "rpc_s_host_unreachable", 

247 0x16c9a04a : "rpc_s_access_control_info_inv", 

248 0x16c9a04b : "rpc_s_loc_connect_aborted", 

249 0x16c9a04c : "rpc_s_connect_closed_by_rem", 

250 0x16c9a04d : "rpc_s_rem_host_crashed", 

251 0x16c9a04e : "rpc_s_invalid_endpoint_format", 

252 0x16c9a04f : "rpc_s_unknown_status_code", 

253 0x16c9a050 : "rpc_s_unknown_mgr_type", 

254 0x16c9a051 : "rpc_s_assoc_creation_failed", 

255 0x16c9a052 : "rpc_s_assoc_grp_max_exceeded", 

256 0x16c9a053 : "rpc_s_assoc_grp_alloc_failed", 

257 0x16c9a054 : "rpc_s_sm_invalid_state", 

258 0x16c9a055 : "rpc_s_assoc_req_rejected", 

259 0x16c9a056 : "rpc_s_assoc_shutdown", 

260 0x16c9a057 : "rpc_s_tsyntaxes_unsupported", 

261 0x16c9a058 : "rpc_s_context_id_not_found", 

262 0x16c9a059 : "rpc_s_cant_listen_socket", 

263 0x16c9a05a : "rpc_s_no_addrs", 

264 0x16c9a05b : "rpc_s_cant_getpeername", 

265 0x16c9a05c : "rpc_s_cant_get_if_id", 

266 0x16c9a05d : "rpc_s_protseq_not_supported", 

267 0x16c9a05e : "rpc_s_call_orphaned", 

268 0x16c9a05f : "rpc_s_who_are_you_failed", 

269 0x16c9a060 : "rpc_s_unknown_reject", 

270 0x16c9a061 : "rpc_s_type_already_registered", 

271 0x16c9a062 : "rpc_s_stop_listening_disabled", 

272 0x16c9a063 : "rpc_s_invalid_arg", 

273 0x16c9a064 : "rpc_s_not_supported", 

274 0x16c9a065 : "rpc_s_wrong_kind_of_binding", 

275 0x16c9a066 : "rpc_s_authn_authz_mismatch", 

276 0x16c9a067 : "rpc_s_call_queued", 

277 0x16c9a068 : "rpc_s_cannot_set_nodelay", 

278 0x16c9a069 : "rpc_s_not_rpc_tower", 

279 0x16c9a06a : "rpc_s_invalid_rpc_protid", 

280 0x16c9a06b : "rpc_s_invalid_rpc_floor", 

281 0x16c9a06c : "rpc_s_call_timeout", 

282 0x16c9a06d : "rpc_s_mgmt_op_disallowed", 

283 0x16c9a06e : "rpc_s_manager_not_entered", 

284 0x16c9a06f : "rpc_s_calls_too_large_for_wk_ep", 

285 0x16c9a070 : "rpc_s_server_too_busy", 

286 0x16c9a071 : "rpc_s_prot_version_mismatch", 

287 0x16c9a072 : "rpc_s_rpc_prot_version_mismatch", 

288 0x16c9a073 : "rpc_s_ss_no_import_cursor", 

289 0x16c9a074 : "rpc_s_fault_addr_error", 

290 0x16c9a075 : "rpc_s_fault_context_mismatch", 

291 0x16c9a076 : "rpc_s_fault_fp_div_by_zero", 

292 0x16c9a077 : "rpc_s_fault_fp_error", 

293 0x16c9a078 : "rpc_s_fault_fp_overflow", 

294 0x16c9a079 : "rpc_s_fault_fp_underflow", 

295 0x16c9a07a : "rpc_s_fault_ill_inst", 

296 0x16c9a07b : "rpc_s_fault_int_div_by_zero", 

297 0x16c9a07c : "rpc_s_fault_int_overflow", 

298 0x16c9a07d : "rpc_s_fault_invalid_bound", 

299 0x16c9a07e : "rpc_s_fault_invalid_tag", 

300 0x16c9a07f : "rpc_s_fault_pipe_closed", 

301 0x16c9a080 : "rpc_s_fault_pipe_comm_error", 

302 0x16c9a081 : "rpc_s_fault_pipe_discipline", 

303 0x16c9a082 : "rpc_s_fault_pipe_empty", 

304 0x16c9a083 : "rpc_s_fault_pipe_memory", 

305 0x16c9a084 : "rpc_s_fault_pipe_order", 

306 0x16c9a085 : "rpc_s_fault_remote_comm_failure", 

307 0x16c9a086 : "rpc_s_fault_remote_no_memory", 

308 0x16c9a087 : "rpc_s_fault_unspec", 

309 0x16c9a088 : "uuid_s_bad_version", 

310 0x16c9a089 : "uuid_s_socket_failure", 

311 0x16c9a08a : "uuid_s_getconf_failure", 

312 0x16c9a08b : "uuid_s_no_address", 

313 0x16c9a08c : "uuid_s_overrun", 

314 0x16c9a08d : "uuid_s_internal_error", 

315 0x16c9a08e : "uuid_s_coding_error", 

316 0x16c9a08f : "uuid_s_invalid_string_uuid", 

317 0x16c9a090 : "uuid_s_no_memory", 

318 0x16c9a091 : "rpc_s_no_more_entries", 

319 0x16c9a092 : "rpc_s_unknown_ns_error", 

320 0x16c9a093 : "rpc_s_name_service_unavailable", 

321 0x16c9a094 : "rpc_s_incomplete_name", 

322 0x16c9a095 : "rpc_s_group_not_found", 

323 0x16c9a096 : "rpc_s_invalid_name_syntax", 

324 0x16c9a097 : "rpc_s_no_more_members", 

325 0x16c9a098 : "rpc_s_no_more_interfaces", 

326 0x16c9a099 : "rpc_s_invalid_name_service", 

327 0x16c9a09a : "rpc_s_no_name_mapping", 

328 0x16c9a09b : "rpc_s_profile_not_found", 

329 0x16c9a09c : "rpc_s_not_found", 

330 0x16c9a09d : "rpc_s_no_updates", 

331 0x16c9a09e : "rpc_s_update_failed", 

332 0x16c9a09f : "rpc_s_no_match_exported", 

333 0x16c9a0a0 : "rpc_s_entry_not_found", 

334 0x16c9a0a1 : "rpc_s_invalid_inquiry_context", 

335 0x16c9a0a2 : "rpc_s_interface_not_found", 

336 0x16c9a0a3 : "rpc_s_group_member_not_found", 

337 0x16c9a0a4 : "rpc_s_entry_already_exists", 

338 0x16c9a0a5 : "rpc_s_nsinit_failure", 

339 0x16c9a0a6 : "rpc_s_unsupported_name_syntax", 

340 0x16c9a0a7 : "rpc_s_no_more_elements", 

341 0x16c9a0a8 : "rpc_s_no_ns_permission", 

342 0x16c9a0a9 : "rpc_s_invalid_inquiry_type", 

343 0x16c9a0aa : "rpc_s_profile_element_not_found", 

344 0x16c9a0ab : "rpc_s_profile_element_replaced", 

345 0x16c9a0ac : "rpc_s_import_already_done", 

346 0x16c9a0ad : "rpc_s_database_busy", 

347 0x16c9a0ae : "rpc_s_invalid_import_context", 

348 0x16c9a0af : "rpc_s_uuid_set_not_found", 

349 0x16c9a0b0 : "rpc_s_uuid_member_not_found", 

350 0x16c9a0b1 : "rpc_s_no_interfaces_exported", 

351 0x16c9a0b2 : "rpc_s_tower_set_not_found", 

352 0x16c9a0b3 : "rpc_s_tower_member_not_found", 

353 0x16c9a0b4 : "rpc_s_obj_uuid_not_found", 

354 0x16c9a0b5 : "rpc_s_no_more_bindings", 

355 0x16c9a0b6 : "rpc_s_invalid_priority", 

356 0x16c9a0b7 : "rpc_s_not_rpc_entry", 

357 0x16c9a0b8 : "rpc_s_invalid_lookup_context", 

358 0x16c9a0b9 : "rpc_s_binding_vector_full", 

359 0x16c9a0ba : "rpc_s_cycle_detected", 

360 0x16c9a0bb : "rpc_s_nothing_to_export", 

361 0x16c9a0bc : "rpc_s_nothing_to_unexport", 

362 0x16c9a0bd : "rpc_s_invalid_vers_option", 

363 0x16c9a0be : "rpc_s_no_rpc_data", 

364 0x16c9a0bf : "rpc_s_mbr_picked", 

365 0x16c9a0c0 : "rpc_s_not_all_objs_unexported", 

366 0x16c9a0c1 : "rpc_s_no_entry_name", 

367 0x16c9a0c2 : "rpc_s_priority_group_done", 

368 0x16c9a0c3 : "rpc_s_partial_results", 

369 0x16c9a0c4 : "rpc_s_no_env_setup", 

370 0x16c9a0c5 : "twr_s_unknown_sa", 

371 0x16c9a0c6 : "twr_s_unknown_tower", 

372 0x16c9a0c7 : "twr_s_not_implemented", 

373 0x16c9a0c8 : "rpc_s_max_calls_too_small", 

374 0x16c9a0c9 : "rpc_s_cthread_create_failed", 

375 0x16c9a0ca : "rpc_s_cthread_pool_exists", 

376 0x16c9a0cb : "rpc_s_cthread_no_such_pool", 

377 0x16c9a0cc : "rpc_s_cthread_invoke_disabled", 

378 0x16c9a0cd : "ept_s_cant_perform_op", 

379 0x16c9a0ce : "ept_s_no_memory", 

380 0x16c9a0cf : "ept_s_database_invalid", 

381 0x16c9a0d0 : "ept_s_cant_create", 

382 0x16c9a0d1 : "ept_s_cant_access", 

383 0x16c9a0d2 : "ept_s_database_already_open", 

384 0x16c9a0d3 : "ept_s_invalid_entry", 

385 0x16c9a0d4 : "ept_s_update_failed", 

386 0x16c9a0d5 : "ept_s_invalid_context", 

387 0x16c9a0d6 : "ept_s_not_registered", 

388 0x16c9a0d7 : "ept_s_server_unavailable", 

389 0x16c9a0d8 : "rpc_s_underspecified_name", 

390 0x16c9a0d9 : "rpc_s_invalid_ns_handle", 

391 0x16c9a0da : "rpc_s_unknown_error", 

392 0x16c9a0db : "rpc_s_ss_char_trans_open_fail", 

393 0x16c9a0dc : "rpc_s_ss_char_trans_short_file", 

394 0x16c9a0dd : "rpc_s_ss_context_damaged", 

395 0x16c9a0de : "rpc_s_ss_in_null_context", 

396 0x16c9a0df : "rpc_s_socket_failure", 

397 0x16c9a0e0 : "rpc_s_unsupported_protect_level", 

398 0x16c9a0e1 : "rpc_s_invalid_checksum", 

399 0x16c9a0e2 : "rpc_s_invalid_credentials", 

400 0x16c9a0e3 : "rpc_s_credentials_too_large", 

401 0x16c9a0e4 : "rpc_s_call_id_not_found", 

402 0x16c9a0e5 : "rpc_s_key_id_not_found", 

403 0x16c9a0e6 : "rpc_s_auth_bad_integrity", 

404 0x16c9a0e7 : "rpc_s_auth_tkt_expired", 

405 0x16c9a0e8 : "rpc_s_auth_tkt_nyv", 

406 0x16c9a0e9 : "rpc_s_auth_repeat", 

407 0x16c9a0ea : "rpc_s_auth_not_us", 

408 0x16c9a0eb : "rpc_s_auth_badmatch", 

409 0x16c9a0ec : "rpc_s_auth_skew", 

410 0x16c9a0ed : "rpc_s_auth_badaddr", 

411 0x16c9a0ee : "rpc_s_auth_badversion", 

412 0x16c9a0ef : "rpc_s_auth_msg_type", 

413 0x16c9a0f0 : "rpc_s_auth_modified", 

414 0x16c9a0f1 : "rpc_s_auth_badorder", 

415 0x16c9a0f2 : "rpc_s_auth_badkeyver", 

416 0x16c9a0f3 : "rpc_s_auth_nokey", 

417 0x16c9a0f4 : "rpc_s_auth_mut_fail", 

418 0x16c9a0f5 : "rpc_s_auth_baddirection", 

419 0x16c9a0f6 : "rpc_s_auth_method", 

420 0x16c9a0f7 : "rpc_s_auth_badseq", 

421 0x16c9a0f8 : "rpc_s_auth_inapp_cksum", 

422 0x16c9a0f9 : "rpc_s_auth_field_toolong", 

423 0x16c9a0fa : "rpc_s_invalid_crc", 

424 0x16c9a0fb : "rpc_s_binding_incomplete", 

425 0x16c9a0fc : "rpc_s_key_func_not_allowed", 

426 0x16c9a0fd : "rpc_s_unknown_stub_rtl_if_vers", 

427 0x16c9a0fe : "rpc_s_unknown_ifspec_vers", 

428 0x16c9a0ff : "rpc_s_proto_unsupp_by_auth", 

429 0x16c9a100 : "rpc_s_authn_challenge_malformed", 

430 0x16c9a101 : "rpc_s_protect_level_mismatch", 

431 0x16c9a102 : "rpc_s_no_mepv", 

432 0x16c9a103 : "rpc_s_stub_protocol_error", 

433 0x16c9a104 : "rpc_s_class_version_mismatch", 

434 0x16c9a105 : "rpc_s_helper_not_running", 

435 0x16c9a106 : "rpc_s_helper_short_read", 

436 0x16c9a107 : "rpc_s_helper_catatonic", 

437 0x16c9a108 : "rpc_s_helper_aborted", 

438 0x16c9a109 : "rpc_s_not_in_kernel", 

439 0x16c9a10a : "rpc_s_helper_wrong_user", 

440 0x16c9a10b : "rpc_s_helper_overflow", 

441 0x16c9a10c : "rpc_s_dg_need_way_auth", 

442 0x16c9a10d : "rpc_s_unsupported_auth_subtype", 

443 0x16c9a10e : "rpc_s_wrong_pickle_type", 

444 0x16c9a10f : "rpc_s_not_listening", 

445 0x16c9a110 : "rpc_s_ss_bad_buffer", 

446 0x16c9a111 : "rpc_s_ss_bad_es_action", 

447 0x16c9a112 : "rpc_s_ss_wrong_es_version", 

448 0x16c9a113 : "rpc_s_fault_user_defined", 

449 0x16c9a114 : "rpc_s_ss_incompatible_codesets", 

450 0x16c9a115 : "rpc_s_tx_not_in_transaction", 

451 0x16c9a116 : "rpc_s_tx_open_failed", 

452 0x16c9a117 : "rpc_s_partial_credentials", 

453 0x16c9a118 : "rpc_s_ss_invalid_codeset_tag", 

454 0x16c9a119 : "rpc_s_mgmt_bad_type", 

455 0x16c9a11a : "rpc_s_ss_invalid_char_input", 

456 0x16c9a11b : "rpc_s_ss_short_conv_buffer", 

457 0x16c9a11c : "rpc_s_ss_iconv_error", 

458 0x16c9a11d : "rpc_s_ss_no_compat_codeset", 

459 0x16c9a11e : "rpc_s_ss_no_compat_charsets", 

460 0x16c9a11f : "dce_cs_c_ok", 

461 0x16c9a120 : "dce_cs_c_unknown", 

462 0x16c9a121 : "dce_cs_c_notfound", 

463 0x16c9a122 : "dce_cs_c_cannot_open_file", 

464 0x16c9a123 : "dce_cs_c_cannot_read_file", 

465 0x16c9a124 : "dce_cs_c_cannot_allocate_memory", 

466 0x16c9a125 : "rpc_s_ss_cleanup_failed", 

467 0x16c9a126 : "rpc_svc_desc_general", 

468 0x16c9a127 : "rpc_svc_desc_mutex", 

469 0x16c9a128 : "rpc_svc_desc_xmit", 

470 0x16c9a129 : "rpc_svc_desc_recv", 

471 0x16c9a12a : "rpc_svc_desc_dg_state", 

472 0x16c9a12b : "rpc_svc_desc_cancel", 

473 0x16c9a12c : "rpc_svc_desc_orphan", 

474 0x16c9a12d : "rpc_svc_desc_cn_state", 

475 0x16c9a12e : "rpc_svc_desc_cn_pkt", 

476 0x16c9a12f : "rpc_svc_desc_pkt_quotas", 

477 0x16c9a130 : "rpc_svc_desc_auth", 

478 0x16c9a131 : "rpc_svc_desc_source", 

479 0x16c9a132 : "rpc_svc_desc_stats", 

480 0x16c9a133 : "rpc_svc_desc_mem", 

481 0x16c9a134 : "rpc_svc_desc_mem_type", 

482 0x16c9a135 : "rpc_svc_desc_dg_pktlog", 

483 0x16c9a136 : "rpc_svc_desc_thread_id", 

484 0x16c9a137 : "rpc_svc_desc_timestamp", 

485 0x16c9a138 : "rpc_svc_desc_cn_errors", 

486 0x16c9a139 : "rpc_svc_desc_conv_thread", 

487 0x16c9a13a : "rpc_svc_desc_pid", 

488 0x16c9a13b : "rpc_svc_desc_atfork", 

489 0x16c9a13c : "rpc_svc_desc_cma_thread", 

490 0x16c9a13d : "rpc_svc_desc_inherit", 

491 0x16c9a13e : "rpc_svc_desc_dg_sockets", 

492 0x16c9a13f : "rpc_svc_desc_timer", 

493 0x16c9a140 : "rpc_svc_desc_threads", 

494 0x16c9a141 : "rpc_svc_desc_server_call", 

495 0x16c9a142 : "rpc_svc_desc_nsi", 

496 0x16c9a143 : "rpc_svc_desc_dg_pkt", 

497 0x16c9a144 : "rpc_m_cn_ill_state_trans_sa", 

498 0x16c9a145 : "rpc_m_cn_ill_state_trans_ca", 

499 0x16c9a146 : "rpc_m_cn_ill_state_trans_sg", 

500 0x16c9a147 : "rpc_m_cn_ill_state_trans_cg", 

501 0x16c9a148 : "rpc_m_cn_ill_state_trans_sr", 

502 0x16c9a149 : "rpc_m_cn_ill_state_trans_cr", 

503 0x16c9a14a : "rpc_m_bad_pkt_type", 

504 0x16c9a14b : "rpc_m_prot_mismatch", 

505 0x16c9a14c : "rpc_m_frag_toobig", 

506 0x16c9a14d : "rpc_m_unsupp_stub_rtl_if", 

507 0x16c9a14e : "rpc_m_unhandled_callstate", 

508 0x16c9a14f : "rpc_m_call_failed", 

509 0x16c9a150 : "rpc_m_call_failed_no_status", 

510 0x16c9a151 : "rpc_m_call_failed_errno", 

511 0x16c9a152 : "rpc_m_call_failed_s", 

512 0x16c9a153 : "rpc_m_call_failed_c", 

513 0x16c9a154 : "rpc_m_errmsg_toobig", 

514 0x16c9a155 : "rpc_m_invalid_srchattr", 

515 0x16c9a156 : "rpc_m_nts_not_found", 

516 0x16c9a157 : "rpc_m_invalid_accbytcnt", 

517 0x16c9a158 : "rpc_m_pre_v2_ifspec", 

518 0x16c9a159 : "rpc_m_unk_ifspec", 

519 0x16c9a15a : "rpc_m_recvbuf_toosmall", 

520 0x16c9a15b : "rpc_m_unalign_authtrl", 

521 0x16c9a15c : "rpc_m_unexpected_exc", 

522 0x16c9a15d : "rpc_m_no_stub_data", 

523 0x16c9a15e : "rpc_m_eventlist_full", 

524 0x16c9a15f : "rpc_m_unk_sock_type", 

525 0x16c9a160 : "rpc_m_unimp_call", 

526 0x16c9a161 : "rpc_m_invalid_seqnum", 

527 0x16c9a162 : "rpc_m_cant_create_uuid", 

528 0x16c9a163 : "rpc_m_pre_v2_ss", 

529 0x16c9a164 : "rpc_m_dgpkt_pool_corrupt", 

530 0x16c9a165 : "rpc_m_dgpkt_bad_free", 

531 0x16c9a166 : "rpc_m_lookaside_corrupt", 

532 0x16c9a167 : "rpc_m_alloc_fail", 

533 0x16c9a168 : "rpc_m_realloc_fail", 

534 0x16c9a169 : "rpc_m_cant_open_file", 

535 0x16c9a16a : "rpc_m_cant_read_addr", 

536 0x16c9a16b : "rpc_svc_desc_libidl", 

537 0x16c9a16c : "rpc_m_ctxrundown_nomem", 

538 0x16c9a16d : "rpc_m_ctxrundown_exc", 

539 0x16c9a16e : "rpc_s_fault_codeset_conv_error", 

540 0x16c9a16f : "rpc_s_no_call_active", 

541 0x16c9a170 : "rpc_s_cannot_support", 

542 0x16c9a171 : "rpc_s_no_context_available", 

543} 

544 

545class DCERPCException(Exception): 

546 """ 

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

548 DCERPC Transport used. 

549 """ 

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

551 """ 

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

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

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

555 information 

556 """ 

557 Exception.__init__(self) 

558 self.packet = packet 

559 self.error_string = error_string 

560 if packet is not None: 

561 try: 

562 self.error_code = packet['ErrorCode'] 

563 except: 

564 self.error_code = error_code 

565 else: 

566 self.error_code = error_code 

567 

568 def get_error_code( self ): 

569 return self.error_code 

570 

571 def get_packet( self ): 

572 return self.packet 

573 

574 def __str__( self ): 

575 key = self.error_code 

576 if self.error_string is not None: 

577 return self.error_string 

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

579 error_msg_short = rpc_status_codes[key] 

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

581 else: 

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

583 

584# Context Item 

585class CtxItem(Structure): 

586 structure = ( 

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

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

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

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

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

592 ) 

593 

594class CtxItemResult(Structure): 

595 structure = ( 

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

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

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

599 ) 

600 

601class SEC_TRAILER(Structure): 

602 commonHdr = ( 

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

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

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

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

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

608 ) 

609 

610class MSRPCHeader(Structure): 

611 _SIZE = 16 

612 commonHdr = ( 

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

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

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

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

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

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

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

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

621 ) 

622 

623 structure = ( 

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

625 ('pduData',':'), 

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

627 ('pad', ':'), 

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

629 ('sec_trailer',':'), 

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

631 ('auth_data',':'), 

632 ) 

633 

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

635 Structure.__init__(self,data, alignment) 

636 if data is None: 

637 self['ver_major'] = 5 

638 self['ver_minor'] = 0 

639 self['flags'] = PFC_FIRST_FRAG | PFC_LAST_FRAG 

640 self['type'] = MSRPC_REQUEST 

641 self.__frag_len_set = 0 

642 self['auth_len'] = 0 

643 self['pduData'] = b'' 

644 self['auth_data'] = b'' 

645 self['sec_trailer'] = b'' 

646 self['pad'] = b'' 

647 

648 def get_header_size(self): 

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

650 

651 def get_packet(self): 

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

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

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

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

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

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

658 

659 return self.getData() 

660 

661class MSRPCRequestHeader(MSRPCHeader): 

662 _SIZE = 24 

663 commonHdr = MSRPCHeader.commonHdr + ( 

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

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

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

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

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

669 ) 

670 

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

672 MSRPCHeader.__init__(self, data, alignment) 

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

674 self['type'] = MSRPC_REQUEST 

675 self['ctx_id'] = 0 

676 self['uuid'] = b'' 

677 

678class MSRPCRespHeader(MSRPCHeader): 

679 _SIZE = 24 

680 commonHdr = MSRPCHeader.commonHdr + ( 

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

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

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

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

685 ) 

686 

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

688 MSRPCHeader.__init__(self, aBuffer, alignment) 

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

690 self['type'] = MSRPC_RESPONSE 

691 self['ctx_id'] = 0 

692 

693class MSRPCBind(Structure): 

694 _CTX_ITEM_LEN = len(CtxItem()) 

695 structure = ( 

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

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

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

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

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

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

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

703 ('ctx_items',':'), 

704 ) 

705 

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

707 Structure.__init__(self, data, alignment) 

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

709 self['max_tfrag'] = 4280 

710 self['max_rfrag'] = 4280 

711 self['assoc_group'] = 0 

712 self['ctx_num'] = 1 

713 self['ctx_items'] = b'' 

714 self.__ctx_items = [] 

715 

716 def addCtxItem(self, item): 

717 self.__ctx_items.append(item) 

718 

719 def getData(self): 

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

721 for i in self.__ctx_items: 

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

723 return Structure.getData(self) 

724 

725class MSRPCBindAck(MSRPCHeader): 

726 _SIZE = 26 # Up to SecondaryAddr 

727 _CTX_ITEM_LEN = len(CtxItemResult()) 

728 structure = ( 

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

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

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

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

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

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

735 ('Pad',':'), 

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

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

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

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

740 ('ctx_items',':'), 

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

742 ('sec_trailer',':'), 

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

744 ('auth_data',':'), 

745 ) 

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

747 self.__ctx_items = [] 

748 MSRPCHeader.__init__(self,data,alignment) 

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

750 self['Pad'] = b'' 

751 self['ctx_items'] = b'' 

752 self['sec_trailer'] = b'' 

753 self['auth_data'] = b'' 

754 

755 def getCtxItems(self): 

756 return self.__ctx_items 

757 

758 def getCtxItem(self,index): 

759 return self.__ctx_items[index-1] 

760 

761 def fromString(self, data): 

762 Structure.fromString(self,data) 

763 # Parse the ctx_items 

764 data = self['ctx_items'] 

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

766 item = CtxItemResult(data) 

767 self.__ctx_items.append(item) 

768 data = data[len(item):] 

769 

770class MSRPCBindNak(Structure): 

771 structure = ( 

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

773 ('SupportedVersions',':'), 

774 ) 

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

776 Structure.__init__(self,data,alignment) 

777 if data is None: 

778 self['SupportedVersions'] = b'' 

779 

780class DCERPC: 

781 # Standard NDR Representation 

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

783 # NDR 64 

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

785 transfer_syntax = NDRSyntax 

786 

787 def __init__(self,transport): 

788 self._transport = transport 

789 self.set_ctx_id(0) 

790 self._max_user_frag = None 

791 self.set_default_max_fragment_size() 

792 self._ctx = None 

793 

794 def get_rpc_transport(self): 

795 return self._transport 

796 

797 def set_ctx_id(self, ctx_id): 

798 self._ctx = ctx_id 

799 

800 def connect(self): 

801 return self._transport.connect() 

802 

803 def disconnect(self): 

804 return self._transport.disconnect() 

805 

806 def set_max_fragment_size(self, fragment_size): 

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

808 # 0 is don't fragment 

809 # other values are max fragment size 

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

811 self.set_default_max_fragment_size() 

812 else: 

813 self._max_user_frag = fragment_size 

814 

815 def set_default_max_fragment_size(self): 

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

817 self._max_user_frag = 0 

818 

819 def send(self, data): 

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

821 

822 def recv(self): 

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

824 

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

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

827 

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

829 pass 

830 

831 def set_auth_level(self, auth_level): 

832 pass 

833 

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

835 pass 

836 

837 def get_idempotent(self): 

838 return 0 

839 

840 def set_idempotent(self, flag): 

841 pass 

842 

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

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

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

846 else: 

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

848 

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

850 if self.transfer_syntax == self.NDR64Syntax: 

851 request.changeTransferSyntax(self.NDR64Syntax) 

852 isNDR64 = True 

853 else: 

854 isNDR64 = False 

855 

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

857 answer = self.recv() 

858 

859 __import__(request.__module__) 

860 module = sys.modules[request.__module__] 

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

862 

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

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

865 if error_code in rpc_status_codes: 

866 # This is an error we can handle 

867 exception = DCERPCException(error_code = error_code) 

868 else: 

869 sessionErrorClass = getattr(module, 'DCERPCSessionError') 

870 try: 

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

872 response = respClass(answer, isNDR64 = isNDR64) 

873 except: 

874 # No luck :( 

875 exception = sessionErrorClass(error_code = error_code) 

876 else: 

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

878 raise exception 

879 else: 

880 response = respClass(answer, isNDR64 = isNDR64) 

881 return response 

882 

883class DCERPC_v4(DCERPC): 

884 pass 

885 

886class DCERPC_v5(DCERPC): 

887 def __init__(self, transport): 

888 DCERPC.__init__(self, transport) 

889 self.__auth_level = RPC_C_AUTHN_LEVEL_NONE 

890 self.__auth_type = RPC_C_AUTHN_WINNT 

891 self.__auth_type_callback = None 

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

893 self.__auth_flags = 0 

894 self.__username = None 

895 self.__password = None 

896 self.__domain = '' 

897 self.__lmhash = '' 

898 self.__nthash = '' 

899 self.__aesKey = '' 

900 self.__TGT = None 

901 self.__TGS = None 

902 

903 self.__clientSigningKey = b'' 

904 self.__serverSigningKey = b'' 

905 self.__clientSealingKey = b'' 

906 self.__clientSealingHandle = b'' 

907 self.__serverSealingKey = b'' 

908 self.__serverSealingHandle = b'' 

909 self.__sequence = 0 

910 

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

912 self.__callid = 1 

913 self._ctx = 0 

914 self.__sessionKey = None 

915 self.__max_xmit_size = 0 

916 self.__flags = 0 

917 self.__cipher = None 

918 self.__confounder = b'' 

919 self.__gss = None 

920 

921 def set_session_key(self, session_key): 

922 self.__sessionKey = session_key 

923 

924 def get_session_key(self): 

925 return self.__sessionKey 

926 

927 def set_auth_level(self, auth_level): 

928 self.__auth_level = auth_level 

929 

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

931 self.__auth_type = auth_type 

932 self.__auth_type_callback = callback 

933 

934 def get_auth_type(self): 

935 return self.__auth_type 

936 

937 def set_max_tfrag(self, size): 

938 self.__max_xmit_size = size 

939 

940 def get_credentials(self): 

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

942 

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

944 self.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT) 

945 self.__username = username 

946 self.__password = password 

947 self.__domain = domain 

948 self.__aesKey = aesKey 

949 self.__TGT = TGT 

950 self.__TGS = TGS 

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

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

953 lmhash = '0%s' % lmhash 

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

955 nthash = '0%s' % nthash 

956 try: # just in case they were converted already 

957 self.__lmhash = unhexlify(lmhash) 

958 self.__nthash = unhexlify(nthash) 

959 except: 

960 self.__lmhash = lmhash 

961 self.__nthash = nthash 

962 pass 

963 

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

965 bind = MSRPCBind() 

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

967 ctx = self._ctx 

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

969 item = CtxItem() 

970 item['ContextID'] = ctx 

971 item['TransItems'] = 1 

972 item['ContextID'] = ctx 

973 # We generate random UUIDs for bogus binds 

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

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

976 bind.addCtxItem(item) 

977 self._ctx += 1 

978 ctx += 1 

979 

980 # The true one :) 

981 item = CtxItem() 

982 item['AbstractSyntax'] = iface_uuid 

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

984 item['ContextID'] = ctx 

985 item['TransItems'] = 1 

986 bind.addCtxItem(item) 

987 

988 packet = MSRPCHeader() 

989 packet['type'] = MSRPC_BIND 

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

991 packet['call_id'] = self.__callid 

992 

993 if alter: 

994 packet['type'] = MSRPC_ALTERCTX 

995 

996 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE: 

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

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

999 

1000 if self.__auth_type == RPC_C_AUTHN_WINNT: 

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

1002 use_ntlmv2=self._transport.doesSupportNTLMv2()) 

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

1004 from impacket.dcerpc.v5 import nrpc 

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

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

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

1008 self.__domain, self.__lmhash, 

1009 self.__nthash, self.__aesKey, 

1010 self.__TGT, self.__TGS, 

1011 self._transport.getRemoteName(), 

1012 self._transport.get_kdcHost()) 

1013 else: 

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

1015 

1016 sec_trailer = SEC_TRAILER() 

1017 sec_trailer['auth_type'] = self.__auth_type 

1018 sec_trailer['auth_level'] = self.__auth_level 

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

1020 

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

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

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

1024 sec_trailer['auth_pad_len']=pad 

1025 

1026 packet['sec_trailer'] = sec_trailer 

1027 packet['auth_data'] = auth 

1028 

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

1030 

1031 s = self._transport.recv() 

1032 

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

1034 resp = MSRPCHeader(s) 

1035 else: 

1036 return 0 #mmm why not None? 

1037 

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

1039 bindResp = MSRPCBindAck(resp.getData()) 

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

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

1042 resp = MSRPCRespHeader(resp.getData()) 

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

1044 else: 

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

1046 status_code = resp['RejectedReason'] 

1047 if status_code in rpc_status_codes: 

1048 raise DCERPCException(error_code = status_code) 

1049 elif status_code in rpc_provider_reason: 

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

1051 else: 

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

1053 else: 

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

1055 

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

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

1058 ctxItems = bindResp.getCtxItem(ctx) 

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

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

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

1062 msg += "; " 

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

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

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

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

1067 raise DCERPCException(msg) 

1068 

1069 # Save the transfer syntax for later use 

1070 self.transfer_syntax = ctxItems['TransferSyntax'] 

1071 

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

1073 self.__max_xmit_size = bindResp['max_rfrag'] 

1074 

1075 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE: 

1076 if self.__auth_type == RPC_C_AUTHN_WINNT: 

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

1078 self.__password, self.__domain, self.__lmhash, 

1079 self.__nthash, 

1080 use_ntlmv2=self._transport.doesSupportNTLMv2()) 

1081 self.__flags = response['flags'] 

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

1083 response = None 

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

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

1086 self.__sessionKey, 

1087 bindResp['auth_data']) 

1088 

1089 self.__sequence = 0 

1090 

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

1092 if self.__auth_type == RPC_C_AUTHN_WINNT: 

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

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

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

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

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

1098 # Preparing the keys handle states 

1099 cipher3 = ARC4.new(self.__clientSealingKey) 

1100 self.__clientSealingHandle = cipher3.encrypt 

1101 cipher4 = ARC4.new(self.__serverSealingKey) 

1102 self.__serverSealingHandle = cipher4.encrypt 

1103 else: 

1104 # Same key for everything 

1105 self.__clientSigningKey = self.__sessionKey 

1106 self.__serverSigningKey = self.__sessionKey 

1107 self.__clientSealingKey = self.__sessionKey 

1108 self.__serverSealingKey = self.__sessionKey 

1109 cipher = ARC4.new(self.__clientSigningKey) 

1110 self.__clientSealingHandle = cipher.encrypt 

1111 self.__serverSealingHandle = cipher.encrypt 

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

1113 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 

1114 self.__confounder = b'' 

1115 else: 

1116 self.__confounder = b'12345678' 

1117 

1118 sec_trailer = SEC_TRAILER() 

1119 sec_trailer['auth_type'] = self.__auth_type 

1120 sec_trailer['auth_level'] = self.__auth_level 

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

1122 

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

1124 if self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 

1125 alter_ctx = MSRPCHeader() 

1126 alter_ctx['type'] = MSRPC_ALTERCTX 

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

1128 alter_ctx['sec_trailer'] = sec_trailer 

1129 alter_ctx['auth_data'] = response 

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

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

1132 self.__sequence = 0 

1133 self.recv() 

1134 self.__sequence = 0 

1135 else: 

1136 auth3 = MSRPCHeader() 

1137 auth3['type'] = MSRPC_AUTH3 

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

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

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

1141 # specified in section 2.2.2.11 

1142 auth3['pduData'] = b' ' 

1143 auth3['sec_trailer'] = sec_trailer 

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

1145 

1146 # Use the same call_id 

1147 self.__callid = resp['call_id'] 

1148 auth3['call_id'] = self.__callid 

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

1150 

1151 self.__callid += 1 

1152 

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

1154 

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

1156 rpc_packet['ctx_id'] = self._ctx 

1157 rpc_packet['sec_trailer'] = b'' 

1158 rpc_packet['auth_data'] = b'' 

1159 

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

1161 # Dummy verifier, just for the calculations 

1162 sec_trailer = SEC_TRAILER() 

1163 sec_trailer['auth_type'] = self.__auth_type 

1164 sec_trailer['auth_level'] = self.__auth_level 

1165 sec_trailer['auth_pad_len'] = 0 

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

1167 

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

1169 if pad != 0: 

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

1171 sec_trailer['auth_pad_len']=pad 

1172 

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

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

1175 

1176 plain_data = rpc_packet['pduData'] 

1177 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY: 

1178 if self.__auth_type == RPC_C_AUTHN_WINNT: 

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

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

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

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

1183 self.__clientSigningKey, 

1184 self.__clientSealingKey, 

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

1186 plain_data, 

1187 self.__sequence, 

1188 self.__clientSealingHandle) 

1189 else: 

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

1191 self.__clientSigningKey, 

1192 self.__clientSealingKey, 

1193 plain_data, 

1194 plain_data, 

1195 self.__sequence, 

1196 self.__clientSealingHandle) 

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

1198 from impacket.dcerpc.v5 import nrpc 

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

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

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

1202 

1203 rpc_packet['pduData'] = sealedMessage 

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

1205 if self.__auth_type == RPC_C_AUTHN_WINNT: 

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

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

1208 # whole PDU, not just the data 

1209 signature = ntlm.SIGN(self.__flags, 

1210 self.__clientSigningKey, 

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

1212 self.__sequence, 

1213 self.__clientSealingHandle) 

1214 else: 

1215 signature = ntlm.SIGN(self.__flags, 

1216 self.__clientSigningKey, 

1217 plain_data, 

1218 self.__sequence, 

1219 self.__clientSealingHandle) 

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

1221 from impacket.dcerpc.v5 import nrpc 

1222 signature = nrpc.SIGN(plain_data, 

1223 self.__confounder, 

1224 self.__sequence, 

1225 self.__sessionKey, 

1226 False) 

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

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

1229 

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

1231 rpc_packet['auth_data'] = signature 

1232 

1233 self.__sequence += 1 

1234 

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

1236 

1237 def send(self, data): 

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

1239 # Must be an Impacket, transform to structure 

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

1241 

1242 try: 

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

1244 data['flags'] |= PFC_OBJECT_UUID 

1245 except: 

1246 # Structure doesn't have uuid 

1247 pass 

1248 data['ctx_id'] = self._ctx 

1249 data['call_id'] = self.__callid 

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

1251 # We should fragment PDUs if: 

1252 # 1) Payload exceeds __max_xmit_size received during BIND response 

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

1254 should_fragment = False 

1255 

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

1257 if self._max_user_frag > 0: 

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

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

1260 else: 

1261 fragment_size = self.__max_xmit_size 

1262 

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

1264 

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

1266 if fragment_size <= 8: 

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

1268 # (Kerberos) 

1269 fragment_size = 8 

1270 

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

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

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

1274 should_fragment = True 

1275 if fragment_size+128 > self.__max_xmit_size: 

1276 fragment_size = self.__max_xmit_size - 128 

1277 

1278 if should_fragment: 

1279 packet = data['pduData'] 

1280 offset = 0 

1281 

1282 while 1: 

1283 toSend = packet[offset:offset+fragment_size] 

1284 if not toSend: 

1285 break 

1286 if offset == 0: 

1287 data['flags'] |= PFC_FIRST_FRAG 

1288 else: 

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

1290 offset += len(toSend) 

1291 if offset >= len(packet): 

1292 data['flags'] |= PFC_LAST_FRAG 

1293 else: 

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

1295 data['pduData'] = toSend 

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

1297 else: 

1298 self._transport_send(data) 

1299 self.__callid += 1 

1300 

1301 def recv(self): 

1302 finished = False 

1303 forceRecv = 0 

1304 retAnswer = b'' 

1305 while not finished: 

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

1307 # TCP/UDP Transports 

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

1309 response_header = MSRPCRespHeader(response_data) 

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

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

1312 # So we gotta check we received it all 

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

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

1315 

1316 off = response_header.get_header_size() 

1317 

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

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

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

1321 raise DCERPCException(rpc_status_codes[status_code]) 

1322 elif status_code & 0xffff in rpc_status_codes: 

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

1324 else: 

1325 if status_code in hresult_errors.ERROR_MESSAGES: 

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

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

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

1329 else: 

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

1331 

1332 if response_header['flags'] & PFC_LAST_FRAG: 

1333 # No need to reassembly DCERPC 

1334 finished = True 

1335 else: 

1336 # Forcing Read Recv, we need more packets! 

1337 forceRecv = 1 

1338 

1339 answer = response_data[off:] 

1340 auth_len = response_header['auth_len'] 

1341 if auth_len: 

1342 auth_len += 8 

1343 auth_data = answer[-auth_len:] 

1344 sec_trailer = SEC_TRAILER(data = auth_data) 

1345 answer = answer[:-auth_len] 

1346 

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

1348 if self.__auth_type == RPC_C_AUTHN_WINNT: 

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

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

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

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

1353 self.__serverSigningKey, 

1354 self.__serverSealingKey, 

1355 answer, 

1356 answer, 

1357 self.__sequence, 

1358 self.__serverSealingHandle) 

1359 else: 

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

1361 self.__serverSigningKey, 

1362 self.__serverSealingKey, 

1363 answer, 

1364 answer, 

1365 self.__sequence, 

1366 self.__serverSealingHandle) 

1367 self.__sequence += 1 

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

1369 from impacket.dcerpc.v5 import nrpc 

1370 answer, cfounder = nrpc.UNSEAL(answer, 

1371 auth_data[len(sec_trailer):], 

1372 self.__sessionKey, 

1373 False) 

1374 self.__sequence += 1 

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

1376 if self.__sequence > 0: 

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

1378 direction='init', authData=auth_data) 

1379 

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

1381 if self.__auth_type == RPC_C_AUTHN_WINNT: 

1382 ntlmssp = auth_data[12:] 

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

1384 signature = ntlm.SIGN(self.__flags, 

1385 self.__serverSigningKey, 

1386 answer, 

1387 self.__sequence, 

1388 self.__serverSealingHandle) 

1389 else: 

1390 signature = ntlm.SIGN(self.__flags, 

1391 self.__serverSigningKey, 

1392 ntlmssp, 

1393 self.__sequence, 

1394 self.__serverSealingHandle) 

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

1396 # the packet :P 

1397 self.__sequence += 1 

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

1399 from impacket.dcerpc.v5 import nrpc 

1400 ntlmssp = auth_data[12:] 

1401 signature = nrpc.SIGN(ntlmssp, 

1402 self.__confounder, 

1403 self.__sequence, 

1404 self.__sessionKey, 

1405 False) 

1406 self.__sequence += 1 

1407 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 

1408 # Do NOT increment the sequence number when Signing Kerberos 

1409 #self.__sequence += 1 

1410 pass 

1411 

1412 

1413 if sec_trailer['auth_pad_len']: 

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

1415 

1416 retAnswer += answer 

1417 return retAnswer 

1418 

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

1420 answer = self.__class__(self._transport) 

1421 

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

1423 self.__aesKey, self.__TGT, self.__TGS) 

1424 answer.set_auth_type(self.__auth_type) 

1425 answer.set_auth_level(self.__auth_level) 

1426 

1427 answer.set_ctx_id(self._ctx+1) 

1428 answer.__callid = self.__callid 

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

1430 return answer 

1431 

1432class DCERPC_RawCall(MSRPCRequestHeader): 

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

1434 MSRPCRequestHeader.__init__(self) 

1435 self['op_num'] = op_num 

1436 self['pduData'] = data 

1437 if uuid is not None: 

1438 self['flags'] |= PFC_OBJECT_UUID 

1439 self['uuid'] = uuid 

1440 

1441 def setData(self, data): 

1442 self['pduData'] = data 

1443 

1444# 2.2.6 Type Serialization Version 1 

1445class CommonHeader(NDRSTRUCT): 

1446 structure = ( 

1447 ('Version', UCHAR), 

1448 ('Endianness', UCHAR), 

1449 ('CommonHeaderLength', USHORT), 

1450 ('Filler', ULONG), 

1451 ) 

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

1453 NDRSTRUCT.__init__(self, data, isNDR64) 

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

1455 self['Version'] = 1 

1456 self['Endianness'] = 0x10 

1457 self['CommonHeaderLength'] = 8 

1458 self['Filler'] = 0xcccccccc 

1459 

1460class PrivateHeader(NDRSTRUCT): 

1461 structure = ( 

1462 ('ObjectBufferLength', ULONG), 

1463 ('Filler', ULONG), 

1464 ) 

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

1466 NDRSTRUCT.__init__(self, data, isNDR64) 

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

1468 self['Filler'] = 0xcccccccc 

1469 

1470class TypeSerialization1(NDRSTRUCT): 

1471 commonHdr = ( 

1472 ('CommonHeader', CommonHeader), 

1473 ('PrivateHeader', PrivateHeader), 

1474 ) 

1475 def getData(self, soFar = 0): 

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

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

1478 return NDRSTRUCT.getData(self, soFar) 

1479 

1480class DCERPCServer(Thread): 

1481 """ 

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

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

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

1485 """ 

1486 def __init__(self): 

1487 Thread.__init__(self) 

1488 self._listenPort = 0 

1489 self._listenAddress = '127.0.0.1' 

1490 self._listenUUIDS = {} 

1491 self._boundUUID = b'' 

1492 self._sock = None 

1493 self._clientSock = None 

1494 self._callid = 1 

1495 self._max_frag = None 

1496 self._max_xmit_size = 4280 

1497 self.__log = LOG 

1498 self._sock = socket.socket() 

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

1500 

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

1502 self.__log.log(level,msg) 

1503 

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

1505 """ 

1506 adds a call back to a UUID/opnum call 

1507  

1508 :param uuid ifaceUUID: the interface UUID 

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

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

1511 """ 

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

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

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

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

1516 

1517 def setListenPort(self, portNum): 

1518 self._listenPort = portNum 

1519 self._sock = socket.socket() 

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

1521 

1522 def getListenPort(self): 

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

1524 

1525 def recv(self): 

1526 finished = False 

1527 retAnswer = b'' 

1528 response_data = b'' 

1529 while not finished: 

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

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

1532 # No data?, connection might have closed 

1533 if response_data == b'': 

1534 return None 

1535 response_header = MSRPCRespHeader(response_data) 

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

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

1538 # So we gotta check we received it all 

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

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

1541 response_header = MSRPCRespHeader(response_data) 

1542 if response_header['flags'] & PFC_LAST_FRAG: 

1543 # No need to reassembly DCERPC 

1544 finished = True 

1545 answer = response_header['pduData'] 

1546 auth_len = response_header['auth_len'] 

1547 if auth_len: 

1548 auth_len += 8 

1549 auth_data = answer[-auth_len:] 

1550 sec_trailer = SEC_TRAILER(data = auth_data) 

1551 answer = answer[:-auth_len] 

1552 if sec_trailer['auth_pad_len']: 

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

1554 

1555 retAnswer += answer 

1556 return response_data 

1557 

1558 def run(self): 

1559 self._sock.listen(10) 

1560 while True: 

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

1562 try: 

1563 while True: 

1564 data = self.recv() 

1565 if data is None: 

1566 # No data.. connection closed 

1567 break 

1568 answer = self.processRequest(data) 

1569 if answer is not None: 

1570 self.send(answer) 

1571 except Exception: 

1572 #import traceback 

1573 #traceback.print_exc() 

1574 pass 

1575 self._clientSock.close() 

1576 

1577 def send(self, data): 

1578 max_frag = self._max_frag 

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

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

1581 

1582 if self._max_frag: 

1583 max_frag = min(max_frag, self._max_frag) 

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

1585 packet = data['pduData'] 

1586 offset = 0 

1587 while 1: 

1588 toSend = packet[offset:offset+max_frag] 

1589 if not toSend: 

1590 break 

1591 flags = 0 

1592 if offset == 0: 

1593 flags |= PFC_FIRST_FRAG 

1594 offset += len(toSend) 

1595 if offset == len(packet): 

1596 flags |= PFC_LAST_FRAG 

1597 data['flags'] = flags 

1598 data['pduData'] = toSend 

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

1600 else: 

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

1602 self._callid += 1 

1603 

1604 def bind(self,packet, bind): 

1605 # Standard NDR Representation 

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

1607 resp = MSRPCBindAck() 

1608 

1609 resp['type'] = MSRPC_BINDACK 

1610 resp['flags'] = packet['flags'] 

1611 resp['frag_len'] = 0 

1612 resp['auth_len'] = 0 

1613 resp['auth_data'] = b'' 

1614 resp['call_id'] = packet['call_id'] 

1615 resp['max_tfrag'] = bind['max_tfrag'] 

1616 resp['max_rfrag'] = bind['max_rfrag'] 

1617 resp['assoc_group'] = 0x1234 

1618 resp['ctx_num'] = 0 

1619 

1620 data = bind['ctx_items'] 

1621 ctx_items = b'' 

1622 resp['SecondaryAddrLen'] = 0 

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

1624 result = MSRPC_CONT_RESULT_USER_REJECT 

1625 item = CtxItem(data) 

1626 data = data[len(item):] 

1627 

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

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

1630 # Now Check if the interface is what we listen 

1631 reason = 1 # Default, Abstract Syntax not supported 

1632 for j in self._listenUUIDS: 

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

1634 # Match, we accept the bind request 

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

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

1637 reason = 0 

1638 self._boundUUID = j 

1639 else: 

1640 # Fail the bind request for this context 

1641 reason = 2 # Transfer Syntax not supported 

1642 if reason == 0: 

1643 result = MSRPC_CONT_RESULT_ACCEPT 

1644 if reason == 1: 

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

1646 

1647 resp['ctx_num'] += 1 

1648 itemResult = CtxItemResult() 

1649 itemResult['Result'] = result 

1650 itemResult['Reason'] = reason 

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

1652 ctx_items += itemResult.getData() 

1653 

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

1655 resp['ctx_items'] = ctx_items 

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

1657 

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

1659 return None 

1660 

1661 def processRequest(self,data): 

1662 packet = MSRPCHeader(data) 

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

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

1665 self.bind(packet, bind) 

1666 packet = None 

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

1668 request = MSRPCRequestHeader(data) 

1669 response = MSRPCRespHeader(data) 

1670 response['type'] = MSRPC_RESPONSE 

1671 # Serve the opnum requested, if not, fails 

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

1673 # Call the function  

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

1675 response['pduData'] = returnData 

1676 else: 

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

1678 response['type'] = MSRPC_FAULT 

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

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

1681 return response 

1682 else: 

1683 # Defaults to a fault 

1684 packet = MSRPCRespHeader(data) 

1685 packet['type'] = MSRPC_FAULT 

1686 

1687 return packet