#coding:utf-8 #!/usr/bin/env python ''' ___ ________ ________ ___ ________ ___ ___ _________ |\ \|\ ___ \|\ ____\|\ \|\ ____\|\ \|\ \|\___ ___\ \ \ \ \ \\ \ \ \ \___|\ \ \ \ \___|\ \ \\\ \|___ \ \_| \ \ \ \ \\ \ \ \_____ \ \ \ \ \ __\ \ __ \ \ \ \ \ \ \ \ \\ \ \|____|\ \ \ \ \ \|\ \ \ \ \ \ \ \ \ \ \__\ \__\\ \__\____\_\ \ \__\ \_______\ \__\ \__\ \ \__\ \|__|\|__| \|__|\_________\|__|\|_______|\|__|\|__| \|__| \|_________| ___ ________ ________ ________ |\ \ |\ __ \|\ __ \|\ ____\ \ \ \ \ \ \|\ \ \ \|\ /\ \ \___|_ \ \ \ \ \ __ \ \ __ \ \_____ \ \ \ \____\ \ \ \ \ \ \|\ \|____|\ \ \ \_______\ \__\ \__\ \_______\____\_\ \ \|_______|\|__|\|__|\|_______|\_________\ \|_________| By Anthr@X ''' #V1.01 import platform import sys import socket as sk import httplib try: from subprocess import Popen, PIPE lowversion=False except: lowversion=True import re from optparse import OptionParser import threading from threading import Thread from Queue import Queue NUM = 50 TIMEOUT=2 PORTS=[21,22,23,25,80,81,110,135,139,389,443,445,873,1433,1434,1521,2433,3306,3307,3389,5800,5900,8080,22222,22022,27017,28017] URLS=['','phpinfo.php','phpmyadmin/','xampp/','zabbix/','jmx-console/','.svn/entries','nagios/','index.action','login.action'] PROBES=[ '\r\n\r\n', 'GET / HTTP/1.0\r\n\r\n', 'GET / \r\n\r\n', '\x01\x00\x00\x00\x01\x00\x00\x00\x08\x08', '\x80\0\0\x28\x72\xFE\x1D\x13\0\0\0\0\0\0\0\x02\0\x01\x86\xA0\0\x01\x97\x7C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', '\x03\0\0\x0b\x06\xe0\0\0\0\0\0', '\0\0\0\xa4\xff\x53\x4d\x42\x72\0\0\0\0\x08\x01\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x06\0\0\x01\0\0\x81\0\x02PC NETWORK PROGRAM 1.0\0\x02MICROSOFT NETWORKS 1.03\0\x02MICROSOFT NETWORKS 3.0\0\x02LANMAN1.0\0\x02LM1.2X002\0\x02Samba\0\x02NT LANMAN 1.0\0\x02NT LM 0.12\0', '\x80\x9e\x01\x03\x01\x00u\x00\x00\x00 \x00\x00f\x00\x00e\x00\x00d\x00\x00c\x00\x00b\x00\x00:\x00\x009\x00\x008\x00\x005\x00\x004\x00\x003\x00\x002\x00\x00/\x00\x00\x1b\x00\x00\x1a\x00\x00\x19\x00\x00\x18\x00\x00\x17\x00\x00\x16\x00\x00\x15\x00\x00\x14\x00\x00\x13\x00\x00\x12\x00\x00\x11\x00\x00\n\x00\x00\t\x00\x00\x08\x00\x00\x06\x00\x00\x05\x00\x00\x04\x00\x00\x03\x07\x00\xc0\x06\x00@\x04\x00\x80\x03\x00\x80\x02\x00\x80\x01\x00\x80\x00\x00\x02\x00\x00\x01\xe4i<+\xf6\xd6\x9b\xbb\xd3\x81\x9f\xbf\x15\xc1@\xa5o\x14,M \xc4\xc7\xe0\xb6\xb0\xb2\x1f\xf9)\xe8\x98', '\x16\x03\0\0S\x01\0\0O\x03\0?G\xd7\xf7\xba,\xee\xea\xb2`~\xf3\0\xfd\x82{\xb9\xd5\x96\xc8w\x9b\xe6\xc4\xdb<=\xdbo\xef\x10n\0\0(\0\x16\0\x13\0\x0a\0f\0\x05\0\x04\0e\0d\0c\0b\0a\0`\0\x15\0\x12\0\x09\0\x14\0\x11\0\x08\0\x06\0\x03\x01\0', '< NTP/1.2 >\n', '< NTP/1.1 >\n', '< NTP/1.0 >\n', '\0Z\0\0\x01\0\0\0\x016\x01,\0\0\x08\0\x7F\xFF\x7F\x08\0\0\0\x01\0 \0:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\04\xE6\0\0\0\x01\0\0\0\0\0\0\0\0(CONNECT_DATA=(COMMAND=version))', '\x12\x01\x00\x34\x00\x00\x00\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x0c\x03\x00\x28\x00\x04\xff\x08\x00\x01\x55\x00\x00\x00\x4d\x53\x53\x51\x4c\x53\x65\x72\x76\x65\x72\x00\x48\x0f\x00\x00', '\0\0\0\0\x44\x42\x32\x44\x41\x53\x20\x20\x20\x20\x20\x20\x01\x04\0\0\0\x10\x39\x7a\0\x01\0\0\0\0\0\0\0\0\0\0\x01\x0c\0\0\0\0\0\0\x0c\0\0\0\x0c\0\0\0\x04', '\x01\xc2\0\0\0\x04\0\0\xb6\x01\0\0\x53\x51\x4c\x44\x42\x32\x52\x41\0\x01\0\0\x04\x01\x01\0\x05\0\x1d\0\x88\0\0\0\x01\0\0\x80\0\0\0\x01\x09\0\0\0\x01\0\0\x40\0\0\0\x01\x09\0\0\0\x01\0\0\x40\0\0\0\x01\x08\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x01\0\0\x40\0\0\0\x40\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x02\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\0\0\0\0\x01\0\0\x40\0\0\0\0\x04\0\0\0\x04\0\0\x80\0\0\0\x01\x04\0\0\0\x04\0\0\x80\0\0\0\x01\x04\0\0\0\x03\0\0\x80\0\0\0\x01\x04\0\0\0\x04\0\0\x80\0\0\0\x01\x08\0\0\0\x01\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x10\0\0\0\x01\0\0\x80\0\0\0\x01\x10\0\0\0\x01\0\0\x80\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x09\0\0\0\x01\0\0\x40\0\0\0\x01\x09\0\0\0\x01\0\0\x80\0\0\0\x01\x04\0\0\0\x03\0\0\x80\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\x01\x04\0\0\x01\0\0\x80\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\x40\0\0\0\x01\0\0\0\0\x01\0\0\x40\0\0\0\0\x20\x20\x20\x20\x20\x20\x20\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe4\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f', '\x41\0\0\0\x3a\x30\0\0\xff\xff\xff\xff\xd4\x07\0\0\0\0\0\0test.$cmd\0\0\0\0\0\xff\xff\xff\xff\x1b\0\0\0\x01serverStatus\0\0\0\0\0\0\0\xf0\x3f\0' ] SIGNS=[ 'http|^HTTP.*', 'ssh|SSH-2.0-OpenSSH.*', 'ssh|SSH-1.0-OpenSSH.*', 'netbios|^\x79\x08.*BROWSE', 'netbios|^\x79\x08.\x00\x00\x00\x00', 'netbios|^\x05\x00\x0d\x03', 'netbios|^\x83\x00', 'netbios|^\x82\x00\x00\x00', 'netbios|\x83\x00\x00\x01\x8f', 'backdoor-fxsvc|^500 Not Loged in', 'backdoor-shell|GET: command', 'backdoor-shell|sh: GET:', 'bachdoor-shell|[a-z]*sh: .* command not found', 'backdoor-shell|^bash[$#]', 'backdoor-shell|^sh[$#]', 'backdoor-cmdshell|^Microsoft Windows .* Copyright .*>', 'db2|.*SQLDB2RA', 'db2jds|^N\x00', 'dell-openmanage|^\x4e\x00\x0d', 'finger|^\r\n Line User', 'finger|Line User', 'finger|Login name: ', 'finger|Login.*Name.*TTY.*Idle', 'finger|^No one logged on', 'finger|^\r\nWelcome', 'finger|^finger:', 'finger|^must provide username', 'finger|finger: GET: ', 'ftp|^220.*\n331', 'ftp|^220.*\n530', 'ftp|^220.*FTP', 'ftp|^220 .* Microsoft .* FTP', 'ftp|^220 Inactivity timer', 'ftp|^220 .* UserGate', 'http|^HTTP/0.', 'http|^HTTP/1.', 'http|.*', 'http|.*', 'http|.*', 'http|Bad Request .Invalid URL.', 'http-jserv|^HTTP/.*Cookie.*JServSessionId', 'http-tomcat|^HTTP/.*Cookie.*JSESSIONID', 'http-weblogic|^HTTP/.*Cookie.*WebLogicSession', 'http-vnc|^HTTP/.*VNC desktop', 'http-vnc|^HTTP/.*RealVNC/', 'ldap|^\x30\x0c\x02\x01\x01\x61', 'ldap|^\x30\x32\x02\x01', 'ldap|^\x30\x33\x02\x01', 'ldap|^\x30\x38\x02\x01', 'ldap|^\x30\x84', 'ldap|^\x30\x45', 'smb|^\0\0\0.\xffSMBr\0\0\0\0.*', 'msrdp|^\x03\x00\x00\x0b', 'msrdp|^\x03\x00\x00\x11', 'msrdp|^\x03\0\0\x0b\x06\xd0\0\0\x12.\0$', 'msrdp|^\x03\0\0\x17\x08\x02\0\0Z~\0\x0b\x05\x05@\x06\0\x08\x91J\0\x02X$', 'msrdp|^\x03\0\0\x11\x08\x02..}\x08\x03\0\0\xdf\x14\x01\x01$', 'msrdp|^\x03\0\0\x0b\x06\xd0\0\0\x03.\0$', 'msrdp|^\x03\0\0\x0b\x06\xd0\0\0\0\0\0', 'msrdp|^\x03\0\0\x0e\t\xd0\0\0\0[\x02\xa1]\0\xc0\x01\n$', 'msrdp|^\x03\0\0\x0b\x06\xd0\0\x004\x12\0', 'msrdp-proxy|^nmproxy: Procotol byte is not 8\n$', 'msrpc|^\x05\x00\x0d\x03\x10\x00\x00\x00\x18\x00\x00\x00\x00\x00', 'msrpc|\x05\0\r\x03\x10\0\0\0\x18\0\0\0....\x04\0\x01\x05\0\0\0\0$', 'mssql|^\x04\x01\0C..\0\0\xaa\0\0\0/\x0f\xa2\x01\x0e.*', 'mssql|^\x05\x6e\x00', 'mssql|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15.*', 'mssql|^\x04\x01\x00.\x00\x00\x01\x00\x00\x00\x15.*', 'mssql|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15.*', 'mssql|^\x04\x01\x00.\x00\x00\x01\x00\x00\x00\x15.*', 'mssql|^\x04\x01\0\x25\0\0\x01\0\0\0\x15\0\x06\x01.*', 'mssql|^\x04\x01\x00\x25\x00\x00\x01.*', 'telnet|^xff\xfb\x01\xff\xfb\x03\xff\xfb\0\xff\xfd.*', 'mssql|;MSSQLSERVER;', 'mysql|^\x19\x00\x00\x00\x0a', 'mysql|^\x2c\x00\x00\x00\x0a', 'mysql|hhost \'', 'mysql|khost \'', 'mysql|mysqladmin', 'mysql|whost \'', 'mysql-blocked|^\(\x00\x00', 'mysql-secured|this MySQL', 'mongodb|^.*version.....([\.\d]+)', 'nagiosd|Sorry, you \(.*are not among the allowed hosts...', 'nessus|< NTP 1.2 >\x0aUser:', 'oracle-tns-listener|\(ERROR_STACK=\(ERROR=\(CODE=', 'oracle-tns-listener|\(ADDRESS=\(PROTOCOL=', 'oracle-dbsnmp|^\x00\x0c\x00\x00\x04\x00\x00\x00\x00', 'oracle-https|^220- ora', 'oracle-rmi|\x00\x00\x00\x76\x49\x6e\x76\x61', 'oracle-rmi|^\x4e\x00\x09', 'postgres|Invalid packet length', 'postgres|^EFATAL', 'rlogin|login: ', 'rlogin|rlogind: ', 'rlogin|^\x01\x50\x65\x72\x6d\x69\x73\x73\x69\x6f\x6e\x20\x64\x65\x6e\x69\x65\x64\x2e\x0a', 'rpc-nfs|^\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00', 'rpc|\x01\x86\xa0', 'rpc|\x03\x9b\x65\x42\x00\x00\x00\x01', 'rpc|^\x80\x00\x00', 'rsync|^@RSYNCD:.*', 'smux|^\x41\x01\x02\x00', 'snmp-public|\x70\x75\x62\x6c\x69\x63\xa2', 'snmp|\x41\x01\x02', 'socks|^\x05[\x00-\x08]\x00', 'ssh|^SSH-', 'ssh|^SSH-.*openssh', 'ssl|^..\x04\0.\0\x02', 'ssl|^\x16\x03\x01..\x02...\x03\x01', 'ssl|^\x16\x03\0..\x02...\x03\0', 'ssl|SSL.*GET_CLIENT_HELLO', 'ssl|-ERR .*tls_start_servertls', 'ssl|^\x16\x03\0\0J\x02\0\0F\x03\0', 'ssl|^\x16\x03\0..\x02\0\0F\x03\0', 'ssl|^\x15\x03\0\0\x02\x02\.*', 'ssl|^\x16\x03\x01..\x02...\x03\x01', 'ssl|^\x16\x03\0..\x02...\x03\0', 'sybase|^\x04\x01\x00', 'telnet|^\xff\xfd', 'telnet|Telnet is disabled now', 'telnet|^\xff\xfe', 'tftp|^\x00[\x03\x05]\x00', 'http-tomcat|.*Servlet-Engine', 'uucp|^login: password: ', 'vnc|^RFB.*', 'webmin|.*MiniServ', 'webmin|^0\.0\.0\.0:.*:[0-9]', 'websphere-javaw|^\x15\x00\x00\x00\x02\x02\x0a'] #For python2.4 Queue class... if sys.version_info[1]<=4: class Queue(Queue): def __init__(self, maxsize=0): self.maxsize = maxsize self._init(maxsize) self.mutex = threading.Lock() self.not_empty = threading.Condition(self.mutex) self.not_full = threading.Condition(self.mutex) self.all_tasks_done = threading.Condition(self.mutex) self.unfinished_tasks = 0 def task_done(self): self.all_tasks_done.acquire() try: unfinished = self.unfinished_tasks - 1 if unfinished <= 0: if unfinished < 0: raise ValueError('task_done() called too many times') self.all_tasks_done.notifyAll() self.unfinished_tasks = unfinished finally: self.all_tasks_done.release() def join(self): self.all_tasks_done.acquire() try: while self.unfinished_tasks: self.all_tasks_done.wait() finally: self.all_tasks_done.release() def put(self, item, block=True, timeout=None): self.not_full.acquire() try: if self.maxsize > 0: if not block: if self._qsize() == self.maxsize: raise Full elif timeout is None: while self._qsize() == self.maxsize: self.not_full.wait() elif timeout < 0: raise ValueError("'timeout' must be a positive number") else: endtime = _time() + timeout while self._qsize() == self.maxsize: remaining = endtime - _time() if remaining <= 0.0: raise Full self.not_full.wait(remaining) self._put(item) self.unfinished_tasks += 1 self.not_empty.notify() finally: self.not_full.release() class Queue(Queue): def randget(self): from random import randrange self.queue.rotate(randrange(0,self._qsize()+1)) return self.get() # convert an IP address from its dotted-quad format to its # 32 binary digit representation def ip2bin(ip): b = "" inQuads = ip.split(".") outQuads = 4 for q in inQuads: if q != "": b += dec2bin(int(q),8) outQuads -= 1 while outQuads > 0: b += "00000000" outQuads -= 1 return b # convert a decimal number to binary representation # if d is specified, left-pad the binary number with 0s to that length def dec2bin(n,d=None): s = "" while n>0: if n&1: s = "1"+s else: s = "0"+s n >>= 1 if d is not None: while len(s) "myStrin" but "myString"[:0] -> "" # if a subnet of 32 was specified simply print the single IP if subnet == 32: print bin2ip(baseIP) # for any other size subnet, print a list of IP addresses by concatenating # the prefix with each of the suffixes in the subnet else: ipPrefix = baseIP[:-(32-subnet)] for i in range(2**(32-subnet)): cidrlist.append(bin2ip(ipPrefix+dec2bin(i, (32-subnet)))) return cidrlist # input validation routine for the CIDR block specified def validateCIDRBlock(b): # appropriate format for CIDR block ($prefix/$subnet) p = re.compile("^([0-9]{1,3}\.){0,3}[0-9]{1,3}(/[0-9]{1,2}){1}$") if not p.match(b): print "Error: Invalid CIDR format!" return False # extract prefix and subnet size prefix, subnet = b.split("/") # each quad has an appropriate value (1-255) quads = prefix.split(".") for q in quads: if (int(q) < 0) or (int(q) > 255): print "Error: quad "+str(q)+" wrong size." return False # subnet is an appropriate value (1-32) if (int(subnet) < 1) or (int(subnet) > 32): print "Error: subnet "+str(subnet)+" wrong size." return False # passed all checks -> return True return True def pinger(): global pinglist while True: ip=q.randget() if platform.system()=='Linux': p=Popen(['ping','-c 2',ip],stdout=PIPE) m = re.search('(\d)\sreceived', p.stdout.read()) try: if m.group(1)!='0': pinglist.append(ip) except:pass if platform.system()=='Windows': p=Popen('ping -n 2 ' + ip, stdout=PIPE) m = re.search('TTL', p.stdout.read()) if m: pinglist.append(ip) q.task_done() def pingsubnet(q): global pinglist pinglist=[] while True: tup=q.randget() (gt,bc)=tup sys.stdout.write('.') if platform.system()=='Linux': try: p=Popen(['ping','-c 2',gt],stdout=PIPE) m = re.search('(\d)\sreceived', p.stdout.read()) gt=gt.split('.') gt=gt[0]+'.'+gt[1]+'.'+gt[2]+'.'+'0' except:pass try: if m.group(1)!='0': pinglist.append(gt) else: p=Popen(['ping','-c 2 -b',bc],stdout=PIPE) m = re.search('(\d)\sreceived', p.stdout.read()) try: if m.group(1)!='0': pinglist.append(gt) except:pass except:pass if platform.system()=='Windows': try: p=Popen('ping -n 2 ' + gt, stdout=PIPE) m = re.search('TTL', p.stdout.read()) gt=gt.split('.') gt=gt[0]+'.'+gt[1]+'.'+gt[2]+'.'+'0' if m: pinglist.append(gt) else: p=Popen('ping -n 2 ' + bc, stdout=PIPE) m = re.search('TTL', p.stdout.read()) if m: pinglist.append(gt) except:pass q.task_done() def networkdiscovery(subclass): if subclass not in ['A','B','C']: print 'Option incorrect, only A,B,C are allowed' exit() global pinglist iplist=[] if subclass=='A': for i in xrange(256): for j in xrange(256): iplist.append(('10.'+str(i)+'.'+str(j)+'.1','10.'+str(i)+'.'+str(j)+'.255')) if subclass=='B': for i in xrange(16,32): for j in xrange(256): iplist.append(('172.'+str(i)+'.'+str(j)+'.1','172.'+str(i)+'.'+str(j)+'.255')) if subclass=='C': for i in xrange(256): iplist.append(('192.168.'+str(i)+'.1','192.168.'+str(i)+'.255')) q=Queue() for i in range(NUM): th = Thread(target=pingsubnet,args=(q,)) th.setDaemon(True) th.start() for ip in iplist: q.put(ip) q.join() for addr in pinglist: print addr,'is reachable.' def scanipport(): global lock while True: host,port=sq.randget() sd=sk.socket(sk.AF_INET, sk.SOCK_STREAM) sd.settimeout(TIMEOUT) try: sd.connect((host,port)) if options.genlist==True: if port not in ipdict: ipdict[port]=[] ipdict[port].append(host) else: ipdict[port].append(host) else: lock.acquire() print "%s:%d OPEN" % (host, port) lock.release() sd.close() if options.downpage==True and port in [80,81,1080,8080]: dlpage(host,port) if options.downpage==True and port ==443: dlpage(host,port,True) if options.hostname!=None and port in [80,81,1080,8080]: findhost(host,port,options.hostname) if options.hostname!=None and port ==443: findhost(host,port,options.hostname,True) except: pass sq.task_done() def scanservice(): global signs,lock while True: host,port=sq.randget() sd=sk.socket(sk.AF_INET, sk.SOCK_STREAM) sd.settimeout(TIMEOUT) service='Unknown' try: sd.connect((host,port)) except: sq.task_done() continue try: result = sd.recv(256) service=matchbanner(result,signs) except: for probe in PROBES: try: sd.close() sd=sk.socket(sk.AF_INET, sk.SOCK_STREAM) sd.settimeout(TIMEOUT) sd.connect((host,port)) sd.sendall(probe) except: continue try: result = sd.recv(256) service=matchbanner(result,signs) if service!='Unknown': break except: continue if options.genlist==True: if service not in ipdict: ipdict[service]=[] ipdict[service].append(host+':'+str(port)) else: ipdict[service].append(host+':'+str(port)) else: lock.acquire() if service!='Unknown': print "%s:%d OPEN %s" % (host, port, service) else: print "%s:%d OPEN" % (host, port) lock.release() sd.close() if options.downpage==True and service=='http': dlpage(host,port) if options.downpage==True and service=='ssl': dlpage(host,port,True) if options.hostname!=None and service=='http': findhost(host,port,options.hostname) if options.hostname!=None and service=='ssl': findhost(host,port,options.hostname,True) sq.task_done() def prepsigns(): signlist=[] for item in SIGNS: #print item (label,pattern)=item.split('|',2) sign=(label,pattern) signlist.append(sign) return signlist def matchbanner(banner,slist): for item in slist: p=re.compile(item[1]) if p.search(banner)!=None: return item[0] return 'Unknown' def dlpage(ip,port,ssl=False): global page,lock page+='

'+ip+':'+str(port)+'


' for url in URLS: if ssl==True: try: c=httplib.HTTPSConnection(ip+':'+str(port)) c.request('GET','/'+url) r=c.getresponse() except: return else: try: c=httplib.HTTPConnection(ip+':'+str(port)) c.request('GET','/'+url) r=c.getresponse() #print url,r.status except: return if url=='': url='Homepage' lock.acquire() if r.status==200: result=r.read() cc=re.search('charset=(.*?)"',result) try: charset=cc.group(1) except: charset=None if charset in ['gb2312','gbk']: try: result=result.decode(charset).encode('utf8') except:pass tt=re.search('(.*)',result) try: title=tt.group(1) except: title='' try: header=r.getheader('Server') except: header='' print ip+':'+str(port),url,'exists.','Code:',r.status,header,title page+='

'+url+'


'+result if r.status==401: print ip+':'+str(port),url,'exists.','Code:',r.status,'Auth required' if r.status in [301,302]: print ip+':'+str(port),url,'Code:',r.status lock.release() c.close() def findhost(ip,port,hostname,ssl=False): global lock if ssl==True: try: c=httplib.HTTPSConnection(ip+':'+str(port)) header={"Host":hostname} c.request('GET','/','',header) r=c.getresponse() except: return else: try: c=httplib.HTTPConnection(ip+':'+str(port)) header={"Host":hostname} c.request('GET','/','',header) r=c.getresponse() #print url,r.status except: return if r.status in [200,301,302]: try: redirect=r.getheader('Location') except: pass try: result=r.read() except: return cc=re.search('charset=(.*?)"',result) try: charset=cc.group(1) except: charset=None if charset in ['gb2312','gbk']: try: result=result.decode(charset).encode('utf8') except:pass tt=re.search('(.*)',result) try: title=tt.group(1) except: title='' lock.acquire() if redirect!=None: print hostname,'running on',ip+':'+str(port),'Location',redirect else: print hostname,'running on',ip+':'+str(port),'Title:',title lock.release() c.close() if __name__ == "__main__": usage="usage: insightscan.py [start port] [end port] -t threads\n\nExample: insightscan.py 192.168.0.0/24 1 1024 -t 20" parser = OptionParser(usage=usage) parser.add_option("-t", "--threads", dest="NUM",help="Maximum threads, default 50") parser.add_option("-T", "--timeout", dest="TIMEOUT",help="Scan timeout, per thread") parser.add_option("-n", "--network", dest="network",help="Quick Network discovery, find reachable networks. Local IP range only. A=10.0.0.0-10.255.255.255\nB=172.16.0.0-172.31.255.255\nC=192.168.0.0-192.168.255.255\nExample: -n B will try Class B addresses") parser.add_option("-H", "--findhost", dest="hostname",help="Help you find which IP address is running a particular virtual host.\nExample: 192.168.0.0/24 -H example.com") parser.add_option("-p", "--portlist", dest="PORTS",help="Customize port list, separate with ',' example: 21,22,23,25 ...") parser.add_option("-N", '--noping', action="store_true", dest="noping",help="Skip ping sweep, port scan whether targets are alive or not") parser.add_option("-P", '--pingonly', action="store_true", dest="noscan",help="Ping scan only,disable port scan") parser.add_option("-S", '--service', action="store_true", dest="service",help="Service detection, using banner and signature") parser.add_option("-d", '--downpage', action="store_true", dest="downpage",help="Detects interesting stuff on HTTP ports(80,80,8080), when used with -S , will try all ports with HTTP service. Grab and save to HTML pages if found anything.") parser.add_option("-l", '--genlist', action="store_true", dest="genlist",help="Output a list, ordered by port number(service, with -S option),for THC-Hydra IP list") parser.add_option("-L", '--genfile', action="store_true", dest="genfile",help="Put the IP list in separate files named by port number(service, with -S option). Implies -l option.\nExample: IPs with port 445 opened will be put into 445.txt") (options, args) = parser.parse_args() if lowversion: print "Python version too low, cannot use ping...\n" options.noping=True options.noscan=False options.network=None if options.NUM !=None and options.NUM!=0: NUM=int(options.NUM) print 'Scanning with',NUM,'threads...' if options.TIMEOUT != None and int(options.TIMEOUT)!=0: TIMEOUT=int(options.TIMEOUT) if options.network!=None: networkdiscovery(options.network) sys.exit() if len(args)<1: parser.print_help() sys.exit() if options.noping== True and options.noscan == True: print 'ERROR: Cannot use -N and -P together' sys.exit() iplist=[] ipaddr=args[0] if len(args)==2: print 'Must specify end port' sys.exit() try: sk.inet_aton(ipaddr) iplist.append(ipaddr) except: if not validateCIDRBlock(ipaddr): print 'IP address not valid!' sys.exit() else: iplist=listCIDR(ipaddr) if len(args)==3: startport=int(args[1]) endport=int(args[2]) if startport>endport: print 'start port must be smaller or equal to end port' sys.exit() PORTS=[] for i in xrange(startport,endport+1): PORTS.append(i) if options.PORTS!= None: PORTS=[int(pn) for pn in options.PORTS.split(',') ] global page page='' #start ping threads if options.noping != True: print "Scanning for live machines...\n" global pinglist q=Queue() pinglist=[] for i in range(NUM): t = Thread(target=pinger) t.setDaemon(True) t.start() for ip in iplist: q.put(ip) q.join() else: pinglist=iplist #print pinglist if options.noscan == True: for host in pinglist: print host sys.exit() if len(pinglist)==0: print 'No live machines detected. Try again with -N switch' sys.exit() print "Scanning ports...\n" sq=Queue() lock = threading.Lock() if options.service==True: global signs signs=prepsigns() if options.genfile==True: options.genlist=True if options.genlist==True: global ipdict ipdict={} for i in range(NUM): st = Thread(target=scanipport) if options.service==True: st = Thread(target=scanservice) st.setDaemon(True) st.start() for scanip in pinglist: for port in PORTS: sq.put((scanip,port)) sq.join() if options.genlist==True: for port,iplist in ipdict.items(): if options.genfile==True: file=open(str(port)+'.txt', "a") else: print "\n========",port,'========' for ip in iplist: if options.genfile==True: file.write(ip+"\n") else: print ip if options.downpage==True and page!='': f = open('page.html', 'a') f.write(page) f.close() print 'page dumped to page.html'