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

Réseau C Discussion :

Somme de controle (checksum) TCP erronée


Sujet :

Réseau C

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Par défaut Somme de controle (checksum) TCP erronée
    Bonjour,

    Je suis actuellement en train de faire un scanner de port TCP.
    Pour cela j'envoie des paquets SYN, mais la checksum que je créé malgré avoir suivi toutes les info de la rfc1071 - TCP n'est pas bonne et Wireshark me le confirme.

    J'ai essayé d'envoyer un paquet avec la checksum de Wireshark en dur et ça passe, j'ai une réponse ACK.
    Mais là je n'ai pas de réponse car le unsigned short n'a pas la bonne valeur.

    Voici mon 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
     
    unsigned short ComputeChecksum(unsigned char *data, int len)
    {
        long sum = 0;  /* assume 32 bit long, 16 bit short */
        unsigned short *temp = (unsigned short *)data;
     
        while(len > 1)
        {
            sum += *temp++;
            if(sum & 0x80000000)   /* if high order bit set, fold */
                sum = (sum & 0xFFFF) + (sum >> 16);
            len -= 2;
        }
     
        if(len)       /* take care of left over byte */
            sum += (unsigned short) *((unsigned char *)temp);
     
        while(sum>>16)
            sum = (sum & 0xFFFF) + (sum >> 16);
     
        return ~sum;
    }
     
    // Structure du pseudo-en-tête TCP
    struct pseudo_header {
        uint32_t source_address;  // Adresse IP source
        uint32_t dest_address;    // Adresse IP destination
        uint8_t placeholder;       // Zéro
        uint8_t protocol;         // Protocole (TCP = 6)
        uint16_t tcp_length;      // Longueur de l'en-tête TCP + données
    };
     
    // Fonction pour construire un paquet TCP SYN
    uint create_syn_packet(char *packet, void *dest, int port, int ipversion, struct in_addr dest_ip, struct in_addr src_ip) {
        if (ipversion == 4) {
            struct tcphdr *tcp_header = (struct tcphdr *)packet;
            struct sockaddr_in *dest_4 = (struct sockaddr_in *)dest;
     
            // Remplir l'en-tête TCP
            memset(tcp_header, 0, sizeof(struct tcphdr));
            ///memcpy(tcp_header, tcp_syn, sizeof(struct tcphdr));
            tcp_header->source = htons(12345);
            tcp_header->dest = htons(port);
            tcp_header->seq = 3093775308;
            tcp_header->ack_seq = 0;
            tcp_header->doff = 5; // 5 * 4 = 20 octets
            tcp_header->syn = 1;
            tcp_header->window = htons(64240);
     
            uint optionlen;
            optionlen = add_tcp_options(packet + sizeof(struct tcphdr));
            tcp_header->doff += (optionlen + 3) / 4;
     
            // Calculer la somme de contrôle
            tcp_header->check = 0;
     
            // Remplir le pseudo-en-tête
            struct pseudo_header psh;
            psh.source_address = *((uint32_t *)&src_ip);
            psh.dest_address = *((uint32_t *)&dest_ip);
            psh.placeholder = 0;
            psh.protocol = IPPROTO_TCP;
            psh.tcp_length = htons(sizeof(struct tcphdr));
     
            // Calculer la somme de contrôle
            int psize;
            psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + optionlen;
            char *pseudogram = ALLOC(psize);
     
            // Copier le pseudo-en-tête et l'en-tête TCP dans le tampon
            memcpy(pseudogram, (char *)&psh, sizeof(struct pseudo_header));
            memcpy(pseudogram + sizeof(struct pseudo_header), (char *)tcp_header, sizeof(struct tcphdr) + optionlen);
            // Pas de data
     
            // Calculer la somme de contrôle et l'insérer dans l'en-tête TCP
            tcp_header->check = ComputeChecksum((unsigned char *)pseudogram, psize);
     
            // Libérer la mémoire allouée
            FREE(pseudogram);
            printf("checksum: %u\n", tcp_header->check); ///
     
            return (optionlen);
     
        }
    }
    Exemple:
    Pour le paquet envoyé au port 22 j'ai 0x3dcb alors que Wireshark attend 0x5c62

    Avez vous spot une erreur dans mon code?
    Merci de m'avoir lu <3

  2. #2
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    753
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 753
    Par défaut
    Hello,

    Peux-tu donner les valeurs de pseudogram et psize à la ligne 76 ? (celles pour lesquelles la réponse correcte est 0x5c62). Merci. J'aurais voulu tester avec cet algorithme. Mais si c'est trop long à mettre ici, teste toi-même l'algorithme.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent ;)

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Par défaut
    Bonjour,

    Merci pour ta réponse.
    En effet les valeurs du pseudogramme étaient incorrect, j'avais mal inscrit les adresses IP dedans (j'aurai dû voir ça dès le début)!
    Du coup désolé pour mon post mais je peux attester au cas où d'autres gens voudraient faire la même chose que le code que j'ai posté est BON et donne la BONNE checksum.

    Assurez vous de bien remplir le pseudogram et tout ira bien.
    Lignes 59 et 60
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            psh.source_address = *((uint32_t *)&src_ip);
            psh.dest_address = *((uint32_t *)&dest_ip);
    Ces valeurs étaient à zéro.

    Pour répondre à ta question la taille de psize vaut (ligne 67):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + optionlen;
    Ce qui veux dire qu'il faut inclure le pseudogram, ensuite le paquet TCP ainsi que ses options.

    Merci pour votre aide!

    EDIT: Là, le souci c'est de rendre la tâche multithread et j'ai des faux positifs à cet endroit là !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        // Attendre une réponse
        received = recvfrom(sock, packet, sizeof(packet), 0, (struct sockaddr *)&from, &from_len);
        if (received >= 0) {
            struct tcphdr *tcp_header = (struct tcphdr *)(packet + sizeof(struct iphdr));
            if (tcp_header->syn == 1 && tcp_header->ack == 1) {
                close(sock);
                return (1);
            } else if (tcp_header->rst == 1) {
                close(sock);
                return (0);
            }
        }

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

Discussions similaires

  1. [XL-2007] Vérification clé de contrôle (somme de contrôle)
    Par Excel_man dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 04/02/2013, 10h18
  2. Contrôle réseau TCP
    Par feuilleton dans le forum Réseau
    Réponses: 5
    Dernier message: 18/05/2012, 15h14
  3. svn: Sommes de contrôle de base différentes
    Par nauttilus dans le forum Subversion
    Réponses: 3
    Dernier message: 31/08/2011, 14h07
  4. Réponses: 5
    Dernier message: 10/06/2009, 11h59
  5. Controle de date erroné
    Par jcachico dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 11/02/2008, 14h35

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