Soporte OnLine

Escaner de puertos con rangos en python


Bueno, aquí os dejo un pequeño escáner de puertos que usa multi-hilos para aumentar la velocidad de respuesta por cada petición.

Este módulo permite escanear rangos de IP’s (X-Y, *) y puertos (A-Z, A,B,C,…Z) y nos informa del tipo de servicio que esta en uso en el caso que el puerto este abierto (ej.: 80 => www).

Código portscan.py

#!/usr/bin/env python
# -*- coding: utf8 -*-
 
import socket, sys, threading, time, os
from thread import error
 
timeout = 2
maxthread = 1024
 
x = 0
err = False
show = True
 
def usage():
    print "Uso: %s IP PORT" % sys.argv[0]
    print "nIP admite rangos a-z y el port rangos x-y a,b,...z."
    print "Ejemplos:"
    print "t%s 127.0.0.1 1-1024" % sys.argv[0]
    print "t%s 192.168.1.2-100 21,22,25,80,115,443" % sys.argv[0]
    print "t%s 217.127.97.* 21n" % sys.argv[0]
    if sys.platform == "win32":
        os.system("pause")
    sys.exit()
 
class PortScanner(threading.Thread):
    def __init__(self, host, port, services):
        threading.Thread.__init__(self)
        self.host = host
        self.port = int(port)
        self.services = services
    def run(self):
        global x
        global err
        global show
        if err:
            sys.exit()
        socket.setdefaulttimeout(timeout)
        try:
            self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error as e:
            print e
            err = True
            sys.exit()
        try:
            self.s.connect((self.host, self.port))
            service = "unknown"
            for serv in self.services:
                serv = serv.strip("n")
                if str(self.port)+"/tcp" in serv.split():
                    service = serv.split()[0]
                    break
            if show:
                print "nPORTtSTATUStSERVICE"
                show = False
            print "%stOPENt%s" % (str(self.port), service)
            x += 1
        except:
            pass
        self.s.close()
 
if __name__ == "__main__":
    servs = []
    if sys.platform == "linux2":
        f = open("/etc/services", "r")
    else:
        f = open("c:WINDOWSsystem32driversetcservices", "r")
    servs = f.readlines()
    f.close()
    if len(sys.argv) < 2:
        usage()
    elif len(sys.argv) == 3:
        try:
            host = socket.gethostbyname(sys.argv[1]).split(".")
        except:
            host = sys.argv[1].split(".")
        try:
            a = host[0]; b = host[1]; c = host[2]; d = host[3]
        except:
            print "Error en la resolucion del host"
            sys.exit()
        if host[0] == "*": a = "1-255"
        if host[1] == "*": b = "1-255"
        if host[2] == "*": c = "1-255"
        if host[3] == "*": d = "1-254"
        if a.find("-") == -1: a += "-"+a
        if b.find("-") == -1: b += "-"+b
        if c.find("-") == -1: c += "-"+c
        if d.find("-") == -1: d += "-"+d
        for A in range(int(a.split("-")[0]), int(a.split("-")[1])+1):
            for B in range(int(b.split("-")[0]), int(b.split("-")[1])+1):
                for C in range(int(c.split("-")[0]), int(c.split("-")[1])+1):
                    for D in range(int(d.split("-")[0]), int(d.split("-")[1])+1):
                        ip = str(A)+"."+str(B)+"."+str(C)+"."+str(D)
                        ports = sys.argv[2]
                        if ports.find("-") == -1 and ports.find(",") == -1:
                            ports += "-"+ports
                        x = 0
                        if ports.find("-") > 0:
                            ports = ports.split("-")
                            if not ports[0].isdigit() or not ports[1].isdigit():
                                print "Rango invalidon"
                                usage()
                                sys.exit()
                            print "Escanenado %s:" % ip
                            for port in range(int(ports[0]), int(ports[1])+1):
                                if err:
                                    sys.exit()
                                while threading.activeCount() >= maxthread:
                                    time.sleep(0.5)
                                scan = PortScanner(ip, port, servs)
                                try:
                                    scan.start()
                                except error as err:
                                    print "nError: "%s"" % err
                            scan.join()
                            if x > 0:
                                print "n%d puerto(s) abierto(s)n" % x
                            show = True
                        elif ports.find(",") > 0:
                            ports = ports.split(",")
                            print "Escanenado %s:" % ip
                            for port in ports:
                                if err:
                                    sys.exit()
                                if not port.isdigit():
                                    print "%s no es un digito" % port
                                    sys.exit()
                                while threading.activeCount() >= maxthread:
                                    time.sleep(0.5)
                                scan = PortScanner(ip, port, servs)
                                try:
                                    time.sleep(0.005)
                                    scan.start()
                                except error as err:
                                    print "nError: "%s"" % err
                            scan.join()
                            if x > 0:
                                print "n%d puerto(s) abierto(s)n" % x
                            show = True
    else: usage()

Lo primero que necesitamos es el interprete de python. En Linux normalmente ya vendrá, en Windows lo bajamos aquí. En Linux lo hacemos ejecutable para facilitar la ejecución:

chmod +x portscan.py

Y para ejecurarlo:

./portscan.py IP PORT

En Windows una vez que tenemos el interprete de python instalado no es mas que situarnos desde la consola (cmd) en el directorio donde tenemos el programa y escribir:

portscan.py IP PORT

Su uso es fácil, para escanear por ejemplo todos los puertos privilgiados del 1 al 1024 de nuestra IP:

./portscan.py 127.0.0.1 1-1024

En mi caso, la salida del ejemplo anterior sería:

Escanenado 127.0.0.1:
 
PORT     STATUS     SERVICE
21       OPEN       ftp
25       OPEN       smtp
53       OPEN       domain
80       OPEN       www
 
4 puerto(s) abierto(s)

Para escanear los puertos 22 y 80 de nuestra red local, por ejemplo, 192.168.1.X:

./portscan.py 192.168.1.* 22,80

o

./portscan.py 192.168.1.1-254 22,80

Este programa tiene 2 parametros que se pueden modificar que estan en la cabezera del mismo modulo y son timeout y maxthread.

Donde:
timeout: Es el tiempo maximo que debemos esperar antes de dar como cerrado el puerto.
maxthread: Define el maximo numero de hilos (thread) que se pueden lanzar simultaneamente.

Un saludo

Dejar un comentario?

0 Comentarios.

Deje un comentario