def scan(self): command = ( '{masscan_bin} -oX {result_xml} --rate={rate} --retries={retries} --wait={wait} -p {ports} {hosts}' ).format(masscan_bin=self.masscan_bin, result_xml=self.result_xml, rate=self.rate, retries=self.retries, wait=self.wait, hosts=self.hosts, ports=self.ports) process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) try: _, stderr = process.communicate() if not stderr.startswith(b'\nStarting masscan'): logger.failure('Masscan Error\n{}'.format(stderr)) os._exit(1) except KeyboardInterrupt: logger.failure('User aborted') os._exit(1)
def get_plugins(path='./plugins'): """Get plugins object via PluginBase.""" if os.path.exists(path): plugin_base = PluginBase(package='scan_plugins') plugin_source = plugin_base.make_plugin_source(searchpath=[path]) return plugin_source else: logger.failure( 'The plugin directory was not found (default: ./plugins).') sys.exit(1)
def exception_handler(pattern, func, url, params): """Exception handler""" result = {} try: result = func(url, params) except Exception as e: file_name = os.path.splitext(os.path.basename(func.__code__.co_filename))[0] if pattern == 'vuln': result.update({'url': url, 'plugin': file_name, 'success': 'Exception'}) logger.failure('Error: {}\n{}\n'.format(file_name, e)) return result
def prepare_result(url, success, data={}): """Prepare the result via the values that the plugins have returned.""" plugin = os.path.splitext(os.path.basename(inspect.stack()[1][1]))[0] if data: if success: logger.success('Success! {} -- {}\n{}\n'.format( url, plugin, pformat(data))) else: logger.failure('Failed. {} -- {}\n{}\n'.format( url, plugin, pformat(data))) else: if success: logger.success('Success! {} -- {}\n'.format(url, plugin)) else: logger.failure('Failed. {} -- {}\n'.format(url, plugin)) return {'url': url, 'plugin': plugin, 'success': success, 'data': data}
def save_result(pattern, result, output='', db=False): """Save the result.""" if pattern == 'port': table = _set_port_table(result) elif pattern == 'vuln': table = _set_vuln_table(result) else: table = _set_sens_table(result) logger.info('Here is the result: ') print(table) if output: with open(output, 'w') as f: json.dump(result, f, default=str) if db: try: mongo_client = MongoClient(config.MONGODB_URI) db = mongo_client[config.MONGODB_DATABASE] if pattern == 'port': collection = db[config.MONGODB_PORT_COLLECTION] elif pattern == 'vuln': collection = db[config.MONGODB_VULN_COLLECTION] else: collection = db[config.MONGODB_SENS_COLLECTION] for data in result: if pattern == 'port': query = {'host': data['host'], 'port': data['port']} elif pattern == 'vuln': query = {'url': data['url'], 'plugin': data['plugin']} else: query = {'url': data['url'], 'sens': data['sens']} collection.update(query, data, upsert=True) except PyMongoError as e: logger.failure('Failed to save to database\n{}'.format(e)) os._exit(1)
def run_threads(targets, args, plugins=None): """Create a thread pool and run the task""" thread_num = int(args.threads) result = [] with ThreadPoolExecutor(max_workers=thread_num) as executor: if args.pattern == 'vuln': task_list = _run_vuln_task(executor, targets, plugins, args) else: task_list = _run_sens_task(executor, targets, args) try: for future in as_completed(task_list): if future.result(): result.append(future.result()) except KeyboardInterrupt: logger.failure('User aborted') os._exit(1) return result