vendredi 25 janvier 2008

Sniffer TCP with Raw Sockets

Plop all :)
aujourd'hui je me penche un peu sur les raw sockets et je vous propose ce petit code qui permet de sniffer les trames TCP entrentent. Bon ici je montre que les bases mais le code ne demande qu'à être renchérit.

Le principe est simple, on créé un socket qui va écouter et intercepter toutes les données qui passent notre réseau. La création du socket se fait presque normalement, si ce n'est qu'il ne faut pas oublier d'activer le mode promiscuous de la carte réseau, à savoir grace à la fonction WSAIoctl().

Référence de la fonction : http://msdn2.microsoft.com/en-us/library/ms741621(VS.85).aspx

Prototype de la fonction WASIoctl() :

int WSAIoctl(
__in SOCKET s,
__in DWORD dwIoControlCode,
__in LPVOID lpvInBuffer,
__in DWORD cbInBuffer,
__out LPVOID lpvOutBuffer,
__in DWORD cbOutBuffer,
__out LPDWORD lpcbBytesReturned,
__in LPWSAOVERLAPPED lpOverlapped,
__in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine


Ensuite on fait un simple recv() et le tour est joué, on peux récupérer la trame TCP.
Viens ensuite le traitement, il faut récupérer les données dont nous avons besoin.
Voyons ces deux schémas issuent de www.frameip.com


Entête IP:





Entête TCP:





De là on peut en déduire deux structures, une qui contiendra l'entete IP et l'autre l'entete TCP. Toutefois ceci reste minimaliste.
typedef struct iphdr //Entete IP
{
unsigned char IHL:4;
unsigned char Version :4;
unsigned char TypeOfService;
unsigned short TotalLength;
unsigned short ID;
unsigned char FlagOffset :5;
unsigned char MoreFragment :1;
unsigned char DontFragment :1;
unsigned char ReservedZero :1;
unsigned char FragOffset;
unsigned char Ttl;
unsigned char Protocol;
unsigned short Checksum;
unsigned int Source;
unsigned int Destination;
}IP_HDR;

typedef struct tcphdr // Entente TCP
{
unsigned short PortSource;
unsigned short PortDest;
unsigned int seqnum;
unsigned int acknum;
unsigned char unused:4, tcp_hl:4;
unsigned char flags;
unsigned short window;
unsigned short checksum;
unsigned short urgPointer;
} TCP_HDR;

Et voilà il ne nous reste plus qu'à remplir les structures et le tour est joué!

De la doc sur : http://www.frameip.com/
http://msdn2.microsoft.com/en-us/library/ms741394%28VS.85%29.aspx

Le code : main.cpp

Le projet + binaire : SnifferTCP.zip

Have Fun ;)
lilxam.

1 commentaire:

Anonyme a dit…

Est-ce que vous-savez pour le Linux les commands pour ouvrir le socket et écouter le traffic?
Se parreil pour les socket en C++ ??

Sérgio - seni0re@hotmail.com