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

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

## 784 statements

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.

2#

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

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

5# for more information.

6#

7# Description:

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

9#

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

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

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

13#

14# ToDo:

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

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

17# more SSP (e.g. NETLOGON)

18#

19

20 import logging

21 import socket

22 import sys

23 from binascii import unhexlify

24 from Cryptodome.Cipher import ARC4

25

26 from impacket import ntlm, LOG

27 from impacket.structure import Structure,pack,unpack

28 from impacket.krb5 import kerberosv5, gssapi

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

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

31 from impacket.dcerpc.v5.ndr import NDRSTRUCT

32 from impacket import hresult_errors

33 from threading import Thread

34

35# MS/RPC Constants

36 MSRPC_REQUEST = 0x00

37 MSRPC_PING = 0x01

38 MSRPC_RESPONSE = 0x02

39 MSRPC_FAULT = 0x03

40 MSRPC_WORKING = 0x04

41 MSRPC_NOCALL = 0x05

42 MSRPC_REJECT = 0x06

43 MSRPC_ACK = 0x07

44 MSRPC_CL_CANCEL = 0x08

45 MSRPC_FACK = 0x09

46 MSRPC_CANCELACK = 0x0A

47 MSRPC_BIND = 0x0B

48 MSRPC_BINDACK = 0x0C

49 MSRPC_BINDNAK = 0x0D

50 MSRPC_ALTERCTX = 0x0E

51 MSRPC_ALTERCTX_R= 0x0F

52 MSRPC_AUTH3 = 0x10

53 MSRPC_SHUTDOWN = 0x11

54 MSRPC_CO_CANCEL = 0x12

55 MSRPC_ORPHANED = 0x13

56 MSRPC_RTS = 0x14

57

58# MS/RPC Packet Flags

59 PFC_FIRST_FRAG = 0x01

60 PFC_LAST_FRAG = 0x02

61

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

63# alter_context_resp, this flag MUST be interpreted as PFC_SUPPORT_HEADER_SIGN

64 MSRPC_SUPPORT_SIGN = 0x04

65

66#For the

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

68 MSRPC_PENDING_CANCEL= 0x04

69

70 PFC_RESERVED_1 = 0x08

71 PFC_CONC_MPX = 0x10

72 PFC_DID_NOT_EXECUTE = 0x20

73 PFC_MAYBE = 0x40

74 PFC_OBJECT_UUID = 0x80

75

76# Auth Types - Security Providers

77 RPC_C_AUTHN_NONE = 0x00

78 RPC_C_AUTHN_GSS_NEGOTIATE = 0x09

79 RPC_C_AUTHN_WINNT = 0x0A

80 RPC_C_AUTHN_GSS_SCHANNEL = 0x0E

81 RPC_C_AUTHN_GSS_KERBEROS = 0x10

82 RPC_C_AUTHN_NETLOGON = 0x44

83 RPC_C_AUTHN_DEFAULT = 0xFF

84

85# Auth Levels

86 RPC_C_AUTHN_LEVEL_NONE = 1

87 RPC_C_AUTHN_LEVEL_CONNECT = 2

88 RPC_C_AUTHN_LEVEL_CALL = 3

89 RPC_C_AUTHN_LEVEL_PKT = 4

90 RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5

91 RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6

92

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

94 rpc_provider_reason = {

95 0 : 'reason_not_specified',

96 1 : 'abstract_syntax_not_supported',

97 2 : 'proposed_transfer_syntaxes_not_supported',

98 3 : 'local_limit_exceeded',

99 4 : 'protocol_version_not_specified',

100 8 : 'authentication_type_not_recognized',

101 9 : 'invalid_checksum'

102}

103

104 MSRPC_CONT_RESULT_ACCEPT = 0

105 MSRPC_CONT_RESULT_USER_REJECT = 1

106 MSRPC_CONT_RESULT_PROV_REJECT = 2

107

108#Results of a presentation context negotiation

109 rpc_cont_def_result = {

110 0 : 'acceptance',

111 1 : 'user_rejection',

112 2 : 'provider_rejection'

113}

114

115#status codes, references:

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

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

118#winerror.h

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

120

121 rpc_status_codes = {

122 0x00000005 : 'rpc_s_access_denied',

123 0x00000008 : 'Authentication type not recognized',

124 0x000006D8 : 'rpc_fault_cant_perform',

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

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

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

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

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

130 0x1C010003 : 'nca_s_unk_if', # unknown interface

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

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

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

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

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

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

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

138 0x1C000001 : 'nca_s_fault_int_div_by_zero',

139 0x1C000002 : 'nca_s_fault_addr_error ',

140 0x1C000003 : 'nca_s_fault_fp_div_zero',

141 0x1C000004 : 'nca_s_fault_fp_underflow',

142 0x1C000005 : 'nca_s_fault_fp_overflow',

143 0x1C000006 : 'nca_s_fault_invalid_tag',

144 0x1C000007 : 'nca_s_fault_invalid_bound ',

145 0x1C000008 : 'nca_s_rpc_version_mismatch',

146 0x1C000009 : 'nca_s_unspec_reject ',

147 0x1C00000A : 'nca_s_bad_actid',

148 0x1C00000B : 'nca_s_who_are_you_failed',

149 0x1C00000C : 'nca_s_manager_not_entered ',

150 0x1C00000D : 'nca_s_fault_cancel',

151 0x1C00000E : 'nca_s_fault_ill_inst',

152 0x1C00000F : 'nca_s_fault_fp_error',

153 0x1C000010 : 'nca_s_fault_int_overflow',

154 0x1C000012 : 'nca_s_fault_unspec',

155 0x1C000013 : 'nca_s_fault_remote_comm_failure ',

156 0x1C000014 : 'nca_s_fault_pipe_empty ',

157 0x1C000015 : 'nca_s_fault_pipe_closed',

158 0x1C000016 : 'nca_s_fault_pipe_order ',

159 0x1C000017 : 'nca_s_fault_pipe_discipline',

160 0x1C000018 : 'nca_s_fault_pipe_comm_error',

161 0x1C000019 : 'nca_s_fault_pipe_memory',

162 0x1C00001A : 'nca_s_fault_context_mismatch ',

163 0x1C00001B : 'nca_s_fault_remote_no_memory ',

164 0x1C00001C : 'nca_s_invalid_pres_context_id',

165 0x1C00001D : 'nca_s_unsupported_authn_level',

166 0x1C00001F : 'nca_s_invalid_checksum ',

167 0x1C000020 : 'nca_s_invalid_crc',

168 0x1C000021 : 'nca_s_fault_user_defined',

169 0x1C000022 : 'nca_s_fault_tx_open_failed',

170 0x1C000023 : 'nca_s_fault_codeset_conv_error',

171 0x1C000024 : 'nca_s_fault_object_not_found ',

172 0x1C000025 : 'nca_s_fault_no_client_stub',

173 0x16c9a000 : "rpc_s_mod",

174 0x16c9a001 : "rpc_s_op_rng_error",

175 0x16c9a002 : "rpc_s_cant_create_socket",

176 0x16c9a003 : "rpc_s_cant_bind_socket",

177 0x16c9a004 : "rpc_s_not_in_call",

178 0x16c9a005 : "rpc_s_no_port",

179 0x16c9a006 : "rpc_s_wrong_boot_time",

180 0x16c9a007 : "rpc_s_too_many_sockets",

181 0x16c9a008 : "rpc_s_illegal_register",

182 0x16c9a009 : "rpc_s_cant_recv",

183 0x16c9a00a : "rpc_s_bad_pkt",

184 0x16c9a00b : "rpc_s_unbound_handle",

185 0x16c9a00c : "rpc_s_addr_in_use",

186 0x16c9a00d : "rpc_s_in_args_too_big",

187 0x16c9a00e : "rpc_s_string_too_long",

188 0x16c9a00f : "rpc_s_too_many_objects",

189 0x16c9a010 : "rpc_s_binding_has_no_auth",

190 0x16c9a011 : "rpc_s_unknown_authn_service",

191 0x16c9a012 : "rpc_s_no_memory",

192 0x16c9a013 : "rpc_s_cant_nmalloc",

193 0x16c9a014 : "rpc_s_call_faulted",

194 0x16c9a015 : "rpc_s_call_failed",

195 0x16c9a016 : "rpc_s_comm_failure",

196 0x16c9a017 : "rpc_s_rpcd_comm_failure",

197 0x16c9a018 : "rpc_s_illegal_family_rebind",

198 0x16c9a019 : "rpc_s_invalid_handle",

199 0x16c9a01a : "rpc_s_coding_error",

200 0x16c9a01b : "rpc_s_object_not_found",

201 0x16c9a01c : "rpc_s_cthread_not_found",

202 0x16c9a01d : "rpc_s_invalid_binding",

203 0x16c9a01e : "rpc_s_already_registered",

204 0x16c9a01f : "rpc_s_endpoint_not_found",

205 0x16c9a020 : "rpc_s_invalid_rpc_protseq",

206 0x16c9a021 : "rpc_s_desc_not_registered",

207 0x16c9a022 : "rpc_s_already_listening",

208 0x16c9a023 : "rpc_s_no_protseqs",

209 0x16c9a024 : "rpc_s_no_protseqs_registered",

210 0x16c9a025 : "rpc_s_no_bindings",

211 0x16c9a026 : "rpc_s_max_descs_exceeded",

212 0x16c9a027 : "rpc_s_no_interfaces",

213 0x16c9a028 : "rpc_s_invalid_timeout",

214 0x16c9a029 : "rpc_s_cant_inq_socket",

215 0x16c9a02a : "rpc_s_invalid_naf_id",

216 0x16c9a02b : "rpc_s_inval_net_addr",

217 0x16c9a02c : "rpc_s_unknown_if",

218 0x16c9a02d : "rpc_s_unsupported_type",

219 0x16c9a02e : "rpc_s_invalid_call_opt",

220 0x16c9a02f : "rpc_s_no_fault",

221 0x16c9a030 : "rpc_s_cancel_timeout",

222 0x16c9a031 : "rpc_s_call_cancelled",

223 0x16c9a032 : "rpc_s_invalid_call_handle",

224 0x16c9a033 : "rpc_s_cannot_alloc_assoc",

225 0x16c9a034 : "rpc_s_cannot_connect",

226 0x16c9a035 : "rpc_s_connection_aborted",

227 0x16c9a036 : "rpc_s_connection_closed",

228 0x16c9a037 : "rpc_s_cannot_accept",

229 0x16c9a038 : "rpc_s_assoc_grp_not_found",

230 0x16c9a039 : "rpc_s_stub_interface_error",

231 0x16c9a03a : "rpc_s_invalid_object",

232 0x16c9a03b : "rpc_s_invalid_type",

233 0x16c9a03c : "rpc_s_invalid_if_opnum",

234 0x16c9a03d : "rpc_s_different_server_instance",

235 0x16c9a03e : "rpc_s_protocol_error",

236 0x16c9a03f : "rpc_s_cant_recvmsg",

237 0x16c9a040 : "rpc_s_invalid_string_binding",

238 0x16c9a041 : "rpc_s_connect_timed_out",

239 0x16c9a042 : "rpc_s_connect_rejected",

240 0x16c9a043 : "rpc_s_network_unreachable",

241 0x16c9a044 : "rpc_s_connect_no_resources",

242 0x16c9a045 : "rpc_s_rem_network_shutdown",

243 0x16c9a046 : "rpc_s_too_many_rem_connects",

244 0x16c9a047 : "rpc_s_no_rem_endpoint",

245 0x16c9a048 : "rpc_s_rem_host_down",

246 0x16c9a049 : "rpc_s_host_unreachable",

247 0x16c9a04a : "rpc_s_access_control_info_inv",

248 0x16c9a04b : "rpc_s_loc_connect_aborted",

249 0x16c9a04c : "rpc_s_connect_closed_by_rem",

250 0x16c9a04d : "rpc_s_rem_host_crashed",

251 0x16c9a04e : "rpc_s_invalid_endpoint_format",

252 0x16c9a04f : "rpc_s_unknown_status_code",

253 0x16c9a050 : "rpc_s_unknown_mgr_type",

254 0x16c9a051 : "rpc_s_assoc_creation_failed",

255 0x16c9a052 : "rpc_s_assoc_grp_max_exceeded",

256 0x16c9a053 : "rpc_s_assoc_grp_alloc_failed",

257 0x16c9a054 : "rpc_s_sm_invalid_state",

258 0x16c9a055 : "rpc_s_assoc_req_rejected",

259 0x16c9a056 : "rpc_s_assoc_shutdown",

260 0x16c9a057 : "rpc_s_tsyntaxes_unsupported",

261 0x16c9a058 : "rpc_s_context_id_not_found",

262 0x16c9a059 : "rpc_s_cant_listen_socket",

263 0x16c9a05a : "rpc_s_no_addrs",

264 0x16c9a05b : "rpc_s_cant_getpeername",

265 0x16c9a05c : "rpc_s_cant_get_if_id",

266 0x16c9a05d : "rpc_s_protseq_not_supported",

267 0x16c9a05e : "rpc_s_call_orphaned",

268 0x16c9a05f : "rpc_s_who_are_you_failed",

269 0x16c9a060 : "rpc_s_unknown_reject",

270 0x16c9a061 : "rpc_s_type_already_registered",

271 0x16c9a062 : "rpc_s_stop_listening_disabled",

272 0x16c9a063 : "rpc_s_invalid_arg",

273 0x16c9a064 : "rpc_s_not_supported",

274 0x16c9a065 : "rpc_s_wrong_kind_of_binding",

275 0x16c9a066 : "rpc_s_authn_authz_mismatch",

276 0x16c9a067 : "rpc_s_call_queued",

277 0x16c9a068 : "rpc_s_cannot_set_nodelay",

278 0x16c9a069 : "rpc_s_not_rpc_tower",

279 0x16c9a06a : "rpc_s_invalid_rpc_protid",

280 0x16c9a06b : "rpc_s_invalid_rpc_floor",

281 0x16c9a06c : "rpc_s_call_timeout",

282 0x16c9a06d : "rpc_s_mgmt_op_disallowed",

283 0x16c9a06e : "rpc_s_manager_not_entered",

284 0x16c9a06f : "rpc_s_calls_too_large_for_wk_ep",

285 0x16c9a070 : "rpc_s_server_too_busy",

286 0x16c9a071 : "rpc_s_prot_version_mismatch",

287 0x16c9a072 : "rpc_s_rpc_prot_version_mismatch",

288 0x16c9a073 : "rpc_s_ss_no_import_cursor",

289 0x16c9a074 : "rpc_s_fault_addr_error",

290 0x16c9a075 : "rpc_s_fault_context_mismatch",

291 0x16c9a076 : "rpc_s_fault_fp_div_by_zero",

292 0x16c9a077 : "rpc_s_fault_fp_error",

293 0x16c9a078 : "rpc_s_fault_fp_overflow",

294 0x16c9a079 : "rpc_s_fault_fp_underflow",

295 0x16c9a07a : "rpc_s_fault_ill_inst",

296 0x16c9a07b : "rpc_s_fault_int_div_by_zero",

297 0x16c9a07c : "rpc_s_fault_int_overflow",

298 0x16c9a07d : "rpc_s_fault_invalid_bound",

299 0x16c9a07e : "rpc_s_fault_invalid_tag",

300 0x16c9a07f : "rpc_s_fault_pipe_closed",

301 0x16c9a080 : "rpc_s_fault_pipe_comm_error",

302 0x16c9a081 : "rpc_s_fault_pipe_discipline",

303 0x16c9a082 : "rpc_s_fault_pipe_empty",

304 0x16c9a083 : "rpc_s_fault_pipe_memory",

305 0x16c9a084 : "rpc_s_fault_pipe_order",

306 0x16c9a085 : "rpc_s_fault_remote_comm_failure",

307 0x16c9a086 : "rpc_s_fault_remote_no_memory",

308 0x16c9a087 : "rpc_s_fault_unspec",

309 0x16c9a088 : "uuid_s_bad_version",

310 0x16c9a089 : "uuid_s_socket_failure",

311 0x16c9a08a : "uuid_s_getconf_failure",

312 0x16c9a08b : "uuid_s_no_address",

313 0x16c9a08c : "uuid_s_overrun",

314 0x16c9a08d : "uuid_s_internal_error",

315 0x16c9a08e : "uuid_s_coding_error",

316 0x16c9a08f : "uuid_s_invalid_string_uuid",

317 0x16c9a090 : "uuid_s_no_memory",

318 0x16c9a091 : "rpc_s_no_more_entries",

319 0x16c9a092 : "rpc_s_unknown_ns_error",

320 0x16c9a093 : "rpc_s_name_service_unavailable",

321 0x16c9a094 : "rpc_s_incomplete_name",

322 0x16c9a095 : "rpc_s_group_not_found",

323 0x16c9a096 : "rpc_s_invalid_name_syntax",

324 0x16c9a097 : "rpc_s_no_more_members",

325 0x16c9a098 : "rpc_s_no_more_interfaces",

326 0x16c9a099 : "rpc_s_invalid_name_service",

327 0x16c9a09a : "rpc_s_no_name_mapping",

328 0x16c9a09b : "rpc_s_profile_not_found",

329 0x16c9a09c : "rpc_s_not_found",

330 0x16c9a09d : "rpc_s_no_updates",

331 0x16c9a09e : "rpc_s_update_failed",

332 0x16c9a09f : "rpc_s_no_match_exported",

333 0x16c9a0a0 : "rpc_s_entry_not_found",

334 0x16c9a0a1 : "rpc_s_invalid_inquiry_context",

335 0x16c9a0a2 : "rpc_s_interface_not_found",

336 0x16c9a0a3 : "rpc_s_group_member_not_found",

337 0x16c9a0a4 : "rpc_s_entry_already_exists",

338 0x16c9a0a5 : "rpc_s_nsinit_failure",

339 0x16c9a0a6 : "rpc_s_unsupported_name_syntax",

340 0x16c9a0a7 : "rpc_s_no_more_elements",

341 0x16c9a0a8 : "rpc_s_no_ns_permission",

342 0x16c9a0a9 : "rpc_s_invalid_inquiry_type",

343 0x16c9a0aa : "rpc_s_profile_element_not_found",

344 0x16c9a0ab : "rpc_s_profile_element_replaced",

345 0x16c9a0ac : "rpc_s_import_already_done",

346 0x16c9a0ad : "rpc_s_database_busy",

347 0x16c9a0ae : "rpc_s_invalid_import_context",

348 0x16c9a0af : "rpc_s_uuid_set_not_found",

349 0x16c9a0b0 : "rpc_s_uuid_member_not_found",

350 0x16c9a0b1 : "rpc_s_no_interfaces_exported",

351 0x16c9a0b2 : "rpc_s_tower_set_not_found",

352 0x16c9a0b3 : "rpc_s_tower_member_not_found",

353 0x16c9a0b4 : "rpc_s_obj_uuid_not_found",

354 0x16c9a0b5 : "rpc_s_no_more_bindings",

355 0x16c9a0b6 : "rpc_s_invalid_priority",

356 0x16c9a0b7 : "rpc_s_not_rpc_entry",

357 0x16c9a0b8 : "rpc_s_invalid_lookup_context",

358 0x16c9a0b9 : "rpc_s_binding_vector_full",

359 0x16c9a0ba : "rpc_s_cycle_detected",

360 0x16c9a0bb : "rpc_s_nothing_to_export",

361 0x16c9a0bc : "rpc_s_nothing_to_unexport",

362 0x16c9a0bd : "rpc_s_invalid_vers_option",

363 0x16c9a0be : "rpc_s_no_rpc_data",

364 0x16c9a0bf : "rpc_s_mbr_picked",

365 0x16c9a0c0 : "rpc_s_not_all_objs_unexported",

366 0x16c9a0c1 : "rpc_s_no_entry_name",

367 0x16c9a0c2 : "rpc_s_priority_group_done",

368 0x16c9a0c3 : "rpc_s_partial_results",

369 0x16c9a0c4 : "rpc_s_no_env_setup",

370 0x16c9a0c5 : "twr_s_unknown_sa",

371 0x16c9a0c6 : "twr_s_unknown_tower",

372 0x16c9a0c7 : "twr_s_not_implemented",

373 0x16c9a0c8 : "rpc_s_max_calls_too_small",

374 0x16c9a0c9 : "rpc_s_cthread_create_failed",

375 0x16c9a0ca : "rpc_s_cthread_pool_exists",

376 0x16c9a0cb : "rpc_s_cthread_no_such_pool",

377 0x16c9a0cc : "rpc_s_cthread_invoke_disabled",

378 0x16c9a0cd : "ept_s_cant_perform_op",

379 0x16c9a0ce : "ept_s_no_memory",

380 0x16c9a0cf : "ept_s_database_invalid",

381 0x16c9a0d0 : "ept_s_cant_create",

382 0x16c9a0d1 : "ept_s_cant_access",

383 0x16c9a0d2 : "ept_s_database_already_open",

384 0x16c9a0d3 : "ept_s_invalid_entry",

385 0x16c9a0d4 : "ept_s_update_failed",

386 0x16c9a0d5 : "ept_s_invalid_context",

387 0x16c9a0d6 : "ept_s_not_registered",

388 0x16c9a0d7 : "ept_s_server_unavailable",

389 0x16c9a0d8 : "rpc_s_underspecified_name",

390 0x16c9a0d9 : "rpc_s_invalid_ns_handle",

391 0x16c9a0da : "rpc_s_unknown_error",

392 0x16c9a0db : "rpc_s_ss_char_trans_open_fail",

393 0x16c9a0dc : "rpc_s_ss_char_trans_short_file",

394 0x16c9a0dd : "rpc_s_ss_context_damaged",

395 0x16c9a0de : "rpc_s_ss_in_null_context",

396 0x16c9a0df : "rpc_s_socket_failure",

397 0x16c9a0e0 : "rpc_s_unsupported_protect_level",

398 0x16c9a0e1 : "rpc_s_invalid_checksum",

399 0x16c9a0e2 : "rpc_s_invalid_credentials",

400 0x16c9a0e3 : "rpc_s_credentials_too_large",

401 0x16c9a0e4 : "rpc_s_call_id_not_found",

402 0x16c9a0e5 : "rpc_s_key_id_not_found",

403 0x16c9a0e6 : "rpc_s_auth_bad_integrity",

404 0x16c9a0e7 : "rpc_s_auth_tkt_expired",

405 0x16c9a0e8 : "rpc_s_auth_tkt_nyv",

406 0x16c9a0e9 : "rpc_s_auth_repeat",

407 0x16c9a0ea : "rpc_s_auth_not_us",

408 0x16c9a0eb : "rpc_s_auth_badmatch",

409 0x16c9a0ec : "rpc_s_auth_skew",

410 0x16c9a0ed : "rpc_s_auth_badaddr",

411 0x16c9a0ee : "rpc_s_auth_badversion",

412 0x16c9a0ef : "rpc_s_auth_msg_type",

413 0x16c9a0f0 : "rpc_s_auth_modified",

414 0x16c9a0f1 : "rpc_s_auth_badorder",

415 0x16c9a0f2 : "rpc_s_auth_badkeyver",

416 0x16c9a0f3 : "rpc_s_auth_nokey",

417 0x16c9a0f4 : "rpc_s_auth_mut_fail",

418 0x16c9a0f5 : "rpc_s_auth_baddirection",

419 0x16c9a0f6 : "rpc_s_auth_method",

420 0x16c9a0f7 : "rpc_s_auth_badseq",

421 0x16c9a0f8 : "rpc_s_auth_inapp_cksum",

422 0x16c9a0f9 : "rpc_s_auth_field_toolong",

423 0x16c9a0fa : "rpc_s_invalid_crc",

424 0x16c9a0fb : "rpc_s_binding_incomplete",

425 0x16c9a0fc : "rpc_s_key_func_not_allowed",

426 0x16c9a0fd : "rpc_s_unknown_stub_rtl_if_vers",

427 0x16c9a0fe : "rpc_s_unknown_ifspec_vers",

428 0x16c9a0ff : "rpc_s_proto_unsupp_by_auth",

429 0x16c9a100 : "rpc_s_authn_challenge_malformed",

430 0x16c9a101 : "rpc_s_protect_level_mismatch",

431 0x16c9a102 : "rpc_s_no_mepv",

432 0x16c9a103 : "rpc_s_stub_protocol_error",

433 0x16c9a104 : "rpc_s_class_version_mismatch",

434 0x16c9a105 : "rpc_s_helper_not_running",

435 0x16c9a106 : "rpc_s_helper_short_read",

436 0x16c9a107 : "rpc_s_helper_catatonic",

437 0x16c9a108 : "rpc_s_helper_aborted",

438 0x16c9a109 : "rpc_s_not_in_kernel",

439 0x16c9a10a : "rpc_s_helper_wrong_user",

440 0x16c9a10b : "rpc_s_helper_overflow",

441 0x16c9a10c : "rpc_s_dg_need_way_auth",

442 0x16c9a10d : "rpc_s_unsupported_auth_subtype",

443 0x16c9a10e : "rpc_s_wrong_pickle_type",

444 0x16c9a10f : "rpc_s_not_listening",

445 0x16c9a110 : "rpc_s_ss_bad_buffer",

446 0x16c9a111 : "rpc_s_ss_bad_es_action",

447 0x16c9a112 : "rpc_s_ss_wrong_es_version",

448 0x16c9a113 : "rpc_s_fault_user_defined",

449 0x16c9a114 : "rpc_s_ss_incompatible_codesets",

450 0x16c9a115 : "rpc_s_tx_not_in_transaction",

451 0x16c9a116 : "rpc_s_tx_open_failed",

452 0x16c9a117 : "rpc_s_partial_credentials",

453 0x16c9a118 : "rpc_s_ss_invalid_codeset_tag",

454 0x16c9a119 : "rpc_s_mgmt_bad_type",

455 0x16c9a11a : "rpc_s_ss_invalid_char_input",

456 0x16c9a11b : "rpc_s_ss_short_conv_buffer",

457 0x16c9a11c : "rpc_s_ss_iconv_error",

458 0x16c9a11d : "rpc_s_ss_no_compat_codeset",

459 0x16c9a11e : "rpc_s_ss_no_compat_charsets",

460 0x16c9a11f : "dce_cs_c_ok",

461 0x16c9a120 : "dce_cs_c_unknown",

462 0x16c9a121 : "dce_cs_c_notfound",

463 0x16c9a122 : "dce_cs_c_cannot_open_file",

464 0x16c9a123 : "dce_cs_c_cannot_read_file",

465 0x16c9a124 : "dce_cs_c_cannot_allocate_memory",

466 0x16c9a125 : "rpc_s_ss_cleanup_failed",

467 0x16c9a126 : "rpc_svc_desc_general",

468 0x16c9a127 : "rpc_svc_desc_mutex",

469 0x16c9a128 : "rpc_svc_desc_xmit",

470 0x16c9a129 : "rpc_svc_desc_recv",

471 0x16c9a12a : "rpc_svc_desc_dg_state",

472 0x16c9a12b : "rpc_svc_desc_cancel",

473 0x16c9a12c : "rpc_svc_desc_orphan",

474 0x16c9a12d : "rpc_svc_desc_cn_state",

475 0x16c9a12e : "rpc_svc_desc_cn_pkt",

476 0x16c9a12f : "rpc_svc_desc_pkt_quotas",

477 0x16c9a130 : "rpc_svc_desc_auth",

478 0x16c9a131 : "rpc_svc_desc_source",

479 0x16c9a132 : "rpc_svc_desc_stats",

480 0x16c9a133 : "rpc_svc_desc_mem",

481 0x16c9a134 : "rpc_svc_desc_mem_type",

482 0x16c9a135 : "rpc_svc_desc_dg_pktlog",

483 0x16c9a136 : "rpc_svc_desc_thread_id",

484 0x16c9a137 : "rpc_svc_desc_timestamp",

485 0x16c9a138 : "rpc_svc_desc_cn_errors",

486 0x16c9a139 : "rpc_svc_desc_conv_thread",

487 0x16c9a13a : "rpc_svc_desc_pid",

488 0x16c9a13b : "rpc_svc_desc_atfork",

489 0x16c9a13c : "rpc_svc_desc_cma_thread",

490 0x16c9a13d : "rpc_svc_desc_inherit",

491 0x16c9a13e : "rpc_svc_desc_dg_sockets",

492 0x16c9a13f : "rpc_svc_desc_timer",

493 0x16c9a140 : "rpc_svc_desc_threads",

494 0x16c9a141 : "rpc_svc_desc_server_call",

495 0x16c9a142 : "rpc_svc_desc_nsi",

496 0x16c9a143 : "rpc_svc_desc_dg_pkt",

497 0x16c9a144 : "rpc_m_cn_ill_state_trans_sa",

498 0x16c9a145 : "rpc_m_cn_ill_state_trans_ca",

499 0x16c9a146 : "rpc_m_cn_ill_state_trans_sg",

500 0x16c9a147 : "rpc_m_cn_ill_state_trans_cg",

501 0x16c9a148 : "rpc_m_cn_ill_state_trans_sr",

502 0x16c9a149 : "rpc_m_cn_ill_state_trans_cr",

503 0x16c9a14a : "rpc_m_bad_pkt_type",

504 0x16c9a14b : "rpc_m_prot_mismatch",

505 0x16c9a14c : "rpc_m_frag_toobig",

506 0x16c9a14d : "rpc_m_unsupp_stub_rtl_if",

507 0x16c9a14e : "rpc_m_unhandled_callstate",

508 0x16c9a14f : "rpc_m_call_failed",

509 0x16c9a150 : "rpc_m_call_failed_no_status",

510 0x16c9a151 : "rpc_m_call_failed_errno",

511 0x16c9a152 : "rpc_m_call_failed_s",

512 0x16c9a153 : "rpc_m_call_failed_c",

513 0x16c9a154 : "rpc_m_errmsg_toobig",

514 0x16c9a155 : "rpc_m_invalid_srchattr",

515 0x16c9a156 : "rpc_m_nts_not_found",

516 0x16c9a157 : "rpc_m_invalid_accbytcnt",

517 0x16c9a158 : "rpc_m_pre_v2_ifspec",

518 0x16c9a159 : "rpc_m_unk_ifspec",

519 0x16c9a15a : "rpc_m_recvbuf_toosmall",

520 0x16c9a15b : "rpc_m_unalign_authtrl",

521 0x16c9a15c : "rpc_m_unexpected_exc",

522 0x16c9a15d : "rpc_m_no_stub_data",

523 0x16c9a15e : "rpc_m_eventlist_full",

524 0x16c9a15f : "rpc_m_unk_sock_type",

525 0x16c9a160 : "rpc_m_unimp_call",

526 0x16c9a161 : "rpc_m_invalid_seqnum",

527 0x16c9a162 : "rpc_m_cant_create_uuid",

528 0x16c9a163 : "rpc_m_pre_v2_ss",

529 0x16c9a164 : "rpc_m_dgpkt_pool_corrupt",

530 0x16c9a165 : "rpc_m_dgpkt_bad_free",

531 0x16c9a166 : "rpc_m_lookaside_corrupt",

532 0x16c9a167 : "rpc_m_alloc_fail",

533 0x16c9a168 : "rpc_m_realloc_fail",

534 0x16c9a169 : "rpc_m_cant_open_file",

535 0x16c9a16a : "rpc_m_cant_read_addr",

536 0x16c9a16b : "rpc_svc_desc_libidl",

537 0x16c9a16c : "rpc_m_ctxrundown_nomem",

538 0x16c9a16d : "rpc_m_ctxrundown_exc",

539 0x16c9a16e : "rpc_s_fault_codeset_conv_error",

540 0x16c9a16f : "rpc_s_no_call_active",

541 0x16c9a170 : "rpc_s_cannot_support",

542 0x16c9a171 : "rpc_s_no_context_available",

543}

544

545 class DCERPCException(Exception):

546 """

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

548 DCERPC Transport used.

549 """

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

551 """

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

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

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

555 information

556 """

557 Exception.__init__(self)

558 self.packet = packet

559 self.error_string = error_string

560 if packet is not None:

561 try:

562 self.error_code = packet['ErrorCode']

563 except:

564 self.error_code = error_code

565 else:

566 self.error_code = error_code

567

568 def get_error_code( self ):

569 return self.error_code

570

571 def get_packet( self ):

572 return self.packet

573

574 def __str__( self ):

575 key = self.error_code

576 if self.error_string is not None:

577 return self.error_string

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

579 error_msg_short = rpc_status_codes[key]

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

581 else:

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

583

584# Context Item

585 class CtxItem(Structure):

586 structure = (

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

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

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

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

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

592 )

593

594 class CtxItemResult(Structure):

595 structure = (

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

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

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

599 )

600

601 class SEC_TRAILER(Structure):

602 commonHdr = (

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

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

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

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

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

608 )

609

610 class MSRPCHeader(Structure):

611 _SIZE = 16

612 commonHdr = (

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

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

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

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

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

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

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

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

621 )

622

623 structure = (

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

625 ('pduData',':'),

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

627 ('pad', ':'),

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

629 ('sec_trailer',':'),

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

631 ('auth_data',':'),

632 )

633

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

635 Structure.__init__(self,data, alignment)

636 if data is None:

637 self['ver_major'] = 5

638 self['ver_minor'] = 0

639 self['flags'] = PFC_FIRST_FRAG | PFC_LAST_FRAG

640 self['type'] = MSRPC_REQUEST

641 self.__frag_len_set = 0

642 self['auth_len'] = 0

643 self['pduData'] = b''

644 self['auth_data'] = b''

645 self['sec_trailer'] = b''

646 self['pad'] = b''

647

648 def get_header_size(self):

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

650

651 def get_packet(self):

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

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

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

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

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

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

658

659 return self.getData()

660

661 class MSRPCRequestHeader(MSRPCHeader):

662 _SIZE = 24

663 commonHdr = MSRPCHeader.commonHdr + (

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

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

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

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

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

669 )

670

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

672 MSRPCHeader.__init__(self, data, alignment)

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

674 self['type'] = MSRPC_REQUEST

675 self['ctx_id'] = 0

676 self['uuid'] = b''

677

678 class MSRPCRespHeader(MSRPCHeader):

679 _SIZE = 24

680 commonHdr = MSRPCHeader.commonHdr + (

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

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

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

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

685 )

686

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

688 MSRPCHeader.__init__(self, aBuffer, alignment)

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

690 self['type'] = MSRPC_RESPONSE

691 self['ctx_id'] = 0

692

693 class MSRPCBind(Structure):

694 _CTX_ITEM_LEN = len(CtxItem())

695 structure = (

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

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

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

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

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

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

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

703 ('ctx_items',':'),

704 )

705

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

707 Structure.__init__(self, data, alignment)

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

709 self['max_tfrag'] = 4280

710 self['max_rfrag'] = 4280

711 self['assoc_group'] = 0

712 self['ctx_num'] = 1

713 self['ctx_items'] = b''

714 self.__ctx_items = []

715

716 def addCtxItem(self, item):

717 self.__ctx_items.append(item)

718

719 def getData(self):

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

721 for i in self.__ctx_items:

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

723 return Structure.getData(self)

724

725 class MSRPCBindAck(MSRPCHeader):

726 _SIZE = 26 # Up to SecondaryAddr

727 _CTX_ITEM_LEN = len(CtxItemResult())

728 structure = (

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

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

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

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

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

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

735 ('Pad',':'),

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

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

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

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

740 ('ctx_items',':'),

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

742 ('sec_trailer',':'),

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

744 ('auth_data',':'),

745 )

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

747 self.__ctx_items = []

748 MSRPCHeader.__init__(self,data,alignment)

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

750 self['Pad'] = b''

751 self['ctx_items'] = b''

752 self['sec_trailer'] = b''

753 self['auth_data'] = b''

754

755 def getCtxItems(self):

756 return self.__ctx_items

757

758 def getCtxItem(self,index):

759 return self.__ctx_items[index-1]

760

761 def fromString(self, data):

762 Structure.fromString(self,data)

763 # Parse the ctx_items

764 data = self['ctx_items']

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

766 item = CtxItemResult(data)

767 self.__ctx_items.append(item)

768 data = data[len(item):]

769

770 class MSRPCBindNak(Structure):

771 structure = (

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

773 ('SupportedVersions',':'),

774 )

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

776 Structure.__init__(self,data,alignment)

777 if data is None:

778 self['SupportedVersions'] = b''

779

780 class DCERPC:

781 # Standard NDR Representation

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

783 # NDR 64

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

785 transfer_syntax = NDRSyntax

786

787 def __init__(self,transport):

788 self._transport = transport

789 self.set_ctx_id(0)

790 self._max_user_frag = None

791 self.set_default_max_fragment_size()

792 self._ctx = None

793

794 def get_rpc_transport(self):

795 return self._transport

796

797 def set_ctx_id(self, ctx_id):

798 self._ctx = ctx_id

799

800 def connect(self):

801 return self._transport.connect()

802

803 def disconnect(self):

804 return self._transport.disconnect()

805

806 def set_max_fragment_size(self, fragment_size):

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

808 # 0 is don't fragment

809 # other values are max fragment size

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

811 self.set_default_max_fragment_size()

812 else:

813 self._max_user_frag = fragment_size

814

815 def set_default_max_fragment_size(self):

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

817 self._max_user_frag = 0

818

819 def send(self, data):

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

821

822 def recv(self):

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

824

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

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

827

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

829 pass

830

831 def set_auth_level(self, auth_level):

832 pass

833

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

835 pass

836

837 def get_idempotent(self):

838 return 0

839

840 def set_idempotent(self, flag):

841 pass

842

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

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

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

846 else:

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

848

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

850 if self.transfer_syntax == self.NDR64Syntax:

851 request.changeTransferSyntax(self.NDR64Syntax)

852 isNDR64 = True

853 else:

854 isNDR64 = False

855

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

857 answer = self.recv()

858

859 __import__(request.__module__)

860 module = sys.modules[request.__module__]

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

862

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

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

865 if error_code in rpc_status_codes:

866 # This is an error we can handle

867 exception = DCERPCException(error_code = error_code)

868 else:

869 sessionErrorClass = getattr(module, 'DCERPCSessionError')

870 try:

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

872 response = respClass(answer, isNDR64 = isNDR64)

873 except:

874 # No luck :(

875 exception = sessionErrorClass(error_code = error_code)

876 else:

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

878 raise exception

879 else:

880 response = respClass(answer, isNDR64 = isNDR64)

881 return response

882

883 class DCERPC_v4(DCERPC):

884 pass

885

886 class DCERPC_v5(DCERPC):

887 def __init__(self, transport):

888 DCERPC.__init__(self, transport)

889 self.__auth_level = RPC_C_AUTHN_LEVEL_NONE

890 self.__auth_type = RPC_C_AUTHN_WINNT

891 self.__auth_type_callback = None

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

893 self.__auth_flags = 0

894 self.__username = None

895 self.__password = None

896 self.__domain = ''

897 self.__lmhash = ''

898 self.__nthash = ''

899 self.__aesKey = ''

900 self.__TGT = None

901 self.__TGS = None

902

903 self.__clientSigningKey = b''

904 self.__serverSigningKey = b''

905 self.__clientSealingKey = b''

906 self.__clientSealingHandle = b''

907 self.__serverSealingKey = b''

908 self.__serverSealingHandle = b''

909 self.__sequence = 0

910

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

912 self.__callid = 1

913 self._ctx = 0

914 self.__sessionKey = None

915 self.__max_xmit_size = 0

916 self.__flags = 0

917 self.__cipher = None

918 self.__confounder = b''

919 self.__gss = None

920

921 def set_session_key(self, session_key):

922 self.__sessionKey = session_key

923

924 def get_session_key(self):

925 return self.__sessionKey

926

927 def set_auth_level(self, auth_level):

928 self.__auth_level = auth_level

929

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

931 self.__auth_type = auth_type

932 self.__auth_type_callback = callback

933

934 def get_auth_type(self):

935 return self.__auth_type

936

937 def set_max_tfrag(self, size):

938 self.__max_xmit_size = size

939

940 def get_credentials(self):

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

942

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

944 self.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT)

945 self.__username = username

946 self.__password = password

947 self.__domain = domain

948 self.__aesKey = aesKey

949 self.__TGT = TGT

950 self.__TGS = TGS

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

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

953 lmhash = '0%s' % lmhash

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

955 nthash = '0%s' % nthash

956 try: # just in case they were converted already

957 self.__lmhash = unhexlify(lmhash)

958 self.__nthash = unhexlify(nthash)

959 except:

960 self.__lmhash = lmhash

961 self.__nthash = nthash

962 pass

963

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

965 bind = MSRPCBind()

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

967 ctx = self._ctx

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

969 item = CtxItem()

970 item['ContextID'] = ctx

971 item['TransItems'] = 1

972 item['ContextID'] = ctx

973 # We generate random UUIDs for bogus binds

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

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

976 bind.addCtxItem(item)

977 self._ctx += 1

978 ctx += 1

979

980 # The true one :)

981 item = CtxItem()

982 item['AbstractSyntax'] = iface_uuid

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

984 item['ContextID'] = ctx

985 item['TransItems'] = 1

986 bind.addCtxItem(item)

987

988 packet = MSRPCHeader()

989 packet['type'] = MSRPC_BIND

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

991 packet['call_id'] = self.__callid

992

993 if alter:

994 packet['type'] = MSRPC_ALTERCTX

995

996 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:

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

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

999

1000 if self.__auth_type == RPC_C_AUTHN_WINNT:

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

1002 use_ntlmv2=self._transport.doesSupportNTLMv2())

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

1004 from impacket.dcerpc.v5 import nrpc

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

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

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

1008 self.__domain, self.__lmhash,

1009 self.__nthash, self.__aesKey,

1010 self.__TGT, self.__TGS,

1011 self._transport.getRemoteName(),

1012 self._transport.get_kdcHost())

1013 else:

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

1015

1016 sec_trailer = SEC_TRAILER()

1017 sec_trailer['auth_type'] = self.__auth_type

1018 sec_trailer['auth_level'] = self.__auth_level

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

1020

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

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

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

1024 sec_trailer['auth_pad_len']=pad

1025

1026 packet['sec_trailer'] = sec_trailer

1027 packet['auth_data'] = auth

1028

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

1030

1031 s = self._transport.recv()

1032

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

1034 resp = MSRPCHeader(s)

1035 else:

1036 return 0 #mmm why not None?

1037

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

1039 bindResp = MSRPCBindAck(resp.getData())

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

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

1042 resp = MSRPCRespHeader(resp.getData())

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

1044 else:

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

1046 status_code = resp['RejectedReason']

1047 if status_code in rpc_status_codes:

1048 raise DCERPCException(error_code = status_code)

1049 elif status_code in rpc_provider_reason:

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

1051 else:

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

1053 else:

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

1055

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

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

1058 ctxItems = bindResp.getCtxItem(ctx)

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

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

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

1062 msg += "; "

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

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

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

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

1067 raise DCERPCException(msg)

1068

1069 # Save the transfer syntax for later use

1070 self.transfer_syntax = ctxItems['TransferSyntax']

1071

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

1073 self.__max_xmit_size = bindResp['max_rfrag']

1074

1075 if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:

1076 if self.__auth_type == RPC_C_AUTHN_WINNT:

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

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

1079 self.__nthash,

1080 use_ntlmv2=self._transport.doesSupportNTLMv2())

1081 self.__flags = response['flags']

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

1083 response = None

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

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

1086 self.__sessionKey,

1087 bindResp['auth_data'])

1088

1089 self.__sequence = 0

1090

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

1092 if self.__auth_type == RPC_C_AUTHN_WINNT:

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

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

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

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

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

1098 # Preparing the keys handle states

1099 cipher3 = ARC4.new(self.__clientSealingKey)

1100 self.__clientSealingHandle = cipher3.encrypt

1101 cipher4 = ARC4.new(self.__serverSealingKey)

1102 self.__serverSealingHandle = cipher4.encrypt

1103 else:

1104 # Same key for everything

1105 self.__clientSigningKey = self.__sessionKey

1106 self.__serverSigningKey = self.__sessionKey

1107 self.__clientSealingKey = self.__sessionKey

1108 self.__serverSealingKey = self.__sessionKey

1109 cipher = ARC4.new(self.__clientSigningKey)

1110 self.__clientSealingHandle = cipher.encrypt

1111 self.__serverSealingHandle = cipher.encrypt

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

1113 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:

1114 self.__confounder = b''

1115 else:

1116 self.__confounder = b'12345678'

1117

1118 sec_trailer = SEC_TRAILER()

1119 sec_trailer['auth_type'] = self.__auth_type

1120 sec_trailer['auth_level'] = self.__auth_level

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

1122

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

1124 if self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:

1125 alter_ctx = MSRPCHeader()

1126 alter_ctx['type'] = MSRPC_ALTERCTX

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

1128 alter_ctx['sec_trailer'] = sec_trailer

1129 alter_ctx['auth_data'] = response

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

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

1132 self.__sequence = 0

1133 self.recv()

1134 self.__sequence = 0

1135 else:

1136 auth3 = MSRPCHeader()

1137 auth3['type'] = MSRPC_AUTH3

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

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

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

1141 # specified in section 2.2.2.11

1142 auth3['pduData'] = b' '

1143 auth3['sec_trailer'] = sec_trailer

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

1145

1146 # Use the same call_id

1147 self.__callid = resp['call_id']

1148 auth3['call_id'] = self.__callid

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

1150

1151 self.__callid += 1

1152

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

1154

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

1156 rpc_packet['ctx_id'] = self._ctx

1157 rpc_packet['sec_trailer'] = b''

1158 rpc_packet['auth_data'] = b''

1159

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

1161 # Dummy verifier, just for the calculations

1162 sec_trailer = SEC_TRAILER()

1163 sec_trailer['auth_type'] = self.__auth_type

1164 sec_trailer['auth_level'] = self.__auth_level

1165 sec_trailer['auth_pad_len'] = 0

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

1167

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

1169 if pad != 0:

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

1171 sec_trailer['auth_pad_len']=pad

1172

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

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

1175

1176 plain_data = rpc_packet['pduData']

1177 if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY:

1178 if self.__auth_type == RPC_C_AUTHN_WINNT:

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

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

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

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

1183 self.__clientSigningKey,

1184 self.__clientSealingKey,

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

1186 plain_data,

1187 self.__sequence,

1188 self.__clientSealingHandle)

1189 else:

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

1191 self.__clientSigningKey,

1192 self.__clientSealingKey,

1193 plain_data,

1194 plain_data,

1195 self.__sequence,

1196 self.__clientSealingHandle)

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

1198 from impacket.dcerpc.v5 import nrpc

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

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

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

1202

1203 rpc_packet['pduData'] = sealedMessage

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

1205 if self.__auth_type == RPC_C_AUTHN_WINNT:

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

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

1208 # whole PDU, not just the data

1209 signature = ntlm.SIGN(self.__flags,

1210 self.__clientSigningKey,

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

1212 self.__sequence,

1213 self.__clientSealingHandle)

1214 else:

1215 signature = ntlm.SIGN(self.__flags,

1216 self.__clientSigningKey,

1217 plain_data,

1218 self.__sequence,

1219 self.__clientSealingHandle)

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

1221 from impacket.dcerpc.v5 import nrpc

1222 signature = nrpc.SIGN(plain_data,

1223 self.__confounder,

1224 self.__sequence,

1225 self.__sessionKey,

1226 False)

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

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

1229

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

1231 rpc_packet['auth_data'] = signature

1232

1233 self.__sequence += 1

1234

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

1236

1237 def send(self, data):

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

1239 # Must be an Impacket, transform to structure

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

1241

1242 try:

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

1244 data['flags'] |= PFC_OBJECT_UUID

1245 except:

1246 # Structure doesn't have uuid

1247 pass

1248 data['ctx_id'] = self._ctx

1249 data['call_id'] = self.__callid

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

1251 # We should fragment PDUs if:

1252 # 1) Payload exceeds __max_xmit_size received during BIND response

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

1254 should_fragment = False

1255

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

1257 if self._max_user_frag > 0:

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

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

1260 else:

1261 fragment_size = self.__max_xmit_size

1262

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

1264

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

1266 if fragment_size <= 8:

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

1268 # (Kerberos)

1269 fragment_size = 8

1270

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

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

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

1274 should_fragment = True

1275 if fragment_size+128 > self.__max_xmit_size:

1276 fragment_size = self.__max_xmit_size - 128

1277

1278 if should_fragment:

1279 packet = data['pduData']

1280 offset = 0

1281

1282 while 1:

1283 toSend = packet[offset: offset+fragment_size]

1284 if not toSend:

1285 break

1286 if offset == 0:

1287 data['flags'] |= PFC_FIRST_FRAG

1288 else:

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

1290 offset += len(toSend)

1291 if offset >= len(packet):

1292 data['flags'] |= PFC_LAST_FRAG

1293 else:

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

1295 data['pduData'] = toSend

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

1297 else:

1298 self._transport_send(data)

1299 self.__callid += 1

1300

1301 def recv(self):

1302 finished = False

1303 forceRecv = 0

1304 retAnswer = b''

1305 while not finished:

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

1307 # TCP/UDP Transports

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

1309 response_header = MSRPCRespHeader(response_data)

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

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

1312 # So we gotta check we received it all

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

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

1315

1316 off = response_header.get_header_size()

1317

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

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

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

1321 raise DCERPCException(rpc_status_codes[status_code])

1322 elif status_code & 0xffff in rpc_status_codes:

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

1324 else:

1325 if status_code in hresult_errors.ERROR_MESSAGES:

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

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

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

1329 else:

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

1331

1332 if response_header['flags'] & PFC_LAST_FRAG:

1333 # No need to reassembly DCERPC

1334 finished = True

1335 else:

1336 # Forcing Read Recv, we need more packets!

1337 forceRecv = 1

1338

1339 answer = response_data[off:]

1340 auth_len = response_header['auth_len']

1341 if auth_len:

1342 auth_len += 8

1343 auth_data = answer[-auth_len:]

1344 sec_trailer = SEC_TRAILER(data = auth_data)

1345 answer = answer[:-auth_len]

1346

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

1348 if self.__auth_type == RPC_C_AUTHN_WINNT:

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

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

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

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

1353 self.__serverSigningKey,

1354 self.__serverSealingKey,

1355 answer,

1356 answer,

1357 self.__sequence,

1358 self.__serverSealingHandle)

1359 else:

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

1361 self.__serverSigningKey,

1362 self.__serverSealingKey,

1363 answer,

1364 answer,

1365 self.__sequence,

1366 self.__serverSealingHandle)

1367 self.__sequence += 1

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

1369 from impacket.dcerpc.v5 import nrpc

1370 answer, cfounder = nrpc.UNSEAL(answer,

1371 auth_data[len(sec_trailer):],

1372 self.__sessionKey,

1373 False)

1374 self.__sequence += 1

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

1376 if self.__sequence > 0:

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

1378 direction='init', authData=auth_data)

1379

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

1381 if self.__auth_type == RPC_C_AUTHN_WINNT:

1382 ntlmssp = auth_data[12:]

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

1384 signature = ntlm.SIGN(self.__flags,

1385 self.__serverSigningKey,

1386 answer,

1387 self.__sequence,

1388 self.__serverSealingHandle)

1389 else:

1390 signature = ntlm.SIGN(self.__flags,

1391 self.__serverSigningKey,

1392 ntlmssp,

1393 self.__sequence,

1394 self.__serverSealingHandle)

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

1396 # the packet :P

1397 self.__sequence += 1

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

1399 from impacket.dcerpc.v5 import nrpc

1400 ntlmssp = auth_data[12:]

1401 signature = nrpc.SIGN(ntlmssp,

1402 self.__confounder,

1403 self.__sequence,

1404 self.__sessionKey,

1405 False)

1406 self.__sequence += 1

1407 elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:

1408 # Do NOT increment the sequence number when Signing Kerberos

1409 #self.__sequence += 1

1410 pass

1411

1412

1413 if sec_trailer['auth_pad_len']:

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

1415

1416 retAnswer += answer

1417 return retAnswer

1418

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

1420 answer = self.__class__(self._transport)

1421

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

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

1424 answer.set_auth_type(self.__auth_type)

1425 answer.set_auth_level(self.__auth_level)

1426

1427 answer.set_ctx_id(self._ctx+1)

1428 answer.__callid = self.__callid

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

1430 return answer

1431

1432 class DCERPC_RawCall(MSRPCRequestHeader):

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

1434 MSRPCRequestHeader.__init__(self)

1435 self['op_num'] = op_num

1436 self['pduData'] = data

1437 if uuid is not None:

1438 self['flags'] |= PFC_OBJECT_UUID

1439 self['uuid'] = uuid

1440

1441 def setData(self, data):

1442 self['pduData'] = data

1443

1444# 2.2.6 Type Serialization Version 1

1445 class CommonHeader(NDRSTRUCT):

1446 structure = (

1447 ('Version', UCHAR),

1448 ('Endianness', UCHAR),

1449 ('CommonHeaderLength', USHORT),

1450 ('Filler', ULONG),

1451 )

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

1453 NDRSTRUCT.__init__(self, data, isNDR64)

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

1455 self['Version'] = 1

1456 self['Endianness'] = 0x10

1457 self['CommonHeaderLength'] = 8

1458 self['Filler'] = 0xcccccccc

1459

1460 class PrivateHeader(NDRSTRUCT):

1461 structure = (

1462 ('ObjectBufferLength', ULONG),

1463 ('Filler', ULONG),

1464 )

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

1466 NDRSTRUCT.__init__(self, data, isNDR64)

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

1468 self['Filler'] = 0xcccccccc

1469

1470 class TypeSerialization1(NDRSTRUCT):

1471 commonHdr = (

1472 ('CommonHeader', CommonHeader),

1473 ('PrivateHeader', PrivateHeader),

1474 )

1475 def getData(self, soFar = 0):

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

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

1478 return NDRSTRUCT.getData(self, soFar)

1479

1480 class DCERPCServer(Thread):

1481 """

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

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

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

1485 """

1486 def __init__(self):

1487 Thread.__init__(self)

1488 self._listenPort = 0

1489 self._listenAddress = '127.0.0.1'

1490 self._listenUUIDS = {}

1491 self._boundUUID = b''

1492 self._sock = None

1493 self._clientSock = None

1494 self._callid = 1

1495 self._max_frag = None

1496 self._max_xmit_size = 4280

1497 self.__log = LOG

1498 self._sock = socket.socket()

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

1500

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

1502 self.__log.log(level,msg)

1503

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

1505 """

1506 adds a call back to a UUID/opnum call

1507

1508 :param uuid ifaceUUID: the interface UUID

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

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

1511 """

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

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

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

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

1516

1517 def setListenPort(self, portNum):

1518 self._listenPort = portNum

1519 self._sock = socket.socket()

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

1521

1522 def getListenPort(self):

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

1524

1525 def recv(self):

1526 finished = False

1527 retAnswer = b''

1528 response_data = b''

1529 while not finished:

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

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

1532 # No data?, connection might have closed

1533 if response_data == b'':

1534 return None

1535 response_header = MSRPCRespHeader(response_data)

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

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

1538 # So we gotta check we received it all

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

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

1541 response_header = MSRPCRespHeader(response_data)

1542 if response_header['flags'] & PFC_LAST_FRAG:

1543 # No need to reassembly DCERPC

1544 finished = True

1545 answer = response_header['pduData']

1546 auth_len = response_header['auth_len']

1547 if auth_len:

1548 auth_len += 8

1549 auth_data = answer[-auth_len:]

1550 sec_trailer = SEC_TRAILER(data = auth_data)

1551 answer = answer[:-auth_len]

1552 if sec_trailer['auth_pad_len']:

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

1554

1555 retAnswer += answer

1556 return response_data

1557

1558 def run(self):

1559 self._sock.listen(10)

1560 while True:

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

1562 try:

1563 while True:

1564 data = self.recv()

1565 if data is None:

1566 # No data.. connection closed

1567 break

1568 answer = self.processRequest(data)

1569 if answer is not None:

1570 self.send(answer)

1571 except Exception:

1572 #import traceback

1573 #traceback.print_exc()

1574 pass

1575 self._clientSock.close()

1576

1577 def send(self, data):

1578 max_frag = self._max_frag

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

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

1581

1582 if self._max_frag:

1583 max_frag = min(max_frag, self._max_frag)

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

1585 packet = data['pduData']

1586 offset = 0

1587 while 1:

1588 toSend = packet[offset: offset+max_frag]

1589 if not toSend:

1590 break

1591 flags = 0

1592 if offset == 0:

1593 flags |= PFC_FIRST_FRAG

1594 offset += len(toSend)

1595 if offset == len(packet):

1596 flags |= PFC_LAST_FRAG

1597 data['flags'] = flags

1598 data['pduData'] = toSend

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

1600 else:

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

1602 self._callid += 1

1603

1604 def bind(self,packet, bind):

1605 # Standard NDR Representation

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

1607 resp = MSRPCBindAck()

1608

1609 resp['type'] = MSRPC_BINDACK

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

1611 resp['frag_len'] = 0

1612 resp['auth_len'] = 0

1613 resp['auth_data'] = b''

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

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

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

1617 resp['assoc_group'] = 0x1234

1618 resp['ctx_num'] = 0

1619

1620 data = bind['ctx_items']

1621 ctx_items = b''

1622 resp['SecondaryAddrLen'] = 0

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

1624 result = MSRPC_CONT_RESULT_USER_REJECT

1625 item = CtxItem(data)

1626 data = data[len(item):]

1627

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

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

1630 # Now Check if the interface is what we listen

1631 reason = 1 # Default, Abstract Syntax not supported

1632 for j in self._listenUUIDS:

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

1634 # Match, we accept the bind request

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

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

1637 reason = 0

1638 self._boundUUID = j

1639 else:

1640 # Fail the bind request for this context

1641 reason = 2 # Transfer Syntax not supported

1642 if reason == 0:

1643 result = MSRPC_CONT_RESULT_ACCEPT

1644 if reason == 1:

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

1646

1647 resp['ctx_num'] += 1

1648 itemResult = CtxItemResult()

1649 itemResult['Result'] = result

1650 itemResult['Reason'] = reason

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

1652 ctx_items += itemResult.getData()

1653

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

1655 resp['ctx_items'] = ctx_items

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

1657

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

1659 return None

1660

1661 def processRequest(self,data):

1662 packet = MSRPCHeader(data)

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

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

1665 self.bind(packet, bind)

1666 packet = None

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

1668 request = MSRPCRequestHeader(data)

1669 response = MSRPCRespHeader(data)

1670 response['type'] = MSRPC_RESPONSE

1671 # Serve the opnum requested, if not, fails

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

1673 # Call the function

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

1675 response['pduData'] = returnData

1676 else:

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

1678 response['type'] = MSRPC_FAULT

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

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

1681 return response

1682 else:

1683 # Defaults to a fault

1684 packet = MSRPCRespHeader(data)

1685 packet['type'] = MSRPC_FAULT

1686

1687 return packet