github.com/n00py/Slackor@v0.0.0-20200610224921-d007fcea1740/impacket/examples/rpcdump.py (about) 1 #!/usr/bin/env python 2 # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 # 4 # This software is provided under under a slightly modified version 5 # of the Apache Software License. See the accompanying LICENSE file 6 # for more information. 7 # 8 # DCE/RPC endpoint mapper dumper. 9 # 10 # Author: 11 # Javier Kohen <jkohen@coresecurity.com> 12 # Alberto Solino <beto@coresecurity.com> 13 # 14 # Reference for: 15 # DCE/RPC. 16 from __future__ import division 17 from __future__ import print_function 18 import sys 19 import logging 20 import argparse 21 22 from impacket.examples import logger 23 from impacket import uuid, version 24 from impacket.dcerpc.v5 import transport, epm 25 26 class RPCDump: 27 KNOWN_PROTOCOLS = { 28 135: {'bindstr': r'ncacn_ip_tcp:%s', 'set_host': False}, 29 139: {'bindstr': r'ncacn_np:%s[\pipe\epmapper]', 'set_host': True}, 30 445: {'bindstr': r'ncacn_np:%s[\pipe\epmapper]', 'set_host': True} 31 } 32 33 def __init__(self, username = '', password = '', domain='', hashes = None, port=135): 34 35 self.__username = username 36 self.__password = password 37 self.__domain = domain 38 self.__lmhash = '' 39 self.__nthash = '' 40 self.__port = port 41 if hashes is not None: 42 self.__lmhash, self.__nthash = hashes.split(':') 43 44 def dump(self, remoteName, remoteHost): 45 """Dumps the list of endpoints registered with the mapper 46 listening at addr. remoteName is a valid host name or IP 47 address in string format. 48 """ 49 50 logging.info('Retrieving endpoint list from %s' % remoteName) 51 52 entries = [] 53 54 stringbinding = self.KNOWN_PROTOCOLS[self.__port]['bindstr'] % remoteName 55 logging.debug('StringBinding %s'%stringbinding) 56 rpctransport = transport.DCERPCTransportFactory(stringbinding) 57 rpctransport.set_dport(self.__port) 58 59 if self.KNOWN_PROTOCOLS[self.__port]['set_host']: 60 rpctransport.setRemoteHost(remoteHost) 61 62 if hasattr(rpctransport, 'set_credentials'): 63 # This method exists only for selected protocol sequences. 64 rpctransport.set_credentials(self.__username, self.__password, self.__domain, 65 self.__lmhash, self.__nthash) 66 67 try: 68 entries = self.__fetchList(rpctransport) 69 except Exception as e: 70 logging.critical('Protocol failed: %s' % e) 71 72 # Display results. 73 74 endpoints = {} 75 # Let's groups the UUIDS 76 for entry in entries: 77 binding = epm.PrintStringBinding(entry['tower']['Floors'], rpctransport.getRemoteHost()) 78 tmpUUID = str(entry['tower']['Floors'][0]) 79 if (tmpUUID in endpoints) is not True: 80 endpoints[tmpUUID] = {} 81 endpoints[tmpUUID]['Bindings'] = list() 82 if uuid.uuidtup_to_bin(uuid.string_to_uuidtup(tmpUUID))[:18] in epm.KNOWN_UUIDS: 83 endpoints[tmpUUID]['EXE'] = epm.KNOWN_UUIDS[uuid.uuidtup_to_bin(uuid.string_to_uuidtup(tmpUUID))[:18]] 84 else: 85 endpoints[tmpUUID]['EXE'] = 'N/A' 86 endpoints[tmpUUID]['annotation'] = entry['annotation'][:-1].decode('utf-8') 87 endpoints[tmpUUID]['Bindings'].append(binding) 88 89 if tmpUUID[:36] in epm.KNOWN_PROTOCOLS: 90 endpoints[tmpUUID]['Protocol'] = epm.KNOWN_PROTOCOLS[tmpUUID[:36]] 91 else: 92 endpoints[tmpUUID]['Protocol'] = "N/A" 93 #print "Transfer Syntax: %s" % entry['Tower']['Floors'][1] 94 95 for endpoint in list(endpoints.keys()): 96 print("Protocol: %s " % endpoints[endpoint]['Protocol']) 97 print("Provider: %s " % endpoints[endpoint]['EXE']) 98 print("UUID : %s %s" % (endpoint, endpoints[endpoint]['annotation'])) 99 print("Bindings: ") 100 for binding in endpoints[endpoint]['Bindings']: 101 print(" %s" % binding) 102 print("") 103 104 if entries: 105 num = len(entries) 106 if 1 == num: 107 logging.info('Received one endpoint.') 108 else: 109 logging.info('Received %d endpoints.' % num) 110 else: 111 logging.info('No endpoints found.') 112 113 114 def __fetchList(self, rpctransport): 115 dce = rpctransport.get_dce_rpc() 116 117 dce.connect() 118 #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_INTEGRITY) 119 #dce.bind(epm.MSRPC_UUID_PORTMAP) 120 #rpcepm = epm.DCERPCEpm(dce) 121 122 resp = epm.hept_lookup(None, dce=dce) 123 124 dce.disconnect() 125 126 return resp 127 128 129 # Process command-line arguments. 130 if __name__ == '__main__': 131 # Init the example's logger theme 132 logger.init() 133 print(version.BANNER) 134 135 parser = argparse.ArgumentParser(add_help = True, description = "Dumps the remote RPC enpoints information.") 136 parser.add_argument('target', action='store', help='[[domain/]username[:password]@]<targetName or address>') 137 parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 138 139 group = parser.add_argument_group('connection') 140 141 group.add_argument('-target-ip', action='store', metavar="ip address", help='IP Address of the target machine. If ' 142 'ommited it will use whatever was specified as target. This is useful when target is the NetBIOS ' 143 'name and you cannot resolve it') 144 group.add_argument('-port', choices=['135', '139', '445'], nargs='?', default='135', metavar="destination port", 145 help='Destination port to connect to SMB Server') 146 147 group = parser.add_argument_group('authentication') 148 149 group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 150 if len(sys.argv)==1: 151 parser.print_help() 152 sys.exit(1) 153 154 options = parser.parse_args() 155 156 if options.debug is True: 157 logging.getLogger().setLevel(logging.DEBUG) 158 else: 159 logging.getLogger().setLevel(logging.INFO) 160 161 import re 162 domain, username, password, remoteName = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match(options.target).groups('') 163 164 #In case the password contains '@' 165 if '@' in remoteName: 166 password = password + '@' + remoteName.rpartition('@')[0] 167 remoteName = remoteName.rpartition('@')[2] 168 169 if domain is None: 170 domain = '' 171 172 if password == '' and username != '' and options.hashes is None: 173 from getpass import getpass 174 password = getpass("Password:") 175 176 if options.target_ip is None: 177 options.target_ip = remoteName 178 179 dumper = RPCDump(username, password, domain, options.hashes, int(options.port)) 180 181 dumper.dump(remoteName, options.target_ip)