Portscan

 

 

1 - Introduzione

 

Portscan permette il controllo delle porte aperte all’interno di una rete di macchine comunicanti in TCP/IP.

 

Figura 9

 

 

Come tutti i programmi, anche portscan si è evoluto col passare del tempo. Per valutare però quanto è efficace un programma del genere è importante tenere conto di alcuni particolari.

Prima di tutto deve permettere l’inserimento arbitrario dell’indirizzo di inizio e fine scansione, controllare un gruppo di porte o semplicemente una porta in particolare, e permettere il salvataggio del risultato della scansione.

La caratteristica però più importante di portscan è quella di poter attivare, in parallelo, più scansioni. La parallelizzazione del lavoro è infatti importate, in quanto permette di diminuire di molto i tempi di ricerca. Per avere la certezza che una determinata porta sia aperta o meno, occorrono almeno 3 secondi. In questo modo, una scansione normale non multithread, occupa circa 3 o 4 minuti per controllare solamente 256 porte. Invece in un regime di multithread di controllo, possiamo abbassare questo tempo anche sotto i 10 secondi.

 

 

2 - Tipi di portscan

 

Di portscan ne esistono diversi in base al sistema operativo, software house che lo ha realizzato e alle funzionalità presenti.

Tra i tanti citiamo i seguenti:

 

2.1 - TCP PortScan fro Java 1.0

sistema operativo: Win95, Win98, WinNT
data di creazione : 27/05/99 bytes: 30.661
Freeware

Scanner di porte scritto completamente in Java. È necessario avere un Java JDK o JRE.

 

2.2 -  Hoppa PortScanner 2.0

sistema operativo: WinNT
data di creazione : 11/09/98 bytes: 633.549
Freeware

Software per la scansione dei numeri IP e delle porte di una rete TCP. È possibile definire il numero di thread attivi e l'intervallo di scansione.

 

2.3 -  Ostrosoft Portscan 2.0

sistema operativo: Win95
data di creazione : 15/05/98 bytes: 1.897.825
Freeware

Portscan 2.0 effettua lo scanning di tutte le porte TCP/IP specificate in un determinato range. Tra le funzioni ricordiamo lo scan veloce, la possibilità di salvare l'output in un file, facilità di installazione/rimozione.

 

2.4 -  TCP/IP PortScanner 1.7

sistema operativo: OS/2
data di creazione: 26/03/98 bytes: 165.064
Freeware

Software per OS/2 che visualizza graficamente i servizi collegati alle varie porte di un indirizzo IP specificato. Ideale per vedere se un certo sito dispone anche dei servizi di posta elettronica, chat, FTP, telnet, etc.

 

 

3 - Come scrivere un portscan in c

 

Un portscanner, è uno strumento che essenzialmente serve per sapere quali servizi offre un determinato server. Quest'informazione noi potremmo acquisirla non mandando una email

all'amministratore, ma facendo dei tentativi, ovvero provando a connetterci ad ogni servizio e verificandone la sua presenza.

Tutto ciò può essere automatizzato, ed è questo il compito di un portscanner.

Di portscanner ne esistono diversi tipi, dai più semplici che provano la semplice connessione ai più elaborati che cercano di farlo in tutta trasparenza, ovvero senza che il sysadmin lo venga a sapere, e usando le tecniche più raffinate che presupppongono una buona conoscenza dei protocolli di comunicazione.

Quello che si illustra è del più semplice e meno trasparente ma è molto utile a scopo didattico.

Il presente ha come riferimento il C/ANSI e le librerie UNIX.

In UNIX, come dice l'ottima guida "Beej's Guide to Network Programming" "tutto è un file", e quindi viene trattato come se si stesse parlando di file , e quindi anche le connessioni vengono

trattate quasi nella stessa maniera.

Si può cominciare a dire che un port-scanning è in C come il cercare di aprire un pò di files, ciascuno con un nome formato da un numero incrementale, e riportare alla fine quanti se ne è riusciti ad aprire.

 

Una programma del genere in C si scrive al volo:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Una volta compilato ed eseguito, si mette a cercare nella directory corrente se ci sono i file che cerca (dal nome "file_NUMERO", in cui numero è variabile da 1 a 1024) e se ne trova uno, ci avvisa.

Lo stesso si fa con i port-scanner, solo che al posto di "fopen()" si usa "connect()", ed esiste una funzione in più per creare il descrittore di file: la funzione "socket()". Per il resto è tutto simile.

I tipi di dati che vengono utilizzati sono

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Questa struttura verrà passata alla funzione "connect()" come si passa per lo stesso motivo il nome del file alla funzione "fopen()".

La novità, come già accennato, è che qui non basta definire un descrittore tramite una dichiarazione di variabile (quello che per il caso di prima era semplicemente "FILE *fp;"), ma c'è una funziona apposita che li crea, la funzione socket():

 

  #include <sys/types.h>

  #include <sys/socket.h>

  int socket(int domain, int type, int protocol);

 

in cui i parametri da passare sono:

 

int domain   --> la famiglia di protocolli da utilizzare, ovvero IP piuttosto che IPX o appletalk o

                         altri

int type        --> la "semantica" per costruire pacchetti

int protocol  --> altre eventuali specificazioni

 

Il valore restituito è il descrittore o -1 nel caso di errore.

Nel nostro caso, che rappresenta il più comune, si vuole creare un socket per comunicare su internet con protocollo IP tramite TCP e il socket giusto (il descrittore di file che verrà usato) sara creato con:

 

int sock;

sock=socket(AF_INET, SOCK_STREAM, 0);

 

Il valore restituito come già detto è il descrittore che stavamo cercando, e tutte le operazioni di connessione, lettura e invio dati faranno riferimento a questo numero.

Il passo successivo è quello di tentare di instaurare la connessione, e poi verificare quale esito ha avuto, e lo si fa tramite connect():

 

#include <sys/types.h>

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

 

Qui i parametri passati sono:

 

int sockfd                                      --> il socket precedentemente creato

const struct sockaddr *serv_addr --> la struttura contenente le informazioni necessarie alla 

                                                           connessione (ip, porta, protocollo)

socklen_t addrel                           --> la lunghezza della struttura passata, si calcola tranquillamente

                                                           con sizeof()

 

E viene restituito un valore come risultato della connect():

- se tutto è andato come previsto, ritorna 0

- se c'è stato qualche errore e la connessione non s'è potuta instaurare, ritorna -1

 

 

Byte Order

 

Gli indirizzi ip vengono memorizzati sotto forma di unsigned long int quindi saremmo portati a credere che, per esempio,

127.0.0.1

venga  memorizzato come (conversione 4 numeri a base 256 in un numero a base 10):

127.0.0.1 = 127*256^3 + 0*256^2 + 0*256 + 1 = 2130706433

oppure 212.216.10.20:

            212.216.10.20 = 212*256^3 + 216*256^2 + 10*256 + 20 = 3570928148

fino a   255.255.255.255:

            255.255.255.255 = 255*256^3 + 255*256^2 + 255*256 + 255 = 4294967295

 

Oss: Quest'ultimo valore è uguale a (2^32)-1, quindi un unsigned long int è pienamente utilizzato per memorizzare un indirizzo ip).

Quest’ultima è una osservazione errata poiché il byte order è semplicemente l'ordine con cui i sistemi considerano i byte più significativi, ovvero se da sinistra o se da destra.

Il Network Byte Order, ovvero la regola usata per comunicare, considera l'ultimo byte quello più significativo mentre l'Host Byte Order, quello  usato dalla maggiornaza dei sistemi operativi, considera come più significativo il primo. quindi quello che per noi è 127.0.0.1, quando scriviamo applicazioni in C (e penso anche per altri linguaggi) va trasformato in 1.0.0.127, e 212.216.10.20 diventa 20.10.216.212.

Quindi avremo:

 

127.0.0.1           --> 1.0.0.127 = 256^3*1 +256^2*0 + 256*0 + 127 = 16777343

212.216.10.20   --> 20.10.216.212=20*256^3+10*256^2+216*256+212=336255188

255.255.255.255  

 

resta invariato, anche al contrario è sempre uguale.

E non è necessario ogni volta mettersi a fare questi calcoli poichè esistono funzioni apposite, per esempio:

 

    unsigned long int inet_addr(const char *cp);

 

che da un ip scritto nella notazione standard visto come stringa di caratteri (ad esempio "127.0.0.1") calcola il corrispondente unsigned long già nel Network Byte Order  mentre

 

    char *inet_ntoa(struct in_addr in);

 

Dalla struttura sockaddr_in.in_addr (quella che contiene solo l'unsigned long int dell'ip, per intenderci) ci restituisce un puntatore ad una stringa di caratteri della notazione standard.

Lo stesso discorso si applica non solo per gli indirizzi ip, ma anche, per esempio, per in numero che identifica la porta alla quale ci si vuole collegare, che va scritta nel Network Byte Order. Per non costringerci ad inutili calcoli su come traformare un unsigned short int  esistono anche qui funzioni apposite, ad esempio:

 

   unsigned short int htons(unsigned short int hostshort);

 

il cui nome, htons, significa Host_TO_Network_Short, che useremo per convertire il numero della porta dall'Host Byte Order (23, 80, 31337) al Network Byte Order (5888, 20480, 27002)

 

Implementazione

Possiamo adesso cimentarci a scrivere un semplice port-scanner.

 

// questi sono gli include standard che servono a questo programma

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

 

main(int argn, char **argv)

{

// cominciamo a dichiarare le variabili prima descritte

 struct sockaddr_in indirizzo;

 int porta, sock, z;

 

// ora inizia subito il ciclo che farà scannare tutte le porte comprese

// tra le due specificate nella command line

 for (porta=atoi(argv[2]); porta<=atoi(argv[3]); porta++)

      {

 

// creo il socket con una verifica di eventuali errori, e se ritorna un

// valore uguale a "-1" si è verificato un errore, altrimenti...

      if ((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) perror("Socket:");

      else {

 

//... comincio a riempire i campi della struttura sockaddr_in

// nota che uso inet_ntoa() con l'ip scritto nella riga di comando

// e htons(porta) per la questione del byte order prima descritta

          indirizzo.sin_family=AF_INET;

          indirizzo.sin_addr.s_addr=inet_addr(argv[1]);

          indirizzo.sin_port=htons(porta);

 

// cerco di instaurare la connessione (analoga a fopen() ),

// e se questa avviene...

          if (z=connect(sock,(struct sockaddr*) &indirizzo,

                                             sizeof(indirizzo))==0)

 

// ... avviso l'utente con un printf()

             printf ("\nfound port %d open!", porta);

 

// infine, finito il singolo ciclo, chiudo il socket che ormai non serve

// più, esattemante come quando chiudo un file che ho appena letto

           }

     close (sock);

     }

}

 

 

 

4 – Portscan Ostrosoft Internet Tool

 

4.1 - OstroSoft  Internet Tools

Il Portscanner visionato e analizzato è quello della Ostrosoft e si è usato il pacchetto Ostrosoft Internet Tools 5.3 [Build 0009] (http://www.ostrosoft.com/ostronet.com) che lo integra con la sua ultima release (Figura 10).

Esso è scritto in Visual Basic ed è primariamente rivolto all'analisi della sicurezza e alle implicazioni dei risultati, tramite il suo utilizzo si possono guadagnare anche tantissime generiche informazioni sulla rete.

 

 

Figura 10

 

4.2 – I servizi di OstroSoft  Internet Tools

 

Ostrosoft Internet Tools integra un insieme di utility di informazioni di rete.

Le informazioni che offre sono le seguenti:

 

4.3 - Requisiti di sistema

 

Sistema Operativo

Windows 95, Windows 98, Windows NT 4.0, Windows 2000

Processore

Pentium 133 MHz

RAM

32 MB

Hard-disk

20 MB of free space

Qualsiasi connessione di rete TCP/IP (LAN, Internet, etc.)

 

4.4 - Cosa offre di nuovo la Versione 5

4.5 - Supporto per linea di comando

OstroSoft Internet Tools (versione registrata) supporta le seguenti linee di comando:

Utility

Supported arguments

Scan Wizard

scanwiz scenario:[scenario name]

Port Scanner

portscan host:[host name or IP address] from:[port number] to:[port number]

Domain Scanner

domscan domain:[domain name] port:[port number]

Ping

Ping host:[host name or IP address]

Traceroute

tracert host:[host name or IP address]

NS Lookup

nslookup dns:[server name] type:[*/A/NS/CNAME/SOA/MX] query:[query string]

Host Resolver

resolve host:[host name] ip:[IP address]

Netstat

netstat

Network Info

netinfo host:[host name]

Local Info

localhost

Finger

finger email:[email address]

HTML Viewer

htmlview url:[url]

Ph

ph server:[server name] query:[query string]

Simple Services

sns server:[server name] service:[echo/discard/daytime/qotd/chargen]

TCP Client

tcp host:[host name or IP address] port:[port number]

WhoIs

whois server:[server name] query:[query string]

Host Watcher

Whost

Service Watcher

wservice

Mail Watcher

wmail

HTML Watcher

whtml

Service Watcher

wconn

 

La linea di comando può includere anche i seguenti switches in qualsiasi combinazione:

/r - run
/x - exit when finished
/h - hide

 

 

 

 

 


4.6 - Distribuzione

 

 

 

 

4.6 - Distribuzione

 

Nessuna componente facente parte di Ostrosoft Internet Tools può essere distribuita individualmente, disassemblata, o alterata in qualsiasi altra forma.

1.      Le copie SHAREWARE possono essere distribuite liberamente da utenti individuali per scopi dimostrativi.

2.      Le informazioni sulla registrazione sono provviste da OstroSoft, o da distributori autorizzati. Le copie registrate non possono essere ridistribuite senza qualsiasi eccezione.

4.7 - Legalità

 

La legalità di Ostrosoft Portscan è legata alla legalità degli scanner in generale e questa è soggetta a dibattiti. Alcune persone considerano questa attività illecita identificando l’attività di uno scanner simile all’intrusione in casa di qualcuno. Altri invece pensano che avendo un sito internet si è dato un permesso implicito, consentendo quindi, ad essere analizzati dagli scanner.

 


 


Per concludere fino ad oggi, nessuna legge è stata scritta all’indirizzo degli scanner.

 

 

4.8 - Simulazione di OstroSoft PortScan

 

Portscan scandisce l’host (Figura 12) oppure un indirizzo IP (Figura 11) per individuare i servizi erogati in un particolare port range.

 

Figura 11

 

 

Figura 12

 

 

Il programma prende in input:

1)      Il nome dell’host o l’indirizzo IP ad esso associato. Nel nostro esempio è 169.254.202.70.

2)      L’intervallo delle porte da controllare. Nel nostro esempio di scansione si controllano le porte da 1 a 127.

Non resta quindi che fare click sul bottone Scan per avviare la scansione.

Il Programma da in output una lista delle porte aperte, il servizio ad esse associato con relativa descrizione.

Dopo che la scansione è completata mediante un doppio click su ognuna delle porte presenti nell’elenco di output si può prender visione se  vi è associato un determinato programma (per default non vi è associato alcun programma).

 

Ciccando sul bottone  si aprirà una finestra “Port Scanner Setting” (Figura 13):

Figura 13

 

L’utente può configurare:

¬ La  velocità della scansione. Tale velocità può variare da 1 a 600 ports/min e per default è impostata a 60 ports/min.

¬ Il tempo massimo di attesa di ogni socket. Il timeout è scelto dall’utente e varia da 1 a 30000 msec. tale range consente all’applicazione di adeguarsi alla velocità della connessione. Per default il valore è 100 msec.

¬ Il numero di host da tenere nella storia (della scansione). Tale numero può variare da 0 a 255 e per default è impostato a 5.

¬ L’intervallo di porte da controllare, tale intervallo è compreso tra 1- 65536.

¬ Se scegliere di salvare l’output.

Ciccando sul bottone  “Port Properties” si aprirà una finestra dove è possibile editare informazioni circa le porte (Figura 14):

 

Figura 14

 

E per concludere cliccando sul bottone  “Port Viewers” si aprirà una finestra dove è possibile editare informazioni circa le informazioni di visualizzazione (Figura 15):

 

Figura 15

 

5 – Conclusioni e contromisure

 

Diminuite al minimo la possibilità di fare accesso alle vostre macchine da postazioni remote, al di fuori della vostra sottorete di indirizzi TCP/IP.

 

 

 

 

 

 

 

 

 

 

 


Fate attenzione quando ponete macchine sulla rete.

Ricordate che una semplice scansione delle porte aperte, tramite un portscanner, non è gran cosa; ma se questa scansione porta poi ad un successivo attacco, allora il problema potrebbe diventare più importante.

 

Gli strumenti in grado di proteggere il sistema da qualsiasi intrusione, comprese le scansioni sono i Firewall i quali hanno la facoltà di rilevare e bloccare scansioni, dove possibile.

 

 

 

 

 

 

 

 

 

 


Esempio di Firewall all’opera:

 

Abbiamo installato e ben configurato sulla macchina obiettivo il Norton Personal Firewall 2001 Trial.

Successivamente da una postazione remota abbiamo messo all’opera portscan cercando di individuare le porte aperte sulla macchina obiettivo.

Tale operazione è stata subito rilevata dal Firewall in esame:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


E dalle opzioni configurate, il Norton Personal Firewall 2001 ha bloccato la scansione per un tempo pari a 30 minuti dalla macchina che ha lanciato in esecuzione portscan.