ich habe ne Weile nicht in Python geschrieben, verzeiht mir also bitte etwas seltsame Codezeilen.
Es geht um Folgendes:
Ich soll (Uni) einen Portscanner bauen.
Der soll Connect Scanning und SYN Scanning beherrschen.
Connect Scanning ist kein Problem, habe ich mit dem Standard socket Modul gelöst.
Was leider nur bedingt klappt ist der SYN Scan.
Wir wurde gebeten nur die Libraries pylibpcap und pylibnet zu nutzen.
Ich möchte also mit libnet ein Paket mit gesetztem TCP SYN Flag bauen und dann mit pcap nach Paketen mit SYN-ACK oder ACK-RST Flags lauschen(da kann ich mit dem promiscuous Modus natürlich gleich filtern nach Paketen, die an mich gerichtet sind).
So das Bauen der Pakete ist kein Problem.
Das Capturen schon eher.
Eigentlich läuft es, es wird nur leider irgendwann nichts mehr aufgenommen.
Wenn ich bspw. die Ports 1 - 1000 scanne, dann geben der Connect Scan und der SYN Scan das gleiche Ergebnis, wenn ich aber 1 - 10.000 scanne gehen einige verloren (habe Differenz aus abgeschickten und erhaltenen gebildet).
Ich füge mal den gesammten Code an, interessant für euch dürfte nur die Klasse PortScanner_SYN sein.
Ganz unten gibt es zwei Aufrufe, einmal als Connect- und einmal als SYN Scan (jeweils des Localhosts)
Code: Alles auswählen
import threading
from random import shuffle
from time import sleep
import Queue
from sys import argv
import socket
import libnet
from libnet.constants import *
import pcap
class PortScanner_Connect:
def __init__(self, host, port_start, port_end, maxThreads):
print('Performing Connect Scan\nHost: {0}\nPorts: {1} - {2}\nScanning...'.format(host, port_start, port_end))
self.openPorts=[]
self.tasks=Queue.Queue()
portList = range(port_start, port_end+1)
shuffle(portList)
for port in portList:
self.tasks.put((host, port))
for i in range(port_start, port_end+1):
while threading.activeCount() > maxThreads: pass
thread = threading.Thread(target=self.scan)
thread.daemon = True
thread.start()
self.tasks.join()
self.openPorts.sort()
print("The following ports were open at {0}: {1}".format(host, self.openPorts))
def scan(self):
host, port = self.tasks.get()
try:
sock=socket.socket()
sock.connect((host, port))
sock.close()
self.openPorts.append(port)
except socket.error:
pass
self.tasks.task_done()
class PortScanner_SYN:
def __init__(self, host, port_start, port_end, maxThreads, device='wlan0'):
print('Performing SYN Scan\nHost: {0}\nPorts: {1} - {2}\nScanning...'.format(host, port_start, port_end))
self.tasks=Queue.Queue()
ports = set(range(port_start, port_end+1))
for port in ports:
self.tasks.put((host, port))
capture = self.buildCapture(device, host)
for i in ports:
while threading.activeCount() > maxThreads: pass
thread = threading.Thread(target=self.sendPacket(device))
thread.daemon = True
thread.start()
self.tasks.join()
result = self.capturePacket(ports, capture)
print("The following ports were open at {0}: {1}\n{2} ports were filtered".format(host, result['open'], len(result['filtered' ])))
def buildCapture(self, device, host):
capture = pcap.pcapObject()
capture.open_live(device, 48, 0, 100)
capture.setfilter('(tcp[13] == 0x14 || tcp[13] == 0x12) && src host {0}'.format(host), 0, 0)
return capture
def sendPacket(self, device):
host, port = self.tasks.get()
packet = libnet.context(RAW4,device)
packet.build_tcp(dp=port,control=TH_SYN)
packet.autobuild_ipv4(len=IPV4_H + TCP_H, prot=IPPROTO_TCP, dst=packet.name2addr4(host))
packet.write()
self.tasks.task_done()
def capturePacket(self, ports, capture):
results = {'open': [], 'closed': [], 'filtered': []}
for i in ports:
packet = capture.next()
if packet is None:
break
data = packet[1]
port = ord(data[34]) * 256 + ord(data[35])
if ord(data[47]) == 0x12:
results['open'].append(port)
elif ord(data[47]) == 0x14:
results['closed'].append(port)
responded = results['open'] + results['closed']
results['filtered'] = list(ports.difference(responded))
return results
maxThreads=100
PortScanner_Connect('127.0.0.1', 1, 10000, maxThreads)
PortScanner_SYN('127.0.0.1', 1, 10000, maxThreads, 'lo')
Ich vermute, dass das pcapObject einfach einen Puffer hat, der voll ist. Könnte es daran liegen?
Oder sind die Antworten auf einige Pakete vllt einfach noch nicht da?
In dem Fall hatte ich daran gedacht, jeden Thread ein paar sekunden warten zu lassen, bevor er meldet, dass er fertig ist.
Code: Alles auswählen
packet.write()
time.sleep(2)
self.tasks.task_done()
Ich hatte noch mehr Ideen, eine dümmer als die andere
Also ich muss gestehe ich habe keine Ahnung, habe aber bisher auch kaum mit Threads und noch nie mit pcap oder libnet gearbeitet.
Wo wir gerade dabei sind: Habt ihr eine Idee, wo es eine Dokumentation zu pcap gibt? Bei dem was ich mir da aus fremden Codes zusammengeschrieben habe, drehen sich einem die Fußnägel hoch... =(
Habt ihr Vorschläge, oder könnt ihr mir sagen, wo der Fehler liegt?
LG
elactic