Hab mal weiter gebastelt... Weil Spass macht!
Es werden nun die iana.org Seite verwendet. Diese wird in einer Datei zwischen gespeichert...
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# http://www.python-forum.de/viewtopic.php?t=3262
import sys, socket, urllib, time
import zipfile, zlib
zlib.Z_DEFAULT_COMPRESSION = 9
class iana_port_info:
"""
Stell Port-Informationen bereit.
Diese werden von iana.org gelesen und in einer Cache-Datei
gespeichert. Beim nächsten Aufruf werden die Daten direkt
aus der Cache-Datei genutzt.
"""
url = "http://www.iana.org/assignments/port-numbers"
cachefile = "portscanner_data.zip"
def __init__( self, verbose = True ):
self.verbose = verbose
self.side_data = self._get_side_data()
self.port_data = {}
# Daten in Dict schreiben
self.prepare_data()
def prepare_data( self ):
"""
Die Rohdaten von iana.org parsen
"""
for line in self.side_data.splitlines():
line = line.split()
try:
if not "/tcp" in line[1]:
continue
self._insert_port_info( line )
except IndexError:
pass
def _insert_port_info( self, data ):
"""
Daten aufteilen und in Dict speichern
"""
try:
port_number = int( data[1].rsplit("/")[0] )
except ValueError:
return
keyword = data[0]
description = " ".join( data[2:] )
self.port_data[ port_number ] = "%s, %s" % (
keyword, description
)
def _get_side_data( self ):
"""
Port Daten lesen. Entweder aus Datei oder direkt von
iana.org, wenn die Datei nicht existiert.
"""
try:
return self._read_side_data()
except IOError:
# Aus Datei konnte nicht gelesen werden, also
# holen wir uns die Daten frisch von iana.org
data = self._iana_data_from_url()
# Speicher das ganze ab, für nächstes mal
self._save_side_data( data )
return data
def _iana_data_from_url( self ):
"""
Port Info-Seite von iana.org holen
"""
if self.verbose: print "connect to '%s'..." % self.url,
c = urllib.urlopen( self.url )
if self.verbose: print "OK"
if self.verbose: print "download portinfo...",
data = c.read()
if self.verbose: print "OK"
c.close()
return data
def _save_side_data( self, data ):
""" Port-Seite in Cache Datei schreiben """
print "Write Port-Data in ZIP-File...",
ziparchiv = zipfile.ZipFile( self.cachefile, "w", zipfile.ZIP_DEFLATED)
ziparchiv.writestr( "port-numbers.txt", data)
ziparchiv.close()
print "OK"
def _read_side_data( self ):
""" Port-Seite aus Cache Datei lesen """
ziparchiv = zipfile.ZipFile( self.cachefile, "r" )
data = ziparchiv.read( "port-numbers.txt")
ziparchiv.close()
return data
def known_ports( self ):
""" Liefert Liste aller bekannten Ports zurück """
return sorted( self.port_data.keys() )
def iteritems( self ):
""" Hilfreich zum Auflisten der Port-Informationen """
return sorted( self.port_data.iteritems() )
def __getitem__( self, port ):
""" Liefert Informationen zum angegebenen port """
try:
return self.port_data[port]
except KeyError:
return "unknow port"
def __len__( self ):
return len(self.port_data)
#~ t = iana_port_info()
#~ for port, info in t.iteritems():
#~ print port, "-", info
#~ sys.exit()
class portscanner:
# Timeout in Sek. nachdem ein Port als zu erkannt werden soll
timeout = 1
# Auf wievielfachen Wert soll der timeout gesenkt werden, wenn
# ein Port offen gescannt wurde
buffer_multiply = 2
def __init__( self ):
self.iana_port_info = iana_port_info()
print len(self.iana_port_info),"known ports"
def scan_range( self, host, start_port=1, end_port=65535 ):
"""
Scannt eine Port-Bereich durch.
"""
print "\n--> Beginning scan on %s Port %s - %s" % (
host, start_port, end_port
)
print "-"*80
for port in xrange( start_port, end_port+1 ):
self.scan_port( host, port )
def scan_known_ports( self, host, well_know=True ):
"""
Scannt nur Ports die in der iana.org Liste auftauchen.
Ist well_know == True werden nur Ports gescannt die als
Keyword in der iana.org Liste kein '#'-Zeichen haben
"""
print "\n--> scan know ports on %s" % host
for port in self.iana_port_info.known_ports():
if well_know and self.iana_port_info[port].startswith("#"):
continue
self.scan_port( host, port )
def scan_port( self, host, port ):
"""
Scannt einen port
"""
print "Port:%5s (%-40s)..." % (
port, self.iana_port_info[port]
),
start_time = time.time()
try:
sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout( self.timeout )
sock.connect( (host, port) )
sock.shutdown( socket.SHUT_RDWR )
scan_time = time.time() - start_time
except Exception, e:
print "Closed [%s]" % e
else:
print "Open! (%.0fms, %.0fms)" % (
scan_time*100, self.timeout*100
)
sock.close()
if scan_time < self.timeout:
# Server reagierte schneller, als der aktuelle Timeout
self.timeout = scan_time * self.buffer_multiply
if __name__ == '__main__':
scanner = portscanner()
host = "82.105.57.129"
#~ scanner.scan_range( host, 1,65535 )
scanner.scan_known_ports( host )
EDIT: Weil die Portliste so groß ist, hab ich es nun in eine ZIP-Datei gepackt
EDIT2: Weil die Scanzeiten so lang sind, hab ich am Timeout etwas rumgeschraubt... Sobald ein Port als offen erkannt wurde, wird der Timeout runtergesetzt.
Bei dem SPAM-TEST-Server ist der Port 22 und 25 offen. Danach wird es spürbar schneller
