Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # To run this. you to go to the
- import os, subprocess, sys, socket, itertools
- from threading import Thread
- from threading import active_count
- from Queue import Queue
- from optparse import OptionParser
- from struct import *
- from time import sleep
- source_ips = {}
- try:
- ips = sys.argv[1]
- except Exception:
- print("IP must be first argument")
- sys.exit(1)
- devnull = open(os.devnull,'w')
- ip_queue = Queue()
- socket_queue = Queue()
- parser = OptionParser()
- parser.add_option("-t", "--threads", type="int", dest="threads", default=64, help="Set number of threads")
- parser.add_option("--timeout", type="int", dest="timeout", default=5, help="Set timeout value (for ping and TCP)")
- parser.add_option("-s", type="string", dest="scan_type", default="T", help="Set the scan type\n\tT = TCP full connect\n\tS = TCP Syn Scan")
- parser.add_option("--ping","--ping-scan", action="store_true", dest="ping_only",default=False, help="Perform a ping-only scan")
- parser.add_option("-P", type="string",dest="ping", default="y",help="Use -PN or -Pn to skip pinging targets")
- parser.add_option("-p","--ports",type="string",dest="ports", help="Ports to scan. Format is comma separated, and accepts ranges with a \"-\"")
- parser.add_option("--source",type="string",dest="source",default="auto", help="Optional. Set a source IP if using -sS option. Skips sending UDP packets to auto-determine source IP")
- parser.add_option("-v","--verbose",action="store_true",dest="verbose",default=False, help="Verbose output (for debugging)")
- parser.add_option("--example",help="Example usage: ./scan 192.168.0-10.0-255 -sS -Pn -p 20-80,400-500\n./scan 1.1.1.1 --ping --threads 1 --timeout 10")
- options,args = parser.parse_args()
- print(options)
- def tcp_listener():
- listen = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
- ips_of_interest = [n for n in convert_ips(ips)]
- print("Starting Listener")
- while True:
- raw_packet = listen.recvfrom(65565)
- packet = raw_packet[0]
- ip_header = unpack('!BBHHHBBH4s',packet[0:16])
- ip_header_length = (ip_header[0] & 0xf) * 4
- src_addr = socket.inet_ntoa(ip_header[8])
- tcp_header_raw = packet[ip_header_length:ip_header_length+14]
- tcp_header = unpack('!HHLLBB',tcp_header_raw)
- src_port = tcp_header[0]
- dst_port = tcp_header[1]
- flag = tcp_header[5]
- if flag == 18:
- if src_addr in ips_of_interest and src_port in options.ports:
- sys.stdout.write("OPEN: \t{} : {}\n".format(src_addr,src_port))
- def ping(ip_q):
- while True:
- ip = ip_q.get()
- if ip == "HALT":
- ip_q.task_done()
- return
- if "win" in sys.platform.lower():
- command = ["ping","-n","1","-w",str(options.timeout*1000),ip]
- else:
- command = ["ping","-c 1","-W {}".format(options.timeout),ip]
- ret_value = subprocess.call(command, stdin=devnull, stdout=devnull, stderr=devnull)
- if ret_value == 0:
- sys.stdout.write("UP: \t{0}\n".format(ip))
- if options.ping_only != True:
- for port in options.ports:
- if options.verbose: sys.stdout.write("Placing ({},{}) in socket queue\n".format(ip,port))
- socket_queue.put((ip,port))
- if options.verbose: print(socket_queue.queue)
- if options.verbose: sys.stdout.write("DONE: {} ping\n".format(ip))
- ip_q.task_done()
- def port_check(socket_q):
- while True:
- ip,port = socket_q.get()
- if options.scan_type.upper() == "T":
- send_full_connect_syn(ip,port)
- elif options.scan_type.upper() == "S":
- send_raw_syn(ip,port)
- else:
- sys.stderr.write("Invalid port scan type, doing nothing...\n")
- socket_q.task_done()
- def convert_ips(ips):
- octets = []
- for ip in ips.split("."):
- if "-" in ip:
- lo,hi = ip.split("-")
- octets.append(range(int(lo),int(hi)+1))
- else:
- octets.append([int(ip)])
- for ip in itertools.product(octets[0],octets[1],octets[2],octets[3]):
- yield "{}.{}.{}.{}".format(ip[0],ip[1],ip[2],ip[3])
- def convert_ports(ports):
- if ports == None: return [21,22,23,25,80,443,110,111,135,139,445,8080,8443,53,143,989,990,3306,1080,5554,6667,2222,4444,666,6666,1337,2020,31337]
- else:
- if "-" not in ports:
- tports = ports.split(",")
- print(tports)
- else:
- ports = ports.split(",")
- tports = []
- for port in ports:
- if "-" not in port: tports.append(int(port))
- else: tports.extend(range(int(port.split("-")[0]),int(port.split("-")[1])+1)) #I made this one line because I wanted to
- ports = [int(n) for n in tports if int(n) > 0 and int(n) < 65536]
- if options.verbose: print("Converted ports: {}".format(ports))
- return ports
- class TCPHeader():
- def __init__(self,src_port=47123,dst_port=80,seqnum=1000,acknum=0,data_offset=80,fin=0,syn=1,rst=0,psh=0,ack=0,urg=0,window=5840,check=0,urg_ptr=0):
- self.order = "!HHLLBBHHH"
- self.src_port = src_port
- self.dst_port = dst_port
- self.seqnum = seqnum
- self.acknum = acknum
- self.data_offset = data_offset
- self.fin = fin
- self.syn = syn
- self.rst = rst
- self.psh = psh
- self.ack = ack
- self.urg = urg
- self.window = socket.htons(window)
- self.check = check
- self.urg_ptr = urg_ptr
- def flags(self):
- return self.fin + (self.syn << 1) + (self.rst << 2) + (self.psh <<3) + (self.ack << 4) + (self.urg << 5)
- def get_struct(self,check=False,checksummed=False):
- if check != False: self.check = check
- if checksummed:
- return pack('!HHLLBBH',self.src_port,self.dst_port,self.seqnum,self.acknum,self.data_offset,self.flags(),self.window)+pack('H',self.check)+pack('!H',self.urg_ptr)
- else:
- return pack(self.order,self.src_port,self.dst_port,self.seqnum,self.acknum,self.data_offset,self.flags(),self.window,self.check,self.urg_ptr)
- def checksum(msg):
- sum = 0
- for i in range(0,len(msg),2):
- w = ord(msg[i]) + (ord(msg[i+1]) << 8 )
- sum = sum + w
- sum = (sum>>16) + (sum & 0xffff)
- sum = sum + (sum >> 16)
- sum = ~sum & 0xffff
- return sum
- def tcp_checksum(source_ip,dest_ip,tcp_header,user_data=''):
- tcp_length = len(tcp_header) + len(user_data)
- ip_header = pack('!4s4sBBH',socket.inet_aton(source_ip),socket.inet_aton(dest_ip),0,socket.IPPROTO_TCP,tcp_length)
- packet = ip_header + tcp_header + user_data
- return checksum(packet)
- def send_raw_syn(dest_ip,dst_port):
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
- except Exception:
- sys.stderr.write("Error creating socket in send_raw_syn\n")
- if options.source == "auto":
- src_addr = get_source_ip(dest_ip)
- else:
- src_addr = options.source
- src_port = 54321
- make_tcpheader = TCPHeader(src_port,dst_port)
- tcp_header = make_tcpheader.get_struct()
- packet = make_tcpheader.get_struct(check=tcp_checksum(src_addr,dest_ip,tcp_header),checksummed=True)
- if options.verbose: sys.stdout.write("SEND: SYN packet {} {}\n".format(dest_ip,dst_port))
- try: s.sendto(packet,(dest_ip,0))
- except Exception: sys.stderr.write("Error utilizing raw socket in send_raw_syn\n")
- def send_full_connect_syn(ip,port):
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.settimeout(options.timeout)
- except Exception:
- sys.stdout.write("Error creating socket in send_full_connect_syn\n")
- try:
- if options.verbose: sys.stdout.write("START: {} {} port\n".format(ip,port))
- s.connect((ip,port))
- sys.stdout.write("OPEN: \t{0} : {1}\n".format(ip,port))
- s.close()
- except Exception:
- pass
- if options.verbose: sys.stdout.write("DONE: {} {} port\n".format(ip,port))
- def populate_queues():
- options.ports = convert_ports(options.ports)
- for ip in convert_ips(ips):
- if options.ping.lower() == "n":
- for port in options.ports:
- if options.verbose: sys.stdout.write("Placing ({},{}) in socket queue\n".format(ip,port))
- if options.verbose: print(socket_queue.queue)
- socket_queue.put((ip,port))
- else:
- ip_queue.put(ip)
- def start_ping_threads():
- for index in range(options.threads):
- if options.ping == "y":
- ping_worker = Thread(target=ping, args=(ip_queue,))
- ping_worker.setDaemon(True)
- ping_worker.start()
- if options.verbose: print("THREADS inside ping: {}".format(active_count()))
- ip_queue.join()
- print("********* IP QUEUE BLOCK RELEASED ************")
- def start_port_threads():
- if options.scan_type.lower() == "s":
- listen_thread = Thread(target=tcp_listener)
- listen_thread.setDaemon(True)
- listen_thread.start()
- for index in range(options.threads):
- port_worker = Thread(target=port_check, args=(socket_queue,))
- port_worker.setDaemon(True)
- port_worker.start()
- if options.verbose: print("THREADS inside port: {}".format(active_count()))
- socket_queue.join()
- if options.scan_type.lower() == "s": sleep(options.timeout)
- print("********* SOCKET QUEUE BLOCK RELEASED *************")
- def halt_ping_threads():
- if options.ping == "y":
- for i in range(options.threads):
- ip_queue.put("HALT")
- def get_source_ip(dst_addr):
- global source_ips
- try:
- if dst_addr in source_ips:
- return source_ips[dst_addr]
- else:
- source_ips[dst_addr] = [(s.connect((dst_addr, 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]
- return source_ips[dst_addr]
- except Exception:
- sys.stderr.write("Something went wrong in get_source_ip, results might be wrong\n")
- populate_queues()
- start_ping_threads()
- halt_ping_threads()
- if options.ping_only != True:
- start_port_threads()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement