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.* 21\n" % 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 "\nPORT\tSTATUS\tSERVICE"
                show = False
            print "%s\tOPEN\t%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:\WINDOWS\system32\drivers\etc\services", "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 invalido\n"
                                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

QR Code - Take this post Mobile!
Use this unique QR (Quick Response) code with your smart device. The code will save the url of this webpage to the device for mobile sharing and storage.
Dejar un comentario?

1 Comentarios.

  1. Howdy would you mind letting me know which hosting company you’re working with?

    I’ve loaded your blog in 3 completely different internet browsers and I must say this
    blog loads a lot quicker then most. Can you suggest a good hosting
    provider at a fair price? Thanks, I appreciate it!

Deje un comentario


NOTA - Puede usar estosHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>