def generate_report(self, output_file): Logger.log_verbose("Writing OpenOffice report to file: %s" % output_file) # Load docutils. with catch_warnings(record=True): from docutils.core import publish_file from docutils.writers.odf_odt import Writer, Reader # Create a temporary file for the reStructured Text report. with tempfile(suffix=".rst") as filename: # Generate the report in reStructured Text format. Logger.log_more_verbose("Writing temporary file in rST format...") with open(filename, "w") as source: self.write_report_to_open_file(source) # Convert to OpenOffice format. Logger.log_more_verbose("Converting to OpenOffice format...") with open(filename, "rU") as source: writer = Writer() reader = Reader() with catch_warnings(record=True): with open(output_file, "wb") as destination: publish_file( source=source, destination=destination, destination_path=output_file, reader=reader, writer=writer, )
def __generate_report(self, output_file): Logger.log_verbose( "Writing LaTeX report to file: %s" % output_file) # Load docutils. with warnings.catch_warnings(record=True): from docutils.core import publish_file # Create a temporary file for the reStructured Text report. with tempfile(suffix=".rst") as filename: # Generate the report in reStructured Text format. Logger.log_more_verbose("Writing temporary file in rST format...") with open(filename, "w") as source: self.write_report_to_open_file(source) # Convert to LaTeX format. Logger.log_more_verbose("Converting to LaTeX format...") with open(filename, "rU") as source: with warnings.catch_warnings(record=True): with open(output_file, "wb") as destination: publish_file( source = source, destination = destination, destination_path = output_file, writer_name = "latex", )
def run(self, info): # Build the command line arguments for Nmap. args = shlex.split(Config.plugin_args["args"]) if info.version == 6 and "-6" not in args: args.append("-6") args.append(info.address) # The Nmap output will be saved in XML format in a temporary file. with tempfile(suffix=".xml") as output: args.append("-oX") args.append(output) # Run Nmap and capture the text output. Logger.log("Launching Nmap against: %s" % info.address) Logger.log_more_verbose("Nmap arguments: %s" % " ".join(args)) with ConnectionSlot(info.address): t1 = time() code = run_external_tool("nmap", args, callback=Logger.log_verbose) t2 = time() # Log the output in extra verbose mode. if code: Logger.log_error("Nmap execution failed, status code: %d" % code) else: Logger.log("Nmap scan finished in %s seconds for target: %s" % (t2 - t1, info.address)) # Parse and return the results. return self.parse_nmap_results(info, output)
def generate_report(self, output_file): Logger.log_verbose( "Writing OpenOffice report to file: %s" % output_file) # Load docutils. with catch_warnings(record=True): from docutils.core import publish_file from docutils.writers.odf_odt import Writer, Reader # Create a temporary file for the reStructured Text report. with tempfile(suffix=".rst") as filename: # Generate the report in reStructured Text format. Logger.log_more_verbose("Writing temporary file in rST format...") with open(filename, "w") as source: self.write_report_to_open_file(source) # Convert to OpenOffice format. Logger.log_more_verbose("Converting to OpenOffice format...") with open(filename, "rU") as source: writer = Writer() reader = Reader() with catch_warnings(record=True): with open(output_file, "wb") as destination: publish_file( source = source, destination = destination, destination_path = output_file, reader = reader, writer = writer, )
def recv_info(self, info): # Get the hostname to test. m_host = info.hostname # Workaround for a bug in SSLScan: if the target port doesn't answer # back the SSL handshake (i.e. if port 443 is open but another protocol # is being used) then SSLScan just blocks indefinitely. try: with ConnectionSlot(m_host): s = socket(AF_INET, SOCK_STREAM) try: s.settimeout(4.0) s.connect( (m_host, 443) ) s = wrap_socket(s) s.shutdown(2) finally: s.close() except Exception: Logger.log_error_more_verbose( "Host %r doesn't seem to support SSL, aborting." % m_host) return # Create a temporary output file. with tempfile(suffix = ".xml") as output: # Build the command line arguments. args = [ "--no-failed", "--xml=" + output, # non standard cmdline parsing :( m_host ] # Run SSLScan and capture the text output. Logger.log("Launching SSLScan against: %s" % m_host) Logger.log_more_verbose("SSLScan arguments: %s" % " ".join(args)) with ConnectionSlot(m_host): t1 = time() code = run_external_tool("sslscan", args, callback=Logger.log_verbose) t2 = time() if code: Logger.log_error( "SSLScan execution failed, status code: %d" % code) else: Logger.log("SSLScan scan finished in %s seconds for target: %s" % (t2 - t1, m_host)) # Parse and return the results. r, v = self.parse_sslscan_results(output) if v: Logger.log("Found %s SSL vulnerabilities." % v) else: Logger.log("No SSL vulnerabilities found.") return r
def recv_info(self, info): if not isinstance(info, Url): return if not info.has_url_params and not info.has_post_params: Logger.log("URL '%s' has not parameters" % info.url) return # Get xss script executable xsser_script = self.get_xsser() results = [] args = [ "-u", info.url, ] with tempfile(prefix="tmpxss", suffix=".xml") as filename: args.extend([ "--xml=%s" % filename ]) if info.has_url_params: if self.run_xsser(info.url,xsser_script, args): results.extend(self.parse_xsser_result(info,filename)) if info.has_post_params: args.extend([ "-p", "&".join([ "%s=%s" % (k, v) for k, v in info.post_params.iteritems()]) ]) if self.run_xsser(info.url,xsser_script, args): results.extend(self.parse_xsser_result(info,filename)) if results: Logger.log("Found %s xss vulns." % len(results)) else: Logger.log("No xss vulns found.") return results
def recv_info(self, info): m_host = info.hostname # Create a temporary output file. with tempfile(suffix = ".xml") as output: # Build the command line arguments. args = [ "--no-failed", "--xml=%s" % output, m_host ] # Run Nmap and capture the text output. Logger.log("Launching SSLscan against: %s" % m_host) Logger.log_more_verbose("SSLscan arguments: %s" % " ".join(args)) t1 = time() code = run_external_tool("sslscan", args, callback=Logger.log_verbose) t2 = time() # Log the output in extra verbose mode. if code: Logger.log_error( "SSLscan execution failed, status code: %d" % code) else: Logger.log("SSLscan scan finished in %s seconds for target: %s" % (t2 - t1, m_host)) # Parse and return the results. r = self.parse_sslscan_results(info, output) if r: Logger.log("Found %s SSL vulns." % len(r)) else: Logger.log("No SSL vulns found.") return r
def run(self, info): if not isinstance(info, URL): return if not info.has_url_params and not info.has_post_params: return # Get user args user_args = shlex.split(Config.plugin_args.get("args", [])) # Result info results = [] with tempfile(prefix="tmpxss", suffix=".xml") as filename: args = ["--xml=%s" % filename, "--no-head", "--threads", "1"] # Add the user args args.extend(user_args) if info.has_url_params: # Get payload for config injection point args.extend([ "-u", "%s://%s" % (info.parsed_url.scheme, info.parsed_url.host), ]) # When we want to try GET parameters, we must pass to xsser one by one. for param, value in info.parsed_url.query_params.iteritems(): # Not evaluate web server params if param in WEB_SERVERS_VARS: continue # Prepare and reorder params fixed_params = "&".join([ "%s=%s" % (x, y) for x, y in info.parsed_url.query_params.iteritems() if x != param ]) # Add param to text + fixed params if fixed_params: # -> empty fixed params params = "%s?%s&%s=" % (info.parsed_url.path, fixed_params, param) else: params = "%s?%s=" % (info.parsed_url.path, param) # Prepary args for xsser args.extend(["-g", params]) # Run xsser if self.run_xsser(info.hostname, info.url, args): results.extend(self.parse_xsser_result(info, filename)) if info.has_post_params: args.extend([ "-u", info.url, "-p", "&".join([ "%s=%s" % (k, v) for k, v in info.post_params.iteritems() if k not in WEB_SERVERS_VARS ]), ]) if self.run_xsser(info.hostname, info.url, args): results.extend(self.parse_xsser_result(info, filename)) if results: Logger.log("Found %s XSS vulnerabilities." % len(results)) else: Logger.log_verbose("No XSS vulnerabilities found.") return results
def run(self, info): # Get the path to the Nikto scanner and the configuration file. nikto_script, config = self.get_nikto() # Build the command line arguments. # The -output argument will be filled by run_nikto. args = [ "-host", info.hostname, "-ssl" if info.is_https else "-nossl", "-port", str(info.parsed_url.port), "-Format", "csv", "-ask", "no", "-nointeractive", ##"-useproxy", ] for option in ("Pause", "timeout", "Tuning", "Plugins"): value = Config.plugin_args.get(option.lower(), "") value = value.replace("\r", "") value = value.replace("\n", "") value = value.replace("\t", "") value = value.replace(" ", "") if value: args.extend(["-" + option, value]) # Create a temporary output file. with tempfile(suffix = ".csv") as output: # Append the output file name to the arguments. args.append("-output") args.append(output) # If we need to set the proxy or the cookies, we'll have to create # a temporary config file with the modified settings, since there's # no way of passing these options through the command line. if Config.audit_config.proxy_addr or Config.audit_config.cookie: # Make sure we have a config file. if not config: raise ValueError("Missing configuration file!") # Create a temporary config file. with tempfile(suffix = ".conf") as tmp_config: # Open the original config file. with open(config, "rU") as src: # Open the new config file. with open(tmp_config, "w") as dst: # Copy the contents of the original config file. dst.write( src.read() ) # Append the new settings. proxy_addr = Config.audit_config.proxy_addr if proxy_addr: parsed = parse_url(proxy_addr) dst.write("PROXYHOST=%s\n" % parsed.host) dst.write("PROXYPORT=%s\n" % parsed.port) if Config.audit_config.proxy_user: dst.write("PROXYUSER=%s\n" % Config.audit_config.proxy_user) if Config.audit_config.proxy_pass: dst.write("PROXYPASS=%s\n" % Config.audit_config.proxy_pass) cookie_dict = Config.audit_config.cookie if cookie_dict: cookie = ";".join( '"%s=%s"' % x for x in cookie_dict.iteritems() ) dst.write("STATIC-COOKIE=%s\n" % cookie) # Set the new config file. args = ["-config", tmp_config] + args # Run Nikto and parse the output. return self.run_nikto(info, output, nikto_script, args) # Otherwise, just use the supplied config file. else: if config: args = ["-config", config] + args # Run Nikto and parse the output. return self.run_nikto(info, output, nikto_script, args)
def launch_sslscan(self, hostname, port): """ Launch SSLScan against the specified hostname and port. :param hostname: Hostname to test. :type hostname: str :param port: TCP port to test. :type port: int """ # Don't scan the same host and port twice. if self.state.put("%s:%d" % (hostname, port), True): Logger.log_more_verbose( "Host %s:%d already scanned, skipped." % (hostname, port)) return # Workaround for a bug in SSLScan: if the target port doesn't # answer back the SSL handshake (i.e. if port 443 is open but # another protocol is being used) then SSLScan just blocks # indefinitely. try: with ConnectionSlot(hostname): s = socket(AF_INET, SOCK_STREAM) try: s.settimeout(4.0) s.connect( (hostname, port) ) s = wrap_socket(s) s.shutdown(2) finally: s.close() except Exception: Logger.log_error_more_verbose( "Host %s:%d doesn't seem to support SSL, aborting." % (hostname, port)) return # Create a temporary output file. with tempfile(suffix = ".xml") as output: # Build the command line arguments. args = [ "--no-failed", "--xml=" + output, # non standard cmdline parsing :( "%s:%d" % (hostname, port), ] # Run SSLScan and capture the text output. Logger.log("Launching SSLScan against: %s" % hostname) Logger.log_more_verbose("SSLScan arguments: %s" % " ".join(args)) with ConnectionSlot(hostname): t1 = time() code = run_external_tool("sslscan", args, callback=Logger.log_verbose) t2 = time() if code: if code < 0 and sep == "\\": asc_code = "0x%.8X" % code else: asc_code = str(code) Logger.log_error( "SSLScan execution failed, status code: %s" % asc_code) else: Logger.log("SSLScan scan finished in %s seconds for target: %s" % (t2 - t1, hostname)) # Parse and return the results. r, v = self.parse_sslscan_results(output) if v: Logger.log("Found %s SSL vulnerabilities." % v) else: Logger.log("No SSL vulnerabilities found.") return r
def run(self, info): if not isinstance(info, URL): return if not info.has_url_params and not info.has_post_params: return # Get user args user_args = shlex.split(Config.plugin_args.get("args", [])) # Result info results = [] with tempfile(prefix="tmpxss", suffix=".xml") as filename: args = [ "--xml=%s" % filename, "--no-head", "--threads", "1" ] # Add the user args args.extend(user_args) if info.has_url_params: # Get payload for config injection point args.extend([ "-u", "%s://%s" % (info.parsed_url.scheme, info.parsed_url.host), ]) # When we want to try GET parameters, we must pass to xsser one by one. for param, value in info.parsed_url.query_params.iteritems(): # Not evaluate web server params if param in WEB_SERVERS_VARS: continue # Prepare and reorder params fixed_params = "&".join(["%s=%s" % (x, y) for x, y in info.parsed_url.query_params.iteritems() if x != param]) # Add param to text + fixed params if fixed_params: # -> empty fixed params params = "%s?%s&%s=" % (info.parsed_url.path, fixed_params, param) else: params = "%s?%s=" % (info.parsed_url.path, param) # Prepary args for xsser args.extend([ "-g", params ]) # Run xsser if self.run_xsser(info.hostname, info.url, args): results.extend(self.parse_xsser_result(info, filename)) if info.has_post_params: args.extend([ "-u", info.url, "-p", "&".join( ["%s=%s" % (k, v) for k, v in info.post_params.iteritems() if k not in WEB_SERVERS_VARS] ), ]) if self.run_xsser(info.hostname, info.url, args): results.extend(self.parse_xsser_result(info, filename)) if results: Logger.log("Found %s XSS vulnerabilities." % len(results)) else: Logger.log_verbose("No XSS vulnerabilities found.") return results
def recv_info(self, info): # Get the path to the Nikto scanner. nikto_script = Config.plugin_args["exec"] if nikto_script and exists(nikto_script): nikto_dir = split(nikto_script)[0] nikto_dir = abspath(nikto_dir) else: nikto_dir = split(__file__)[0] nikto_dir = join(nikto_dir, "nikto") nikto_dir = abspath(nikto_dir) nikto_script = join(nikto_dir, "nikto.pl") if not nikto_script or not exists(nikto_script): nikto_script = "/usr/bin/nikto" if not exists(nikto_script): nikto_script = Config.plugin_args["exec"] if nikto_script: Logger.log_error("Nikto not found! File: %s" % nikto_script) else: Logger.log_error("Nikto not found!") return # Get the path to the configuration file. config = Config.plugin_args["config"] if config: config = join(nikto_dir, config) config = abspath(config) if not exists(config): config = "/etc/nikto.conf" if not exists(config): config = Config.plugin_args["config"] if config and exists(config): config = abspath(config) else: if config: Logger.log_error( "Nikto config file not found! File: %s" % config) else: Logger.log_error("Nikto config file not found!") return # Build the command line arguments. # The -output argument will be filled by run_nikto. args = [ "-host", info.hostname, "-ssl" if info.is_https else "-nossl", "-port", str(info.parsed_url.port), "-Format", "csv", "-ask", "no", "-nointeractive", ##"-useproxy", ] if config: args = ["-config", config] + args for option in ("Pause", "timeout", "Tuning"): value = Config.plugin_args.get(option.lower(), None) if value: args.extend(["-" + option, value]) # Create a temporary output file. with tempfile(suffix=".csv") as output: # Append the output file name to the arguments. args.append("-output") args.append(output) # Run Nikto and parse the output. return self.run_nikto(info, output, nikto_script, args)
def recv_info(self, info): # Get the path to the Nikto scanner. nikto_script = Config.plugin_args["exec"] if nikto_script and exists(nikto_script): nikto_dir = split(nikto_script)[0] nikto_dir = abspath(nikto_dir) else: nikto_dir = split(__file__)[0] nikto_dir = join(nikto_dir, "nikto") nikto_dir = abspath(nikto_dir) nikto_script = join(nikto_dir, "nikto.pl") if not nikto_script or not exists(nikto_script): nikto_script = "/usr/bin/nikto" if not exists(nikto_script): nikto_script = Config.plugin_args["exec"] if nikto_script: Logger.log_error( "Nikto not found! File: %s" % nikto_script) else: Logger.log_error("Nikto not found!") return # Get the path to the configuration file. config = Config.plugin_args["config"] if config: config = join(nikto_dir, config) config = abspath(config) if not exists(config): config = "/etc/nikto.conf" if not exists(config): config = Config.plugin_args["config"] if config and exists(config): config = abspath(config) else: if config: Logger.log_error( "Nikto config file not found! File: %s" % config ) else: Logger.log_error("Nikto config file not found!") return # Build the command line arguments. # The -output argument will be filled by run_nikto. args = [ "-host", info.hostname, "-ssl" if info.is_https else "-nossl", "-port", str(info.parsed_url.port), "-Format", "csv", "-ask", "no", "-nointeractive", ##"-useproxy", ] if config: args = ["-config", config] + args for option in ("Pause", "timeout", "Tuning"): value = Config.plugin_args.get(option.lower(), None) if value: args.extend(["-" + option, value]) # Create a temporary output file. with tempfile(suffix = ".csv") as output: # Append the output file name to the arguments. args.append("-output") args.append(output) # Run Nikto and parse the output. return self.run_nikto(info, output, nikto_script, args)
def run(self, info): # Get the path to the Nikto scanner and the configuration file. nikto_script, config = self.get_nikto() # Build the command line arguments. # The -output argument will be filled by run_nikto. args = [ "-host", info.hostname, "-ssl" if info.is_https else "-nossl", "-port", str(info.parsed_url.port), "-Format", "csv", "-ask", "no", "-nointeractive", ##"-useproxy", ] for option in ("Pause", "timeout", "Tuning", "Plugins"): value = Config.plugin_args.get(option.lower(), "") value = value.replace("\r", "") value = value.replace("\n", "") value = value.replace("\t", "") value = value.replace(" ", "") if value: args.extend(["-" + option, value]) # Create a temporary output file. with tempfile(suffix=".csv") as output: # Append the output file name to the arguments. args.append("-output") args.append(output) # If we need to set the proxy or the cookies, we'll have to create # a temporary config file with the modified settings, since there's # no way of passing these options through the command line. if Config.audit_config.proxy_addr or Config.audit_config.cookie: # Make sure we have a config file. if not config: raise ValueError("Missing configuration file!") # Create a temporary config file. with tempfile(suffix=".conf") as tmp_config: # Open the original config file. with open(config, "rU") as src: # Open the new config file. with open(tmp_config, "w") as dst: # Copy the contents of the original config file. dst.write(src.read()) # Append the new settings. proxy_addr = Config.audit_config.proxy_addr if proxy_addr: parsed = parse_url(proxy_addr) dst.write("PROXYHOST=%s\n" % parsed.host) dst.write("PROXYPORT=%s\n" % parsed.port) if Config.audit_config.proxy_user: dst.write("PROXYUSER=%s\n" % Config.audit_config.proxy_user) if Config.audit_config.proxy_pass: dst.write("PROXYPASS=%s\n" % Config.audit_config.proxy_pass) cookie_dict = Config.audit_config.cookie if cookie_dict: cookie = ";".join( '"%s=%s"' % x for x in cookie_dict.iteritems()) dst.write("STATIC-COOKIE=%s\n" % cookie) # Set the new config file. args = ["-config", tmp_config] + args # Run Nikto and parse the output. return self.run_nikto(info, output, nikto_script, args) # Otherwise, just use the supplied config file. else: if config: args = ["-config", config] + args # Run Nikto and parse the output. return self.run_nikto(info, output, nikto_script, args)