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 :

Problème raw socket


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 10
    Points : 2
    Points
    2
    Par défaut Problème raw socket
    J'ai un problème pour forger un packet tcp avec syn comme flag pour ouvrir une connection entre les deux machine.J'ai une erreur 10004 c'est à dire Appel système interrompu,lors de mon appelle de la fonction sendto.

    voici le code :
    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
    172
    173
    174
    175
    176
     
    #include <winsock2.h> 
    #include<iostream> 
     
    using namespace std; 
     
    typedef struct iphdr {  
        unsigned char  verlen;   /* version du protocol IP + la longeur de l'en t?te */ 
        unsigned char  tos;	     /* type de service */ 
        unsigned short tot_len;  /* longueur totale du datagramme */ 
        unsigned short id;	     /* identification */ 
        unsigned short offset;   /* décalage */ 
        unsigned char  ttl;	     /* dur?e de vie du paquet */ 
        unsigned char  protocol; /* protocole */ 
        unsigned short checksum; /* somme de contr?le */ 
        unsigned int   saddr;    /* adresse IP source */  
        unsigned int   daddr;    /* adresse IP destinataire */ 
    } IP_HDR; 
     
     
    typedef struct tcphdr 
    { 
    	unsigned short sport;      /* port source */ 
    	unsigned short dport;      /* port de destination */ 
    	unsigned int   seqnum;     /* num?ro de s?quence */ 
    	unsigned int   acknum;     /* accus? de r?ception */ 
    	unsigned char  dataoffset; /* d?calage des donn?es (data offset) */  
    	unsigned char  flags;	   /* flags */ 
    	unsigned short windows;    /* fen?tre */ 
    	unsigned short checksum;   /* checksum */ 
    	unsigned short urgpointer; /* pointeur de donn?es urgentes */ 
    } TCP_HDR; 
     
    struct pseudohdr 
    { 
    	unsigned long saddr; 
    	unsigned long daddr; 
    	char useless; 
    	unsigned char protocol; 
    	unsigned short length; 
    	struct tcphdr TCP; 
    }; 
     
     
    USHORT cksum(USHORT *buffer, int size) 
    { 
    unsigned long cksum=0; 
     
    while (size > 1) 
    { 
    cksum += *buffer++; 
    size -= sizeof(USHORT); 
    } 
    if (size) 
    { 
    cksum += *(UCHAR*)buffer; 
    } 
    cksum = (cksum >> 16) + (cksum & 0xffff); 
    cksum += (cksum >>16); 
     
    return (USHORT)(~cksum); 
    } 
     
    int main() 
    { 
    system("TITLE Forgeur de packet TCP"); 
    WSADATA WSAData; 
    WSAStartup(MAKEWORD(2,0), &WSAData); 
    SOCKET socket;	 
    socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0,0); 
    if (socket == INVALID_SOCKET) 
    { 
    	fprintf(stderr, "erreur lors de la cr?ation du raw socket : %d\n", WSAGetLastError()); 
    	WSACleanup(); 
    	exit(-1); 
    } 
    int optval = 1; 
     
    if (setsockopt(socket, IPPROTO_IP, 2, (char *)&optval, sizeof(optval)) == SOCKET_ERROR) 
    { 
        fprintf(stderr, "erreur lors de l'appel ? setsockopt : %d\n", WSAGetLastError()); 
        WSACleanup(); 
        exit(-1); 
    } 
     
    //-----------------------------------remplissage en-tête de l'ip------------------------------------ 
    unsigned short packet_size, ip_version, ip_len;	/* taille de notre paquet, IP version, longueur */ 
    struct iphdr *ip; /* notre structure IP */ 
    /* taille de notre paquet */ 
    packet_size = sizeof(struct iphdr) + sizeof(struct tcphdr);  
    /* on alloue un espace m?moire pour notre structure IP */ 
    ip = (struct iphdr *)malloc(sizeof(struct iphdr)); 
    /* On l'initialise ? 0 */ 
    memset(ip, 0x0, sizeof(struct iphdr));  
     
    /* longueur de l'en t?te IP */ 
    ip_len = sizeof(struct iphdr) / sizeof(unsigned long); 
    /* IP version */ 
    ip_version = 4; 
    /* on remplie la structure IP */ 
    ip->verlen   = (ip_version << 4) | ip_len; 
    ip->tos      = 0; 
    ip->tot_len  = htons (sizeof (struct iphdr) + sizeof (struct tcphdr)); 
    ip->id       = 1; 
    ip->offset   = 0; 
    ip->ttl      = 255; 
    ip->protocol = IPPROTO_TCP; 
    ip->saddr    = inet_addr("192.168.1.81"); /* adresse IP source */ 
    ip->daddr    = inet_addr("192.168.1.1"); /* adresse IP de destination */ 
    ip->checksum = 0; /* on initialise le champ checksum de notre structure IP ? 0 avant l'appel de la fonction calculant le checksum */ 
    ip->checksum = cksum((unsigned short *)ip, sizeof(struct iphdr));  
     
     
    //----------------------------------remplissage en-tête tcp------------------------------------------- 
    struct tcphdr *tcp;  /* notre structure TCP */ 
    /* maintenant passons ? la structure TCP */ 
    /* on alloue de la m?moire pour celle ci */ 
    tcp = (struct tcphdr *)malloc(sizeof(struct tcphdr)); 
    memset(tcp, 0x0, sizeof(struct tcphdr)); 
     
    /* on la remplie */ 
    tcp->sport      = htons(1500);	/* port source */ 
    tcp->dport      = htons(80) ;	/* port de destination */ 
    tcp->seqnum     = htonl(1337);	/* num?ro de s?quence */ 
    tcp->acknum     = htonl(1337);  /* ack number */ 
    tcp->dataoffset = (5) << 4;     /* d?calage */ 
    tcp->flags      = 0x02;         /* 0x02 = flag syn */ 
    tcp->windows     = htons(1337);  /* fen?tre */ 
    tcp->checksum   = 0;		/* checksum */ 
    tcp->urgpointer = 0;		/* options */ 
     
     
    //---------------------remplissage de la structure pseudo hdr pour calculer le checksum de notre packet tcp----------------------- 
    struct pseudohdr *psdheader; /* pseudo header */ 
    /* allocation m?moire pour notre pseudo header */ 
    psdheader = (struct pseudohdr *)malloc(sizeof(struct pseudohdr)); 
    memset(psdheader, 0x0, sizeof(struct pseudohdr)); 
     
    /* on remplie notre structure */ 
    psdheader->saddr    = inet_addr("192.168.1.81"); /* adresse source */ 
    psdheader->daddr    = inet_addr("192.168.1.1"); /* adresse de destination */ 
    psdheader->useless  = 0;		  /* null */ 
    psdheader->protocol = IPPROTO_TCP;	  /* protocol */ 
    psdheader->length   = htons(sizeof(struct tcphdr)); /* longueur de notre structure TCP_HDR */ 
    psdheader->TCP      = *tcp;		  /* structure TCP_HDR */ 
     
    /* Maintenant nous calculons le checksum pour notre paquet */ 
    tcp->checksum =cksum((unsigned short *)psdheader, sizeof(struct pseudohdr));  
     
    char *ptr = NULL, packet[32]; /* notre paquet, 32 = sizeof(struct icmphdr) + sizeof(struct iphdr) */ 
     
    ZeroMemory(packet, sizeof(packet)); 
    ptr = packet; 
    memcpy(ptr, ip, sizeof(struct iphdr)); 
    ptr += sizeof(struct iphdr); 
    memcpy(ptr, tcp, sizeof(struct tcphdr)); 
    ptr += sizeof(struct tcphdr); 
     
     
    //-------------------------------------------------envoi du packet---------------------------------------- 
    struct sockaddr_in sin; /* notre structure sockaddr_in qui contiendra l'adresse de destination */ 
     
    /* on rempli notre structure sockaddr_in */  
    sin.sin_family           = AF_INET; 
    sin.sin_addr.s_addr	     = inet_addr("192.168.1.1"); // Adresse de destination 
     
    /* hop, nous envoyons notre paquet ? destination */ 
    if(sendto(socket, packet, sizeof(packet), 0x0, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR)	     
    { 
    	fprintf(stderr, "Erreur lors de l'appel de la fonction sendto. Code erreur : %d\n", WSAGetLastError());	 
    } 
    free(ip); 
    free(tcp); 
    WSACleanup(); 
    system("pause"); 
    return 0;}

  2. #2
    Expert éminent
    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 : 38
    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
    Points : 8 389
    Points
    8 389
    Par défaut
    C'est du à une limitation bien connue du pouvoir des raw sockets depuis Windows XP SP 2, on ne peut pas envoyer des paquets TCP forgés par l'application ni des paquets UDP si l'adresse source spécifiée n'existe pas sur le réseau.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Donc mon code est bon ok.Mais en fait l'adresse que je fourni est l'adresse de ma machine sur le réseau local,j'ai une livebox et donc c'est mon ip.Avec cette adresse mes packets icmp marche donc je ne comprend pas bien d'où vient le problème.

    Donc voila merci en tout cas pour ta réponse rapide.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Donc je ne sais toujours pas ou mon code n'est pas bon étant donné que l'ip est bien la mienne et que j'ai réussi a coder un forgeur de packet icmp. donc je ne voit pas le problème,enfin sa ne vient pas des rawsocket donc j'èspere que quelqu'un trouvera ,se serait sympa.Merci d'avance.

  5. #5
    Expert éminent
    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 : 38
    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
    Points : 8 389
    Points
    8 389
    Par défaut
    Je vois que je n'ai pas été très clair dans ma première réponse :

    1 - On ne peut pas forger des paquets TCP.
    2 - On peut forger des paquets UDP à condition que l'adresse source spécifiée existe réellement sur le réseau
    3 - On peut forger des paquets ICMP

    Source (http://msdn.microsoft.com/en-us/libr...48(VS.85).aspx):
    Citation Envoyé par MSDN :: TCP/IP Raw Sockets
    ...
    Limitations on Raw Sockets

    On Windows XP Service Pack 2 (SP2) and Windows Vista, the ability to send traffic over raw sockets has been restricted in several ways:

    * TCP data cannot be sent over raw sockets.
    * UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).
    * A call to the bind function with a raw socket is not allowed.

    These above restrictions do not apply to Windows Server 2003 and Windows Server 2008 or to versions of the operating system earlier than Windows XP SP2.
    ...

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    ok,désolé je n'avais pas compris cela donc il suffit de que je rétrograde en sp1 pour pouvoir forger mes propre packet tcp.C'est dommage que se ne soit possible j'aime bien voir comment cela fonctionne en-dessous.Tampis merci pour acharnement avec mon cas impossible.

  7. #7
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    L'histoire des raw sockets sous Windows est savoureuse. Au départ, MS prétend réinventer toutes les APIs et présente des sockets bien pourris sans la plupart des fonctionnalités des (à l'époque standard) sockets BSD. Puis sous la pression des utilisateurs, MS clone directement les BSD sockets, y compris la possibilité de spoofer l'adresse d'envoi, ce qui franchement ne sert qu'à faire des choses louches (je développe des drivers matériels Ethernet 1000, et pourtant je n'ai jamais eu à spoofer une adresse). Steve Gibson fait une crise cardiaque annonçant la fin du monde si MS persiste, comme quoi les virus pondus par les nerds sous Linux vont envahir les PC de sa grand-mère, et MS répond qu'ils sont au courant du problème, que ce n'en est pas un, et que la priorité de MS est ... le respect des standards .
    Évidemment, les virus des nerds envahissent les PC des grand-mères, et les DDoS fleurissent grâce à l'énorme base installée de Windows comparée à Unix. MS finit par pondre un compromis correct, décrit dans le post ci-dessus.
    Un des passages trouvés dans le site de Steve Gibson:
    Leo: <...> And I think you deserve credit for it because I don't think anybody would have thought of this as a security issue, would have known about it, if you hadn't raised a ruckus about raw sockets those years ago.

    Steve: Well, the big problem, of course, are not individual end-users who are doing this, but there are people whose computers are affected by these remote-control IRC bots.

    Leo: Right. We're not worrying about Granny using raw sockets. But we're worried about her computer being used by a bad guy and raw sockets.

    Steve: Exactly. And then attacks being launched from her computer. And having the advantage of raw sockets means that it's easier to produce a denial-of-service attack on other machines, which is virtually impossible, I mean, practically impossible to trace back. So I was really...

    Leo: I think it's good news.

    Steve: Yeah, I was really glad to see that Microsoft, you know, finally woke up with Service Pack 2 and removed raw sockets.
    Tout ça c'est du passé maintenant que les ISP vérifient les packets avec adresse d'envoi forgée, mais c'est la raison historique pour laquelle ces restrictions existent dans les raw sockets de Windows.
    "Maybe C++0x will inspire people to write tutorials emphasizing simple use, rather than just papers showing off cleverness." - Bjarne Stroustrup
    "Modern C++11 is not your daddy’s C++" - Herb Sutter

  8. #8
    Expert éminent
    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 : 38
    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
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par chichou10
    donc il suffit de que je rétrograde en sp1 pour pouvoir forger mes propre packet tcp
    Ou que tu upgrades en Windows 2008 Server .

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Re bonjour ou bonsoir,
    Je ne cherche pas à spoofer les ip des mes packets tcp forger mes seulement d'en créer un.J'essaie de comprendre comment fonctionne les réseaux.Je m'y interesse en amateur et aime chercher ce qu'il y a en dessous,mais j'ai du mal.
    Je recherche donc tous plein de cours sur les réseaux ,c'est un petit appel,même si je vois à peut près le systeme je suis avide de détails grace a un bouquin assez clair sur les réseaux provenat des infos de commentçamarche une sorte de concentré léger avec lequel j'ai pu me faire une idée.
    Sinon j'ai vue qu'il été possible de passer sa carte réseau en mode moniteur, et de récupérer des packet tcp udp icmp,...
    Celà marche t'il avec windows xp sp2 on peut pas forger mais on peut capturer?
    et est il possible de récuperer des packet ethernet, je sais pas si je m'exprime clairement,avec winsock?

    PS : J'ai tester mon programme pour forger mon packet tcp sur une machine sous windows 2000 et il me sort la même erreur mais mon forgeur de packet icmp marche donc les raw socket sont possible,donc sa doit peut être venir de mon prog sinon je suis désolé pour mon orthographe désolante désolé encore.

    Merci à vous pour ces réponses, j'en attendant encore beaucoup de votre part

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Je viens de voir tes tuto Melem et je les trouves fort intéréssant pour les raw socket car mon prog pour forger un packet tcp derive d'un prog pour l'icmp et jai vue que je n'est pas mis IP_HDRINCL dans setsockopt le problème pourrait venir de la?
    bon je vais arreter de vous ennuié et bien étudier des tuto.

Discussions similaires

  1. Raw socket et problème d'endianness
    Par Eyyub dans le forum D
    Réponses: 0
    Dernier message: 04/02/2012, 11h45
  2. Problème de Raw Sockets
    Par simrapman dans le forum Réseau/Web
    Réponses: 1
    Dernier message: 07/09/2009, 13h31
  3. Réponses: 15
    Dernier message: 04/01/2007, 11h15
  4. Mysql ne se lance pas problème de socket
    Par Riko dans le forum Installation
    Réponses: 5
    Dernier message: 05/02/2004, 09h28
  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