Commit version 24.12.13800
This commit is contained in:
201
scripts/wmic
Executable file
201
scripts/wmic
Executable file
@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2015 David Lundgren
|
||||
#
|
||||
# Python WMI Client
|
||||
#
|
||||
# Can be used in place of wmic when using check_wmi_plus.pl with Nagios.
|
||||
#
|
||||
# @author David Lundgren (@drlundgren)
|
||||
#
|
||||
# https://github.com/ProjectPatatoe/py-wmi-client/
|
||||
#
|
||||
# need additional packages:
|
||||
# sudo pip3 install natsort
|
||||
# sudo pip3 install impacket
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
import configparser
|
||||
|
||||
from natsort import natsorted, ns
|
||||
from impacket.dcerpc.v5.dtypes import NULL
|
||||
from impacket.dcerpc.v5.dcom import wmi
|
||||
from impacket.dcerpc.v5.dcomrt import DCOMConnection
|
||||
|
||||
APP_VERSION = '0.1.0'
|
||||
|
||||
|
||||
class WmiClient(object):
|
||||
"""WMI Client"""
|
||||
|
||||
def __init__(self, auth, host):
|
||||
"""
|
||||
|
||||
:param auth:
|
||||
:param host:
|
||||
"""
|
||||
self.auth = auth
|
||||
self.host = host
|
||||
|
||||
def get_language(self, lang):
|
||||
"""
|
||||
Retrieve the language passed in from int to string
|
||||
|
||||
:param lang: string
|
||||
:return:
|
||||
"""
|
||||
if lang == 552:
|
||||
return 'en-US'
|
||||
return '??-??'
|
||||
|
||||
def format_value(self, value, cimtype, type):
|
||||
"""
|
||||
Formats the value based on the cimtype and type
|
||||
|
||||
:param value:
|
||||
:param cimtype: string
|
||||
:param type: int
|
||||
:return:
|
||||
"""
|
||||
if cimtype == 'string':
|
||||
if value == 0:
|
||||
return '(null)'
|
||||
else:
|
||||
return str(value).strip()
|
||||
elif cimtype == 'boolean': # boolean
|
||||
if value == 'True':
|
||||
return 'True'
|
||||
else:
|
||||
return 'False'
|
||||
elif value is None:
|
||||
if cimtype == 'uint32' or cimtype == 'uint64':
|
||||
return '0'
|
||||
else:
|
||||
return ('%s' % value).strip()
|
||||
|
||||
def print_results(self, queryObject, delimiter):
|
||||
"""
|
||||
Prints the results in the classObject as wmic.c would
|
||||
|
||||
:param queryObject: IEnumWbemClassObject
|
||||
:param delimiter: string
|
||||
:return:
|
||||
"""
|
||||
|
||||
while True:
|
||||
try:
|
||||
classObject = queryObject.Next(0xffffffff, 1)[0]
|
||||
print('CLASS: %s' % classObject.getClassName())
|
||||
record = classObject.getProperties()
|
||||
keys = []
|
||||
for name in record:
|
||||
keys.append(name.strip())
|
||||
keys = natsorted(keys, alg=ns.IGNORECASE)
|
||||
print(delimiter.join(keys))
|
||||
tmp = []
|
||||
for key in keys:
|
||||
if key == 'MUILanguages':
|
||||
vals = []
|
||||
for v in record[key]['value']:
|
||||
vals.append(self.get_language(v))
|
||||
record[key]['value'] = vals
|
||||
|
||||
if isinstance(record[key]['value'], list):
|
||||
values = []
|
||||
for v in record[key]['value']:
|
||||
values.append(
|
||||
self.format_value(v, record[key]['qualifiers']['CIMTYPE'], record[key]['type']))
|
||||
tmp.append('(%s)' % ','.join(values))
|
||||
else:
|
||||
tmp.append('%s' % self.format_value(record[key]['value'], record[key]['qualifiers']['CIMTYPE'],
|
||||
record[key]['type']))
|
||||
print(delimiter.join(tmp))
|
||||
except Exception as e:
|
||||
if e.get_error_code() != wmi.WBEMSTATUS.WBEM_S_FALSE:
|
||||
raise
|
||||
else:
|
||||
break
|
||||
|
||||
def query_and_print(self, wql, **kwargs):
|
||||
"""
|
||||
Querys and prints the results
|
||||
|
||||
:param wql:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
namespace = '//./root/cimv2'
|
||||
delimiter = '|'
|
||||
conn = None
|
||||
classObject = None
|
||||
wmiService = None
|
||||
wmiLogin = None
|
||||
|
||||
if 'namespace' in kwargs:
|
||||
namespace = kwargs['namespace']
|
||||
if 'delimiter' in kwargs:
|
||||
delimiter = kwargs['delimiter']
|
||||
|
||||
try:
|
||||
conn = DCOMConnection(self.host, self.auth['username'], self.auth['password'], self.auth['domain'], '', '',
|
||||
None, oxidResolver=True, doKerberos=False)
|
||||
wmiInterface = conn.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
|
||||
wmiLogin = wmi.IWbemLevel1Login(wmiInterface)
|
||||
wmiService = wmiLogin.NTLMLogin(namespace, NULL, NULL)
|
||||
wmiLogin.RemRelease()
|
||||
|
||||
queryObject = wmiService.ExecQuery(wql.strip('\n'),
|
||||
wmi.WBEM_FLAG_RETURN_IMMEDIATELY | wmi.WBEM_FLAG_ENSURE_LOCATABLE)
|
||||
self.print_results(queryObject, delimiter)
|
||||
queryObject.RemRelease()
|
||||
|
||||
wmiService.RemRelease()
|
||||
conn.disconnect()
|
||||
except Exception as e:
|
||||
if classObject is not None:
|
||||
classObject.RemRelease()
|
||||
if wmiLogin is not None:
|
||||
wmiLogin.RemRelease()
|
||||
if wmiService is not None:
|
||||
wmiService.RemRelease()
|
||||
if conn is not None:
|
||||
conn.disconnect()
|
||||
raise Exception("Could not connect to %s: %s" % (self.host, str(e)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="WMI client")
|
||||
parser.add_argument('-U', '--user', dest='user', help="[DOMAIN\]USERNAME[%%PASSWORD]")
|
||||
parser.add_argument('-A', '--authentication-file', dest='authfile', help="Authentication file")
|
||||
parser.add_argument('--delimiter', default='|', help="delimiter, default: |")
|
||||
parser.add_argument('--namespace', default='//./root/cimv2', help='namespace name (default //./root/cimv2)')
|
||||
parser.add_argument('host', metavar="//host")
|
||||
parser.add_argument('wql', metavar="query")
|
||||
|
||||
options = parser.parse_args()
|
||||
|
||||
auth = {
|
||||
'username': '',
|
||||
'password': '',
|
||||
'domain': ''
|
||||
}
|
||||
if options.authfile is not None:
|
||||
authfile = '[root]\n' + open(options.authfile, 'r').read()
|
||||
config = configparser.ConfigParser()
|
||||
config.read_string(authfile)
|
||||
auth['domain'] = config.get('root', 'domain', fallback='WORKGROUP')
|
||||
auth['username'] = config.get('root', 'username')
|
||||
auth['password'] = config.get('root', 'password')
|
||||
elif options.user is not None:
|
||||
auth['domain'], auth['username'], auth['password'] = re.compile(
|
||||
'(?:(?:([^/\\\\%]*)[/\\\\])?([^%]*))(?:%(.*))?').match(options.user).groups('')
|
||||
else:
|
||||
print("Missing user information")
|
||||
sys.exit(1)
|
||||
|
||||
if auth['domain'] == '':
|
||||
auth['domain'] = 'WORKGROUP'
|
||||
|
||||
WmiClient(auth, options.host[2:]).query_and_print(options.wql, namespace=options.namespace,
|
||||
delimiter=options.delimiter)
|
Reference in New Issue
Block a user