Home -
Security -
Utility -
Notepad -
Contact us
INDICE:PrerequisitiIntroduzione I Socket Il Winsock Conclusioni Piccolo manuale riferimento Winsock |
PROGRAMMI:Client.cServer.c Portscanner.c Fakemail.c Bannerscan.c |
1 Conoscenza di base del linguaggio C.
La programmazione di rete è ciò che permette a due o più computer collegati da una rete fisica
di comunicare tra loro. Per poter comunicare con un computer ho bisogno di:
1. un indirizzo a cui connettermi: infatti ogni computer connesso in una rete dispone di un
indirizzo, che consente di localizzarlo
2. una porta aperta: per connettersi ad un computer
c'è bisogno di conoscere anche questo elemento, il concetto di porta venne inventato per permettere ad un
computer (che ha a disposizione un solo indirizzo) di ricevere diverse
connessioni, infatti tramite diverse porte è possibile dallo stesso computer
fornire diversi servizi (posta, web, telnet, ecc.)
Ecco una lista delle principali porte di comunicazione:
| echo | 7/tcp | |
| echo | 7/udp | |
| ftp-data | 20/tcp | |
| ftp | 21/tcp | server ftp (trasferimento file) |
| telnet | 13/tcp | server telnet |
| smtp | 25/tcp | server posta in uscita |
| http | 80/tcp | server web |
| pop | 110/tcp | server posta in ingresso |
3. un protocollo: che permetta di far capire al programma in ascolto le mie richieste.
Generalmente la comunicazione tra due pc si basa in questo modo:
un computer CLIENT
si collega ad un SERVER chiedendo un particolare servizio, il SERVER se ha a
disposizione questo servizio assolverà la richiesta del CLIENT, inviandogli le
risposte.
Questa comunicazione avviene tramite un protocollo di comunicazione (ossia un insieme
di regole da rispettare), che permette a tutti i computer di qualsiasi tipo di
comunicare tra loro.
Al di sopra di questi protocolli esiste un oggetto, che si
basa su di essi, chiamato socket che permette di trasmettere e ricevere informazioni
senza doversi preoccupare della correttezza delle regole definite dal protocollo utilizzato.
Le socket sono nate dal sistema operativo UNIX, che implementa la loro struttura similmente a
quella di un file, riuscendo così a rendere semplice la comunicazione tra due
computer come la gestione di semplici file. In Windows
inizialmente questa struttura non era prevista e quindi si dovette creare un
insieme di funzione API che permisero la comunicazione tra computer. Venne quindi inventato il Winsock, ossia la
socket per windows, che funziona esattamente come la socket per UNIX, soltanto
con una maggiore difficoltà di programmazione e qualche limite in più. Le socket sono
quindi gli oggetti che vengono implementati per comunicare, ogni socket ha delle
specifiche caratteristiche, riguardanti l'indirizzo e il protocollo da
utilizzare. Inoltre queste socket permettono di effettuare delle operazioni (funzioni), come quella di
connettersi ad un computer, attendere la connessione di qualcuno, inviare e ricevere informazioni.
Come ho spiegato prima nell'introduzione, generalmente la comunicazione si basa su un client che
effettua delle richieste e su un server che attende le richieste,
e quindi le funzioni principali di queste socket sono:
1. Connect(), utilizzata per connettersi ad un server.
2. Accept(), utilizzata per "rimanere in ascolto", ossia attendere le
richieste di qualche client.
(Ho tralasciato i
parametri di ingresso e di ritorno della funzione che troverete in dettaglio alla
fine della spiegazione)
Queste due funzioni sono basilari e hanno lo stesso nome e la stessa forma sia in Unix che
in Windows, mentre per altre funzioni non è così.
Passiamo quindi allo studio del Winsock.
Il winsock si basa su queste principali sette funzioni:
1. Socket(): crea una socket che verrà utilizzata per la comunicazione
2. Connect(): collega la socket ad un indirizzo remoto
3. Read(), Write(); Send(), Sendto(), Recv(), Recvfrom():
funzioni di invio e ricezione dati
4. Listen(): specifica le code di socket client
5. Accept(): attende delle connessioni in una specifica porta
6. Bind(): collega la socket ad una porta specifica
7. Close(): chiude la socket
mentre otto sono i passi fondamentali per programmare le socket in windows:
1. Definizione delle librerie da utilizzare (Winsock.h)
2. Inizializzazione della libreria socket (WSAStartup())
3. Creazione della socket
4. Descrizione delle caratteristiche della socket
5. Connessione al sistema remoto
6. Operazioni sulla socket
7. Chiusura della socket
8. Rilascio delle risorse della libreria (WSACleanup() )
Implementando gli otto passi qui sopra descritti e utilizzando le sette funzioni che
prima abbiamo visto, riusciamo a creare i nostri programmi di comunicazione di rete.
Vediamo ora in
dettaglio gli otto passi, creando un programma che si collega ad un computer
remoto:
1. Definizione delle librerie da utilizzare (Winsock.h)
#include <winsock.h>
Questa istruzione include la libreria di sistema "winsock.h" permettendo così a noi di utilizzare le variabili e le funzioni di questa libreria.
2. Inizializzazione della libreria socket (WSAStartup())
WSADATA data; // inizializzo la variabile che contiene le primitive di Winsock
WORD p;
int err=0; // inizializzo una variabile per gestire gli errori
p=MAKEWORD(2,0); // creo la variabile p che contiene la versione della wsock32.dll
err=WSAStartup(p,&data); // inizializzo la wsock32.dll verificandone la mancanza di errori
queste istruzioni, che non esistono nella gestione delle socket di Unix, sono utilizzate per
inizializzare l'oggetto socket, senza di queste non si possono utilizzare le
socket in Windows.
La funzione WSAStartp() è la funzione che inizializza le socket.
3. Creazione del socket
sock=socket(PF_INET,SOCK_STREAM,0);
ho creato la socket utilizzando la funzione socket(), inserendo come parametri:
PF_INET
indica che utilizzeremo il formato di indirizzo specifico di Internet (per esempio: 123.46.78.231)
SOCK_STREAM indica il tipo di socket da utilizzare, ne esistono tre: SOCK_STREAM che
utilizza il protocollo di comunicazione TCP/IP; SOCK_DGRAM che utilizza il
protocollo di comunicazione UDP/IP e SOCK_RAW che permette di crearsi un
protocollo personale, ma in Windows questo tipo non è implementato.
4. Descrizione delle caratteristiche del socket
sock_addr.sin_family=PF_INET; // indico il protocollo utilizzato (TCP/IP)
sock_addr.sin_port=htons(21); //indico la porta a cui connettere il socket
sock_addr.sin_addr.S_un.S_un_b.s_b1=127; // indico l'indirizzo IP
sock_addr.sin_addr.S_un.S_un_b.s_b2=0;
sock_addr.sin_addr.S_un.S_un_b.s_b3=0;
sock_addr.sin_addr.S_un.S_un_b.s_b4=1;
Con la prima istruzione indico il protocollo che utilizzerà la socket: TCP/IP
Con la seconda istruzione indico la porta a cui mi connetterò: porta 21 (ftp) (htons() serve
per trasformare un numero unsigned short in un numero in network byte order,
ossia un numero adatto all' utilizzo con le socket, che verrà inviato insieme a
tutte le altre informazioni nella rete. Esistono molte altre funzioni di
conversione da numeri semplici a "numeri di rete", se volete
conoscerli alla fine vi elencherò tutte le funzioni principali).
Le ultime quattro
istruzioni hanno tutte la stessa funzione, quella di inserire l'indirizzo a cui la
socket si connetterà, che nel nostro caso è 127.0.0.1, ossia il nostro
computer (per chi non lo sapesse questo indirizzo è sempre l'indirizzo locale
del nostro pc).
5. Connessione al sistema remoto
err=connect(sock,(struct sockaddr*)&sock_addr,sizeof(struct sockaddr)); // mi connetto all' indirizzo scelto
Questa istruzione è quella che permette di connetterci fisicamente ad un altro pc, come
parametri di ingresso ha la socket che noi abbiamo creato al punto 3, la
struttura sockaddr che abbiamo implementato al punto 4 (dove abbiamo inserito le
caratteristiche della nostro socket), e la dimensione di questa struttura.
La struttura sockaddr è una struttura che è già definita nel file winsock.h, noi dobbiamo
solo riempirla con le caratteristiche della nostro socket.
6. Operazioni sulla socket
send(client,mex,22,0);
Questa è l'esempio di una tra le più comuni operazioni sulle socket, ossia (in questo caso) quella di inviare un messaggio (mex) di 22 caratteri al computer a cui siamo connessi.
7. Chiusura della socket
closesocket(sock);
Come penso abbiate già capito questa istruzione chiude la socket, chiudendo la connessione con il computer remoto
8. Rilascio delle risorse della libreria (WSACleanup() )
WSACleanup();
Questa deve essere sempre l'ultima operazione e deve sempre essere eseguita per liberare le risorse della libreria Winsock.
Abbiamo ora ultimato i passi e quindi il nostro programma è a posto e eseguendolo si
connetterà alla porta 21 del nostro pc, solo che la porta 21 del nostro
computer è chiusa!!!
Non ci resta
quindi che creare il server per aprire questa porta. Creare il server
non è tanto diverso, ad eccezione di tre istruzioni:
err=bind(miosock,(struct
sockaddr*)&miosock_addr,sizeof(struct sockaddr_in));
err=listen(miosock,1);
client=accept(miosock,(struct sockaddr*)&client_addr,&lun);
La prima associa un indirizzo al server, la seconda crea una coda di "potenziali client" del nostro server e la terza apre la porta aspettando la connessione da una socket.
Non perdo tempo a spiegarvele perché credo che le abbiate già capite, e comunque potete controllare il loro funzionamento all'interno dei programmi che ho linkato all'inizio. (se per caso non vi sentite ancora sicuri potete sempre guardare nel manuale che ho linkato all'interno dell' indice, in cui descrivo tutte le funzioni principali del Winsock).
E per finire in bellezza vi descrivo l'ultimo programma che ho inserito: bannerscan.c
Questo programma serve a controllare in un range di ip scelto, i banner di tutti i servizi in
ascolto in una determinata porta. Ho inserito anche questo programma in quanto
esso utilizza una funzione del Winsock molto interessante:
ioctlsocket (s, FIONBIO,&arg);
Questa funzione serve per dare delle caratteristiche specifiche ad una socket, vediamo i suoi parametri:
int PASCAL FAR ioctlsocket ( SOCKET s, long cmd, u_long FAR * argp );
s Un descrittore
che identifica una socket
cmd I comandi da dare alla socket.(FIONBIO,FIONREAD,SIOCATMARK)
argp Puntatore per i parametri di cmd
Possiamo dare alla socket tre diversi tipi di comandi (i comandi del parametro cmd),
a noi interessa soprattutto il primo dei tre: FIONBIO. Questo parametro ci permette di creare una socket
di tipo non-bloccante, ossia una socket che non attende che la connessione sia instaurata per poter continuare con il
programma. Questa cosa è davvero utile in programmi "scanner", che
dovendo creare tante connessioni, non possono permettersi di perdere del tempo,
in quanto la capacità di effettuare velocemente le operazioni è fondamentale.
Questo nuovo tipo di socket però crea anche un problema,infatti considerato che
questa socketa non attende le connessioni dovremo essere noi a dare il
tempo ai server di rispondere alle nostre richieste. (per esempio nel programma
è possibile impostare una variabile DELAY che indica il tempo di attesa di una
risposta dal server).
Ora che conoscete questa funzione potete per esempio migliorare il file
portscanner.c, infatti quello che abbiamo creato in precedenza utilizzava socket
di tipo bloccante e, provandolo, noterete subito la lentezza di funzionamento.
Se invece lo migliorerete con la funzione appena imparata potrete renderlo molto
più efficiente.
Ora che sappiamo programmare in rete, possiamo creare svariati programmi: da PortScanner a
programmi generatori di e-mail false, da browser personalizzati a trojan, mi
raccomando però di non creare questi programmi per fare danni.
Concludo dicendo
che comunque oggi esiste un altra versione più recente del Winsock (la 2.0, noi
abbiamo utilizzato la 1.1), comunque ciò che noi abbiamo imparato è
assolutamente funzionante ed è fondamentale per capire i concetti della nuova
versione.
written by Komrade
http://unsecure.altervista.org