github.com/n00py/Slackor@v0.0.0-20200610224921-d007fcea1740/impacket/examples/wmiquery.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 # Description: [MS-WMI] example. It allows to issue WQL queries and 9 # get description of the objects. 10 # 11 # e.g.: select name from win32_account 12 # e.g.: describe win32_process 13 # 14 # Author: 15 # Alberto Solino (@agsolino) 16 # 17 # Reference for: 18 # DCOM 19 # 20 from __future__ import division 21 from __future__ import print_function 22 import argparse 23 import sys 24 import os 25 import logging 26 27 from impacket.examples import logger 28 from impacket import version 29 from impacket.dcerpc.v5.dtypes import NULL 30 from impacket.dcerpc.v5.dcom import wmi 31 from impacket.dcerpc.v5.dcomrt import DCOMConnection 32 from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 33 34 if __name__ == '__main__': 35 import cmd 36 37 class WMIQUERY(cmd.Cmd): 38 def __init__(self, iWbemServices): 39 cmd.Cmd.__init__(self) 40 self.iWbemServices = iWbemServices 41 self.prompt = 'WQL> ' 42 self.intro = '[!] Press help for extra shell commands' 43 44 def do_help(self, line): 45 print(""" 46 lcd {path} - changes the current local directory to {path} 47 exit - terminates the server process (and this session) 48 describe {class} - describes class 49 ! {cmd} - executes a local shell cmd 50 """) 51 52 def do_shell(self, s): 53 os.system(s) 54 55 def do_describe(self, sClass): 56 sClass = sClass.strip('\n') 57 if sClass[-1:] == ';': 58 sClass = sClass[:-1] 59 try: 60 iObject, _ = self.iWbemServices.GetObject(sClass) 61 iObject.printInformation() 62 iObject.RemRelease() 63 except Exception as e: 64 if logging.getLogger().level == logging.DEBUG: 65 import traceback 66 traceback.print_exc() 67 logging.error(str(e)) 68 69 def do_lcd(self, s): 70 if s == '': 71 print(os.getcwd()) 72 else: 73 os.chdir(s) 74 75 def printReply(self, iEnum): 76 printHeader = True 77 while True: 78 try: 79 pEnum = iEnum.Next(0xffffffff,1)[0] 80 record = pEnum.getProperties() 81 if printHeader is True: 82 print('|', end=' ') 83 for col in record: 84 print('%s |' % col, end=' ') 85 print() 86 printHeader = False 87 print('|', end=' ') 88 for key in record: 89 if type(record[key]['value']) is list: 90 for item in record[key]['value']: 91 print(item, end=' ') 92 print(' |', end=' ') 93 else: 94 print('%s |' % record[key]['value'], end=' ') 95 print() 96 except Exception as e: 97 if logging.getLogger().level == logging.DEBUG: 98 import traceback 99 traceback.print_exc() 100 if str(e).find('S_FALSE') < 0: 101 raise 102 else: 103 break 104 iEnum.RemRelease() 105 106 def default(self, line): 107 line = line.strip('\n') 108 if line[-1:] == ';': 109 line = line[:-1] 110 try: 111 iEnumWbemClassObject = self.iWbemServices.ExecQuery(line.strip('\n')) 112 self.printReply(iEnumWbemClassObject) 113 iEnumWbemClassObject.RemRelease() 114 except Exception as e: 115 logging.error(str(e)) 116 117 def emptyline(self): 118 pass 119 120 def do_exit(self, line): 121 return True 122 123 # Init the example's logger theme 124 logger.init() 125 print(version.BANNER) 126 127 parser = argparse.ArgumentParser(add_help = True, description = "Executes WQL queries and gets object descriptions " 128 "using Windows Management Instrumentation.") 129 parser.add_argument('target', action='store', help='[[domain/]username[:password]@]<targetName or address>') 130 parser.add_argument('-namespace', action='store', default='//./root/cimv2', help='namespace name (default //./root/cimv2)') 131 parser.add_argument('-file', type=argparse.FileType('r'), help='input file with commands to execute in the WQL shell') 132 parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 133 134 group = parser.add_argument_group('authentication') 135 136 group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 137 group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 138 group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 139 '(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ' 140 'ones specified in the command line') 141 group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 142 '(128 or 256 bits)') 143 group.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. If ' 144 'ommited it use the domain part (FQDN) specified in the target parameter') 145 group.add_argument('-rpc-auth-level', choices=['integrity', 'privacy','default'], nargs='?', default='default', 146 help='default, integrity (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) or privacy ' 147 '(RPC_C_AUTHN_LEVEL_PKT_PRIVACY). For example CIM path "root/MSCluster" would require ' 148 'privacy level by default)') 149 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 163 domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match( 164 options.target).groups('') 165 166 #In case the password contains '@' 167 if '@' in address: 168 password = password + '@' + address.rpartition('@')[0] 169 address = address.rpartition('@')[2] 170 171 if domain is None: 172 domain = '' 173 174 if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 175 from getpass import getpass 176 password = getpass("Password:") 177 178 if options.aesKey is not None: 179 options.k = True 180 181 if options.hashes is not None: 182 lmhash, nthash = options.hashes.split(':') 183 else: 184 lmhash = '' 185 nthash = '' 186 187 try: 188 dcom = DCOMConnection(address, username, password, domain, lmhash, nthash, options.aesKey, oxidResolver=True, 189 doKerberos=options.k, kdcHost=options.dc_ip) 190 191 iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) 192 iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) 193 iWbemServices= iWbemLevel1Login.NTLMLogin(options.namespace, NULL, NULL) 194 if options.rpc_auth_level == 'privacy': 195 iWbemServices.get_dce_rpc().set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 196 elif options.rpc_auth_level == 'integrity': 197 iWbemServices.get_dce_rpc().set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) 198 199 iWbemLevel1Login.RemRelease() 200 201 shell = WMIQUERY(iWbemServices) 202 if options.file is None: 203 shell.cmdloop() 204 else: 205 for line in options.file.readlines(): 206 print("WQL> %s" % line, end=' ') 207 shell.onecmd(line) 208 209 iWbemServices.RemRelease() 210 dcom.disconnect() 211 except Exception as e: 212 logging.error(str(e)) 213 try: 214 dcom.disconnect() 215 except: 216 pass