def analyzeDNSRoundRobin(domain, nqueries, dns_servers, progOptions): try: utils.printMessage("[*] Looking for round-robin/anycast DNS", "info", progOptions) ips_round = [] # Make x DNS queries to y DNS Servers for x in range(0, nqueries): for nameserver in dns_servers: res = dns.resolver.Resolver() res.nameservers = [nameserver] answers = res.query(domain, 'A') if len(answers) == 1: ips_round.append(str(answers[0])) ips_round = set(ips_round) if len(ips_round) > 1: utils.printMessage(" [+] DNS round-robin/anycast detected", "plus", progOptions) for ip in ips_round: utils.printMessage(" <-> Found DNS A entry: %s" % ip, "plus", progOptions) else: utils.printMessage(" [-] No round-robin/anycast DNS detected", "less", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
def checkLBCookie(host, port, ssl, useragent, timeout, f5enumeration, progOptions, url=""): f5 = 0 lbdetected = "" try: utils.printMessage("[*] Looking for known load balancers cookies", "info", progOptions) cookie = utils.getHTTPHeader(host, port, ssl, "set-cookie", useragent, timeout, progOptions, url) if cookie: # Lookup for some known cookies - Send me yours! if re.search("BIGipServer", cookie) or re.search('\d{8,10}\.\d{1,5}\.\d{4}', cookie): lbdetected = " [+] F5 load balancer detected" f5 = 1 elif re.search("KEMPID=", cookie): lbdetected = " [+] KEMP Technologies load balancer detected" elif re.search("ROUTEID:", cookie) or re.search("sticky-session=", cookie) or re.search("BALANCEID", cookie): lbdetected = " [+] mod_proxy_balancer load balancer detected" elif re.search("SERVERID=", cookie): lbdetected = " [+] HAProxy load balancer detected" elif re.search("ACE-Insert=", cookie): lbdetected = " [+] Cisco ACE load balancer detected" if re.search("Cisco Acceleration", cookie): lbdetected = " [+] Cisco ACE load balancer detected" if lbdetected != "": utils.printMessage(lbdetected, "plus", progOptions) if f5: utils.printMessage(" [*] Going to enumerate some internal IPs", "info", progOptions) try: for x in range(0, int(f5enumeration)): cookie = utils.getHTTPHeader(host, port, ssl, "set-cookie", useragent, timeout, progOptions) BIGIPCookieDecoder(cookie, progOptions) except NameError, e: utils.printMessage(" [-] Encoded cookie didn't have encoded info", "less", progOptions) if lbdetected == "": utils.printMessage(" [-] No known load balancer cookie detected", "less", progOptions)
def BIGIPCookieDecoder(cookie, progOptions): encoded_string = re.search("\d{8,10}\.\d{1,5}\.\d{4}", cookie) if encoded_string is not None: encoded_string = encoded_string.group(0) (host, port, end) = encoded_string.split('.') # Hexadecimal details: (a, b, c, d) = [ord(i) for i in struct.pack("<I", int(host))] #print "HOST: 0x%02X 0x%02X 0x%02X 0x%02X\n" % (a,b,c,d) (v) = [ord(j) for j in struct.pack("<H", int(port))] p = "0x%02X%02X" % (v[0],v[1]) utils.printMessage(" <-> Decoded cookie: %s.%s.%s.%s:%s" % (a,b,c,d, int(p,16)), "plus", progOptions) else: raise NameError('F5-nodata')
def checkTTLF5(host, port, domain, timeout, progOptions): try: utils.printMessage("[*] Analyzing IP TTL value", "info", progOptions) packet = sr1(IP(dst=domain)/TCP(sport=RandNum(1024,65535), dport=port), timeout=timeout) if packet.getlayer('IP').ttl >= 230: utils.printMessage(" [+] IP TTL is %s, so high number is common in F5 Load Balancers" %packet.getlayer('IP').ttl, "plus", progOptions) else: utils.printMessage(" [-] No high IP TTL received", "less", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
def analyzeServerBannerDiff(host, port, ssl, nrequests, useragent, timeout, progOptions, url=""): servers = [] try: utils.printMessage("[*] Looking for banner inconsistencies", "info", progOptions) # Make x requests to get "server" header for x in range(0,nrequests): header = utils.getHTTPHeader(host, port, ssl, "server", useragent, timeout, progOptions, url) if header: servers.append(header.rstrip()) # A set is an unordered collection with no duplicate elements. # Basic uses include membership testing and eliminating duplicate entries (Python DOC) if len(set(servers)) > 1: utils.printMessage(" [+] Multiple HTTP server banners found", "plus", progOptions) for server in servers: utils.printMessage(" <-> %s" %server, "plus", progOptions) else: utils.printMessage(" [-] No banner inconsistencies found", "less", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
def analyzeHTTPTimestamp(host, port, ssl, nrequests, useragent, timeout, verbose, progOptions, url=""): try: utils.printMessage("[*] Looking for HTTP timestamps inconsistencies", "info", progOptions) timestamps = [] found = 0 utc_old = datetime.strptime('Thu, 03 Nov 1666 01:36:28', '%a, %d %b %Y %H:%M:%S') # Make x requests to detect inconsistencies for x in range(0,int(nrequests)): # Get only 'date' header header = utils.getHTTPHeader(host, port, ssl, "date", useragent, timeout, progOptions, url) if header: timestamp = re.search("(.+ \d{0,2}:\d{0,2}:\d{0,2})", header).group(1) # Convert date header to struct_time utc = datetime.strptime(timestamp, '%a, %d %b %Y %H:%M:%S') # If timestamp is greater than last then it's from another host if utc < utc_old: found = 1 utc_old = utc timestamps.append(utc) if len(timestamps) == 0: utils.printMessage(" [-] No HTTP timestamps received", "less", progOptions) return if not found: utils.printMessage(" [-] No HTTP timestamps inconsitencies found", "less", progOptions) else: utils.printMessage(" [+] Timestamp inconsistency found", "plus", progOptions) # Convert datetime to UNIX timestamp for index, timestamp in enumerate(timestamps): timestamps[index] = int(time.mktime(timestamp.timetuple())) if verbose: utils.printMessage(" [v] Timestamps received: %s" %str(timestamps), "verbose", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
import sys import utils # Exit if no arguments provided if len(sys.argv) == 1: print('Please add some command line arguments') exit() args = utils.removeNonInts(sys.argv) for first in args: remainingItems = args.copy() remainingItems.remove(first) for second in remainingItems: otherItems = remainingItems.copy() otherItems.remove(second) for third in otherItems: sum = first + second + third if sum == 2020: result = first * second * third utils.printMessage("The product of " + str(first) + ", " + str(second) + " and " + str(third) + " is " + str(result)) exit() utils.printMessage("No sum of three numbers equal 2020")
def analyzeIPID(domain, port, nsyn, timeout, verbose, progOptions): conf.verb = 0 ipids = [] found = 0 try: utils.printMessage("[*] Analyzing IPID sequence...", "info", progOptions) # Use Scapy to make some TCP SYN requests answers,unanswered=sr(IP(dst=domain)/TCP(sport=RandNum(1024,65535), dport=port)*nsyn, timeout=timeout) for sent, received in answers: ipids.append(received.getlayer('IP').id) # Loop from first IPID through penultimate for x, ipid in enumerate(ipids[0:-1]): # And compare it from current position+1 until last IPID for ipid2 in ipids[x+1:]: if ipid > ipid2: found = 1 if found: utils.printMessage(" [+] IPID inconsistency found", "plus", progOptions) if len(set(ipids)) == 1: utils.printMessage(" [-] IPID always zero", "less", progOptions) else: utils.printMessage(" [+] IPID incremental", "plus", progOptions) utils.printMessage(" [+] It's seem to be %i servers" % getNumHostsfromIPIDS(ipids), "plus", progOptions) # Plot IPID in some axis (maybe useful for some reports) g = pyx.graph.graphxy(width=15,height=10) g.plot(pyx.graph.data.points(zip(range(0,nsyn), ipids), x=1, y=2)) #rint domain fname = domain+"_ipids.jpg" g.pipeGS(fname, device="jpeg") #print "test" utils.printMessage(" [+] Generated %s file with plotted IPIDS" % fname, "info", progOptions) if verbose: utils.printMessage(" [v] IPIDs received: %s" %str(ipids), "verbose", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
def checkMultipleDNS(domain, progOptions): try: utils.printMessage("[*] Checking multiple A DNS entries...", "info", progOptions) try: answers = dns.resolver.query(domain, 'A') except dns.exception.DNSException: utils.printMessage("[!] DNS lookup failed", "error", progOptions) sys.exit() if len(answers) > 1: utils.printMessage(" [+] Multiple A DNS entries found", "plus", progOptions) for rdata in answers: utils.printMessage(" <-> %s" %rdata, "plus", progOptions) else: utils.printMessage(" [-] Just one DNS entry found: %s" %answers[0], "less", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
def checkTCPTimestamp(host, port, ntcp_timestamp, timeout, verbose, progOptions): timestamps = [] timestamp_old = 1 found = 0 try: utils.printMessage("[*] Analyzing TCP timestamps...", "info", progOptions) # Set "Timestamp" option to avoid some firewall dropping packet answers,unanswered=sr(IP(dst=host)/TCP(sport=RandNum(1024,65535), dport=port, options=[('Timestamp',(0,0))])*ntcp_timestamp, timeout=timeout) for sent, received in answers: options = received.getlayer('TCP').options for option in options: if option[0] == 'Timestamp': timestamp = option[1][0] # If timestamp is greater than last then it's from another host if timestamp < timestamp_old and timestamp !=0: found = 1 timestamp_old = timestamp timestamps.append(timestamp) if len(timestamps) == 0: utils.printMessage(" [-] No TCP timestamps received", "less", progOptions) return if not found: utils.printMessage(" [-] No TCP timestamps inconsistencies found", "less", progOptions) else: utils.printMessage(" [+] TCP timestamp inconsistency found", "plus", progOptions) if verbose: utils.printMessage(" [v] TCP timestamps received: %s" %str(timestamps), "verbose", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
gr3 = parser.add_argument_group("Update options") gr3.add_argument('-u','--update', dest='update', action='store_true', help='update Load Balancer Finder') checkArgs() args = parser.parse_args() progOptions = utils.cParams() progOptions.set_normal_output(sys.stdout) progOptions.set_error_output(sys.stderr) progOptions.set_use_colours(args.colour) progOptions.verbose = args.verbose if args.update: utils.printMessage("[*] Going to update Load Balancer Finder", "info", progOptions) updater.update() sys.exit(1) if not os.geteuid()==0: utils.printMessage("[-] You have to be root (scapy packet injection)", "error", progOptions) sys.exit(0) # Configuration parsing cfg = ConfigParser.ConfigParser() try: cfg.read(args.configfile) nsyn = int(cfg.get("packets","ipid_syn")) nicmp_packets = int(cfg.get("packets","nicmp_packets"))
elif re.search("jnAccel", cookie): lbdetected = " [+] jetNexus load balancer detected" elif re.search("BARRACUDA_LB_COOKIE", cookie): lbdetected = " [+] Barracuda load balancer detected" elif re.search("NSC_", cookie): lbdetected = " [+] Net Scaler load balancer detected" elif re.search("X-RBT-Optimized", cookie): lbdetected = " [+] Riverbed load balancer detected" elif re.search("FGTServer", cookie): lbdetected = " [+] Fortigate load balancer detected" elif re.search("Coyote-", cookie): lbdetected = " [+] CoyotePoint load balancer detected" if lbdetected != "": utils.printMessage(lbdetected, "plus", progOptions) if f5: utils.printMessage(" [*] Going to enumerate some internal IPs", "info", progOptions) try: for x in range(0, int(f5enumeration)): cookie = utils.getHTTPHeader(host, port, ssl, "set-cookie", useragent, timeout, progOptions) BIGIPCookieDecoder(cookie, progOptions) except NameError, e: utils.printMessage(" [-] Encoded cookie didn't have encoded info", "less", progOptions) if lbdetected == "": utils.printMessage(" [-] No known load balancer cookie detected", "less", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
def checkICMPTimestamp(host, timeout, nicmp_packets, verbose, progOptions): timestamps = [] timestamp_old = 1 found = 0 try: utils.printMessage("[*] Analyzing ICMP timestamps...", "info", progOptions) # Use Scapy to make some ICMP Timestamp Request (Your ISP could block that or ICMP Timestamp Response) answers,unanswered=sr(IP(dst=host)/ICMP(type=13)*nicmp_packets, timeout=timeout) if len(answers) > 0: for sent, received in answers: timestamp = received.getlayer('ICMP').ts_rx # If timestamp is greater than last then it's from another host if timestamp < timestamp_old: found = 1 timestamp_old = timestamp timestamps.append(timestamp) if not found: utils.printMessage(" [-] No ICMP inconsistencies found", "less", progOptions) else: utils.printMessage(" [+] ICMP timestamp inconsistency found", "plus", progOptions) if verbose: utils.printMessage(" [v] IPIDs received: %s" %str(timestamps), "verbose", progOptions) else: utils.printMessage(" [-] No ICMP timestamp request responses", "less", progOptions) except KeyboardInterrupt: utils.printMessage("[!] Aborted by user...", "error", progOptions) sys.exit() except Exception, e: print str(e) sys.exit()
gr2.add_argument('-v', '--verbose', dest='verbose', default=False, action='store_true', help='show extra info about IPIDs, timpestamps, etc') gr2.add_argument('-c', '--colours', dest='colour', default=False, action='store_true', help='coloured output') checkArgs() args = parser.parse_args() progOptions = utils.cParams() progOptions.set_normal_output(sys.stdout) progOptions.set_error_output(sys.stderr) progOptions.set_use_colours(args.colour) progOptions.verbose = args.verbose if not os.geteuid()==0: utils.printMessage("[-] You have to be root (scapy packet injection)", "error", progOptions) sys.exit(0) # Configuration parsing cfg = ConfigParser.ConfigParser() try: cfg.read(args.configfile) nsyn = int(cfg.get("packets","ipid_syn")) nicmp_packets = int(cfg.get("packets","nicmp_packets")) tcp_timestamp = int(cfg.get("packets","tcp_timestamp")) banner_retrieves = int(cfg.get("packets","banner_retrieves")) cookie_retrieves = int(cfg.get("packets","cookie_retrieves")) httptimestamp_retrieves = int(cfg.get("packets","httptimestamp_retrieves")) socket_timeout = int(cfg.get("packets","socket_timeout")) http_timeout = int(cfg.get("HTTP","http_timeout"))
import sys import utils # Exit if no arguments provided if len(sys.argv) == 1: print('Please add some command line arguments') exit() args = utils.removeNonInts(sys.argv) for current in args: remaining = args.copy() remaining.remove(current) for other in remaining: sum = other + current if sum == 2020: result = other * current utils.printMessage("The product of " + str(current) + " and " + str(other) + " is " + str(result)) exit() utils.printMessage("No sum of two numbers equal 2020")