Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/rpcrt.py : 66%

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#
20import logging
21import socket
22import sys
23from binascii import unhexlify
24from Cryptodome.Cipher import ARC4
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
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
58# MS/RPC Packet Flags
59PFC_FIRST_FRAG = 0x01
60PFC_LAST_FRAG = 0x02
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
66#For the
67#remaining PDU types, this flag MUST be interpreted as PFC_PENDING_CANCEL.
68MSRPC_PENDING_CANCEL= 0x04
70PFC_RESERVED_1 = 0x08
71PFC_CONC_MPX = 0x10
72PFC_DID_NOT_EXECUTE = 0x20
73PFC_MAYBE = 0x40
74PFC_OBJECT_UUID = 0x80
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
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
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}
104MSRPC_CONT_RESULT_ACCEPT = 0
105MSRPC_CONT_RESULT_USER_REJECT = 1
106MSRPC_CONT_RESULT_PROV_REJECT = 2
108#Results of a presentation context negotiation
109rpc_cont_def_result = {
110 0 : 'acceptance',
111 1 : 'user_rejection',
112 2 : 'provider_rejection'
113}
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
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}
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
568 def get_error_code( self ):
569 return self.error_code
571 def get_packet( self ):
572 return self.packet
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
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 )
594class CtxItemResult(Structure):
595 structure = (
596 ('Result','<H=0'),
597 ('Reason','<H=0'),
598 ('TransferSyntax','20s=""'),
599 )
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 )
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 )
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 )
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''
648 def get_header_size(self):
649 return self._SIZE + (16 if (self["flags"] & PFC_OBJECT_UUID) > 0 else 0)
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)
659 return self.getData()
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 )
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''
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 )
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
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 )
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 = []
716 def addCtxItem(self, item):
717 self.__ctx_items.append(item)
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)
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''
755 def getCtxItems(self):
756 return self.__ctx_items
758 def getCtxItem(self,index):
759 return self.__ctx_items[index-1]
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):]
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''
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
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
794 def get_rpc_transport(self):
795 return self._transport
797 def set_ctx_id(self, ctx_id):
798 self._ctx = ctx_id
800 def connect(self):
801 return self._transport.connect()
803 def disconnect(self):
804 return self._transport.disconnect()
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
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
819 def send(self, data):
820 raise RuntimeError ('virtual method. Not implemented in subclass')
822 def recv(self):
823 raise RuntimeError ('virtual method. Not implemented in subclass')
825 def alter_ctx(self, newUID, bogus_binds=''):
826 raise RuntimeError ('virtual method. Not implemented in subclass')
828 def set_credentials(self, username, password, domain='', lmhash='', nthash='', aesKey='', TGT=None, TGS=None):
829 pass
831 def set_auth_level(self, auth_level):
832 pass
834 def set_auth_type(self, auth_type, callback=None):
835 pass
837 def get_idempotent(self):
838 return 0
840 def set_idempotent(self, flag):
841 pass
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))
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
856 self.call(request.opnum, request, uuid)
857 answer = self.recv()
859 __import__(request.__module__)
860 module = sys.modules[request.__module__]
861 respClass = getattr(module, request.__class__.__name__ + 'Response')
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
883class DCERPC_v4(DCERPC):
884 pass
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
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
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
921 def set_session_key(self, session_key):
922 self.__sessionKey = session_key
924 def get_session_key(self):
925 return self.__sessionKey
927 def set_auth_level(self, auth_level):
928 self.__auth_level = auth_level
930 def set_auth_type(self, auth_type, callback = None):
931 self.__auth_type = auth_type
932 self.__auth_type_callback = callback
934 def get_auth_type(self):
935 return self.__auth_type
937 def set_max_tfrag(self, size):
938 self.__max_xmit_size = size
940 def get_credentials(self):
941 return self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS
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
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
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)
988 packet = MSRPCHeader()
989 packet['type'] = MSRPC_BIND
990 packet['pduData'] = bind.getData()
991 packet['call_id'] = self.__callid
993 if alter:
994 packet['type'] = MSRPC_ALTERCTX
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()
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)
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
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
1026 packet['sec_trailer'] = sec_trailer
1027 packet['auth_data'] = auth
1029 self._transport.send(packet.get_packet())
1031 s = self._transport.recv()
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?
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'])
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)
1069 # Save the transfer syntax for later use
1070 self.transfer_syntax = ctxItems['TransferSyntax']
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']
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'])
1089 self.__sequence = 0
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'
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
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()
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)
1151 self.__callid += 1
1153 return resp # means packet is signed, if verifier is wrong it fails
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''
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
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
1173 rpc_packet['sec_trailer'] = sec_trailer.getData()
1174 rpc_packet['auth_data'] = b' '*16
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)
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)
1230 rpc_packet['sec_trailer'] = sec_trailer.getData()
1231 rpc_packet['auth_data'] = signature
1233 self.__sequence += 1
1235 self._transport.send(rpc_packet.get_packet(), forceWriteAndx = forceWriteAndx, forceRecv = forceRecv)
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())
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
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
1263 # Sanity check. Fragmentation can't be too low, otherwise sec_trailer won't fit
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
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
1278 if should_fragment:
1279 packet = data['pduData']
1280 offset = 0
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
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)))
1316 off = response_header.get_header_size()
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)
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
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]
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)
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
1413 if sec_trailer['auth_pad_len']:
1414 answer = answer[:-sec_trailer['auth_pad_len']]
1416 retAnswer += answer
1417 return retAnswer
1419 def alter_ctx(self, newUID, bogus_binds = 0):
1420 answer = self.__class__(self._transport)
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)
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
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
1441 def setData(self, data):
1442 self['pduData'] = data
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
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
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)
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))
1501 def log(self, msg, level=logging.INFO):
1502 self.__log.log(level,msg)
1504 def addCallbacks(self, ifaceUUID, secondaryAddr, callbacks):
1505 """
1506 adds a call back to a UUID/opnum call
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)
1517 def setListenPort(self, portNum):
1518 self._listenPort = portNum
1519 self._sock = socket.socket()
1520 self._sock.bind((self._listenAddress,self._listenPort))
1522 def getListenPort(self):
1523 return self._sock.getsockname()[1]
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']]
1555 retAnswer += answer
1556 return response_data
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()
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
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
1604 def bind(self,packet, bind):
1605 # Standard NDR Representation
1606 NDRSyntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
1607 resp = MSRPCBindAck()
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
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):]
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']))
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()
1654 resp['Pad'] ='A'*((4-((resp["SecondaryAddrLen"]+MSRPCBindAck._SIZE) % 4))%4)
1655 resp['ctx_items'] = ctx_items
1656 resp['frag_len'] = len(resp.getData())
1658 self._clientSock.send(resp.getData())
1659 return None
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
1687 return packet