def scan_log(scan_id): """ :param scan_id: The scan ID to retrieve the scan :return: The scan log contents, paginated using 200 entries per page """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') if scan_info.output is None: abort(404, 'Scan output not found') page = request.args.get('page', None) _id = request.args.get('id', None) if page is not None and not page.isdigit(): abort(400, 'Invalid page number') if _id is not None and not _id.isdigit(): abort(400, 'Invalid log id') if page is not None and _id is not None: abort(400, 'Can only paginate using one of "page" or "id"') next, next_url, log_entries = paginate_logs(scan_id, scan_info, page, _id) return jsonify({'next': next, 'next_url': next_url, 'entries': log_entries})
def exception_creator(scan_id): """ Mostly for testing, but have fun playing ;) :return: None, just create a new exception in the exception handler for this scan, helps me with the unittest process. """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') current_status = FakeStatus(None) current_status.set_running_plugin('phase', 'plugin') current_status.set_current_fuzzable_request('phase', 'http://www.w3af.org/') try: raise Exception('unittest') except Exception, exception: exec_info = sys.exc_info() enabled_plugins = '' scan_info.w3af_core.exception_handler.write_crash_file = lambda x: x scan_info.w3af_core.exception_handler.handle(current_status, exception, exec_info, enabled_plugins)
def scan_log(scan_id): """ :param scan_id: The scan ID to retrieve the scan :return: The scan log contents, paginated using 200 entries per page """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') if scan_info.output is None: abort(404, 'Scan output not found') page = request.args.get('page', None) _id = request.args.get('id', None) if page is not None and not page.isdigit(): abort(400, 'Invalid page number') if _id is not None and not _id.isdigit(): abort(400, 'Invalid log id') if page is not None and _id is not None: abort(400, 'Can only paginate using one of "page" or "id"') next, next_url, log_entries = paginate_logs(scan_id, scan_info, page, _id) return jsonify({ 'next': next, 'next_url': next_url, 'entries': log_entries })
def list_kb(scan_id): """ List vulnerabilities stored in the KB (for a specific scan) Filters: * /scans/0/kb/?name= returns only vulnerabilities which contain the specified string in the vulnerability name. (contains) * /scans/0/kb/?url= returns only vulnerabilities for a specific URL (startswith) If more than one filter is specified they are combined using AND. :return: A JSON containing a list of: - KB resource URL (eg. /scans/0/kb/3) - The KB id (eg. 3) - The vulnerability name - The vulnerability URL - Location A - Location B """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') data = [] for finding_id, finding in enumerate(kb.kb.get_all_findings()): if matches_filter(finding, request): data.append(finding_to_json(finding, scan_id, finding_id)) return jsonify({'items': data})
def list_kb(scan_id): """ List vulnerabilities stored in the KB (for a specific scan) Filters: * /scans/0/kb/?name= returns only vulnerabilities which contain the specified string in the vulnerability name. (contains) * /scans/0/kb/?url= returns only vulnerabilities for a specific URL (startswith) If more than one filter is specified they are combined using AND. :return: A JSON containing a list of: - KB resource URL (eg. /scans/0/kb/3) - The KB id (eg. 3) - The vulnerability name - The vulnerability URL - Location A - Location B """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') data = [] for finding_id, finding in enumerate(kb.kb.get_all_findings()): if matches_filter(finding, request): data.append(finding_to_json(finding, scan_id, finding_id, True)) return jsonify({'items': data})
def get_traffic_details(scan_id, traffic_id): """ The HTTP request and response associated with a vulnerability, usually the user will first get /scans/1/kb/3 and from there (if needed) browse to this resource where the HTTP traffic is available :param scan_id: The scan ID :param traffic_id: The ID of the request/response :return: HTTP request and response in base64 format """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') history_db = HistoryItem() try: details = history_db.read(traffic_id) except DBException: msg = 'Failed to retrieve request with id %s from DB.' abort(404, msg) return data = { 'request': b64encode(details.request.dump()), 'response': b64encode(details.response.dump()) } return jsonify(data)
def get_traffic_details(scan_id, traffic_id): """ The HTTP request and response associated with a vulnerability, usually the user will first get /scans/1/kb/3 and from there (if needed) browse to this resource where the HTTP traffic is available :param scan_id: The scan ID :param traffic_id: The ID of the request/response :return: HTTP request and response in base64 format """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') history_db = HistoryItem() try: details = history_db.read(traffic_id) except DBException: msg = 'Failed to retrieve request with id %s from DB.' abort(404, msg) return data = {'request': b64encode(details.request.dump()), 'response': b64encode(details.response.dump())} return jsonify(data)
def get_url_list(scan_id): """ A list with all the known URLs by this scanner :param scan_id: The scan ID :return: URLs in a list """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') data = [str(u) for u in kb.kb.get_all_known_urls()] return jsonify({'items': data})
def scan_status(scan_id): """ :param scan_id: The scan ID :return: The scan status """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') exc = scan_info.exception status = scan_info.w3af_core.status.get_status_as_dict() status['exception'] = exc if exc is None else str(exc) return jsonify(status)
def list_kb(scan_id): """ List vulnerabilities stored in the KB (for a specific scan) Filters: * /scans/0/kb/?name= returns only vulnerabilities which contain the specified string in the vulnerability name. (contains) * /scans/0/kb/?url= returns only vulnerabilities for a specific URL (startswith) If more than one filter is specified they are combined using AND. :return: A JSON containing a list of: - KB resource URL (eg. /scans/0/kb/3) - The KB id (eg. 3) - The vulnerability name - The vulnerability URL - Location A - Location B """ scanData = scanGetWithScanId(scan_id) if scanData != None and scanData.scanResult != None: return jsonify({'items': scanData.scanResult}) scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') data = [] print 'hostname', urlparse(scanGetUrl(scan_id)).hostname hostname = urlparse(scanGetUrl(scan_id)).hostname for finding_id, finding in enumerate(kb.kb.get_all_findings()): if finding.get_url() == None: continue; if matches_filter(finding, request) and urlparse(finding.get_url().url_string).hostname==hostname: data.append(finding_to_json(finding, scan_id, finding_id)) for id, scan_info in SCANS.iteritems(): if scan_info is None: continue target_urls = scan_info.target_urls status = scan_info.w3af_core.status.get_simplified_status() errors = True if scan_info.exception is not None else False if (errors == False and scan_id == id and status == 'Stopped'): scanData.scanResult = data return jsonify({'items': data})
def get_kb(scan_id, vulnerability_id): """ The whole information related to the specified vulnerability ID :param vulnerability_id: The vulnerability ID to query :return: All the vulnerability information """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') for finding_id, finding in enumerate(kb.kb.get_all_findings()): if vulnerability_id == finding_id: return jsonify( finding_to_json(finding, scan_id, finding_id, detailed=True)) abort(404, 'Not found')
def get_fuzzable_request_list(scan_id): """ A list with all the known fuzzable requests by this scanner :param scan_id: The scan ID :return: Fuzzable requests (serialized as base64 encoded string) in a list """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') data = [] for fuzzable_request in kb.kb.get_all_known_fuzzable_requests(): data.append(b64encode(fuzzable_request.dump())) return jsonify({'items': data})
def get_kb(scan_id, vulnerability_id): """ The whole information related to the specified vulnerability ID :param vulnerability_id: The vulnerability ID to query :return: All the vulnerability information """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') for finding_id, finding in enumerate(kb.kb.get_all_findings()): if vulnerability_id == finding_id: return jsonify(finding_to_json(finding, scan_id, finding_id, detailed=True)) abort(404, 'Not found')
def scan_pause(scan_id): """ Pause a scan :param scan_id: The scan ID to pause :return: Empty result if success, 403 if the current state indicates that the scan can't be paused. """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') if not scan_info.w3af_core.can_pause(): abort(403, 'Scan can not be paused') scan_info.w3af_core.pause() return jsonify({'message': 'Success'})
def get_exception_details(scan_id, exception_id): """ The whole information related to the specified exception ID :param exception_id: The exception ID to query :return: All the vulnerability information """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') all_exceptions = scan_info.w3af_core.exception_handler.get_all_exceptions() for i_exception_id, exception_data in enumerate(all_exceptions): if exception_id == i_exception_id: return jsonify(exception_to_json(exception_data, scan_id, exception_id, detailed=True)) abort(404, 'Not found')
def scan_delete(scan_id): """ Clear all the scan information :param scan_id: The scan ID to stop :return: Empty result if success, 403 if the current state indicates that the scan can't be cleared. """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') if not scan_info.w3af_core.can_cleanup(): abort(403, 'Scan is not ready to be cleared') scan_info.w3af_core.cleanup() SCANS[scan_id] = None return jsonify({'message': 'Success'})
def scan_stop(scan_id): """ Stop a scan :param scan_id: The scan ID to stop :return: Empty result if success, 403 if the current state indicates that the scan can't be stopped. """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') if not scan_info.w3af_core.can_stop(): abort(403, 'Scan can not be stop') t = Process(target=scan_info.w3af_core.stop, name='ScanStopThread', args=()) t.daemon = True t.start() return jsonify({'message': 'Stopping scan'})
def scan_delete(scan_id): """ Clear all the scan information :param scan_id: The scan ID to stop :return: Empty result if success, 403 if the current state indicates that the scan can't be cleared. """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') if scan_info.w3af_core is None: abort(400, 'Scan state is invalid and can not be cleared') if not scan_info.w3af_core.can_cleanup(): abort(403, 'Scan is not ready to be cleared') scan_info.cleanup() SCANS[scan_id] = None return jsonify({'message': 'Success'})
def list_exceptions(scan_id): """ List all exceptions found during a scan :return: A JSON containing a list of: - Exception resource URL (eg. /scans/0/exceptions/3) - The exceptions id (eg. 3) - Exception string - Exception file name - Exception line number """ scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') data = [] all_exceptions = scan_info.w3af_core.exception_handler.get_all_exceptions() for exception_id, exception_data in enumerate(all_exceptions): data.append(exception_to_json(exception_data, scan_id, exception_id)) return jsonify({'items': data})
def list_url(scan_id): scan_info = get_scan_info_from_id(scan_id) if scan_info is None: abort(404, 'Scan not found') return jsonify({'items': CrawlUrls().get()})