1# Copyright (c) 2003-2016 CORE Security Technologies 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# Author: Alberto Solino (@agsolino) 8# 9# Description: 10# [C706] Remote Management Interface 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/CoreSecurity/impacket/tree/master/impacket/testcases/SMB_RPC 15# 16# Some calls have helper functions, which makes it even easier to use. 17# They are located at the end of this file. 18# Helper functions start with "h"<name of the call>. 19# There are test cases for them too. 20# 21from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRUniConformantVaryingArray 22from impacket.dcerpc.v5.epm import PRPC_IF_ID 23from impacket.dcerpc.v5.dtypes import ULONG, DWORD_ARRAY, ULONGLONG 24from impacket.dcerpc.v5.rpcrt import DCERPCException 25from impacket.uuid import uuidtup_to_bin 26from impacket import nt_errors 27 28MSRPC_UUID_MGMT = uuidtup_to_bin(('afa8bd80-7d8a-11c9-bef4-08002b102989','1.0')) 29 30class DCERPCSessionError(DCERPCException): 31 def __init__(self, error_string=None, error_code=None, packet=None): 32 DCERPCException.__init__(self, error_string, error_code, packet) 33 34 def __str__( self ): 35 key = self.error_code 36 if nt_errors.ERROR_MESSAGES.has_key(key): 37 error_msg_short = nt_errors.ERROR_MESSAGES[key][0] 38 error_msg_verbose = nt_errors.ERROR_MESSAGES[key][1] 39 return 'MGMT SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 40 else: 41 return 'MGMT SessionError: unknown error code: 0x%x' % self.error_code 42 43################################################################################ 44# CONSTANTS 45################################################################################ 46 47class rpc_if_id_p_t_array(NDRUniConformantArray): 48 item = PRPC_IF_ID 49 50class rpc_if_id_vector_t(NDRSTRUCT): 51 structure = ( 52 ('count',ULONG), 53 ('if_id',rpc_if_id_p_t_array), 54 ) 55 structure64 = ( 56 ('count',ULONGLONG), 57 ('if_id',rpc_if_id_p_t_array), 58 ) 59 60class rpc_if_id_vector_p_t(NDRPOINTER): 61 referent = ( 62 ('Data', rpc_if_id_vector_t), 63 ) 64 65error_status = ULONG 66################################################################################ 67# STRUCTURES 68################################################################################ 69 70################################################################################ 71# RPC CALLS 72################################################################################ 73class inq_if_ids(NDRCALL): 74 opnum = 0 75 structure = ( 76 ) 77 78class inq_if_idsResponse(NDRCALL): 79 structure = ( 80 ('if_id_vector', rpc_if_id_vector_p_t), 81 ('status', error_status), 82 ) 83 84class inq_stats(NDRCALL): 85 opnum = 1 86 structure = ( 87 ('count', ULONG), 88 ) 89 90class inq_statsResponse(NDRCALL): 91 structure = ( 92 ('count', ULONG), 93 ('statistics', DWORD_ARRAY), 94 ('status', error_status), 95 ) 96 97class is_server_listening(NDRCALL): 98 opnum = 2 99 structure = ( 100 ) 101 102class is_server_listeningResponse(NDRCALL): 103 structure = ( 104 ('status', error_status), 105 ) 106 107class stop_server_listening(NDRCALL): 108 opnum = 3 109 structure = ( 110 ) 111 112class stop_server_listeningResponse(NDRCALL): 113 structure = ( 114 ('status', error_status), 115 ) 116 117class inq_princ_name(NDRCALL): 118 opnum = 4 119 structure = ( 120 ('authn_proto', ULONG), 121 ('princ_name_size', ULONG), 122 ) 123 124class inq_princ_nameResponse(NDRCALL): 125 structure = ( 126 ('princ_name', NDRUniConformantVaryingArray), 127 ('status', error_status), 128 ) 129 130 131################################################################################ 132# OPNUMs and their corresponding structures 133################################################################################ 134OPNUMS = { 135 0 : (inq_if_ids, inq_if_idsResponse), 136 1 : (inq_stats, inq_statsResponse), 137 2 : (is_server_listening, is_server_listeningResponse), 138 3 : (stop_server_listening, stop_server_listeningResponse), 139 4 : (inq_princ_name, inq_princ_nameResponse), 140} 141 142################################################################################ 143# HELPER FUNCTIONS 144################################################################################ 145def hinq_if_ids(dce): 146 request = inq_if_ids() 147 return dce.request(request) 148 149def hinq_stats(dce, count = 4): 150 request = inq_stats() 151 request['count'] = count 152 return dce.request(request) 153 154def his_server_listening(dce): 155 request = is_server_listening() 156 return dce.request(request, checkError=False) 157 158def hstop_server_listening(dce): 159 request = stop_server_listening() 160 return dce.request(request) 161 162def hinq_princ_name(dce, authn_proto=0, princ_name_size=1): 163 request = inq_princ_name() 164 request['authn_proto'] = authn_proto 165 request['princ_name_size'] = princ_name_size 166 return dce.request(request, checkError=False) 167 168 169