Beispiel #1
0
 def zap(config):
     if 'supervisor.sock no such file' in execute(
             'supervisorctl restart zap')[0].decode('utf-8'):
         execute('/usr/bin/supervisord', communicate=False)
     status = execute('zap-cli status')[0].decode('utf-8')
     while 'ZAP is running' not in status:
         sleep(10)
         status = execute('zap-cli status')[0].decode('utf-8')
     if config.get('zap_context_file_path', None):
         context = os.path.join('/tmp', config.get('zap_context_file_path'))
         if os.path.exists(context):
             execute(
                 f'zap-cli context import /tmp/{config.get("zap_context_file_path")}'
             )
             execute(
                 f'zap-cli quick-scan -s {config.get("scan_types", "xss,sqli")} {config.get("params", "")}'
                 f' -c "{context}" -l Informational'
                 f' {config.get("protocol")}://{config.get("host")}:{config.get("port")}'
             )
     else:
         execute(
             f'zap-cli quick-scan -s {config.get("scan_types", "xss,sqli")} {config.get("params", "")}'
             f'-l Informational {config.get("protocol")}://{config.get("host")}:{config.get("port")}'
         )
     execute('zap-cli report -o /tmp/zap.xml -f xml')
     result = ZapXmlParser('/tmp/zap.xml', "ZAP").items
     execute('supervisorctl stop zap')
     common_post_processing(config, result, "ZAP")
     return result
Beispiel #2
0
 def nmap(config):
     excluded_addon = f'--exclude-ports {config.get("exclusions", None)}' if config.get(
         "exclusions", None) else ""
     ports = config.get("inclusions", "0-65535")
     nse_scripts = config.get(
         "nse_scripts",
         "ssl-date,http-mobileversion-checker,http-robots.txt,http-title,"
         "http-waf-detect,http-chrono,http-headers,http-comments-displayer,"
         "http-date")
     exec_cmd = f'nmap -PN -p{ports} {excluded_addon} ' \
                f'--min-rate 1000 --max-retries 0 --max-rtt-timeout 200ms ' \
                f'{config["host"]}'
     res = execute(exec_cmd)
     tcp_ports = ''
     udp_ports = ''
     for each in re.findall(r'([0-9]*/[tcp|udp])', str(res[0])):
         if '/t' in each:
             tcp_ports += f'{each.replace("/t", "")},'
         elif '/u' in each:
             udp_ports += f'{each.replace("/u", "")},'
     ports = f"-pT:{tcp_ports[:-1]}" if tcp_ports else ""
     ports += f" -pU:{udp_ports[:-1]}" if udp_ports else ""
     if not ports:
         return
     params = config.get("params", "-v -sVA")
     exec_cmd = f'nmap {params} {ports} ' \
                f'--min-rate 1000 --max-retries 0 ' \
                f'--script={nse_scripts} {config["host"]} -oX /tmp/nmap.xml'
     execute(exec_cmd)
     result = NmapXMLParser('/tmp/nmap.xml', "NMAP").items
     common_post_processing(config, result, "NMAP")
     return result
Beispiel #3
0
 def python(config):
     exec_cmd = "bandit -r /code --format json"
     res = execute(exec_cmd, cwd='/code')
     with open("/tmp/bandit.json", "w") as f:
         f.write(res[0].decode('utf-8', errors='ignore'))
     result = BanditParser("/tmp/bandit.json", "pybandit").items
     common_post_processing(config, result, "pybandit")
     return result
Beispiel #4
0
 def retirejs(config):
     devdeps = [] if config.get('devdep') \
         else json.load(open('/code/package.json')).get('devDependencies', {}).keys()
     exec_cmd = "retire --jspath=/code --outputformat=json  " \
                "--outputpath=/tmp/retirejs.json --includemeta --exitwith=0"
     res = execute(exec_cmd, cwd='/tmp')
     result = RetireScanParser("/tmp/retirejs.json", "RetireScan",
                               devdeps).items
     common_post_processing(config, result, "RetireScan")
     return result
Beispiel #5
0
 def nikto(config):
     if os.path.exists("/tmp/nikto.xml"):
         os.remove("/tmp/nikto.xml")
     exec_cmd = f'perl nikto.pl {config.get("param", "")} -h {config["host"]} -p {config["port"]} ' \
                f'-Format xml -output /tmp/nikto.xml -Save /tmp/extended_nikto'
     cwd = '/opt/nikto/program'
     execute(exec_cmd, cwd)
     result = NiktoXMLParser("/tmp/nikto.xml", "Nikto").items
     common_post_processing(config, result, "nikto")
     return result
Beispiel #6
0
 def npm(config):
     devdeps = [] if config.get('devdep') \
         else json.load(open('/code/package.json')).get('devDependencies', {}).keys()
     exec_cmd = "npm audit --json"
     res = execute(exec_cmd, cwd='/code')
     with open('/tmp/npm_audit.json', 'w') as npm_audit:
         print(res[0].decode(encoding='ascii', errors='ignore'),
               file=npm_audit)
     result = NpmScanParser("/tmp/npm_audit.json", "NpmScan", devdeps).items
     common_post_processing(config, result, "NpmScan")
     return result
Beispiel #7
0
 def qualys(config):
     qualys_scanner_type = config.get("qualys_scanner_type",
                                      "EXTERNAL").upper()
     # TODO : think on optimization or unification of Qualys pools for Internal scanners
     qualys_scanner = config.get("qualys_scanner", '')
     qualys_scanners_pool = config.get("scanners_pool", '')
     if qualys_scanners_pool:
         qualys_scanners_pool = randrange(1,
                                          int(qualys_scanners_pool) +
                                          1)  # randrange specifics
     qualys_profile_id = config.get("qualys_profile_id", None)
     qualys_template_id = config.get("qualys_template_id", None)
     if not (qualys_profile_id or qualys_template_id):
         return []
     project_name = config.get('project_name')
     target = f'{config.get("protocol")}://{config.get("host")}:{config.get("port")}'
     qualys = WAS()
     ts = datetime.utcfromtimestamp(int(
         time())).strftime('%Y-%m-%d %H:%M:%S')
     project_id = qualys.search_for_project(project_name)
     if qualys_scanner_type == 'INTERNAL':
         scanner_appliance = f"<type>{qualys_scanner_type}</type>" \
                             f"<friendlyName>{qualys_scanner}{qualys_scanners_pool}</friendlyName>"
     else:
         scanner_appliance = f"<type>{qualys_scanner_type}</type>"
     if not project_id:
         project_id = qualys.create_webapp_request(project_name, target,
                                                   qualys_profile_id)
     if not project_id:
         print("Something went wrong and project wasn't found and created")
         return []
     scan_id = qualys.start_scan(project_name, ts, project_id,
                                 qualys_profile_id, scanner_appliance)
     if not scan_id:
         print("Scan haven't been started")
         return []
     while not qualys.scan_status(scan_id):
         sleep(30)
     # qualys.download_scan_report(scan_id)
     report_id = qualys.request_report(project_name, ts, scan_id,
                                       project_id, qualys_template_id)
     if not report_id:
         print("Request report failed")
         return []
     while not qualys.get_report_status(report_id):
         sleep(30)
     qualys.download_report(report_id)
     qualys.delete_asset("report", report_id)
     qualys.delete_asset("wasscan", scan_id)
     qualys.delete_asset("webapp", project_id)
     result = QualysWebAppParser("/tmp/qualys.xml", "qualys_was").items
     common_post_processing(config, result, "qualys_was")
     return result
Beispiel #8
0
 def ruby(config):
     included_checks = ''
     exclude_checks = ''
     if config.get('include_checks', None):
         included_checks = f'-t {config.get("include_checks")} '
     if config.get('exclude_checks', None):
         exclude_checks = f'-x {config.get("exclude_checks")} '
     if config.get('excluded_files', None):
         exclude_checks = f'--skip-files {config.get("excluded_files")} '
     excluded_files = ''
     exec_cmd = f"brakeman {included_checks}{exclude_checks}--no-exit-on-warn --no-exit-on-error {excluded_files}" \
                f"-o /tmp/brakeman.json /code"
     execute(exec_cmd, cwd='/code')
     result = BrakemanParser("/tmp/brakeman.json", "brakeman").items
     common_post_processing(config, result, "brakeman")
     return result
Beispiel #9
0
 def w3af(config):
     config_file = config.get("config_file", "/tmp/w3af_full_audit.w3af")
     w3af_execution_command = f'w3af_console -y -n -s {config_file}'
     with open(config_file, 'r') as f:
         config_content = f.read()
     if '{target}' in config_content:
         config_content = config_content.format(
             target=
             f'{config.get("protocol")}://{config.get("host")}:{config.get("port")}',
             output_section=c.W3AF_OUTPUT_SECTION)
     with open(config_file, 'w') as f:
         f.write(config_content)
     execute(w3af_execution_command)
     result = W3AFXMLParser("/tmp/w3af.xml", "w3af").items
     common_post_processing(config, result, "w3af")
     return result
Beispiel #10
0
 def masscan(config):
     host = config["host"]
     if not (find_ip(host)):
         host = find_ip(str(execute(f'getent hosts {host}')[0]))
         if len(host) > 0:
             host = host[0].strip()
     if host:
         if config.get("exclusions", None):
             excluded_addon = f'--exclude-ports {config.get("exclusions", None)}'
         else:
             excluded_addon = ''
         ports = config.get("inclusions", "0-65535")
         exec_cmd = f'masscan {host} -p {ports} -pU:{ports} --rate 1000 -oJ /tmp/masscan.json {excluded_addon}'
         execute(exec_cmd.strip())
         result = MasscanJSONParser("/tmp/masscan.json", "masscan").items
         common_post_processing(config, result, "masscan")
         return result
     return []
Beispiel #11
0
 def execute_parallel(scan_fns, config, language):
     all_results = []
     params = []
     for fn in scan_fns:
         params.append((fn, config))
     results = run_in_parallel(params)
     for result in results:
         all_results.extend(result)
     filtered_result = common_post_processing(config, all_results, language)
     return filtered_result
Beispiel #12
0
 def nodejs(config):
     exec_cmd = "nodejsscan -o nodejsscan -d /code"
     res = execute(exec_cmd, cwd='/tmp')
     result = NodeJsScanParser("/tmp/nodejsscan.json", "NodeJsScan").items
     common_post_processing(config, result, "NodeJsScan")
     return result
Beispiel #13
0
 def java(config):
     exec_cmd = "spotbugs -xml:withMessages -output /tmp/spotbugs.xml /code"
     res = execute(exec_cmd, cwd='/code')
     result = SpotbugsParser("/tmp/spotbugs.xml", "spotbugs").items
     common_post_processing(config, result, "spotbugs")
     return result
Beispiel #14
0
def main():
    args = parse_args()
    logging_level = logging.DEBUG if args.debug or os.environ.get(
        "debug", False) else logging.INFO

    logging.basicConfig(
        level=logging_level,
        datefmt='%Y.%m.%d %H:%M:%S',
        format='%(asctime)s - %(levelname)8s - %(message)s',
    )
    logging.raiseExceptions = False

    # Disable requests/urllib3 logging
    logging.getLogger("requests").setLevel(logging.WARNING)
    logging.getLogger("urllib3").setLevel(logging.WARNING)

    # Disable qualysapi requests logging
    logging.getLogger("qualysapi.connector").setLevel(logging.WARNING)
    logging.getLogger("qualysapi.config").setLevel(logging.WARNING)
    logging.getLogger("qualysapi.util").setLevel(logging.WARNING)

    start_time = time()

    global_results = []
    global_other_results = []
    global_errors = dict()

    default_config, test_configs = config_from_yaml(args)

    # Enable Loki logging
    enable_loki_logging(default_config)

    for key in test_configs:
        results = []
        other_results = []
        config = test_configs[key]
        if key in constants.SASTY_SCANNERS_CONFIG_KEYS:
            if key == "scan_opts":
                continue
            attr_name = config[key] if 'language' in key else key
            try:
                results = getattr(SastyWrapper, attr_name)(config)
            except BaseException as e:
                logging.error("Exception during %s Scanning" % attr_name)
                global_errors[attr_name] = str(e)
                logging.debug(format_exc())
        else:
            try:
                tool_name, result = getattr(DustyWrapper, key)(config)
                results, other_results = common_post_processing(
                    config,
                    result,
                    tool_name,
                    need_other_results=True,
                    global_errors=global_errors)
            except BaseException as e:
                logging.error("Exception during %s Scanning" % key)
                global_errors[key] = str(e)
                logging.debug(format_exc())

        if default_config.get('jira_service', None) and config.get('jira_service', None) \
                and config.get('jira_service').valid:
            default_config['jira_service'].created_jira_tickets.extend(
                config.get('jira_service').get_created_tickets())

        if default_config.get('generate_html', None) or default_config.get(
                'generate_junit', None):
            global_results.extend(results)
            global_other_results.extend(other_results)

    process_results(default_config,
                    start_time,
                    global_results,
                    other_results=global_other_results,
                    global_errors=global_errors)
    flush_logs()
Beispiel #15
0
 def sslyze(config):
     exec_cmd = f'sslyze --regular --json_out=/tmp/sslyze.json --quiet {config["host"]}:{config["port"]}'
     execute(exec_cmd)
     result = SslyzeJSONParser("/tmp/sslyze.json", "SSlyze").items
     common_post_processing(config, result, "SSlyze")
     return result