IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

sniffer raw socket


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    411
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 411
    Par défaut sniffer raw socket
    Bonjour,

    j'ai repris le code d'un sniffer utilisant les raw socket. Il fonctionne bien à part qu'on ne peut pas indiquer qu'on souhaite écouter sur toutes les interfaces. En principe, je sais qu'on doit ajouter la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        sin.sin_addr.s_addr = htonl(INADDR_ANY);
    mais ça ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
     
    #include <cstdlib>
    #include <iostream>
    #include <winsock2.h>
    #include <windows.h>
    #pragma comment(lib,"ws2_32.lib")
     
    #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
    #define RCVALL_ON 1 
    #define RCVALL_OFF 0
     
    using namespace std;
     
    /*
    Sniffer TCP with Raw Sockets by lilxam
    */
     
    typedef struct iphdr
    {
      unsigned char  IHL:4;  // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
      unsigned char  Version   :4;  // 4-bit IPv4 version
      unsigned char  TypeOfService;           // IP type of service
      unsigned short TotalLength;  // Total length
      unsigned short ID;            // Unique identifier  
      unsigned char  FlagOffset   :5;        // Fragment offset field
      unsigned char  MoreFragment :1;
      unsigned char  DontFragment :1;
      unsigned char  ReservedZero :1;
      unsigned char  FragOffset;    //fragment offset
      unsigned char  Ttl;           // Time to live
      unsigned char  Protocol;      // Protocol(TCP,UDP etc)
      unsigned short Checksum;      // IP checksum
      unsigned int   Source;       // Source address
      unsigned int   Destination;      // Source address
    }IP_HDR;   
     
    typedef struct tcphdr // ici la 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;
     
    int main(int argc, char *argv[])
    {
        char ip[100];
        unsigned short portS, portD;
        char trame[4096];
        char *donnees = NULL;
        unsigned int option;
     
        /* Accés au réseau */ 
        WSAData wsa;
        if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
        {
            printf("\n[!]Impossible d'acceder au reseau.\n--- Erreur avec WSAStartup() : %d\n\n", WSAGetLastError());
            system("pause");
            return 0;
        }
     
        /* Creation d'un socket 
        
        Référence : http://msdn2.microsoft.com/en-us/library/ms740506(VS.85).aspx
            
        Prototype de la fontionc socket() :
            SOCKET WSAAPI socket(
              __in  int af,
              __in  int type,
              __in  int protocol
            );
        */
     
        SOCKET sock;
        if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET)
        {
            printf("\n[!]Impossible de creer le socket.\n--- Erreur avec socket() : %d\n\n", WSAGetLastError());
            system("pause");
            return 0;
        }
     
        /* Initialisation des parametres d'écoute */
        SOCKADDR_IN sin;
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = inet_addr("192.168.100.10"); //Votre ip locale
    /*    sin.sin_addr.s_addr = htonl(INADDR_ANY); ne fonctionne pas !!! */
     
        /* Ecoute du réseau 
        
        Prototype de la fonction bind() :
            int bind(
              __in  SOCKET s,
              __in  const struct sockaddr* name,
              __in  int namelen
            );
        */
     
        if(bind(sock, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR)
        {
            printf("\n[!]Ecoute impossible.\n--- Erreur avec bind() : %d\n\n", WSAGetLastError());
            closesocket(sock);
            system("pause");
            return 0;
        }
     
     
        /* Activation du mode promiscuous 
        Référence : 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
            );
        */
     
        DWORD dwBytesRet;
        WSAIoctl(sock,SIO_RCVALL,&option,sizeof(option),NULL,0,&dwBytesRet,NULL,NULL);
     
     
        /* Gestion des données récupérées sur la trame */
        iphdr *HeaderIP=(iphdr*)trame; // voila
        tcphdr *HeaderTCP=(tcphdr*)(sizeof(iphdr)+trame);
        donnees = (char *)(sizeof(tcphdr)+sizeof(iphdr)+trame);
        char tmp[2048];
     
        for(;;)
        {
            /* En attente de packet */
            recv(sock, trame, sizeof(trame), 0);
     
            /* Traitement des données */
            printf("\n\n    --------| Nouveau Packet |--------");
            portS = ntohs(HeaderTCP->PortSource);
            portD = ntohs(HeaderTCP->PortDest);
            sprintf(ip,"%s:%d",inet_ntoa(*(struct in_addr *)&HeaderIP->Source), portS);
            printf("\n      [+]IP Source : %s",ip);
            sprintf(ip,"%s:%d",inet_ntoa(*(struct in_addr *)&HeaderIP->Destination), portD);
            printf("\n      [+]IP Destination : %s",ip);
            printf("\n      [+]IP Version : %d -> 0x%x", HeaderIP->Version, HeaderIP->Version);
            printf("\n      [+]IP Checksum : %d -> 0x%x", HeaderIP->Checksum, HeaderIP->Checksum);
            printf("\n      [+]Protocol : %d -> 0x%x", HeaderIP->Protocol, HeaderIP->Protocol);
     
     
            memset(tmp, 0, sizeof(tmp));
            for(int i = 0; i <= 2048; i++)
            {
                tmp[i] = donnees[i];
            }
            printf("\n\n    -----* Donnees *----- \n\n%s\n               [...]\n    ------------------------------\n", tmp);
     
        }
     
        closesocket(sock);
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Si je me souviens bien... le bind avec un raw socket DOIT être une addresse locale.

    De plus, j'ai du mal à voir le principle de bind sur toutes les interfaces, le bind étant de niveau Transport, les interfaces de niveau Link.... y a un truc qui colle pas....

    Si tu nous disais ce que tu veux "sniffer" (je déteste ce mot d'ailleurs, ça fait penser à du hacking de bas étage ) peut-être existe t'il une autre méthode ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    411
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 411
    Par défaut
    D'accord, voyons cela différemment. Je souhaite éviter d'avoir besoin que l'utilisateur ajoute son adresse ip dans un textbox. Existe-il une solution qui permet de détecter l'ip locale de la machine exécutant le programme ? ( Ex. pour un programme serveur, il existe : sin.sin_addr.s_addr = htonl(INADDR_ANY); qui ne fonctionne pas dans le cas du sniffer )

  4. #4
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Existe-il une solution qui permet de détecter l'ip locale de la machine exécutant le programme ?
    Oui : [FAQ] Comment obtenir l'adresse IP d'une machine dont je connais le nom ?

    Citation Envoyé par nicroman
    De plus, j'ai du mal à voir le principle de bind sur toutes les interfaces, le bind étant de niveau Transport, les interfaces de niveau Link.... y a un truc qui colle pas....
    Je ne comprends pas bien ce que tu veux dire. INADDR_ANY vaut 0, ou 0.0.0.0 en IPv4 si tu veux, qui est une adresse permettant de désigner n'importe quelle interface de la machine. Donc je ne vois pas où est le problème.

  5. #5
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    En fait il connaitre l'addresse IP locale n'est souvent pas utile... D'autant qu'elle peut très bien ne pas être représentative (lien simulé, VPN, ...). Et surtout être différente en fonction du remote host...

    L'écoute sur INADDR_ANY en IP oui... (mais on est déjà au niveau Réseau), INADDR_ANY en RAW... je suis pas sur que ce soit autorisé (niveau Lien).

  6. #6
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par nicroman
    En fait il connaitre l'adresse IP locale n'est souvent pas utile ...
    Si si, puisqu'il faut attacher le raw socket à une interface locale explicite (pas de INADDR_ANY ou de 127.0.0.1, etc.), comme tu l'as dit toi-même.
    D'autant qu'elle peut très bien ne pas être représentative (lien simulé, VPN, ...). Et surtout être différente en fonction du remote host ...
    Ca, c'est un problème que doit résoudre le programme. Avec les fonctions du IP Helper (GetAdaptersInfo, etc.), on peut connaître la configuration réseau de la machine (comme avec IPCONFIG) ce qui permet de connaître l'adresse sur le réseau local.
    L'écoute sur INADDR_ANY en IP oui... (mais on est déjà au niveau Réseau), INADDR_ANY en RAW... je suis pas sur que ce soit autorisé (niveau Lien).
    Un raw socket n'opère pas forcément au niveau liasion de données. Quand un socket appartient à la famille PF_INET, il opère à un niveau supérieur ou égal à celui ou se trouve IP, c'est-à-dire la couche réseau (qui est la couche logique la plus basse dans l'architecture TCP/IP). Sous Windows, on ne peut pas aller plus bas avec les raw sockets (pas de PF_PACKET comme sous Linux). Il n'est donc pas techniquement impossible d'attacher un raw socket à INADRR_ANY, c'est juste qu'ils ont été créés ainsi.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 15
    Dernier message: 04/01/2007, 11h15
  2. raw sockets et sniffer
    Par ThibG dans le forum C++
    Réponses: 10
    Dernier message: 21/02/2005, 13h58
  3. [C#] raw socket?
    Par Blo0d4x3 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 29/12/2004, 12h20
  4. Raw socket
    Par trax44 dans le forum Assembleur
    Réponses: 2
    Dernier message: 24/11/2004, 18h26
  5. raw socket et langage c
    Par SlayDave dans le forum Développement
    Réponses: 2
    Dernier message: 29/08/2002, 19h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo