def start(session: Session): print(f"Scanning: {session.url}") # make sure it resolves try: socket.gethostbyname(session.domain) except socket.gaierror as error: print( f"Fatal Error: Unable to resolve {session.domain} ({str(error)})") return try: cutils.check_redirect(session) except ValueError as error: print(f"Unable to continue: {str(error)}") return # check to see if we are looking at an HTTPS server if session.url_parsed.scheme == "https": if (session.args.internalssl or utils.is_ip(session.domain) or utils.get_port(session.url) != 443): # use internal scanner ssl_internal.scan(session) else: try: ssl_labs.scan(session) except Exception as error: output.debug_exception() output.error(f"Error running scan with SSL Labs: {str(error)}") if session.args.tdessessioncount: ssl_sweet32.scan(session)
def start(session: Session): print(f"Scanning: {session.url}") # make sure it resolves try: socket.gethostbyname(session.domain) except socket.gaierror as error: output.debug_exception() output.error( f"Fatal Error: Unable to resolve {session.domain} ({str(error)})") return try: cutils.check_redirect(session) except Exception as error: output.debug_exception() output.error(f"Unable to continue: {str(error)}") return if not session.args.nodns: dns.scan(session) if session.args.ports: network.scan(session) # check to see if we are looking at an HTTPS server if session.url_parsed.scheme == "https" and not session.args.nossl: if (session.args.internalssl or utils.is_ip(session.domain) or utils.get_port(session.url) != 443): # use internal scanner ssl_internal.scan(session) else: try: ssl_labs.scan(session) except Exception as error: output.debug_exception() output.error(f"Error running scan with SSL Labs: {str(error)}") output.norm("Switching to internal SSL scanner...") ssl_internal.scan(session) if session.args.tdessessioncount: ssl_sweet32.scan(session) http.scan(session) # reset any stored data http.reset() return
def start(args, url): print(f"Scanning: {url}") # parse the URL, we'll need this parsed = urlparse(url) # get rid of any port number & credentials that may exist domain = utils.get_domain(parsed.netloc) # make sure it resolves try: socket.gethostbyname(domain) except socket.gaierror as error: print(f"Fatal Error: Unable to resolve {domain} ({str(error)})") return if parsed.scheme == "http": try: # check for TLS redirect tls_redirect = network.check_ssl_redirect(url) if tls_redirect != url: print(f"Server redirects to TLS: Scanning: {tls_redirect}") url = tls_redirect parsed = urlparse(url) except Exception as error: output.debug_exception() output.error(f"Failed to connect to {url} ({str(error)})") return www_redirect = network.check_www_redirect(url) if www_redirect is not None and www_redirect != url: print(f"Server performs WWW redirect: Scanning: {www_redirect}") url = www_redirect parsed = urlparse(url) # check to see if we are looking at an HTTPS server if parsed.scheme == "https": if args.internalssl or utils.is_ip(domain) or utils.get_port(url) != 443: # use internal scanner ssl_internal.scan(args, url, domain) else: try: ssl_labs.scan(args, url, domain) except Exception as error: output.debug_exception() output.error(f"Error running scan with SSL Labs: {str(error)}") if args.tdessessioncount: ssl_sweet32.scan(args, url, domain)
def _get_ip(res: HTTPResponse) -> Union[str, None]: loc = res.getheader("Location") if loc is not None: # it's a redirect, check to see if there's an IP in it parsed = urlparse(loc) domain = utils.get_domain(parsed.netloc) if utils.is_ip(domain): # it's an IP, now, is it private? if utils.is_private_ip(domain): return domain else: return None return None
def scan(session: Session): reporter.register_data("url", session.url) reporter.register_data("domain", session.domain) # check to see if this is an IP, if so, bail out if utils.is_ip(session.domain): return output.empty() output.norm("DNS Information:") # get the root domain, by looking up via the PSL psl = PublicSuffixList() root_domain = psl.privatesuffix(session.domain) reporter.register_data("root_domain", root_domain) # IP Addresses for the domain we are scanning ips = basic.get_ips(session.domain) reporter.register_data("ip", ips) for ip in ips: output.norm("\t%s (%s)" % (ip, basic.get_host(str(ip)))) addr = ipaddress.ip_address(str(ip)) if not addr.is_private: ni = network_info.network_info(str(ip)) output.norm("\t\t%s" % ni) if addr.version == 4: output.norm("\t\thttps://www.shodan.io/host/%s" % ip) output.norm("\t\thttps://censys.io/ipv4/%s" % ip) else: output.norm("\t\thttps://www.shodan.io/host/%s" % str(ip).lower()) output.empty() # TXT records for the domain we are scanning try: txt = basic.get_text(session.domain) reporter.register_data("dns_txt", {session.domain: txt}) for rec in txt: output.norm("\tTXT: %s" % rec) except Exception as err: output.error(f"Error getting TXT records: {str(err)}") # TXT records for the root domain try: if root_domain != session.domain: txt = basic.get_text(root_domain) reporter.register_data("dns_txt", {root_domain: txt}) for rec in txt: output.norm("\tTXT (%s): %s" % (root_domain, rec)) except Exception as err: output.error(f"Error getting TXT (root) records: {str(err)}") output.empty() # MX records for the domain we are scanning try: mx = basic.get_mx(session.domain) reporter.register_data("dns_mx", {session.domain: mx}) for rec in mx: server_ip, ni = _get_ip_info(rec[0]) info = "%s (%s) - %s (%s)" % (rec[0], rec[1], server_ip, ni) output.norm("\tMX: %s" % info) except Exception as err: output.error(f"Error getting MX records: {str(err)}") try: # MX records for the root domain if root_domain != session.domain: mx = basic.get_mx(root_domain) reporter.register_data("dns_mx", {root_domain: mx}) for rec in mx: server_ip, ni = _get_ip_info(rec[0]) info = "%s (%s) - %s (%s)" % (rec[0], rec[1], server_ip, ni) output.norm("\tMX (%s): %s" % (root_domain, info)) except Exception as err: output.error(f"Error getting MX (root) records: {str(err)}") output.empty() # NS records for the root domain try: ns = basic.get_ns(root_domain) reporter.register_data("dns_ns", {root_domain: ns}) for rec in ns: server_ip, ni = _get_ip_info(rec) info = "%s - %s (%s)" % (rec, server_ip, ni) output.norm("\tNS: %s" % info) except Exception as err: output.error(f"Error getting NS records: {str(err)}") output.empty() if session.args.srv: try: output.norm( "Searching for SRV records, this will take a minute...") output.empty() with Spinner(): srv_records = srv.find_srv_records(root_domain) reporter.register_data("dns_srv", srv_records) for rec in srv_records: server_ip, ni = _get_ip_info(rec[1]) info = "%s: %s:%s - %s (%s)" % (rec[0], rec[1], rec[2], server_ip, ni) output.norm("\tSRV: %s" % info) output.empty() except Exception as err: output.error(f"Error getting SRV records: {str(err)}") if session.args.subdomains: try: output.norm( "Searching for sub-domains, this will take a few minutes...") output.empty() with Spinner(): sds = subdomains.find_subdomains(root_domain) reporter.register_data("dns_subdomains", sds) for rec in sds: info = "" if rec[0] == "CNAME": server_ip, ni = _get_ip_info(rec[2]) info = "(CNAME) %s -> %s - %s (%s)" % ( rec[1], rec[2], server_ip, ni, ) elif rec[0] == "A": ni = network_info.network_info(rec[2]) info = "(A) %s: %s (%s)" % (rec[1], rec[2], ni) elif rec[0] == "AAAA": ni = network_info.network_info(rec[2]) info = "(AAAA) %s: %s (%s)" % (rec[1], rec[2], ni) output.norm("\tSubdomain: %s" % info) except Exception as err: output.error(f"Error getting subdomain records: {str(err)}") output.empty() try: caa_count = 0 carec = caa.get_caa(session.domain) reporter.register_data("dns_caa", carec) for rec in carec: curr = rec[0] if rec[1] == "CNAME": output.norm("\tCAA (%s): CNAME Found: -> %s" % (curr, rec[2])) elif rec[1] == "CAA": if len(rec[2]) > 0: for line in rec[2]: output.norm('\tCAA (%s): "%s"' % (curr, line)) caa_count += 1 else: output.norm("\tCAA (%s): No Records Found" % curr) # notify the user if there's an issue if caa_count == 0: reporter.display( "\tCAA: Domain does not have protection from CAA", issue.Issue(Vulnerabilities.DNS_CAA_MISSING, session.url, {"caa_records": carec}), ) except Exception as err: output.error(f"Error getting CAA records: {str(err)}") output.empty() try: dk = dnssec.get_dnskey(session.domain) reporter.register_data("dns_dnskey", dk) if len(dk) > 0: for rec in dk: output.norm( "\tDNSKEY: Algorithm: '%s' - Flags: '%s' - Key Length: %s" % (rec[2], rec[0], len(rec[3]) * 8)) else: reporter.display( "\tDNSKEY: Domain does not use DNSSEC", issue.Issue(Vulnerabilities.DNS_DNSSEC_NOT_ENABLED, session.url, {}), ) except Exception as err: output.error(f"Error getting DNSKEY records: {str(err)}") output.empty()
def start(args, url): print(f"Scanning: {url}") # parse the URL, we'll need this parsed = urlparse(url) # get rid of any port number & credentials that may exist domain = utils.get_domain(parsed.netloc) # make sure it resolves try: socket.gethostbyname(domain) except socket.gaierror as error: print(f"Fatal Error: Unable to resolve {domain} ({str(error)})") return # perform some connection testing if parsed.scheme == "http": try: # check for TLS redirect tls_redirect = network.check_ssl_redirect(url) if tls_redirect != url: print(f"Server redirects to TLS: Scanning: {tls_redirect}") url = tls_redirect parsed = urlparse(url) except Exception: output.debug_exception() # we tried to connect to port 80, and it failed # this could mean a couple things, first, we need to # see if it answers to 443 parsed = parsed._replace(scheme="https") url = urlunparse(parsed) print("Server does not respond to HTTP, switching to HTTPS") print() print(f"Scanning: {url}") # grab the head, to see if we get anything try: network.http_head(url, timeout=5) print() except Exception as err: output.debug_exception() print(f"Fatal Error: Can not connect to {url} ({str(err)})") return else: # if we are scanning HTTPS, try HTTP to see what it does try: http_parsed = parsed._replace(scheme="http") http_url = urlunparse(http_parsed) network.http_head(http_url, timeout=5) print("Server responds to HTTP requests") print() except Exception: output.debug_exception() print("Server does not respond to HTTP requests") print() # check for www redirect www_redirect = network.check_www_redirect(url) if www_redirect is not None and www_redirect != url: print(f"Server performs WWW redirect: Scanning: {www_redirect}") url = www_redirect if not args.nodns: dns.scan(args, url, domain) # check to see if we are looking at an HTTPS server if parsed.scheme == "https" and not args.nossl: if args.internalssl or utils.is_ip( domain) or utils.get_port(url) != 443: # use internal scanner ssl_internal.scan(args, url, domain) else: try: ssl_labs.scan(args, url, domain) except Exception as error: output.debug_exception() output.error(f"Error running scan with SSL Labs: {str(error)}") if args.tdessessioncount: ssl_sweet32.scan(args, url, domain) http.scan(args, url, domain) # reset any stored data http.reset() return