Privacy Policy Cookie Policy Tecniche di PortScan in python - Parte 1: Tcp connection scan - Simone Sante Ruffo
You are here
Home > sicurezza informatica > portScanning > Tecniche di PortScan in python – Parte 1: Tcp connection scan

Tecniche di PortScan in python – Parte 1: Tcp connection scan

Fasi connessione tcp

Oggi parliamo di footprinting, ovvero, la fase del penetration testing nella quale si ci occupa di raccogliere le informazioni necessarie ad effettuare un attacco.

Inizio con questo una serie di articoli dove analizzeremo le più comuni tecniche di port scan.

Port scan: il port scan è una serie di tecniche utilizzate per scovare i servizi che permettono una connessione con l’esterno, all’interno del sistema.

Si capisce subito che stiamo parlando di attacchi a macchine remote vulnerabili.

Il primo passo di un attacco informatico è infatti imparare a conoscere, senza farsi scoprire, la vittima prima di effettuare l’attacco.
Questo permette di conoscere le vulnerabilità della stessa e potere quindi implementare una strategia di attacco ottimale e senza rischi per l’attaccante.

Il port scanning è quindi una delle tante tecniche volte a raggiungere questo scopo.

Vi è mai capitato di utilizzare nmap o la più famosa versione grafica zenmap?.
Lo scopo di questo strepitoso software è proprio quello di eseguire il port scanning delle macchine.

Ma chiediamoci perché scriverci un software da zero con python quando già esistono software pronti che effettuano molto meglio questo delicato compito?

Vi pongo questa domanda per anticiparvi un discorso che affronteremo successivamente prima però cerchiamo di rispondere alla domanda.
La risposta è subito data: se state effettuando il port scanning dal vostro pc a un altro pc che raggiungete facilmente attraverso la vostra rete allora potrebbe, tranne che in casi particolari, essere inutile realizzare una propria versione più scadente del software; utilizzate nmap e via…

Ma poniamoci in questa situazione: siamo davanti ad un sistema composto da un pc, unico al quale potete accedere, collegato ad una rete interna che può raggiungere solo lui. Il pc in questione farà da firewall.

Come conoscere la struttura della rete interna se non potete accedervi e nel pc che ha la funzione di firewall non vi è installato nmap (come dovrebbe essere) ma solo python (come spesso accade)?.

L’idea sarebbe quella di accedere al pc firewall ed eseguire all’interno della macchina, con tecniche come ssh tunnel, il nostro script così da ottenere gli indirizzi ip di tutte le macchine della rete interna.

La questione è che, per semplicità, alcune delle tecniche che vi sto per citare, richiedono l’uso di una libreria python che difficilmente troverete installata nella macchina della vittima, per cui sono inutilizzabili.
Ma vale comunque la pena analizzarle per capirne il funzionamento e potersi realizzare una propria libreria tramite la quale sara poi possibile utilizzarle per un attacco.

Il linguaggio che useremo è python perché:

1) Ormai presente in QUASI tutti i sistemi aziendali o server.
2) È rapido e semplice e permette quindi la realizzazione di tools di attacco in pochissimo tempo.

Il potere di python è infatti quello di avere una marea di librerie built-in già pronte, presenti in ogni interprete, che permettono di fare quasi ogni cosa con il minimo sforzo possibile e infatti la prima mossa che dobbiamo fare e vedere quali librerie ci servono.

La prima libreria che ci serve è certamente socket. Una socket è un connettore virtuale tra il livello di applicazione di un sistema e il livello applicazione della macchina con la quale ci connettiamo. Essa è una interfaccia quindi tra il livello applicazione e trasporto della pila TCP/IP.

Una socket viene definita dal protocollo (tipo di socket) e dall’indirizzo IP e dalla porta alla quale dobbiamo connetterci.

Una seconda libreria utile è sys che contiene le librerie per interagire con il sistema nel quale viene eseguito il software.
Altre librerie utili sono getopt e datetime.

Getopt permette di gestione gruppi di operatori che passeremo come argomenti tramite il tipico formato “-lettera” o “—parola” mentre datetime permette di calcolare il tempo di esecuzione e l’orario di scansione per i log.

#Importa le librerie per aprire e chiudere la connessione
from socket import *
#Importa le librerie per ottenere data e ora
from datetime import datetime
#Importa le librerie di sistema
import sys
#Libreria utile per gestire gli argomenti ottenuti da linea di comando
import getopt

Una prima operazione da fare è stabilire le costanti globali. Queste sono dei valori che nel software rimarranno sempre fissi come gli array con le operazioni selezionabili nel menu.

#CONSTANTI
#Lista di opzioni accettabili da linea di comando
OPTIONLIST = "sti:h:p:"
#Lista delle option list lunghe
LONGOPTION = ["tcp","ip","host","port"]

Iniziamo a generare la struttura base del nostro software, la funzione main che chiamera tutti i metodi.
Nel main() inizieremo dichiarando tutte le variabili che utilizzeremo per la gestione del software come l’indirizzo ip, l’host e la porta della vittima oltre a dei flag che porremo a true in base a quali operazioni sono state scelte.

Per ora sarà permessa una sola operazione, il tcp connect scan, man mano che inseriremo altre funzionalità aggiorneremo il menu del software.

tcp connect scan: è un tipo di scansione che utilizza la sys call connect() per effettuare la connessione ad ogni possibile porta fornita dalla macchina bersaglio inviando un segmento TCP con SYN attivo.
Se la porta è aperta il servizio ricevera il frammento SYN con ACK attivo altrimenti rispondera con un frammento con RST attivo.

def main():
#Indirizzo Ip bersaglio
global ipAddress
#host name
global hostName
#lista di porte da controllare
global ports
#Variabili globali
#Execute telnet scan
isConnect = False

La main non fa altro che verificare gli argomenti passati a linea di comando.
Se sono corretti la getopt() restituirà due valori; una mappa chiave-valore con le opzioni inserite come parametri e i valori passati in ingresso ai rispettivi parametri

#Se non sono stati inseriti argomenti nella linea di comando
if not len(sys.argv[1:]):
#Se il numero di argomenti a linea di comando è zero
use();
#Altrimenti leggi le opzioni da linea di comando
try:
#Leggo le opzioni inserite a linea di comando
opts, args = getopt.getopt(sys.argv[1:],OPTIONLIST,LONGOPTION)
except getopt.GetoptError as optError:
#In caso di errore
print(str(optError))
use();

Se vengono passati all’applicazione campi non ammessi abbiamo un errore e allora invochiamo la funzione use() che vedremo dopo ma che anticipo mostrerà l’uso corretto del nostro portscan.

Se il parametri sono giusti invece settiamo le variabili necessarie con i valori passati in input

#Controlliamo ogni opzione e salviamo i giusti dati.
for key,value in opts:
if key in ("-i", "--ip"):
ipAddress = value
elif key in ("-h", "--host"):
hostName = value
ipAddress = gethostbyname(hostName)
elif key in ("-t","--tcp"):
isConnect = True
elif key in ("-s","--syn"):
isSyn = True
elif key in ("-p", "--port"):
ports = value.split(',')

scan(ipAddress,ports,isConnect,isSyn);

La funzione scan che vedremo tra poco eseguirà la funzione corretta in base ai flag attivi.

#Funzione che gestisce lo scan e mostra i risultati
def scan(ipDst, ports,isConnect,isSyn):
#Data di oggi (senza fuso orario)
date = datetime.today()
#porta castata a integer
global intPort
global starTime
global endTime
print("scanning in data ")
print(date)

if isConnect == True:
tcpConnectScan(ipDst, ports)

Vediamo la funzione che esegue la scansione vera e propria

def tcoConnectScan(ipDst, ports):
print("Start tcp scan: \n")
starTime = datetime.now()
for port in ports:
intPort = int(port)

s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((ipDst,intPort))

if(result == 0):
print('Port %d: Open' %(intPort))
else:
print('Port %d: not Open' %(intPort))
s.close
endTime = datetime.now()
print("scan time are %f" %(endTime-starTime))

Come si vede, dopo avere settato lo startTime utile a calcolare successivamente il tempo impiegato per effettuare la scansione vediamo che per ogni porta passata in input quello che viene fatto dalla funzione è semplicemente eseguire una connessione verso quell’IP alla pora indicata e se il risultato è 0 allora la connessione è andata a buon fine quindi la porta è sicuramente aperta.

Per completezza inserisco anche la funzione use() che spiega il funzionamento del programma e che viene eseguita se viene passato in input.

#Metodo spiega il funzionamento del software
def use():
print ("Port scan 1.0")
print ()
print ("Using: portScan -i [target_ip] -p [list_of_ports]")
print ("-i --ip [target_ip]            target ip address")
print ("-h --host   [target_host_name]     target host name")
print ("-p --port [list_of_ports]          port or list of ports to test")
print ("-t --tcp                 performe a tcp scan to tcp port")
print ("-s --syn                  performe a syn scan to tcp port")
print ()
print ("example")
print ("portScan -t 192.168.0.1 -p 5564")
sys.exit(0)

Come si vede, la scansione viene eseguita effettuando una vera e propria connessione al sistema attaccato. Questo tipo di scansione è infatti rumoroso e facilmente rilevabile per cui un sistema IDS ben impostato è in grado di memorizzare l’indirizzo ip dell’attaccante e di segnalare i tentativi di connessione come un possibile attacco.

Simone Sante Ruffo
Diplomato al liceo scientifico, si è laureato in ingegneria informatica e delle telecomunicazioni e sta proseguendo ora gli studi in Ingegneria Elettronica per prendersi la laurea magistrale. Appassionato di informatica, telecomunicazioni ed elettronica gli piace studiare, conoscere, progettare e risolvere problemi
http://simonesanteruffo.it

Lascia una recensione

Please Login to comment

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

  Subscribe  
Notificami
Top