mirror of https://github.com/n1nj4sec/pupy.git
Fix hosts ranges scan
This commit is contained in:
parent
08fc22a932
commit
41932c6362
|
@ -25,11 +25,14 @@ class PortScan(PupyModule):
|
|||
self.arg_parser.add_argument('target', metavar="ip/range", help='IP/range')
|
||||
|
||||
def run(self, args):
|
||||
if "/" in args.target[0]:
|
||||
hosts = IPNetwork(args.target[0])
|
||||
scan_range = False
|
||||
|
||||
if '/' in args.target:
|
||||
hosts = [ str(x) for x in IPNetwork(args.target) ]
|
||||
scan_range = True
|
||||
self.log('Scanning range {}: {} hosts'.format(args.target, len(hosts)))
|
||||
else:
|
||||
hosts = list()
|
||||
hosts.append(args.target)
|
||||
hosts = [ args.target ]
|
||||
|
||||
ports = [
|
||||
p for prange in args.ports.split(',') for p in (
|
||||
|
@ -44,30 +47,36 @@ class PortScan(PupyModule):
|
|||
ports = list(set(ports))
|
||||
random.shuffle(ports)
|
||||
|
||||
for host in hosts:
|
||||
scanner = self.client.conn.modules['network.lib.scan']
|
||||
scanner = self.client.conn.modules['network.lib.scan']
|
||||
|
||||
def set_connectable(ports):
|
||||
self.connectable = ports
|
||||
self.terminated.set()
|
||||
def set_connectable(addrs):
|
||||
self.connectable = addrs
|
||||
self.terminated.set()
|
||||
|
||||
self.abort = scanner.scanthread(
|
||||
str(host), ports, set_connectable, timeout=args.timeout, portion=args.portion
|
||||
)
|
||||
self.connectable = []
|
||||
|
||||
self.terminated.wait()
|
||||
self.abort = scanner.scanthread(
|
||||
hosts, ports, set_connectable, timeout=args.timeout, portion=args.portion
|
||||
)
|
||||
|
||||
ports = sorted(self.connectable)
|
||||
self.terminated.wait()
|
||||
|
||||
if ports:
|
||||
self.log('{}: {}'.format(host, ', '.join([str(x) for x in ports])))
|
||||
else:
|
||||
self.log('{}: closed'.format(host))
|
||||
if self.connectable:
|
||||
connectable = {}
|
||||
for host, port in self.connectable:
|
||||
if host in connectable:
|
||||
connectable[host].add(port)
|
||||
else:
|
||||
connectable[host] = set([port])
|
||||
|
||||
if self.abort.is_set():
|
||||
break
|
||||
for host in sorted(connectable.keys()):
|
||||
ports = ', '.join([str(port) for port in sorted(list(connectable[host]))])
|
||||
self.log('{}: {}'.format(host, ports))
|
||||
|
||||
self.abort = None
|
||||
elif not scan_range:
|
||||
self.log('{}: closed'.format(args.target))
|
||||
|
||||
self.abort = None
|
||||
|
||||
def interrupt(self):
|
||||
if self.abort:
|
||||
|
|
|
@ -6,20 +6,33 @@ import errno
|
|||
import time
|
||||
import threading
|
||||
import rpyc
|
||||
import logging
|
||||
|
||||
def chunks(l, n):
|
||||
for i in xrange(0, len(l), n):
|
||||
yield l[i:i + n]
|
||||
chunk = []
|
||||
for i in l:
|
||||
if len(chunk) == n:
|
||||
yield chunk
|
||||
chunk = []
|
||||
else:
|
||||
chunk.append(i)
|
||||
|
||||
if chunk:
|
||||
yield chunk
|
||||
|
||||
def create_socket(host, port):
|
||||
sock = socket.socket()
|
||||
sock.setblocking(0)
|
||||
r = sock.connect_ex((host, port))
|
||||
try:
|
||||
r = sock.connect_ex((host, port))
|
||||
except Exception, e:
|
||||
return None, None
|
||||
|
||||
return sock, r
|
||||
|
||||
def scan(host, ports, abort=None, timeout=10, portion=32, on_complete=None):
|
||||
def scan(hosts, ports, abort=None, timeout=10, portion=32, on_complete=None, on_open_port=None):
|
||||
connectable=[]
|
||||
for portion in chunks(list(ports), portion):
|
||||
for portion in chunks(((x, y) for x in hosts for y in ports), portion):
|
||||
if not portion:
|
||||
continue
|
||||
|
||||
|
@ -27,29 +40,44 @@ def scan(host, ports, abort=None, timeout=10, portion=32, on_complete=None):
|
|||
break
|
||||
|
||||
sockets = {}
|
||||
for port in portion:
|
||||
for host, port in portion:
|
||||
sock, r = create_socket(host, port)
|
||||
if sock is None:
|
||||
continue
|
||||
|
||||
if r:
|
||||
if r in (errno.EAGAIN, errno.EINPROGRESS):
|
||||
sockets[sock] = port
|
||||
sockets[sock] = (host, port)
|
||||
else:
|
||||
sock.close()
|
||||
continue
|
||||
else:
|
||||
connectable.append(port)
|
||||
if on_open_port:
|
||||
on_open_port((host, port))
|
||||
|
||||
connectable.append((host, port))
|
||||
sock.close()
|
||||
|
||||
start = time.time()
|
||||
while sockets and time.time() - start < timeout:
|
||||
socks = list(sockets.iterkeys())
|
||||
_, w, _ = select.select([], socks, [], timeout - (time.time() - start))
|
||||
if sockets:
|
||||
start = time.time()
|
||||
while sockets and time.time() - start < timeout:
|
||||
socks = list(sockets.iterkeys())
|
||||
_, w, _ = select.select([], socks, [], timeout - (time.time() - start))
|
||||
|
||||
for sock in w:
|
||||
errcode = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
|
||||
if errcode == 0:
|
||||
connectable.append(sockets[sock])
|
||||
sock.close()
|
||||
del sockets[sock]
|
||||
for sock in w:
|
||||
try:
|
||||
errcode = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
|
||||
if errcode == 0:
|
||||
if on_open_port:
|
||||
on_open_port(sockets[sock])
|
||||
|
||||
connectable.append(sockets[sock])
|
||||
except:
|
||||
pass
|
||||
|
||||
finally:
|
||||
sock.close()
|
||||
del sockets[sock]
|
||||
|
||||
if on_complete:
|
||||
if abort and not abort.is_set():
|
||||
|
@ -57,8 +85,8 @@ def scan(host, ports, abort=None, timeout=10, portion=32, on_complete=None):
|
|||
else:
|
||||
return connectable
|
||||
|
||||
def scanthread(host, ports, on_complete, **kwargs):
|
||||
host = str(host)
|
||||
def scanthread(hosts, ports, on_complete, **kwargs):
|
||||
hosts = [ x for x in hosts ]
|
||||
ports = [ x for x in ports ]
|
||||
abort = threading.Event()
|
||||
connectable = []
|
||||
|
@ -66,7 +94,7 @@ def scanthread(host, ports, on_complete, **kwargs):
|
|||
'abort': abort,
|
||||
'on_complete': rpyc.async(on_complete)
|
||||
})
|
||||
scanner = threading.Thread(target=scan, args=(host, ports), kwargs=kwargs)
|
||||
scanner = threading.Thread(target=scan, args=(hosts, ports), kwargs=kwargs)
|
||||
scanner.daemon = True
|
||||
scanner.start()
|
||||
|
||||
|
|
Loading…
Reference in New Issue