Last active
August 29, 2015 14:00
-
-
Save highfestiva/65b127e7cead4e46f6fd to your computer and use it in GitHub Desktop.
Parallel tcp port scan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Scan TCP ports in a multithreaded fashion. | |
import multiprocessing | |
import re | |
import socket | |
import sys | |
def checkport(_): | |
global queue | |
host,port = queue.get() | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
s.settimeout(0.001 if host=='127.0.0.1' else 2) | |
if s.connect_ex((host,port)) == 0: | |
print('%s:%i open' % (host,port)) | |
hostport = (host,port) | |
else: | |
hostport = None | |
s.close() | |
print('%i \r' % port, end='', file=sys.stderr) # Show some progress. | |
return hostport | |
def _clamp(minimum, x, maximum): | |
return max(minimum, min(x, maximum)) | |
def _initio(q, outp): | |
global queue | |
queue = q | |
if not outp: sys.stdout.write = lambda x: x | |
def scan(host_ranges, outp=False): | |
multiprocessing.freeze_support() | |
q = multiprocessing.Queue() | |
all_ports = [] | |
for host,loport,hiport in host_ranges: | |
if outp: | |
print('Scanning %s:%i-%i... ' % (host,loport,hiport)) | |
host = socket.gethostbyname(host) | |
min_workers = _clamp(1, hiport-loport, 5) | |
workers = _clamp(min_workers, (hiport-loport)//20, 80) # Limit the number of threads. | |
pool = multiprocessing.Pool(workers, _initio, [q, outp]) | |
[q.put((host,port)) for port in range(loport,hiport+1)] | |
ports = pool.map(checkport, range(loport,hiport+1)) | |
del pool | |
ports = list(filter(None, ports)) | |
if outp and not ports: | |
print('No ports open on %s.' % host) | |
all_ports += ports | |
return all_ports | |
def parserange(host, default_host): | |
dhost,dloport,dhiport = re.match(r'(.+):(\d+)-(\d+)', default_host).group(1,2,3) | |
try: host,loport,hiport = re.match(r'(.+):(\d+)-(\d+)', host).group(1,2,3) | |
except: loport,hiport = dloport,dhiport | |
return host,int(loport),int(hiport) | |
if __name__ == '__main__': | |
default = 'localhost:1-1024' | |
host_ranges = [parserange(r, default) for r in sys.argv[1:]] | |
scan(host_ranges, outp=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment