def run_scans(cls, ondemand: bool = False) -> None: clear_targets() g = group(nmap_scan.s(target) for target in targets).apply_async(queue='discovery') if ondemand: g.get(on_message=cls.push_update, propagate=False) send_msg('Scan finished.') socketio.emit('scan finished', {}, broadcast=True)
def admin_ws(data): command = data['command'] if command == 'restart': restart_redbot() elif command == 'clear': from redbot.modules.discovery import clear_targets clear_targets() send_msg("Targets cleared.", "warning") log("Targets cleared.", style="warning") for key in storage.smembers('notes'): storage.delete('notes:' + key) elif command == 'clearlogs': storage.delete('log') send_msg("Logs cleared.", "warning") elif command == 'testattack': if data.get('attack'): r = get_class(data['attack']) else: r = get_random_attack() try: result, targets = r.run_attack() except NoTargetsError: send_msg( "There are no hosts to target! Ensure that discovery is properly configured and has been run " "first.", "danger") log("Test attack {} failed with no hosts to target.".format( r.name), style="danger") except Exception as e: send_msg("Failed running attack module '{}': {}".format(r.name, e), "danger") log("Test attack {} failed with {}".format(r.name, e), style="danger") else: send_msg( "Running attack module '{}' against {} targets.".format( r.name, len(targets)), "success") elif command == 'reload': parse('config.yml') emit('reload')
def nmap(): from redbot.modules.discovery import do_discovery log("Discovery scan invoked from web.", "web") send_msg("Running scan.") do_discovery(force=True)
def settings_ws(data): if data['module'] in modules: try: cls = get_class(data['module']) except (AttributeError, ImportError): send_msg("Settings for that module cannot be modified.", "warning") return try: cls.set_setting(data['key'], data['value']) except Exception as e: send_msg("There was an error updating settings.", "danger") log(str(e), style="danger") else: send_msg("Settings updated.", "success") elif data['module'] == 'redbot.core': try: set_core_setting(data['key'], data['value']) except Exception as e: raise e send_msg("There was an error updating settings.", "danger") log(str(e), style="danger") else: send_msg("Settings updated.", "success") else: send_msg("Selected module does not exist.", "warning")
def update_iscore_targets() -> None: """ Performs service discovery via IScorE's API. A list of all service scans are fetched, and the hostnames provided for these services are resolved to IP address so they can be stored in the hosts database. Services that are marked up are added to the hosts database, or the database information is updated if the entry already exists. Requires a privileged IScorE API key in order to quickly resolve hosts, else it may be very slow/network intensive while many DNS queries are performed. """ storage.set('last_iscore_update', int(time())) # Fetch service statuses from API try: r = requests.get(get_url() + 'servicestatus', headers={'Content-Type': 'application/json'}) r.raise_for_status() r = r.json() except MissingSchema: send_msg( 'IScorE update failed. Check that a valid IScorE URL was provided.', 'danger') return except HTTPError as e: send_msg('Error when contacting IScorE: ' + str(e), 'danger') return except JSONDecodeError: send_msg("IScorE didn't return valid JSON.", 'danger') return hosts = {} records = {} # Resolve service hostnames to IP addresses, as they will be stored if Discovery.get_setting('iscore_api'): try: r2 = requests.get(get_url() + 'dns', headers={ 'Content-Type': 'application/json', 'Authorization': 'Token ' + Discovery.get_setting('iscore_api').strip() }) r2.raise_for_status() r2 = r2.json() except HTTPError as e: send_msg('Error with IScorE API: ' + str(e), 'danger') return except JSONDecodeError: send_msg("IScorE API didn't return valid JSON.", 'danger') return for rec in r2: records['{}.team{}.{}'.format(rec['name'], rec['team_number'], TEAM_DOMAIN_SUFFIX)] = rec['value'] else: # Low performance fallback method to obtain IP addresses using DNS lookups = group(dns_lookup.s(host['service_url'] for host in r)) [records.update(l) for l in lookups.get()] for host in r: hostn = records.get(host['service_url'], host['service_url']) if not host['service_status'] == 'down': ports = hosts.get(hostn, {}).get('ports', {}) hosts[hostn] = { 'ports': ports, 'target': "Team " + str(host['team_number']), 'notes': [], } if not hosts[hostn].get('hostname'): hosts[hostn]['hostname'] = host['service_url'] hosts[hostn]['ports'][str(host['service_port'])] = { 'port': host['service_port'], 'banner': "IScorE Service: " + host['service_name'] } update_hosts(hosts) send_msg('IScorE update finished.') socketio.emit('scan finished', {}, broadcast=True)