In questo articolo viene trattato l'utilizzo di un tool di scansione rete con NMAP e Python.
Una delle prime attività di un amministratore per iniziare la messa in sicurezza di una rete LAN è sicuramente la scansione degli indirizzi IP e dello stato delle porte.
Esistono svariati tool che ci permettono questo e tra i tanti sicuramente uno dei piu validi e affidabili è NMAP. Questo tool è disponibile sia per SO Windows che Linux.
ARDEA 1.0 è un progetto che nasce con l'intento di semplificare l'utilizzo di questo tool grazie a Python. Per il corretto funzionamento del tool ARDEA è indispensabile sia installare il modulo python-nmap all'interno delle nostre librerie Python che il tool nmap alll'interno del sistema operativo
Soddisfatti tali requisiti possiamo avviare ARDEA che si presenta con questa schermata iniziale:
Nel menu pricipale abbiamo la possibilità di scegliere se la scansione che vogliamo effettuare riguarda l'intera rete LAN oppure un singolo indirizzo IP.
Analizziamo la scelta 1 ovvero di effettuare la scansione sull'intera rete LAN
Le funzionalita di questo menu sono le seguenti:
1.Attraverso una scansione di tipo SYN il tool rileva le postazioni in LINEA e le postazioni SPENTE.
Unico requisito è inserire l'indirizzo della nostra rete in base 24 (subnet 255.255.255.0), per esempio 192.168.1.0, 10.23.110.0.
Ecco un esempio di OUTPUT
2. Con la scelta 2 potremmo verificare lo stato di una determianta porta su tutte le postazione della rete LAN.
Questo tipo di scansione può rislutare molto utile per verificare velocemente lo stato di un determinato servizio qualora se ne conosca la porta di utilizzo impostata, oppure potrebbe capitare di dover controllare se una determinata minaccia sia presente sulla rete. Infatti di solito questo tipo di attacco viene portato a termine mediante una backdoor che lo script malevolo utilizza per comunicare con un server remoto. Pertanto potrebbe essere molto utile avere una situazione generale riferita ad una determinata porta
3. Avere l'elenco degli indirizi fisici MAC di tutte le postazioni in LINEA
4. Elenco dei nomi assegnati alle postazioi in LINEA.
Questa opzione risulta molto utile in quei contesti in cui viene rispettata una policy di configurazione delle Postazioni in base alla loro ubicazione all'interno per esempio di un contesto aziendale. Infatti questo tipo di policy è fondamentale per una corretta e funzionale configurazione di un server di dominio AD o LDAP.
Vediamo adesso il menu delle scansioni singole:
1. In modo analogo alla funzione vista precedentemente, possiamo controllare lo stato di una postazione
2. Con questa funzione, una volta indicato l'indirizzo IP della postazione da scansionare, potremmo indicare una serie di porte specifiche separate dall virgola ",", il sistema provvederà a scansionare e riportare lo stato nel OUTPUT
3. Individuiamo l'indirizzo MAC di una determianta postazione di cui si conosce l'indirizzo IP.
4. Nome assegnato ad una determinata postazione di cui si conosce l'indirizzo IP.
5. Funzione utile se si vuole conoscere lo stato di un intervallo di porte specifico.
6. Questa funzione risulta essere tanto LENTA quanto EFFICACE. Infatti una volta inserito l'indirizzo IP della postazione da esaminare, il tool provvederà a scansionare tutte le 65535 porte disponibili restituendo solo l'elenco delle porte che risultano OPEN.
In futuro ARDEA verrà dotato di altre funzionalità utili ad acquisire informazioni sulle postazioni presenti su una rete LAN, come per esempio il tipo di sistema operativo oppure l'elenco degli utenti che utilizzano la postazione scansionata.
Di seguito lo script Python per usare ARDEA:
'''ARDEA è un tool di scansione scritto in PYTHON basato essenzialmente sull'utilizzo di NMAP
L'obbiettivo del tool è quello di rendere disponibile l'output delle opzioni di NAMP, attraverso
l'utilizzo di un menu di scelta rapida'''
import nmap
import os
nmap.PortScanner()
primoscan=nmap.PortScanner()
while True:
os.system("clear")
print('\n *** ARDEA TOOL ***\n')
print(''' 1) Scansioni su intera rete\n
2) Scansioni singole\n''')
scelta=input(' SCELTA: ')
if scelta=="1":
os.system("clear")
print('''\n***Scansioni su intera rete***\n
1) Controllo dello stato delle Postazioni\n
2) Controllo stato PORTA/E su tutte le Postazioni\n
3) Indirizzo MAC delle Postazioni\n
4) Nomi assegnati alle Postazioni\n''')
interarete=input("SCEGLI: ")
if interarete=="1":
net=input("Inserisci l'indrizzo di rete /24: ")
split="."
net2=net.split(split)
net_final=net2[0]+split+net2[1]+split+net2[2]+split
all_net=255
for ip in range (1,all_net):
postazione=(net_final+str(ip))
scan=primoscan.scan(postazione,"80","-sS")
stato_postazione=primoscan.scanstats()
if stato_postazione["downhosts"]=="1":
print("La postazione",postazione,"è SPENTA")
if stato_postazione["uphosts"]=="1":
print("La postazione",postazione,"è in LINEA")
input("Premi un tasto per continuare:")
if interarete=="2":
net = input("Inserisci l'indrizzo di rete /24: ")
split = "."
net2 = net.split(split)
net_final = net2[0] + split + net2[1] + split + net2[2] + split
all_net = 255
scanport=input("Inserisci le porte da scansionare separate da una virgola: ")
for ip in range(1, all_net):
postazione = (net_final + str(ip))
scan = primoscan.scan(postazione, scanport, "-sS")
stato_postazione = primoscan.scanstats()
if stato_postazione["uphosts"] == "1":
print("La postazione", postazione, "è in LINEA")
elencoporte=primoscan[postazione]["tcp"].keys()
for port in (elencoporte):
print("La porta",port,"è",primoscan[postazione]["tcp"][port]["state"])
print("\nLe postazioni non in elenco sono da considerarsi SPENTE")
input("\nPremi un tasto per continuare:")
if interarete=="3":
net = input("Inserisci l'indrizzo di rete /24: ")
split = "."
net2 = net.split(split)
net_final = net2[0] + split + net2[1] + split + net2[2] + split
all_net = 255
os.system("clear")
for ip in range(1, all_net):
postazione = (net_final + str(ip))
scan = primoscan.scan(postazione, "80", "-sS")
stato_postazione = primoscan.scanstats()
if stato_postazione["uphosts"] == "1":
mac = (scan["scan"][postazione]["addresses"]["mac"])
print("La postazione", postazione, "ha indirizzo MAC", mac)
print("\nLe postazioni non in elenco sono da considerarsi SPENTE")
input("\nPremi un tasto per continuare:")
if interarete=="4":
net = input("Inserisci l'indrizzo di rete /24: ")
split = "."
net2 = net.split(split)
net_final = net2[0] + split + net2[1] + split + net2[2] + split
all_net = 255
for ip in range(1, all_net):
postazione = (net_final + str(ip))
scan = primoscan.scan(postazione, "80", "-sS")
stato_postazione = primoscan.scanstats()
if stato_postazione["downhosts"] == "0":
name = (scan["scan"][postazione]["hostnames"][0]["name"])
print("La postazione", postazione, "ha il seguente nome assegnato \"", name, "\"")
print("Le postazioni non in elenco sono da considerarsi SPENTE")
input("\nPremi un tasto per continuare:")
if scelta=="2":
os.system("clear")
print('''\n***Scansioni verso una singola postazione***\n
1) Controllo dello stato di una Postazione\n
2) Controllo stato PORTA/E su una Postazione\n
3) Indirizzo MAC di una Postazione\n
4) Nome della Postazione\n
5) Controllo stato intervallo di PORTE\n
6) Controllo porte APERTE su una Postazione\n''')host = input("SCEGLI: ")
if host == "1":
net_host = input("Inserisci l'indrizzo di rete della postazione: ")
split = "."
net2 = net_host.split(split)
net_final = net2[0] + split + net2[1] + split + net2[2] + split+net2[3]
postazione=(net_final)
scan=primoscan.scan(postazione,"80","-sS")
stato_postazione=primoscan.scanstats()
if stato_postazione["downhosts"]=="1":
print("La postazione",postazione,"è SPENTA")
if stato_postazione["uphosts"]=="1":
print("La postazione",postazione,"è in LINEA")
input("Premi un tasto per continuare:")
if host=="2":
net = input("Inserisci l'indrizzo di rete /24: ")
split = "."
net2 = net.split(split)
net_final = net2[0] + split + net2[1] + split + net2[2] + split+net2[3]
scanport=input("Inserisci la porta/e da scansionare separate da una virgola: ")
postazione = (net_final )
scan = primoscan.scan(postazione, scanport, "-sS")
stato_postazione = primoscan.scanstats()
# print(stato_postazione)
if stato_postazione["downhosts"] == "1":
print("La postazione", postazione, "è SPENTA")
if stato_postazione["uphosts"] == "1":
print("La postazione", postazione, "è in LINEA")
elencoporte=primoscan[postazione]["tcp"].keys()
#creiamo un ciclo che itera sulle porte scelt in precedenza
for port in (elencoporte):
print("La porta",port,"è",primoscan[postazione]["tcp"][port]["state"])
input("\nPremi un tasto per continuare:")
if host=="3":
postazione=input("Inserisci l'indirizzo ip della Postazione:")
os.system("clear")
scan=primoscan.scan(postazione,"80","-sS")
stato=primoscan.scanstats()
if stato["downhosts"]=="1":
print("La postazione è SPENTA. Impossibile individuare indirizzo MAC")
input("\nPremi un tasto per continuare:")
if stato["downhosts"]=="0":
mac=(scan["scan"][postazione]["addresses"]["mac"])
print("La postazione",postazione,"ha indirizzo MAC",mac)
print(mac.csv())
input("\nPremi un tasto per continuare:")
if host=="4":
postazione = input("Inserisci l'indirizzo ip della Postazione:")
os.system("clear")
scan = primoscan.scan(postazione, "80", "-sS")
stato = primoscan.scanstats()
if stato["downhosts"] == "1":
print("La postazione è SPENTA. Impossibile recuperare informazioni")
input("\nPremi un tasto per continuare:")
if stato["downhosts"] == "0":
name = (scan["scan"][postazione]["hostnames"][0]["name"])
print("La postazione", postazione, "ha il seguente nome assegnato \"", name,"\"")
input("\nPremi un tasto per continuare:")
if host=="5":
os.system("clear")
postazione = input("Inserisci l'indirizzo ip della Postazione:")
porta_inizio = input("inserisci la porta iniziale dell'intervallo: ")
porta_fine = input("Inserisci la porta finale dell'intervallo; ")
scan = primoscan.scan(postazione, '80', "-sS")
stato = primoscan.scanstats()
if stato["downhosts"] == "1":
print("La postazione è SPENTA. Impossibile recuperare informazioni")
input("\nPremi un tasto per continuare:")
if stato["downhosts"] == "0":
for porta in range (int(porta_inizio),int(porta_fine)):
primoscan2=nmap.PortScanner()
scan = primoscan2.scan(postazione, str(porta), "-sS")
print("La porta " ,porta,"è", primoscan2[postazione]["tcp"][porta]["state"])
input("\nPremi un tasto per continuare:")
if host=="6":
os.system("clear")
print("Questa scansione è molto LENTA ma individua ogni porta APERTA sulla postazione\n")
postazione = input("Inserisci l'indirizzo ip della Postazione:")
scan = primoscan.scan(postazione, '80', "-sS")
stato = primoscan.scanstats()
if stato["downhosts"] == "1":
print("La postazione è SPENTA. Impossibile recuperare informazioni")
input("\nPremi un tasto per continuare:")
if stato["downhosts"] == "0":
print("\nLa postazione",postazione,"è IN LINEA. La scansione è in corso.....")
for porta in range (1,65536):
primoscan2=nmap.PortScanner()
scan = primoscan2.scan(postazione, str(porta), "-sS")
stato_porta=primoscan2[postazione]["tcp"][porta]["state"]
if stato_porta=="open":
print("La porta ", porta, "è", primoscan2[postazione]["tcp"][porta]["state"])
input("\nPremi un tasto per continuare:")