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# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
9# Description:
10# Partial C706.pdf + [MS-RPCE] implementation
11#
12# Best way to learn how to use these calls is to grab the protocol standard
13# so you understand what the call does, and then read the test case located
14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
15#
16# ToDo:
17# [ ] Take out all the security provider stuff out of here (e.g. RPC_C_AUTHN_WINNT)
18# and put it elsewhere. This will make the coder cleaner and easier to add
19# more SSP (e.g. NETLOGON)
20#
22import logging
23import socket
24import sys
25from binascii import unhexlify
26from Cryptodome.Cipher import ARC4
28from impacket import ntlm, LOG
29from impacket.structure import Structure,pack,unpack
30from impacket.krb5 import kerberosv5, gssapi
31from impacket.uuid import uuidtup_to_bin, generate, stringver_to_bin, bin_to_uuidtup
32from impacket.dcerpc.v5.dtypes import UCHAR, ULONG, USHORT
33from impacket.dcerpc.v5.ndr import NDRSTRUCT
34from impacket import hresult_errors
35from threading import Thread
37# MS/RPC Constants
38MSRPC_REQUEST = 0x00
39MSRPC_PING = 0x01
40MSRPC_RESPONSE = 0x02
41MSRPC_FAULT = 0x03
42MSRPC_WORKING = 0x04
43MSRPC_NOCALL = 0x05
44MSRPC_REJECT = 0x06
45MSRPC_ACK = 0x07
46MSRPC_CL_CANCEL = 0x08
47MSRPC_FACK = 0x09
48MSRPC_CANCELACK = 0x0A
49MSRPC_BIND = 0x0B
50MSRPC_BINDACK = 0x0C
51MSRPC_BINDNAK = 0x0D
52MSRPC_ALTERCTX = 0x0E
53MSRPC_ALTERCTX_R= 0x0F
54MSRPC_AUTH3 = 0x10
55MSRPC_SHUTDOWN = 0x11
56MSRPC_CO_CANCEL = 0x12
57MSRPC_ORPHANED = 0x13
58MSRPC_RTS = 0x14
60# MS/RPC Packet Flags
61PFC_FIRST_FRAG = 0x01
62PFC_LAST_FRAG = 0x02
64# For PDU types bind, bind_ack, alter_context, and
65# alter_context_resp, this flag MUST be interpreted as PFC_SUPPORT_HEADER_SIGN
66MSRPC_SUPPORT_SIGN = 0x04
68#For the
69#remaining PDU types, this flag MUST be interpreted as PFC_PENDING_CANCEL.
70MSRPC_PENDING_CANCEL= 0x04
72PFC_RESERVED_1 = 0x08
73PFC_CONC_MPX = 0x10
74PFC_DID_NOT_EXECUTE = 0x20
75PFC_MAYBE = 0x40
76PFC_OBJECT_UUID = 0x80
78# Auth Types - Security Providers
79RPC_C_AUTHN_NONE = 0x00
80RPC_C_AUTHN_GSS_NEGOTIATE = 0x09
81RPC_C_AUTHN_WINNT = 0x0A
82RPC_C_AUTHN_GSS_SCHANNEL = 0x0E
83RPC_C_AUTHN_GSS_KERBEROS = 0x10
84RPC_C_AUTHN_NETLOGON = 0x44
85RPC_C_AUTHN_DEFAULT = 0xFF
87# Auth Levels
88RPC_C_AUTHN_LEVEL_NONE = 1
89RPC_C_AUTHN_LEVEL_CONNECT = 2
90RPC_C_AUTHN_LEVEL_CALL = 3
91RPC_C_AUTHN_LEVEL_PKT = 4
92RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5
93RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6
95#Reasons for rejection of a context element, included in bind_ack result reason
96rpc_provider_reason = {
97 0 : 'reason_not_specified',
98 1 : 'abstract_syntax_not_supported',
99 2 : 'proposed_transfer_syntaxes_not_supported',
100 3 : 'local_limit_exceeded',
101 4 : 'protocol_version_not_specified',
102 8 : 'authentication_type_not_recognized',
103 9 : 'invalid_checksum'
104}
106MSRPC_CONT_RESULT_ACCEPT = 0
107MSRPC_CONT_RESULT_USER_REJECT = 1
108MSRPC_CONT_RESULT_PROV_REJECT = 2
110#Results of a presentation context negotiation
111rpc_cont_def_result = {
112 0 : 'acceptance',
113 1 : 'user_rejection',
114 2 : 'provider_rejection'
115}
117#status codes, references:
118#https://docs.microsoft.com/windows/desktop/Rpc/rpc-return-values
119#https://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/common_return_values.asp
120#winerror.h
121#https://www.opengroup.org/onlinepubs/9629399/apdxn.htm
123rpc_status_codes = {
124 0x00000005 : 'rpc_s_access_denied',
125 0x00000008 : 'Authentication type not recognized',
126 0x000006D8 : 'rpc_fault_cant_perform',
127 0x000006C6 : 'rpc_x_invalid_bound', # the arrays bound are invalid
128 0x000006E4 : 'rpc_s_cannot_support: The requested operation is not supported.', # some operation is not supported
129 0x000006F7 : 'rpc_x_bad_stub_data', # the stub data is invalid, doesn't match with the IDL definition
130 0x1C010001 : 'nca_s_comm_failure', # unable to get response from server:
131 0x1C010002 : 'nca_s_op_rng_error', # bad operation number in call
132 0x1C010003 : 'nca_s_unk_if', # unknown interface
133 0x1C010006 : 'nca_s_wrong_boot_time', # client passed server wrong server boot time
134 0x1C010009 : 'nca_s_you_crashed', # a restarted server called back a client
135 0x1C01000B : 'nca_s_proto_error', # someone messed up the protocol
136 0x1C010013 : 'nca_s_out_args_too_big ', # output args too big
137 0x1C010014 : 'nca_s_server_too_busy', # server is too busy to handle call
138 0x1C010015 : 'nca_s_fault_string_too_long', # string argument longer than declared max len
139 0x1C010017 : 'nca_s_unsupported_type ', # no implementation of generic operation for object
140 0x1C000001 : 'nca_s_fault_int_div_by_zero',
141 0x1C000002 : 'nca_s_fault_addr_error ',
142 0x1C000003 : 'nca_s_fault_fp_div_zero',
143 0x1C000004 : 'nca_s_fault_fp_underflow',
144 0x1C000005 : 'nca_s_fault_fp_overflow',
145 0x1C000006 : 'nca_s_fault_invalid_tag',
146 0x1C000007 : 'nca_s_fault_invalid_bound ',
147 0x1C000008 : 'nca_s_rpc_version_mismatch',
148 0x1C000009 : 'nca_s_unspec_reject ',
149 0x1C00000A : 'nca_s_bad_actid',
150 0x1C00000B : 'nca_s_who_are_you_failed',
151 0x1C00000C : 'nca_s_manager_not_entered ',
152 0x1C00000D : 'nca_s_fault_cancel',
153 0x1C00000E : 'nca_s_fault_ill_inst',
154 0x1C00000F : 'nca_s_fault_fp_error',
155 0x1C000010 : 'nca_s_fault_int_overflow',
156 0x1C000012 : 'nca_s_fault_unspec',
157 0x1C000013 : 'nca_s_fault_remote_comm_failure ',
158 0x1C000014 : 'nca_s_fault_pipe_empty ',
159 0x1C000015 : 'nca_s_fault_pipe_closed',
160 0x1C000016 : 'nca_s_fault_pipe_order ',
161 0x1C000017 : 'nca_s_fault_pipe_discipline',
162 0x1C000018 : 'nca_s_fault_pipe_comm_error',
163 0x1C000019 : 'nca_s_fault_pipe_memory',
164 0x1C00001A : 'nca_s_fault_context_mismatch ',
165 0x1C00001B : 'nca_s_fault_remote_no_memory ',
166 0x1C00001C : 'nca_s_invalid_pres_context_id',
167 0x1C00001D : 'nca_s_unsupported_authn_level',
168 0x1C00001F : 'nca_s_invalid_checksum ',
169 0x1C000020 : 'nca_s_invalid_crc',
170 0x1C000021 : 'nca_s_fault_user_defined',
171 0x1C000022 : 'nca_s_fault_tx_open_failed',
172 0x1C000023 : 'nca_s_fault_codeset_conv_error',
173 0x1C000024 : 'nca_s_fault_object_not_found ',
174 0x1C000025 : 'nca_s_fault_no_client_stub',
175 0x16c9a000 : "rpc_s_mod",
176 0x16c9a001 : "rpc_s_op_rng_error",
177 0x16c9a002 : "rpc_s_cant_create_socket",
178 0x16c9a003 : "rpc_s_cant_bind_socket",
179 0x16c9a004 : "rpc_s_not_in_call",
180 0x16c9a005 : "rpc_s_no_port",
181 0x16c9a006 : "rpc_s_wrong_boot_time",
182 0x16c9a007 : "rpc_s_too_many_sockets",
183 0x16c9a008 : "rpc_s_illegal_register",
184 0x16c9a009 : "rpc_s_cant_recv",
185 0x16c9a00a : "rpc_s_bad_pkt",
186 0x16c9a00b : "rpc_s_unbound_handle",
187 0x16c9a00c : "rpc_s_addr_in_use",
188 0x16c9a00d : "rpc_s_in_args_too_big",
189 0x16c9a00e : "rpc_s_string_too_long",
190 0x16c9a00f : "rpc_s_too_many_objects",
191 0x16c9a010 : "rpc_s_binding_has_no_auth",
192 0x16c9a011 : "rpc_s_unknown_authn_service",
193 0x16c9a012 : "rpc_s_no_memory",
194 0x16c9a013 : "rpc_s_cant_nmalloc",
195 0x16c9a014 : "rpc_s_call_faulted",
196 0x16c9a015 : "rpc_s_call_failed",
197 0x16c9a016 : "rpc_s_comm_failure",
198 0x16c9a017 : "rpc_s_rpcd_comm_failure",
199 0x16c9a018 : "rpc_s_illegal_family_rebind",
200 0x16c9a019 : "rpc_s_invalid_handle",
201 0x16c9a01a : "rpc_s_coding_error",
202 0x16c9a01b : "rpc_s_object_not_found",
203 0x16c9a01c : "rpc_s_cthread_not_found",
204 0x16c9a01d : "rpc_s_invalid_binding",
205 0x16c9a01e : "rpc_s_already_registered",
206 0x16c9a01f : "rpc_s_endpoint_not_found",
207 0x16c9a020 : "rpc_s_invalid_rpc_protseq",
208 0x16c9a021 : "rpc_s_desc_not_registered",
209 0x16c9a022 : "rpc_s_already_listening",
210 0x16c9a023 : "rpc_s_no_protseqs",
211 0x16c9a024 : "rpc_s_no_protseqs_registered",
212 0x16c9a025 : "rpc_s_no_bindings",
213 0x16c9a026 : "rpc_s_max_descs_exceeded",
214 0x16c9a027 : "rpc_s_no_interfaces",
215 0x16c9a028 : "rpc_s_invalid_timeout",
216 0x16c9a029 : "rpc_s_cant_inq_socket",
217 0x16c9a02a : "rpc_s_invalid_naf_id",
218 0x16c9a02b : "rpc_s_inval_net_addr",
219 0x16c9a02c : "rpc_s_unknown_if",
220 0x16c9a02d : "rpc_s_unsupported_type",
221 0x16c9a02e : "rpc_s_invalid_call_opt",
222 0x16c9a02f : "rpc_s_no_fault",
223 0x16c9a030 : "rpc_s_cancel_timeout",
224 0x16c9a031 : "rpc_s_call_cancelled",
225 0x16c9a032 : "rpc_s_invalid_call_handle",
226 0x16c9a033 : "rpc_s_cannot_alloc_assoc",
227 0x16c9a034 : "rpc_s_cannot_connect",
228 0x16c9a035 : "rpc_s_connection_aborted",
229 0x16c9a036 : "rpc_s_connection_closed",
230 0x16c9a037 : "rpc_s_cannot_accept",
231 0x16c9a038 : "rpc_s_assoc_grp_not_found",
232 0x16c9a039 : "rpc_s_stub_interface_error",
233 0x16c9a03a : "rpc_s_invalid_object",
234 0x16c9a03b : "rpc_s_invalid_type",
235 0x16c9a03c : "rpc_s_invalid_if_opnum",
236 0x16c9a03d : "rpc_s_different_server_instance",
237 0x16c9a03e : "rpc_s_protocol_error",
238 0x16c9a03f : "rpc_s_cant_recvmsg",
239 0x16c9a040 : "rpc_s_invalid_string_binding",
240 0x16c9a041 : "rpc_s_connect_timed_out",
241 0x16c9a042 : "rpc_s_connect_rejected",
242 0x16c9a043 : "rpc_s_network_unreachable",
243 0x16c9a044 : "rpc_s_connect_no_resources",
244 0x16c9a045 : "rpc_s_rem_network_shutdown",
245 0x16c9a046 : "rpc_s_too_many_rem_connects",
246 0x16c9a047 : "rpc_s_no_rem_endpoint",
247 0x16c9a048 : "rpc_s_rem_host_down",
248 0x16c9a049 : "rpc_s_host_unreachable",
249 0x16c9a04a : "rpc_s_access_control_info_inv",
250 0x16c9a04b : "rpc_s_loc_connect_aborted",
251 0x16c9a04c : "rpc_s_connect_closed_by_rem",
252 0x16c9a04d : "rpc_s_rem_host_crashed",
253 0x16c9a04e : "rpc_s_invalid_endpoint_format",
254 0x16c9a04f : "rpc_s_unknown_status_code",
255 0x16c9a050 : "rpc_s_unknown_mgr_type",
256 0x16c9a051 : "rpc_s_assoc_creation_failed",
257 0x16c9a052 : "rpc_s_assoc_grp_max_exceeded",
258 0x16c9a053 : "rpc_s_assoc_grp_alloc_failed",
259 0x16c9a054 : "rpc_s_sm_invalid_state",
260 0x16c9a055 : "rpc_s_assoc_req_rejected",
261 0x16c9a056 : "rpc_s_assoc_shutdown",
262 0x16c9a057 : "rpc_s_tsyntaxes_unsupported",
263 0x16c9a058 : "rpc_s_context_id_not_found",
264 0x16c9a059 : "rpc_s_cant_listen_socket",
265 0x16c9a05a : "rpc_s_no_addrs",
266 0x16c9a05b : "rpc_s_cant_getpeername",
267 0x16c9a05c : "rpc_s_cant_get_if_id",
268 0x16c9a05d : "rpc_s_protseq_not_supported",
269 0x16c9a05e : "rpc_s_call_orphaned",
270 0x16c9a05f : "rpc_s_who_are_you_failed",
271 0x16c9a060 : "rpc_s_unknown_reject",
272 0x16c9a061 : "rpc_s_type_already_registered",
273 0x16c9a062 : "rpc_s_stop_listening_disabled",
274 0x16c9a063 : "rpc_s_invalid_arg",
275 0x16c9a064 : "rpc_s_not_supported",
276 0x16c9a065 : "rpc_s_wrong_kind_of_binding",
277 0x16c9a066 : "rpc_s_authn_authz_mismatch",
278 0x16c9a067 : "rpc_s_call_queued",
279 0x16c9a068 : "rpc_s_cannot_set_nodelay",
280 0x16c9a069 : "rpc_s_not_rpc_tower",
281 0x16c9a06a : "rpc_s_invalid_rpc_protid",
282 0x16c9a06b : "rpc_s_invalid_rpc_floor",
283 0x16c9a06c : "rpc_s_call_timeout",
284 0x16c9a06d : "rpc_s_mgmt_op_disallowed",
285 0x16c9a06e : "rpc_s_manager_not_entered",
286 0x16c9a06f : "rpc_s_calls_too_large_for_wk_ep",
287 0x16c9a070 : "rpc_s_server_too_busy",
288 0x16c9a071 : "rpc_s_prot_version_mismatch",
289 0x16c9a072 : "rpc_s_rpc_prot_version_mismatch",
290 0x16c9a073 : "rpc_s_ss_no_import_cursor",
291 0x16c9a074 : "rpc_s_fault_addr_error",
292 0x16c9a075 : "rpc_s_fault_context_mismatch",
293 0x16c9a076 : "rpc_s_fault_fp_div_by_zero",
294 0x16c9a077 : "rpc_s_fault_fp_error",
295 0x16c9a078 : "rpc_s_fault_fp_overflow",
296 0x16c9a079 : "rpc_s_fault_fp_underflow",
297 0x16c9a07a : "rpc_s_fault_ill_inst",
298 0x16c9a07b : "rpc_s_fault_int_div_by_zero",
299 0x16c9a07c : "rpc_s_fault_int_overflow",
300 0x16c9a07d : "rpc_s_fault_invalid_bound",
301 0x16c9a07e : "rpc_s_fault_invalid_tag",
302 0x16c9a07f : "rpc_s_fault_pipe_closed",
303 0x16c9a080 : "rpc_s_fault_pipe_comm_error",
304 0x16c9a081 : "rpc_s_fault_pipe_discipline",
305 0x16c9a082 : "rpc_s_fault_pipe_empty",
306 0x16c9a083 : "rpc_s_fault_pipe_memory",
307 0x16c9a084 : "rpc_s_fault_pipe_order",
308 0x16c9a085 : "rpc_s_fault_remote_comm_failure",
309 0x16c9a086 : "rpc_s_fault_remote_no_memory",
310 0x16c9a087 : "rpc_s_fault_unspec",
311 0x16c9a088 : "uuid_s_bad_version",
312 0x16c9a089 : "uuid_s_socket_failure",
313 0x16c9a08a : "uuid_s_getconf_failure",
314 0x16c9a08b : "uuid_s_no_address",
315 0x16c9a08c : "uuid_s_overrun",
316 0x16c9a08d : "uuid_s_internal_error",
317 0x16c9a08e : "uuid_s_coding_error",
318 0x16c9a08f : "uuid_s_invalid_string_uuid",
319 0x16c9a090 : "uuid_s_no_memory",
320 0x16c9a091 : "rpc_s_no_more_entries",
321 0x16c9a092 : "rpc_s_unknown_ns_error",
322 0x16c9a093 : "rpc_s_name_service_unavailable",
323 0x16c9a094 : "rpc_s_incomplete_name",
324 0x16c9a095 : "rpc_s_group_not_found",
325 0x16c9a096 : "rpc_s_invalid_name_syntax",
326 0x16c9a097 : "rpc_s_no_more_members",
327 0x16c9a098 : "rpc_s_no_more_interfaces",
328 0x16c9a099 : "rpc_s_invalid_name_service",
329 0x16c9a09a : "rpc_s_no_name_mapping",
330 0x16c9a09b : "rpc_s_profile_not_found",
331 0x16c9a09c : "rpc_s_not_found",
332 0x16c9a09d : "rpc_s_no_updates",
333 0x16c9a09e : "rpc_s_update_failed",
334 0x16c9a09f : "rpc_s_no_match_exported",
335 0x16c9a0a0 : "rpc_s_entry_not_found",
336 0x16c9a0a1 : "rpc_s_invalid_inquiry_context",
337 0x16c9a0a2 : "rpc_s_interface_not_found",
338 0x16c9a0a3 : "rpc_s_group_member_not_found",
339 0x16c9a0a4 : "rpc_s_entry_already_exists",
340 0x16c9a0a5 : "rpc_s_nsinit_failure",
341 0x16c9a0a6 : "rpc_s_unsupported_name_syntax",
342 0x16c9a0a7 : "rpc_s_no_more_elements",
343 0x16c9a0a8 : "rpc_s_no_ns_permission",
344 0x16c9a0a9 : "rpc_s_invalid_inquiry_type",
345 0x16c9a0aa : "rpc_s_profile_element_not_found",
346 0x16c9a0ab : "rpc_s_profile_element_replaced",
347 0x16c9a0ac : "rpc_s_import_already_done",
348 0x16c9a0ad : "rpc_s_database_busy",
349 0x16c9a0ae : "rpc_s_invalid_import_context",
350 0x16c9a0af : "rpc_s_uuid_set_not_found",
351 0x16c9a0b0 : "rpc_s_uuid_member_not_found",
352 0x16c9a0b1 : "rpc_s_no_interfaces_exported",
353 0x16c9a0b2 : "rpc_s_tower_set_not_found",
354 0x16c9a0b3 : "rpc_s_tower_member_not_found",
355 0x16c9a0b4 : "rpc_s_obj_uuid_not_found",
356 0x16c9a0b5 : "rpc_s_no_more_bindings",
357 0x16c9a0b6 : "rpc_s_invalid_priority",
358 0x16c9a0b7 : "rpc_s_not_rpc_entry",
359 0x16c9a0b8 : "rpc_s_invalid_lookup_context",
360 0x16c9a0b9 : "rpc_s_binding_vector_full",
361 0x16c9a0ba : "rpc_s_cycle_detected",
362 0x16c9a0bb : "rpc_s_nothing_to_export",
363 0x16c9a0bc : "rpc_s_nothing_to_unexport",
364 0x16c9a0bd : "rpc_s_invalid_vers_option",
365 0x16c9a0be : "rpc_s_no_rpc_data",
366 0x16c9a0bf : "rpc_s_mbr_picked",
367 0x16c9a0c0 : "rpc_s_not_all_objs_unexported",
368 0x16c9a0c1 : "rpc_s_no_entry_name",
369 0x16c9a0c2 : "rpc_s_priority_group_done",
370 0x16c9a0c3 : "rpc_s_partial_results",
371 0x16c9a0c4 : "rpc_s_no_env_setup",
372 0x16c9a0c5 : "twr_s_unknown_sa",
373 0x16c9a0c6 : "twr_s_unknown_tower",
374 0x16c9a0c7 : "twr_s_not_implemented",
375 0x16c9a0c8 : "rpc_s_max_calls_too_small",
376 0x16c9a0c9 : "rpc_s_cthread_create_failed",
377 0x16c9a0ca : "rpc_s_cthread_pool_exists",
378 0x16c9a0cb : "rpc_s_cthread_no_such_pool",
379 0x16c9a0cc : "rpc_s_cthread_invoke_disabled",
380 0x16c9a0cd : "ept_s_cant_perform_op",
381 0x16c9a0ce : "ept_s_no_memory",
382 0x16c9a0cf : "ept_s_database_invalid",
383 0x16c9a0d0 : "ept_s_cant_create",
384 0x16c9a0d1 : "ept_s_cant_access",
385 0x16c9a0d2 : "ept_s_database_already_open",
386 0x16c9a0d3 : "ept_s_invalid_entry",
387 0x16c9a0d4 : "ept_s_update_failed",
388 0x16c9a0d5 : "ept_s_invalid_context",
389 0x16c9a0d6 : "ept_s_not_registered",
390 0x16c9a0d7 : "ept_s_server_unavailable",
391 0x16c9a0d8 : "rpc_s_underspecified_name",
392 0x16c9a0d9 : "rpc_s_invalid_ns_handle",
393 0x16c9a0da : "rpc_s_unknown_error",
394 0x16c9a0db : "rpc_s_ss_char_trans_open_fail",
395 0x16c9a0dc : "rpc_s_ss_char_trans_short_file",
396 0x16c9a0dd : "rpc_s_ss_context_damaged",
397 0x16c9a0de : "rpc_s_ss_in_null_context",
398 0x16c9a0df : "rpc_s_socket_failure",
399 0x16c9a0e0 : "rpc_s_unsupported_protect_level",
400 0x16c9a0e1 : "rpc_s_invalid_checksum",
401 0x16c9a0e2 : "rpc_s_invalid_credentials",
402 0x16c9a0e3 : "rpc_s_credentials_too_large",
403 0x16c9a0e4 : "rpc_s_call_id_not_found",
404 0x16c9a0e5 : "rpc_s_key_id_not_found",
405 0x16c9a0e6 : "rpc_s_auth_bad_integrity",
406 0x16c9a0e7 : "rpc_s_auth_tkt_expired",
407 0x16c9a0e8 : "rpc_s_auth_tkt_nyv",
408 0x16c9a0e9 : "rpc_s_auth_repeat",
409 0x16c9a0ea : "rpc_s_auth_not_us",
410 0x16c9a0eb : "rpc_s_auth_badmatch",
411 0x16c9a0ec : "rpc_s_auth_skew",
412 0x16c9a0ed : "rpc_s_auth_badaddr",
413 0x16c9a0ee : "rpc_s_auth_badversion",
414 0x16c9a0ef : "rpc_s_auth_msg_type",
415 0x16c9a0f0 : "rpc_s_auth_modified",
416 0x16c9a0f1 : "rpc_s_auth_badorder",
417 0x16c9a0f2 : "rpc_s_auth_badkeyver",
418 0x16c9a0f3 : "rpc_s_auth_nokey",
419 0x16c9a0f4 : "rpc_s_auth_mut_fail",
420 0x16c9a0f5 : "rpc_s_auth_baddirection",
421 0x16c9a0f6 : "rpc_s_auth_method",
422 0x16c9a0f7 : "rpc_s_auth_badseq",
423 0x16c9a0f8 : "rpc_s_auth_inapp_cksum",
424 0x16c9a0f9 : "rpc_s_auth_field_toolong",
425 0x16c9a0fa : "rpc_s_invalid_crc",
426 0x16c9a0fb : "rpc_s_binding_incomplete",
427 0x16c9a0fc : "rpc_s_key_func_not_allowed",
428 0x16c9a0fd : "rpc_s_unknown_stub_rtl_if_vers",
429 0x16c9a0fe : "rpc_s_unknown_ifspec_vers",
430 0x16c9a0ff : "rpc_s_proto_unsupp_by_auth",
431 0x16c9a100 : "rpc_s_authn_challenge_malformed",
432 0x16c9a101 : "rpc_s_protect_level_mismatch",
433 0x16c9a102 : "rpc_s_no_mepv",
434 0x16c9a103 : "rpc_s_stub_protocol_error",
435 0x16c9a104 : "rpc_s_class_version_mismatch",
436 0x16c9a105 : "rpc_s_helper_not_running",
437 0x16c9a106 : "rpc_s_helper_short_read",
438 0x16c9a107 : "rpc_s_helper_catatonic",
439 0x16c9a108 : "rpc_s_helper_aborted",
440 0x16c9a109 : "rpc_s_not_in_kernel",
441 0x16c9a10a : "rpc_s_helper_wrong_user",
442 0x16c9a10b : "rpc_s_helper_overflow",
443 0x16c9a10c : "rpc_s_dg_need_way_auth",
444 0x16c9a10d : "rpc_s_unsupported_auth_subtype",
445 0x16c9a10e : "rpc_s_wrong_pickle_type",
446 0x16c9a10f : "rpc_s_not_listening",
447 0x16c9a110 : "rpc_s_ss_bad_buffer",
448 0x16c9a111 : "rpc_s_ss_bad_es_action",
449 0x16c9a112 : "rpc_s_ss_wrong_es_version",
450 0x16c9a113 : "rpc_s_fault_user_defined",
451 0x16c9a114 : "rpc_s_ss_incompatible_codesets",
452 0x16c9a115 : "rpc_s_tx_not_in_transaction",
453 0x16c9a116 : "rpc_s_tx_open_failed",
454 0x16c9a117 : "rpc_s_partial_credentials",
455 0x16c9a118 : "rpc_s_ss_invalid_codeset_tag",
456 0x16c9a119 : "rpc_s_mgmt_bad_type",
457 0x16c9a11a : "rpc_s_ss_invalid_char_input",
458 0x16c9a11b : "rpc_s_ss_short_conv_buffer",
459 0x16c9a11c : "rpc_s_ss_iconv_error",
460 0x16c9a11d : "rpc_s_ss_no_compat_codeset",
461 0x16c9a11e : "rpc_s_ss_no_compat_charsets",
462 0x16c9a11f : "dce_cs_c_ok",
463 0x16c9a120 : "dce_cs_c_unknown",
464 0x16c9a121 : "dce_cs_c_notfound",
465 0x16c9a122 : "dce_cs_c_cannot_open_file",
466 0x16c9a123 : "dce_cs_c_cannot_read_file",
467 0x16c9a124 : "dce_cs_c_cannot_allocate_memory",
468 0x16c9a125 : "rpc_s_ss_cleanup_failed",
469 0x16c9a126 : "rpc_svc_desc_general",
470 0x16c9a127 : "rpc_svc_desc_mutex",
471 0x16c9a128 : "rpc_svc_desc_xmit",
472 0x16c9a129 : "rpc_svc_desc_recv",
473 0x16c9a12a : "rpc_svc_desc_dg_state",
474 0x16c9a12b : "rpc_svc_desc_cancel",
475 0x16c9a12c : "rpc_svc_desc_orphan",
476 0x16c9a12d : "rpc_svc_desc_cn_state",
477 0x16c9a12e : "rpc_svc_desc_cn_pkt",
478 0x16c9a12f : "rpc_svc_desc_pkt_quotas",
479 0x16c9a130 : "rpc_svc_desc_auth",
480 0x16c9a131 : "rpc_svc_desc_source",
481 0x16c9a132 : "rpc_svc_desc_stats",
482 0x16c9a133 : "rpc_svc_desc_mem",
483 0x16c9a134 : "rpc_svc_desc_mem_type",
484 0x16c9a135 : "rpc_svc_desc_dg_pktlog",
485 0x16c9a136 : "rpc_svc_desc_thread_id",
486 0x16c9a137 : "rpc_svc_desc_timestamp",
487 0x16c9a138 : "rpc_svc_desc_cn_errors",
488 0x16c9a139 : "rpc_svc_desc_conv_thread",
489 0x16c9a13a : "rpc_svc_desc_pid",
490 0x16c9a13b : "rpc_svc_desc_atfork",
491 0x16c9a13c : "rpc_svc_desc_cma_thread",
492 0x16c9a13d : "rpc_svc_desc_inherit",
493 0x16c9a13e : "rpc_svc_desc_dg_sockets",
494 0x16c9a13f : "rpc_svc_desc_timer",
495 0x16c9a140 : "rpc_svc_desc_threads",
496 0x16c9a141 : "rpc_svc_desc_server_call",
497 0x16c9a142 : "rpc_svc_desc_nsi",
498 0x16c9a143 : "rpc_svc_desc_dg_pkt",
499 0x16c9a144 : "rpc_m_cn_ill_state_trans_sa",
500 0x16c9a145 : "rpc_m_cn_ill_state_trans_ca",
501 0x16c9a146 : "rpc_m_cn_ill_state_trans_sg",
502 0x16c9a147 : "rpc_m_cn_ill_state_trans_cg",
503 0x16c9a148 : "rpc_m_cn_ill_state_trans_sr",
504 0x16c9a149 : "rpc_m_cn_ill_state_trans_cr",
505 0x16c9a14a : "rpc_m_bad_pkt_type",
506 0x16c9a14b : "rpc_m_prot_mismatch",
507 0x16c9a14c : "rpc_m_frag_toobig",
508 0x16c9a14d : "rpc_m_unsupp_stub_rtl_if",
509 0x16c9a14e : "rpc_m_unhandled_callstate",
510 0x16c9a14f : "rpc_m_call_failed",
511 0x16c9a150 : "rpc_m_call_failed_no_status",
512 0x16c9a151 : "rpc_m_call_failed_errno",
513 0x16c9a152 : "rpc_m_call_failed_s",
514 0x16c9a153 : "rpc_m_call_failed_c",
515 0x16c9a154 : "rpc_m_errmsg_toobig",
516 0x16c9a155 : "rpc_m_invalid_srchattr",
517 0x16c9a156 : "rpc_m_nts_not_found",
518 0x16c9a157 : "rpc_m_invalid_accbytcnt",
519 0x16c9a158 : "rpc_m_pre_v2_ifspec",
520 0x16c9a159 : "rpc_m_unk_ifspec",
521 0x16c9a15a : "rpc_m_recvbuf_toosmall",
522 0x16c9a15b : "rpc_m_unalign_authtrl",
523 0x16c9a15c : "rpc_m_unexpected_exc",
524 0x16c9a15d : "rpc_m_no_stub_data",
525 0x16c9a15e : "rpc_m_eventlist_full",
526 0x16c9a15f : "rpc_m_unk_sock_type",
527 0x16c9a160 : "rpc_m_unimp_call",
528 0x16c9a161 : "rpc_m_invalid_seqnum",
529 0x16c9a162 : "rpc_m_cant_create_uuid",
530 0x16c9a163 : "rpc_m_pre_v2_ss",
531 0x16c9a164 : "rpc_m_dgpkt_pool_corrupt",
532 0x16c9a165 : "rpc_m_dgpkt_bad_free",
533 0x16c9a166 : "rpc_m_lookaside_corrupt",
534 0x16c9a167 : "rpc_m_alloc_fail",
535 0x16c9a168 : "rpc_m_realloc_fail",
536 0x16c9a169 : "rpc_m_cant_open_file",
537 0x16c9a16a : "rpc_m_cant_read_addr",
538 0x16c9a16b : "rpc_svc_desc_libidl",
539 0x16c9a16c : "rpc_m_ctxrundown_nomem",
540 0x16c9a16d : "rpc_m_ctxrundown_exc",
541 0x16c9a16e : "rpc_s_fault_codeset_conv_error",
542 0x16c9a16f : "rpc_s_no_call_active",
543 0x16c9a170 : "rpc_s_cannot_support",
544 0x16c9a171 : "rpc_s_no_context_available",
545}
547class DCERPCException(Exception):
548 """
549 This is the exception every client should catch regardless of the underlying
550 DCERPC Transport used.
551 """
552 def __init__(self, error_string=None, error_code=None, packet=None):
553 """
554 :param string error_string: A string you want to show explaining the exception. Otherwise the default ones will be used
555 :param integer error_code: the error_code if we're using a dictionary with error's descriptions
556 :param NDR packet: if successfully decoded, the NDR packet of the response call. This could probably have useful
557 information
558 """
559 Exception.__init__(self)
560 self.packet = packet
561 self.error_string = error_string
562 if packet is not None:
563 try:
564 self.error_code = packet['ErrorCode']
565 except:
566 self.error_code = error_code
567 else:
568 self.error_code = error_code
570 def get_error_code( self ):
571 return self.error_code
573 def get_packet( self ):
574 return self.packet
576 def __str__( self ):
577 key = self.error_code
578 if self.error_string is not None:
579 return self.error_string
580 if key in rpc_status_codes: 580 ↛ 584line 580 didn't jump to line 584, because the condition on line 580 was never false
581 error_msg_short = rpc_status_codes[key]
582 return 'DCERPC Runtime Error: code: 0x%x - %s ' % (self.error_code, error_msg_short)
583 else:
584 return 'DCERPC Runtime Error: unknown error code: 0x%x' % self.error_code
586# Context Item
587class CtxItem(Structure):
588 structure = (
589 ('ContextID','<H=0'),
590 ('TransItems','B=0'),
591 ('Pad','B=0'),
592 ('AbstractSyntax','20s=""'),
593 ('TransferSyntax','20s=""'),
594 )
596class CtxItemResult(Structure):
597 structure = (
598 ('Result','<H=0'),
599 ('Reason','<H=0'),
600 ('TransferSyntax','20s=""'),
601 )
603class SEC_TRAILER(Structure):
604 commonHdr = (
605 ('auth_type', 'B=10'),
606 ('auth_level','B=0'),
607 ('auth_pad_len','B=0'),
608 ('auth_rsvrd','B=0'),
609 ('auth_ctx_id','<L=747920'),
610 )
612class MSRPCHeader(Structure):
613 _SIZE = 16
614 commonHdr = (
615 ('ver_major','B=5'), # 0
616 ('ver_minor','B=0'), # 1
617 ('type','B=0'), # 2
618 ('flags','B=0'), # 3
619 ('representation','<L=0x10'), # 4
620 ('frag_len','<H=self._SIZE+len(auth_data)+(16 if (self["flags"] & 0x80) > 0 else 0)+len(pduData)+len(pad)+len(sec_trailer)'), # 8
621 ('auth_len','<H=len(auth_data)'), # 10
622 ('call_id','<L=1'), # 12 <-- Common up to here (including this)
623 )
625 structure = (
626 ('dataLen','_-pduData','self["frag_len"]-self["auth_len"]-self._SIZE-(8 if self["auth_len"] > 0 else 0)'),
627 ('pduData',':'),
628 ('_pad', '_-pad','(4 - ((self._SIZE + (16 if (self["flags"] & 0x80) > 0 else 0) + len(self["pduData"])) & 3) & 3)'),
629 ('pad', ':'),
630 ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'),
631 ('sec_trailer',':'),
632 ('auth_dataLen','_-auth_data','self["auth_len"]'),
633 ('auth_data',':'),
634 )
636 def __init__(self, data = None, alignment = 0):
637 Structure.__init__(self,data, alignment)
638 if data is None:
639 self['ver_major'] = 5
640 self['ver_minor'] = 0
641 self['flags'] = PFC_FIRST_FRAG | PFC_LAST_FRAG
642 self['type'] = MSRPC_REQUEST
643 self.__frag_len_set = 0
644 self['auth_len'] = 0
645 self['pduData'] = b''
646 self['auth_data'] = b''
647 self['sec_trailer'] = b''
648 self['pad'] = b''
650 def get_header_size(self):
651 return self._SIZE + (16 if (self["flags"] & PFC_OBJECT_UUID) > 0 else 0)
653 def get_packet(self):
654 if self['auth_data'] != b'':
655 self['auth_len'] = len(self['auth_data'])
656 # The sec_trailer structure MUST be 4-byte aligned with respect to
657 # the beginning of the PDU. Padding octets MUST be used to align the
658 # sec_trailer structure if its natural beginning is not already 4-byte aligned
659 ##self['pad'] = '\xAA' * (4 - ((self._SIZE + len(self['pduData'])) & 3) & 3)
661 return self.getData()
663class MSRPCRequestHeader(MSRPCHeader):
664 _SIZE = 24
665 commonHdr = MSRPCHeader.commonHdr + (
666 ('alloc_hint','<L=0'), # 16
667 ('ctx_id','<H=0'), # 20
668 ('op_num','<H=0'), # 22
669 ('_uuid','_-uuid','16 if self["flags"] & 0x80 > 0 else 0' ), # 22
670 ('uuid',':'), # 22
671 )
673 def __init__(self, data = None, alignment = 0):
674 MSRPCHeader.__init__(self, data, alignment)
675 if data is None: 675 ↛ exitline 675 didn't return from function '__init__', because the condition on line 675 was never false
676 self['type'] = MSRPC_REQUEST
677 self['ctx_id'] = 0
678 self['uuid'] = b''
680class MSRPCRespHeader(MSRPCHeader):
681 _SIZE = 24
682 commonHdr = MSRPCHeader.commonHdr + (
683 ('alloc_hint','<L=0'), # 16
684 ('ctx_id','<H=0'), # 20
685 ('cancel_count','<B=0'), # 22
686 ('padding','<B=0'), # 23
687 )
689 def __init__(self, aBuffer = None, alignment = 0):
690 MSRPCHeader.__init__(self, aBuffer, alignment)
691 if aBuffer is None: 691 ↛ 692line 691 didn't jump to line 692, because the condition on line 691 was never true
692 self['type'] = MSRPC_RESPONSE
693 self['ctx_id'] = 0
695class MSRPCBind(Structure):
696 _CTX_ITEM_LEN = len(CtxItem())
697 structure = (
698 ('max_tfrag','<H=4280'),
699 ('max_rfrag','<H=4280'),
700 ('assoc_group','<L=0'),
701 ('ctx_num','B=0'),
702 ('Reserved','B=0'),
703 ('Reserved2','<H=0'),
704 ('_ctx_items', '_-ctx_items', 'self["ctx_num"]*self._CTX_ITEM_LEN'),
705 ('ctx_items',':'),
706 )
708 def __init__(self, data = None, alignment = 0):
709 Structure.__init__(self, data, alignment)
710 if data is None: 710 ↛ 716line 710 didn't jump to line 716, because the condition on line 710 was never false
711 self['max_tfrag'] = 4280
712 self['max_rfrag'] = 4280
713 self['assoc_group'] = 0
714 self['ctx_num'] = 1
715 self['ctx_items'] = b''
716 self.__ctx_items = []
718 def addCtxItem(self, item):
719 self.__ctx_items.append(item)
721 def getData(self):
722 self['ctx_num'] = len(self.__ctx_items)
723 for i in self.__ctx_items:
724 self['ctx_items'] += i.getData()
725 return Structure.getData(self)
727class MSRPCBindAck(MSRPCHeader):
728 _SIZE = 26 # Up to SecondaryAddr
729 _CTX_ITEM_LEN = len(CtxItemResult())
730 structure = (
731 ('max_tfrag','<H=0'),
732 ('max_rfrag','<H=0'),
733 ('assoc_group','<L=0'),
734 ('SecondaryAddrLen','<H&SecondaryAddr'),
735 ('SecondaryAddr','z'), # Optional if SecondaryAddrLen == 0
736 ('PadLen','_-Pad','(4-((self["SecondaryAddrLen"]+self._SIZE) % 4))%4'),
737 ('Pad',':'),
738 ('ctx_num','B=0'),
739 ('Reserved','B=0'),
740 ('Reserved2','<H=0'),
741 ('_ctx_items','_-ctx_items','self["ctx_num"]*self._CTX_ITEM_LEN'),
742 ('ctx_items',':'),
743 ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'),
744 ('sec_trailer',':'),
745 ('auth_dataLen','_-auth_data','self["auth_len"]'),
746 ('auth_data',':'),
747 )
748 def __init__(self, data = None, alignment = 0):
749 self.__ctx_items = []
750 MSRPCHeader.__init__(self,data,alignment)
751 if data is None: 751 ↛ 752line 751 didn't jump to line 752, because the condition on line 751 was never true
752 self['Pad'] = b''
753 self['ctx_items'] = b''
754 self['sec_trailer'] = b''
755 self['auth_data'] = b''
757 def getCtxItems(self):
758 return self.__ctx_items
760 def getCtxItem(self,index):
761 return self.__ctx_items[index-1]
763 def fromString(self, data):
764 Structure.fromString(self,data)
765 # Parse the ctx_items
766 data = self['ctx_items']
767 for i in range(self['ctx_num']):
768 item = CtxItemResult(data)
769 self.__ctx_items.append(item)
770 data = data[len(item):]
772class MSRPCBindNak(Structure):
773 structure = (
774 ('RejectedReason','<H=0'),
775 ('SupportedVersions',':'),
776 )
777 def __init__(self, data = None, alignment = 0):
778 Structure.__init__(self,data,alignment)
779 if data is None:
780 self['SupportedVersions'] = b''
782class DCERPC:
783 # Standard NDR Representation
784 NDRSyntax = uuidtup_to_bin(('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0'))
785 # NDR 64
786 NDR64Syntax = uuidtup_to_bin(('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0'))
787 transfer_syntax = NDRSyntax
789 def __init__(self,transport):
790 self._transport = transport
791 self.set_ctx_id(0)
792 self._max_user_frag = None
793 self.set_default_max_fragment_size()
794 self._ctx = None
796 def get_rpc_transport(self):
797 return self._transport
799 def set_ctx_id(self, ctx_id):
800 self._ctx = ctx_id
802 def connect(self):
803 return self._transport.connect()
805 def disconnect(self):
806 return self._transport.disconnect()
808 def set_max_fragment_size(self, fragment_size):
809 # -1 is default fragment size: 0 for v5, 1300 y pico for v4
810 # 0 is don't fragment
811 # other values are max fragment size
812 if fragment_size == -1: 812 ↛ 813line 812 didn't jump to line 813, because the condition on line 812 was never true
813 self.set_default_max_fragment_size()
814 else:
815 self._max_user_frag = fragment_size
817 def set_default_max_fragment_size(self):
818 # default is 0: don'fragment. v4 will override this method
819 self._max_user_frag = 0
821 def send(self, data):
822 raise RuntimeError ('virtual method. Not implemented in subclass')
824 def recv(self):
825 raise RuntimeError ('virtual method. Not implemented in subclass')
827 def alter_ctx(self, newUID, bogus_binds=''):
828 raise RuntimeError ('virtual method. Not implemented in subclass')
830 def set_credentials(self, username, password, domain='', lmhash='', nthash='', aesKey='', TGT=None, TGS=None):
831 pass
833 def set_auth_level(self, auth_level):
834 pass
836 def set_auth_type(self, auth_type, callback=None):
837 pass
839 def get_idempotent(self):
840 return 0
842 def set_idempotent(self, flag):
843 pass
845 def call(self, function, body, uuid=None):
846 if hasattr(body, 'getData'): 846 ↛ 849line 846 didn't jump to line 849, because the condition on line 846 was never false
847 return self.send(DCERPC_RawCall(function, body.getData(), uuid))
848 else:
849 return self.send(DCERPC_RawCall(function, body, uuid))
851 def request(self, request, uuid=None, checkError=True):
852 if self.transfer_syntax == self.NDR64Syntax:
853 request.changeTransferSyntax(self.NDR64Syntax)
854 isNDR64 = True
855 else:
856 isNDR64 = False
858 self.call(request.opnum, request, uuid)
859 answer = self.recv()
861 __import__(request.__module__)
862 module = sys.modules[request.__module__]
863 respClass = getattr(module, request.__class__.__name__ + 'Response')
865 if answer[-4:] != b'\x00\x00\x00\x00' and checkError is True:
866 error_code = unpack('<L', answer[-4:])[0]
867 if error_code in rpc_status_codes:
868 # This is an error we can handle
869 exception = DCERPCException(error_code = error_code)
870 else:
871 sessionErrorClass = getattr(module, 'DCERPCSessionError')
872 try:
873 # Try to unpack the answer, even if it is an error, it works most of the times
874 response = respClass(answer, isNDR64 = isNDR64)
875 except:
876 # No luck :(
877 exception = sessionErrorClass(error_code = error_code)
878 else:
879 exception = sessionErrorClass(packet = response, error_code = error_code)
880 raise exception
881 else:
882 response = respClass(answer, isNDR64 = isNDR64)
883 return response
885class DCERPC_v4(DCERPC):
886 pass
888class DCERPC_v5(DCERPC):
889 def __init__(self, transport):
890 DCERPC.__init__(self, transport)
891 self.__auth_level = RPC_C_AUTHN_LEVEL_NONE
892 self.__auth_type = RPC_C_AUTHN_WINNT
893 self.__auth_type_callback = None
894 # Flags of the authenticated session. We will need them throughout the connection
895 self.__auth_flags = 0
896 self.__username = None
897 self.__password = None
898 self.__domain = ''
899 self.__lmhash = ''
900 self.__nthash = ''
901 self.__aesKey = ''
902 self.__TGT = None
903 self.__TGS = None
905 self.__clientSigningKey = b''
906 self.__serverSigningKey = b''
907 self.__clientSealingKey = b''
908 self.__clientSealingHandle = b''
909 self.__serverSealingKey = b''
910 self.__serverSealingHandle = b''
911 self.__sequence = 0
913 self.transfer_syntax = uuidtup_to_bin(('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0'))
914 self.__callid = 1
915 self._ctx = 0
916 self.__sessionKey = None
917 self.__max_xmit_size = 0
918 self.__flags = 0
919 self.__cipher = None
920 self.__confounder = b''
921 self.__gss = None
923 def set_session_key(self, session_key):
924 self.__sessionKey = session_key
926 def get_session_key(self):
927 return self.__sessionKey
929 def set_auth_level(self, auth_level):
930 self.__auth_level = auth_level
932 def set_auth_type(self, auth_type, callback = None):
933 self.__auth_type = auth_type
934 self.__auth_type_callback = callback
936 def get_auth_type(self):
937 return self.__auth_type
939 def set_max_tfrag(self, size):
940 self.__max_xmit_size = size
942 def get_credentials(self):
943 return self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS
945 def set_credentials(self, username, password, domain = '', lmhash = '', nthash = '', aesKey = '', TGT = None, TGS = None):
946 self.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT)
947 self.__username = username
948 self.__password = password
949 self.__domain = domain
950 self.__aesKey = aesKey
951 self.__TGT = TGT
952 self.__TGS = TGS
953 if lmhash != '' or nthash != '':
954 if len(lmhash) % 2: 954 ↛ 955line 954 didn't jump to line 955, because the condition on line 954 was never true
955 lmhash = '0%s' % lmhash
956 if len(nthash) % 2: 956 ↛ 957line 956 didn't jump to line 957, because the condition on line 956 was never true
957 nthash = '0%s' % nthash
958 try: # just in case they were converted already
959 self.__lmhash = unhexlify(lmhash)
960 self.__nthash = unhexlify(nthash)
961 except:
962 self.__lmhash = lmhash
963 self.__nthash = nthash
964 pass
966 def bind(self, iface_uuid, alter = 0, bogus_binds = 0, transfer_syntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')):
967 bind = MSRPCBind()
968 #item['TransferSyntax']['Version'] = 1
969 ctx = self._ctx
970 for i in range(bogus_binds): 970 ↛ 971line 970 didn't jump to line 971, because the loop on line 970 never started
971 item = CtxItem()
972 item['ContextID'] = ctx
973 item['TransItems'] = 1
974 item['ContextID'] = ctx
975 # We generate random UUIDs for bogus binds
976 item['AbstractSyntax'] = generate() + stringver_to_bin('2.0')
977 item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax)
978 bind.addCtxItem(item)
979 self._ctx += 1
980 ctx += 1
982 # The true one :)
983 item = CtxItem()
984 item['AbstractSyntax'] = iface_uuid
985 item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax)
986 item['ContextID'] = ctx
987 item['TransItems'] = 1
988 bind.addCtxItem(item)
990 packet = MSRPCHeader()
991 packet['type'] = MSRPC_BIND
992 packet['pduData'] = bind.getData()
993 packet['call_id'] = self.__callid
995 if alter:
996 packet['type'] = MSRPC_ALTERCTX
998 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:
999 if (self.__username is None) or (self.__password is None):
1000 self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS = self._transport.get_credentials()
1002 if self.__auth_type == RPC_C_AUTHN_WINNT:
1003 auth = ntlm.getNTLMSSPType1('', '', signingRequired=True,
1004 use_ntlmv2=self._transport.doesSupportNTLMv2())
1005 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1005 ↛ 1006line 1005 didn't jump to line 1006, because the condition on line 1005 was never true
1006 from impacket.dcerpc.v5 import nrpc
1007 auth = nrpc.getSSPType1(self.__username[:-1], self.__domain, signingRequired=True)
1008 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1008 ↛ 1016line 1008 didn't jump to line 1016, because the condition on line 1008 was never false
1009 self.__cipher, self.__sessionKey, auth = kerberosv5.getKerberosType1(self.__username, self.__password,
1010 self.__domain, self.__lmhash,
1011 self.__nthash, self.__aesKey,
1012 self.__TGT, self.__TGS,
1013 self._transport.getRemoteName(),
1014 self._transport.get_kdcHost())
1015 else:
1016 raise DCERPCException('Unsupported auth_type 0x%x' % self.__auth_type)
1018 sec_trailer = SEC_TRAILER()
1019 sec_trailer['auth_type'] = self.__auth_type
1020 sec_trailer['auth_level'] = self.__auth_level
1021 sec_trailer['auth_ctx_id'] = self._ctx + 79231
1023 pad = (4 - (len(packet.get_packet()) % 4)) % 4
1024 if pad != 0: 1024 ↛ 1025line 1024 didn't jump to line 1025, because the condition on line 1024 was never true
1025 packet['pduData'] += b'\xFF'*pad
1026 sec_trailer['auth_pad_len']=pad
1028 packet['sec_trailer'] = sec_trailer
1029 packet['auth_data'] = auth
1031 self._transport.send(packet.get_packet())
1033 s = self._transport.recv()
1035 if s != 0: 1035 ↛ 1038line 1035 didn't jump to line 1038, because the condition on line 1035 was never false
1036 resp = MSRPCHeader(s)
1037 else:
1038 return 0 #mmm why not None?
1040 if resp['type'] == MSRPC_BINDACK or resp['type'] == MSRPC_ALTERCTX_R: 1040 ↛ 1042line 1040 didn't jump to line 1042, because the condition on line 1040 was never false
1041 bindResp = MSRPCBindAck(resp.getData())
1042 elif resp['type'] == MSRPC_BINDNAK or resp['type'] == MSRPC_FAULT:
1043 if resp['type'] == MSRPC_FAULT:
1044 resp = MSRPCRespHeader(resp.getData())
1045 status_code = unpack('<L', resp['pduData'][:4])[0]
1046 else:
1047 resp = MSRPCBindNak(resp['pduData'])
1048 status_code = resp['RejectedReason']
1049 if status_code in rpc_status_codes:
1050 raise DCERPCException(error_code = status_code)
1051 elif status_code in rpc_provider_reason:
1052 raise DCERPCException("Bind context rejected: %s" % rpc_provider_reason[status_code])
1053 else:
1054 raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code)
1055 else:
1056 raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type'])
1058 # check ack results for each context, except for the bogus ones
1059 for ctx in range(bogus_binds+1,bindResp['ctx_num']+1):
1060 ctxItems = bindResp.getCtxItem(ctx)
1061 if ctxItems['Result'] != 0: 1061 ↛ 1062line 1061 didn't jump to line 1062, because the condition on line 1061 was never true
1062 msg = "Bind context %d rejected: " % ctx
1063 msg += rpc_cont_def_result.get(ctxItems['Result'], 'Unknown DCE RPC context result code: %.4x' % ctxItems['Result'])
1064 msg += "; "
1065 reason = bindResp.getCtxItem(ctx)['Reason']
1066 msg += rpc_provider_reason.get(reason, 'Unknown reason code: %.4x' % reason)
1067 if (ctxItems['Result'], reason) == (2, 1): # provider_rejection, abstract syntax not supported
1068 msg += " (this usually means the interface isn't listening on the given endpoint)"
1069 raise DCERPCException(msg)
1071 # Save the transfer syntax for later use
1072 self.transfer_syntax = ctxItems['TransferSyntax']
1074 # The received transmit size becomes the client's receive size, and the received receive size becomes the client's transmit size.
1075 self.__max_xmit_size = bindResp['max_rfrag']
1077 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:
1078 if self.__auth_type == RPC_C_AUTHN_WINNT:
1079 response, self.__sessionKey = ntlm.getNTLMSSPType3(auth, bindResp['auth_data'], self.__username,
1080 self.__password, self.__domain, self.__lmhash,
1081 self.__nthash,
1082 use_ntlmv2=self._transport.doesSupportNTLMv2())
1083 self.__flags = response['flags']
1084 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1084 ↛ 1085line 1084 didn't jump to line 1085, because the condition on line 1084 was never true
1085 response = None
1086 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1086 ↛ 1091line 1086 didn't jump to line 1091, because the condition on line 1086 was never false
1087 self.__cipher, self.__sessionKey, response = kerberosv5.getKerberosType3(self.__cipher,
1088 self.__sessionKey,
1089 bindResp['auth_data'])
1091 self.__sequence = 0
1093 if self.__auth_level in (RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY): 1093 ↛ 1120line 1093 didn't jump to line 1120, because the condition on line 1093 was never false
1094 if self.__auth_type == RPC_C_AUTHN_WINNT:
1095 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1095 ↛ 1107line 1095 didn't jump to line 1107, because the condition on line 1095 was never false
1096 self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, self.__sessionKey)
1097 self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, self.__sessionKey,b"Server")
1098 self.__clientSealingKey = ntlm.SEALKEY(self.__flags, self.__sessionKey)
1099 self.__serverSealingKey = ntlm.SEALKEY(self.__flags, self.__sessionKey,b"Server")
1100 # Preparing the keys handle states
1101 cipher3 = ARC4.new(self.__clientSealingKey)
1102 self.__clientSealingHandle = cipher3.encrypt
1103 cipher4 = ARC4.new(self.__serverSealingKey)
1104 self.__serverSealingHandle = cipher4.encrypt
1105 else:
1106 # Same key for everything
1107 self.__clientSigningKey = self.__sessionKey
1108 self.__serverSigningKey = self.__sessionKey
1109 self.__clientSealingKey = self.__sessionKey
1110 self.__serverSealingKey = self.__sessionKey
1111 cipher = ARC4.new(self.__clientSigningKey)
1112 self.__clientSealingHandle = cipher.encrypt
1113 self.__serverSealingHandle = cipher.encrypt
1114 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1114 ↛ 1115line 1114 didn't jump to line 1115, because the condition on line 1114 was never true
1115 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
1116 self.__confounder = b''
1117 else:
1118 self.__confounder = b'12345678'
1120 sec_trailer = SEC_TRAILER()
1121 sec_trailer['auth_type'] = self.__auth_type
1122 sec_trailer['auth_level'] = self.__auth_level
1123 sec_trailer['auth_ctx_id'] = self._ctx + 79231
1125 if response is not None: 1125 ↛ 1153line 1125 didn't jump to line 1153, because the condition on line 1125 was never false
1126 if self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
1127 alter_ctx = MSRPCHeader()
1128 alter_ctx['type'] = MSRPC_ALTERCTX
1129 alter_ctx['pduData'] = bind.getData()
1130 alter_ctx['sec_trailer'] = sec_trailer
1131 alter_ctx['auth_data'] = response
1132 self._transport.send(alter_ctx.get_packet(), forceWriteAndx = 1)
1133 self.__gss = gssapi.GSSAPI(self.__cipher)
1134 self.__sequence = 0
1135 self.recv()
1136 self.__sequence = 0
1137 else:
1138 auth3 = MSRPCHeader()
1139 auth3['type'] = MSRPC_AUTH3
1140 # pad (4 bytes): Can be set to any arbitrary value when set and MUST be
1141 # ignored on receipt. The pad field MUST be immediately followed by a
1142 # sec_trailer structure whose layout, location, and alignment are as
1143 # specified in section 2.2.2.11
1144 auth3['pduData'] = b' '
1145 auth3['sec_trailer'] = sec_trailer
1146 auth3['auth_data'] = response.getData()
1148 # Use the same call_id
1149 self.__callid = resp['call_id']
1150 auth3['call_id'] = self.__callid
1151 self._transport.send(auth3.get_packet(), forceWriteAndx = 1)
1153 self.__callid += 1
1155 return resp # means packet is signed, if verifier is wrong it fails
1157 def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0):
1158 rpc_packet['ctx_id'] = self._ctx
1159 rpc_packet['sec_trailer'] = b''
1160 rpc_packet['auth_data'] = b''
1162 if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]:
1163 # Dummy verifier, just for the calculations
1164 sec_trailer = SEC_TRAILER()
1165 sec_trailer['auth_type'] = self.__auth_type
1166 sec_trailer['auth_level'] = self.__auth_level
1167 sec_trailer['auth_pad_len'] = 0
1168 sec_trailer['auth_ctx_id'] = self._ctx + 79231
1170 pad = (4 - (len(rpc_packet.get_packet()) % 4)) % 4
1171 if pad != 0:
1172 rpc_packet['pduData'] += b'\xBB'*pad
1173 sec_trailer['auth_pad_len']=pad
1175 rpc_packet['sec_trailer'] = sec_trailer.getData()
1176 rpc_packet['auth_data'] = b' '*16
1178 plain_data = rpc_packet['pduData']
1179 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
1180 if self.__auth_type == RPC_C_AUTHN_WINNT:
1181 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1181 ↛ 1192line 1181 didn't jump to line 1192, because the condition on line 1181 was never false
1182 # When NTLM2 is on, we sign the whole pdu, but encrypt just
1183 # the data, not the dcerpc header. Weird..
1184 sealedMessage, signature = ntlm.SEAL(self.__flags,
1185 self.__clientSigningKey,
1186 self.__clientSealingKey,
1187 rpc_packet.get_packet()[:-16],
1188 plain_data,
1189 self.__sequence,
1190 self.__clientSealingHandle)
1191 else:
1192 sealedMessage, signature = ntlm.SEAL(self.__flags,
1193 self.__clientSigningKey,
1194 self.__clientSealingKey,
1195 plain_data,
1196 plain_data,
1197 self.__sequence,
1198 self.__clientSealingHandle)
1199 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1199 ↛ 1200line 1199 didn't jump to line 1200, because the condition on line 1199 was never true
1200 from impacket.dcerpc.v5 import nrpc
1201 sealedMessage, signature = nrpc.SEAL(plain_data, self.__confounder, self.__sequence, self.__sessionKey, False)
1202 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1202 ↛ 1205line 1202 didn't jump to line 1205, because the condition on line 1202 was never false
1203 sealedMessage, signature = self.__gss.GSS_Wrap(self.__sessionKey, plain_data, self.__sequence)
1205 rpc_packet['pduData'] = sealedMessage
1206 elif self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 1206 ↛ 1232line 1206 didn't jump to line 1232, because the condition on line 1206 was never false
1207 if self.__auth_type == RPC_C_AUTHN_WINNT:
1208 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1208 ↛ 1217line 1208 didn't jump to line 1217, because the condition on line 1208 was never false
1209 # Interesting thing.. with NTLM2, what is is signed is the
1210 # whole PDU, not just the data
1211 signature = ntlm.SIGN(self.__flags,
1212 self.__clientSigningKey,
1213 rpc_packet.get_packet()[:-16],
1214 self.__sequence,
1215 self.__clientSealingHandle)
1216 else:
1217 signature = ntlm.SIGN(self.__flags,
1218 self.__clientSigningKey,
1219 plain_data,
1220 self.__sequence,
1221 self.__clientSealingHandle)
1222 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1222 ↛ 1223line 1222 didn't jump to line 1223, because the condition on line 1222 was never true
1223 from impacket.dcerpc.v5 import nrpc
1224 signature = nrpc.SIGN(plain_data,
1225 self.__confounder,
1226 self.__sequence,
1227 self.__sessionKey,
1228 False)
1229 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1229 ↛ 1232line 1229 didn't jump to line 1232, because the condition on line 1229 was never false
1230 signature = self.__gss.GSS_GetMIC(self.__sessionKey, plain_data, self.__sequence)
1232 rpc_packet['sec_trailer'] = sec_trailer.getData()
1233 rpc_packet['auth_data'] = signature
1235 self.__sequence += 1
1237 self._transport.send(rpc_packet.get_packet(), forceWriteAndx = forceWriteAndx, forceRecv = forceRecv)
1239 def send(self, data):
1240 if isinstance(data, MSRPCHeader) is not True: 1240 ↛ 1242line 1240 didn't jump to line 1242, because the condition on line 1240 was never true
1241 # Must be an Impacket, transform to structure
1242 data = DCERPC_RawCall(data.OP_NUM, data.get_packet())
1244 try:
1245 if data['uuid'] != b'':
1246 data['flags'] |= PFC_OBJECT_UUID
1247 except:
1248 # Structure doesn't have uuid
1249 pass
1250 data['ctx_id'] = self._ctx
1251 data['call_id'] = self.__callid
1252 data['alloc_hint'] = len(data['pduData'])
1253 # We should fragment PDUs if:
1254 # 1) Payload exceeds __max_xmit_size received during BIND response
1255 # 2) We'e explicitly fragmenting packets with lower values
1256 should_fragment = False
1258 # Let's decide what will drive fragmentation for this request
1259 if self._max_user_frag > 0:
1260 # User set a frag size, let's compare it with the max transmit size agreed when binding the interface
1261 fragment_size = min(self._max_user_frag, self.__max_xmit_size)
1262 else:
1263 fragment_size = self.__max_xmit_size
1265 # Sanity check. Fragmentation can't be too low, otherwise sec_trailer won't fit
1267 if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]:
1268 if fragment_size <= 8:
1269 # Minimum pdu fragment size is 8, important when doing PKT_INTEGRITY/PRIVACY. We need a minimum size of 8
1270 # (Kerberos)
1271 fragment_size = 8
1273 # ToDo: Better calculate the size needed. Now I'm setting a number that surely is enough for Kerberos and NTLM
1274 # ToDo: trailers, both for INTEGRITY and PRIVACY. This means we're not truly honoring the user's frag request.
1275 if len(data['pduData']) + 128 > fragment_size:
1276 should_fragment = True
1277 if fragment_size+128 > self.__max_xmit_size:
1278 fragment_size = self.__max_xmit_size - 128
1280 if should_fragment:
1281 packet = data['pduData']
1282 offset = 0
1284 while 1:
1285 toSend = packet[offset:offset+fragment_size]
1286 if not toSend:
1287 break
1288 if offset == 0:
1289 data['flags'] |= PFC_FIRST_FRAG
1290 else:
1291 data['flags'] &= (~PFC_FIRST_FRAG)
1292 offset += len(toSend)
1293 if offset >= len(packet):
1294 data['flags'] |= PFC_LAST_FRAG
1295 else:
1296 data['flags'] &= (~PFC_LAST_FRAG)
1297 data['pduData'] = toSend
1298 self._transport_send(data, forceWriteAndx = 1, forceRecv =data['flags'] & PFC_LAST_FRAG)
1299 else:
1300 self._transport_send(data)
1301 self.__callid += 1
1303 def recv(self):
1304 finished = False
1305 forceRecv = 0
1306 retAnswer = b''
1307 while not finished:
1308 # At least give me the MSRPCRespHeader, especially important for
1309 # TCP/UDP Transports
1310 response_data = self._transport.recv(forceRecv, count=MSRPCRespHeader._SIZE)
1311 response_header = MSRPCRespHeader(response_data)
1312 # Ok, there might be situation, especially with large packets, that
1313 # the transport layer didn't send us the full packet's contents
1314 # So we gotta check we received it all
1315 while len(response_data) < response_header['frag_len']:
1316 response_data += self._transport.recv(forceRecv, count=(response_header['frag_len']-len(response_data)))
1318 off = response_header.get_header_size()
1320 if response_header['type'] == MSRPC_FAULT and response_header['frag_len'] >= off+4:
1321 status_code = unpack("<L",response_data[off:off+4])[0]
1322 if status_code in rpc_status_codes: 1322 ↛ 1324line 1322 didn't jump to line 1324, because the condition on line 1322 was never false
1323 raise DCERPCException(rpc_status_codes[status_code])
1324 elif status_code & 0xffff in rpc_status_codes:
1325 raise DCERPCException(rpc_status_codes[status_code & 0xffff])
1326 else:
1327 if status_code in hresult_errors.ERROR_MESSAGES:
1328 error_msg_short = hresult_errors.ERROR_MESSAGES[status_code][0]
1329 error_msg_verbose = hresult_errors.ERROR_MESSAGES[status_code][1]
1330 raise DCERPCException('%s - %s' % (error_msg_short, error_msg_verbose))
1331 else:
1332 raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code)
1334 if response_header['flags'] & PFC_LAST_FRAG:
1335 # No need to reassembly DCERPC
1336 finished = True
1337 else:
1338 # Forcing Read Recv, we need more packets!
1339 forceRecv = 1
1341 answer = response_data[off:]
1342 auth_len = response_header['auth_len']
1343 if auth_len:
1344 auth_len += 8
1345 auth_data = answer[-auth_len:]
1346 sec_trailer = SEC_TRAILER(data = auth_data)
1347 answer = answer[:-auth_len]
1349 if sec_trailer['auth_level'] == RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
1350 if self.__auth_type == RPC_C_AUTHN_WINNT:
1351 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1351 ↛ 1362line 1351 didn't jump to line 1362, because the condition on line 1351 was never false
1352 # TODO: FIX THIS, it's not calculating the signature well
1353 # Since I'm not testing it we don't care... yet
1354 answer, signature = ntlm.SEAL(self.__flags,
1355 self.__serverSigningKey,
1356 self.__serverSealingKey,
1357 answer,
1358 answer,
1359 self.__sequence,
1360 self.__serverSealingHandle)
1361 else:
1362 answer, signature = ntlm.SEAL(self.__flags,
1363 self.__serverSigningKey,
1364 self.__serverSealingKey,
1365 answer,
1366 answer,
1367 self.__sequence,
1368 self.__serverSealingHandle)
1369 self.__sequence += 1
1370 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1370 ↛ 1371line 1370 didn't jump to line 1371, because the condition on line 1370 was never true
1371 from impacket.dcerpc.v5 import nrpc
1372 answer, cfounder = nrpc.UNSEAL(answer,
1373 auth_data[len(sec_trailer):],
1374 self.__sessionKey,
1375 False)
1376 self.__sequence += 1
1377 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE: 1377 ↛ 1415line 1377 didn't jump to line 1415, because the condition on line 1377 was never false
1378 if self.__sequence > 0:
1379 answer, cfounder = self.__gss.GSS_Unwrap(self.__sessionKey, answer, self.__sequence,
1380 direction='init', authData=auth_data)
1382 elif sec_trailer['auth_level'] == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 1382 ↛ 1415line 1382 didn't jump to line 1415, because the condition on line 1382 was never false
1383 if self.__auth_type == RPC_C_AUTHN_WINNT:
1384 ntlmssp = auth_data[12:]
1385 if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 1385 ↛ 1392line 1385 didn't jump to line 1392, because the condition on line 1385 was never false
1386 signature = ntlm.SIGN(self.__flags,
1387 self.__serverSigningKey,
1388 answer,
1389 self.__sequence,
1390 self.__serverSealingHandle)
1391 else:
1392 signature = ntlm.SIGN(self.__flags,
1393 self.__serverSigningKey,
1394 ntlmssp,
1395 self.__sequence,
1396 self.__serverSealingHandle)
1397 # Yes.. NTLM2 doesn't increment sequence when receiving
1398 # the packet :P
1399 self.__sequence += 1
1400 elif self.__auth_type == RPC_C_AUTHN_NETLOGON: 1400 ↛ 1401line 1400 didn't jump to line 1401, because the condition on line 1400 was never true
1401 from impacket.dcerpc.v5 import nrpc
1402 ntlmssp = auth_data[12:]
1403 signature = nrpc.SIGN(ntlmssp,
1404 self.__confounder,
1405 self.__sequence,
1406 self.__sessionKey,
1407 False)
1408 self.__sequence += 1
1409 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
1410 # Do NOT increment the sequence number when Signing Kerberos
1411 #self.__sequence += 1
1412 pass
1415 if sec_trailer['auth_pad_len']:
1416 answer = answer[:-sec_trailer['auth_pad_len']]
1418 retAnswer += answer
1419 return retAnswer
1421 def alter_ctx(self, newUID, bogus_binds = 0):
1422 answer = self.__class__(self._transport)
1424 answer.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash,
1425 self.__aesKey, self.__TGT, self.__TGS)
1426 answer.set_auth_type(self.__auth_type)
1427 answer.set_auth_level(self.__auth_level)
1429 answer.set_ctx_id(self._ctx+1)
1430 answer.__callid = self.__callid
1431 answer.bind(newUID, alter = 1, bogus_binds = bogus_binds, transfer_syntax = bin_to_uuidtup(self.transfer_syntax))
1432 return answer
1434class DCERPC_RawCall(MSRPCRequestHeader):
1435 def __init__(self, op_num, data = b'', uuid=None):
1436 MSRPCRequestHeader.__init__(self)
1437 self['op_num'] = op_num
1438 self['pduData'] = data
1439 if uuid is not None:
1440 self['flags'] |= PFC_OBJECT_UUID
1441 self['uuid'] = uuid
1443 def setData(self, data):
1444 self['pduData'] = data
1446# 2.2.6 Type Serialization Version 1
1447class CommonHeader(NDRSTRUCT):
1448 structure = (
1449 ('Version', UCHAR),
1450 ('Endianness', UCHAR),
1451 ('CommonHeaderLength', USHORT),
1452 ('Filler', ULONG),
1453 )
1454 def __init__(self, data = None,isNDR64 = False):
1455 NDRSTRUCT.__init__(self, data, isNDR64)
1456 if data is None: 1456 ↛ exitline 1456 didn't return from function '__init__', because the condition on line 1456 was never false
1457 self['Version'] = 1
1458 self['Endianness'] = 0x10
1459 self['CommonHeaderLength'] = 8
1460 self['Filler'] = 0xcccccccc
1462class PrivateHeader(NDRSTRUCT):
1463 structure = (
1464 ('ObjectBufferLength', ULONG),
1465 ('Filler', ULONG),
1466 )
1467 def __init__(self, data = None,isNDR64 = False):
1468 NDRSTRUCT.__init__(self, data, isNDR64)
1469 if data is None: 1469 ↛ exitline 1469 didn't return from function '__init__', because the condition on line 1469 was never false
1470 self['Filler'] = 0xcccccccc
1472class TypeSerialization1(NDRSTRUCT):
1473 commonHdr = (
1474 ('CommonHeader', CommonHeader),
1475 ('PrivateHeader', PrivateHeader),
1476 )
1477 def getData(self, soFar = 0):
1478 self['PrivateHeader']['ObjectBufferLength'] = len(NDRSTRUCT.getData(self, soFar)) + len(
1479 NDRSTRUCT.getDataReferents(self, soFar)) - len(self['CommonHeader']) - len(self['PrivateHeader'])
1480 return NDRSTRUCT.getData(self, soFar)
1482class DCERPCServer(Thread):
1483 """
1484 A minimalistic DCERPC Server, mainly used by the smbserver, for now. Might be useful
1485 for other purposes in the future, but we should do it way stronger.
1486 If you want to implement a DCE Interface Server, use this class as the base class
1487 """
1488 def __init__(self):
1489 Thread.__init__(self)
1490 self._listenPort = 0
1491 self._listenAddress = '127.0.0.1'
1492 self._listenUUIDS = {}
1493 self._boundUUID = b''
1494 self._sock = None
1495 self._clientSock = None
1496 self._callid = 1
1497 self._max_frag = None
1498 self._max_xmit_size = 4280
1499 self.__log = LOG
1500 self._sock = socket.socket()
1501 self._sock.bind((self._listenAddress,self._listenPort))
1503 def log(self, msg, level=logging.INFO):
1504 self.__log.log(level,msg)
1506 def addCallbacks(self, ifaceUUID, secondaryAddr, callbacks):
1507 """
1508 adds a call back to a UUID/opnum call
1510 :param uuid ifaceUUID: the interface UUID
1511 :param string secondaryAddr: the secondary address to answer as part of the bind request (e.g. \\\\PIPE\\\\srvsvc)
1512 :param dict callbacks: the callbacks for each opnum. Format is [opnum] = callback
1513 """
1514 self._listenUUIDS[uuidtup_to_bin(ifaceUUID)] = {}
1515 self._listenUUIDS[uuidtup_to_bin(ifaceUUID)]['SecondaryAddr'] = secondaryAddr
1516 self._listenUUIDS[uuidtup_to_bin(ifaceUUID)]['CallBacks'] = callbacks
1517 self.log("Callback added for UUID %s V:%s" % ifaceUUID)
1519 def setListenPort(self, portNum):
1520 self._listenPort = portNum
1521 self._sock = socket.socket()
1522 self._sock.bind((self._listenAddress,self._listenPort))
1524 def getListenPort(self):
1525 return self._sock.getsockname()[1]
1527 def recv(self):
1528 finished = False
1529 retAnswer = b''
1530 response_data = b''
1531 while not finished:
1532 # At least give me the MSRPCRespHeader, especially important for TCP/UDP Transports
1533 response_data = self._clientSock.recv(MSRPCRespHeader._SIZE)
1534 # No data?, connection might have closed
1535 if response_data == b'':
1536 return None
1537 response_header = MSRPCRespHeader(response_data)
1538 # Ok, there might be situation, especially with large packets,
1539 # that the transport layer didn't send us the full packet's contents
1540 # So we gotta check we received it all
1541 while len(response_data) < response_header['frag_len']:
1542 response_data += self._clientSock.recv(response_header['frag_len']-len(response_data))
1543 response_header = MSRPCRespHeader(response_data)
1544 if response_header['flags'] & PFC_LAST_FRAG:
1545 # No need to reassembly DCERPC
1546 finished = True
1547 answer = response_header['pduData']
1548 auth_len = response_header['auth_len']
1549 if auth_len:
1550 auth_len += 8
1551 auth_data = answer[-auth_len:]
1552 sec_trailer = SEC_TRAILER(data = auth_data)
1553 answer = answer[:-auth_len]
1554 if sec_trailer['auth_pad_len']:
1555 answer = answer[:-sec_trailer['auth_pad_len']]
1557 retAnswer += answer
1558 return response_data
1560 def run(self):
1561 self._sock.listen(10)
1562 while True:
1563 self._clientSock, address = self._sock.accept()
1564 try:
1565 while True:
1566 data = self.recv()
1567 if data is None:
1568 # No data.. connection closed
1569 break
1570 answer = self.processRequest(data)
1571 if answer is not None:
1572 self.send(answer)
1573 except Exception:
1574 #import traceback
1575 #traceback.print_exc()
1576 pass
1577 self._clientSock.close()
1579 def send(self, data):
1580 max_frag = self._max_frag
1581 if len(data['pduData']) > self._max_xmit_size - 32:
1582 max_frag = self._max_xmit_size - 32 # XXX: 32 is a safe margin for auth data
1584 if self._max_frag:
1585 max_frag = min(max_frag, self._max_frag)
1586 if max_frag and len(data['pduData']) > 0:
1587 packet = data['pduData']
1588 offset = 0
1589 while 1:
1590 toSend = packet[offset:offset+max_frag]
1591 if not toSend:
1592 break
1593 flags = 0
1594 if offset == 0:
1595 flags |= PFC_FIRST_FRAG
1596 offset += len(toSend)
1597 if offset == len(packet):
1598 flags |= PFC_LAST_FRAG
1599 data['flags'] = flags
1600 data['pduData'] = toSend
1601 self._clientSock.send(data.get_packet())
1602 else:
1603 self._clientSock.send(data.get_packet())
1604 self._callid += 1
1606 def bind(self,packet, bind):
1607 # Standard NDR Representation
1608 NDRSyntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
1609 resp = MSRPCBindAck()
1611 resp['type'] = MSRPC_BINDACK
1612 resp['flags'] = packet['flags']
1613 resp['frag_len'] = 0
1614 resp['auth_len'] = 0
1615 resp['auth_data'] = b''
1616 resp['call_id'] = packet['call_id']
1617 resp['max_tfrag'] = bind['max_tfrag']
1618 resp['max_rfrag'] = bind['max_rfrag']
1619 resp['assoc_group'] = 0x1234
1620 resp['ctx_num'] = 0
1622 data = bind['ctx_items']
1623 ctx_items = b''
1624 resp['SecondaryAddrLen'] = 0
1625 for i in range(bind['ctx_num']):
1626 result = MSRPC_CONT_RESULT_USER_REJECT
1627 item = CtxItem(data)
1628 data = data[len(item):]
1630 # First we check the Transfer Syntax is NDR32, what we support
1631 if item['TransferSyntax'] == uuidtup_to_bin(NDRSyntax):
1632 # Now Check if the interface is what we listen
1633 reason = 1 # Default, Abstract Syntax not supported
1634 for j in self._listenUUIDS:
1635 if item['AbstractSyntax'] == j:
1636 # Match, we accept the bind request
1637 resp['SecondaryAddr'] = self._listenUUIDS[item['AbstractSyntax']]['SecondaryAddr']
1638 resp['SecondaryAddrLen'] = len(resp['SecondaryAddr'])+1
1639 reason = 0
1640 self._boundUUID = j
1641 else:
1642 # Fail the bind request for this context
1643 reason = 2 # Transfer Syntax not supported
1644 if reason == 0:
1645 result = MSRPC_CONT_RESULT_ACCEPT
1646 if reason == 1:
1647 LOG.error('Bind request for an unsupported interface %s' % bin_to_uuidtup(item['AbstractSyntax']))
1649 resp['ctx_num'] += 1
1650 itemResult = CtxItemResult()
1651 itemResult['Result'] = result
1652 itemResult['Reason'] = reason
1653 itemResult['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)
1654 ctx_items += itemResult.getData()
1656 resp['Pad'] ='A'*((4-((resp["SecondaryAddrLen"]+MSRPCBindAck._SIZE) % 4))%4)
1657 resp['ctx_items'] = ctx_items
1658 resp['frag_len'] = len(resp.getData())
1660 self._clientSock.send(resp.getData())
1661 return None
1663 def processRequest(self,data):
1664 packet = MSRPCHeader(data)
1665 if packet['type'] == MSRPC_BIND:
1666 bind = MSRPCBind(packet['pduData'])
1667 self.bind(packet, bind)
1668 packet = None
1669 elif packet['type'] == MSRPC_REQUEST:
1670 request = MSRPCRequestHeader(data)
1671 response = MSRPCRespHeader(data)
1672 response['type'] = MSRPC_RESPONSE
1673 # Serve the opnum requested, if not, fails
1674 if request['op_num'] in self._listenUUIDS[self._boundUUID]['CallBacks']:
1675 # Call the function
1676 returnData = self._listenUUIDS[self._boundUUID]['CallBacks'][request['op_num']](request['pduData'])
1677 response['pduData'] = returnData
1678 else:
1679 LOG.error('Unsupported DCERPC opnum %d called for interface %s' % (request['op_num'], bin_to_uuidtup(self._boundUUID)))
1680 response['type'] = MSRPC_FAULT
1681 response['pduData'] = pack('<L',0x000006E4)
1682 response['frag_len'] = len(response)
1683 return response
1684 else:
1685 # Defaults to a fault
1686 packet = MSRPCRespHeader(data)
1687 packet['type'] = MSRPC_FAULT
1689 return packet