mirror of https://github.com/n1nj4sec/pupy.git
select based trivial port scanner
This commit is contained in:
parent
b089e69ac5
commit
08fc22a932
|
@ -1,23 +1,27 @@
|
|||
# -*- coding: UTF8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pupylib.PupyModule import *
|
||||
from modules.lib.windows.winpcap import init_winpcap
|
||||
from netaddr import IPNetwork, IPAddress
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from netaddr import *
|
||||
import random
|
||||
import threading
|
||||
|
||||
__class_name__="PortScan"
|
||||
|
||||
@config(cat="network")
|
||||
class PortScan(PupyModule):
|
||||
""" run a TCP port scan """
|
||||
dependencies=['portscan', 'scapy']
|
||||
|
||||
abort = None
|
||||
terminated = threading.Event()
|
||||
max_clients = 1
|
||||
connectable = []
|
||||
|
||||
def init_argparse(self):
|
||||
self.arg_parser = PupyArgumentParser(prog="port_scan", description=self.__doc__)
|
||||
self.arg_parser.add_argument('--ports','-p', default="21,22,23,80,139,443,445,1433,1521,3389,7001,8000,8080", help='ports to scan ex: 22,80,443')
|
||||
self.arg_parser.add_argument('--timeout', default=4, help='timeout (default: %(default)s)')
|
||||
self.arg_parser.add_argument('--threads', default=10, help='number of threads (default: %(default)s)')
|
||||
self.arg_parser.add_argument('--timeout', default=10, help='timeout (default: %(default)s)')
|
||||
self.arg_parser.add_argument('--portion', default=32, help='number of ports scanned per timeout (default: %(default)s)')
|
||||
self.arg_parser.add_argument('target', metavar="ip/range", help='IP/range')
|
||||
|
||||
def run(self, args):
|
||||
|
@ -27,20 +31,47 @@ class PortScan(PupyModule):
|
|||
hosts = list()
|
||||
hosts.append(args.target)
|
||||
|
||||
ports = [int(p.strip()) for p in args.ports.split(',')]
|
||||
ports = [
|
||||
p for prange in args.ports.split(',') for p in (
|
||||
xrange(
|
||||
int(prange.split('-')[0]), int(prange.split('-')[1])+1
|
||||
) if '-' in prange else xrange(
|
||||
int(prange), int(prange)+1
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
ports = list(set(ports))
|
||||
random.shuffle(ports)
|
||||
|
||||
for host in hosts:
|
||||
self.success("Scanning remote host: %s" % host)
|
||||
scanner = self.client.conn.modules['network.lib.scan']
|
||||
|
||||
t1 = datetime.now()
|
||||
open_ports = self.client.conn.modules['portscan'].scan(host, ports, args.threads, args.timeout)
|
||||
if open_ports:
|
||||
self.log('PORT STATE')
|
||||
for p in open_ports:
|
||||
self.log("%s open" % p)
|
||||
def set_connectable(ports):
|
||||
self.connectable = ports
|
||||
self.terminated.set()
|
||||
|
||||
self.abort = scanner.scanthread(
|
||||
str(host), ports, set_connectable, timeout=args.timeout, portion=args.portion
|
||||
)
|
||||
|
||||
self.terminated.wait()
|
||||
|
||||
ports = sorted(self.connectable)
|
||||
|
||||
if ports:
|
||||
self.log('{}: {}'.format(host, ', '.join([str(x) for x in ports])))
|
||||
else:
|
||||
self.error('No open port found')
|
||||
self.log('{}: closed'.format(host))
|
||||
|
||||
# Checking the time again
|
||||
t2 = datetime.now()
|
||||
total = t2 - t1
|
||||
self.success('Scanning Completed in: %s' % total)
|
||||
if self.abort.is_set():
|
||||
break
|
||||
|
||||
self.abort = None
|
||||
|
||||
def interrupt(self):
|
||||
if self.abort:
|
||||
self.abort.set()
|
||||
|
||||
if self.terminated:
|
||||
self.terminated.set()
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import socket
|
||||
import select
|
||||
import errno
|
||||
import time
|
||||
import threading
|
||||
import rpyc
|
||||
|
||||
def chunks(l, n):
|
||||
for i in xrange(0, len(l), n):
|
||||
yield l[i:i + n]
|
||||
|
||||
def create_socket(host, port):
|
||||
sock = socket.socket()
|
||||
sock.setblocking(0)
|
||||
r = sock.connect_ex((host, port))
|
||||
return sock, r
|
||||
|
||||
def scan(host, ports, abort=None, timeout=10, portion=32, on_complete=None):
|
||||
connectable=[]
|
||||
for portion in chunks(list(ports), portion):
|
||||
if not portion:
|
||||
continue
|
||||
|
||||
if abort and abort.is_set():
|
||||
break
|
||||
|
||||
sockets = {}
|
||||
for port in portion:
|
||||
sock, r = create_socket(host, port)
|
||||
if r:
|
||||
if r in (errno.EAGAIN, errno.EINPROGRESS):
|
||||
sockets[sock] = port
|
||||
else:
|
||||
sock.close()
|
||||
continue
|
||||
else:
|
||||
connectable.append(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))
|
||||
|
||||
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]
|
||||
|
||||
if on_complete:
|
||||
if abort and not abort.is_set():
|
||||
on_complete(connectable)
|
||||
else:
|
||||
return connectable
|
||||
|
||||
def scanthread(host, ports, on_complete, **kwargs):
|
||||
host = str(host)
|
||||
ports = [ x for x in ports ]
|
||||
abort = threading.Event()
|
||||
connectable = []
|
||||
kwargs.update({
|
||||
'abort': abort,
|
||||
'on_complete': rpyc.async(on_complete)
|
||||
})
|
||||
scanner = threading.Thread(target=scan, args=(host, ports), kwargs=kwargs)
|
||||
scanner.daemon = True
|
||||
scanner.start()
|
||||
|
||||
return abort
|
|
@ -1,58 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
import Queue
|
||||
|
||||
open_port = []
|
||||
|
||||
class WorkerThread(threading.Thread) :
|
||||
|
||||
def __init__(self, queue, tid, remote_ip, ports, settimeout) :
|
||||
threading.Thread.__init__(self)
|
||||
self.queue = queue
|
||||
self.tid = tid
|
||||
self.ports = ports
|
||||
self.remote_ip = remote_ip
|
||||
self.timeout = settimeout
|
||||
|
||||
def check_open_port(self, port):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(self.timeout)
|
||||
result = sock.connect_ex((self.remote_ip, port))
|
||||
if result == 0:
|
||||
sock.close()
|
||||
open_port.append(port)
|
||||
|
||||
def run(self):
|
||||
for port in self.ports:
|
||||
try :
|
||||
port = self.queue.get(timeout=1)
|
||||
except Queue.Empty :
|
||||
return
|
||||
self.check_open_port(port)
|
||||
self.queue.task_done()
|
||||
|
||||
def scan(remote_ip, ports, nb_threads, settimeout):
|
||||
global open_port
|
||||
open_port = []
|
||||
|
||||
queue = Queue.Queue()
|
||||
threads = []
|
||||
|
||||
for i in range(1, nb_threads):
|
||||
worker = WorkerThread(queue, i, remote_ip, ports, settimeout)
|
||||
worker.setDaemon(True)
|
||||
worker.start()
|
||||
threads.append(worker)
|
||||
|
||||
for j in ports:
|
||||
queue.put(j)
|
||||
|
||||
queue.join()
|
||||
|
||||
# wait for all threads to exit
|
||||
for item in threads :
|
||||
item.join()
|
||||
|
||||
return open_port
|
Loading…
Reference in New Issue