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

  1. #1
    Candidat au Club
    Homme Profil pro
    Maintenance
    Inscrit en
    avril 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Maintenance

    Informations forums :
    Inscription : avril 2015
    Messages : 4
    Points : 4
    Points
    4

    Par défaut Raw Socket TCP envoie flag SYN

    Bonjour à tous,
    Je suis en train de m'intéresser gentiment a la programmation de socket brute sous Windows (10). J'ai jusqu'à présent réussi à envoie un Echo request (ping) en ICMP ainsi qu'un datagram en UDP, mais je bloque complet concernant le TCP...
    En effet, je surveille avec Wireshark ce que j'envoie (et reçois sous machine virtuel Windows 7 (en réseau local)) mais pas moyen de trouver ce paquet TCP !
    Tant que j'y suis j'aimerais aussi demander des précisions sur cette fameuse pseudo entêtes que l'on doit remplir avec le TCP pour calculer le checksum, je ne comprend pas son utilité et de plus j'ai à côté de moi un livre répondant au doux nom de "TCP/IP" qui parle bien de pseudo entête concernant le protocole UDP mais pas pour TCP...Et même pour UDP j'avoue que ce header reste assez flou pour moi.

    Voici mon code pour le TCP :

    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
     
    int TCPRequest()
    {
    	int optval = 1;
    	struct tcpHeader *tcp;
    	struct ipHeader *ip;
    	struct pseudoHeader *psd;
     
    	unsigned short packet_size, ip_len;
     
    	//Création du socket
    	SOCKET socketTCP = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, 0);
    	if (socketTCP == INVALID_SOCKET)
    	{
    		Erreur("Creation Socket TCP");
    		return -1;
    	}
     
    	if (setsockopt(socketTCP, IPPROTO_IP, 2, (char*)&optval, sizeof(optval)) == SOCKET_ERROR)
    	{
    		Erreur("Socket Options : TCP");
    		return -1;
    	}
     
    	printf("Creation du socket termine ! \n");
     
    	//Créations des entêtes
    	//IP
    	ip = (struct ipHeader*)malloc(sizeof(struct ipHeader));
    	memset(ip, 0, sizeof(struct ipHeader));
     
    	//Longueur d'entête
    	ip_len = sizeof(struct ipHeader) / sizeof(unsigned long);
     
    	//Remplissage
    	ip->ip_v = 4;
    	ip->hl = 5;
    	ip->tos = 0;
    	ip->tot_len = htons(sizeof(struct ipHeader) + sizeof(struct tcpHeader));
    	ip->id = 1;
    	ip->offset = 0;
    	ip->ttl = 255;
    	ip->protocol = IPPROTO_TCP;
    	ip->saddr = inet_addr("192.168.0.15");
    	ip->daddr = inet_addr("192.168.0.10");
    	ip->checksum = 0;
    	ip->checksum = in_cksum((unsigned short*)ip, sizeof(struct ipHeader));
     
    	//TCP
    	tcp = (struct tcpHeader*)malloc(sizeof(struct tcpHeader));
    	memset(tcp, 0, sizeof(struct tcpHeader));
     
    	//Remplissage
    	tcp->sport = htons(5000);
    	tcp->dport = htons(5500);
    	tcp->seqnum = htonl(1337);
    	tcp->acknum = htonl(1337);
    	tcp->dataoffset = (5) << 4;
    	tcp->flags = 0x02;					//Flag SYN
    	tcp->windows = htons(1337);
    	tcp->checksum = 0;
    	tcp->urgpointer = 0;
     
    	//Pseudo Header (??)
    	psd = (struct pseudoHeader*)malloc(sizeof(struct pseudoHeader));
    	memset(psd, 0, sizeof(struct pseudoHeader));
     
    	psd->saddr = inet_addr("192.168.0.15");
    	psd->daddr = inet_addr("192.168.0.10");
    	psd->useless = 0;
    	psd->protocol = IPPROTO_TCP;
    	psd->length = htons(sizeof(struct tcpHeader));
    	psd->TCP = *tcp;
     
    	tcp->checksum = in_cksum((unsigned short*)psd, sizeof(struct pseudoHeader));
     
    	printf("Structures remplies...\n");
     
    	//Création du packet
    	packet_size = sizeof(struct ipHeader) + sizeof(struct tcpHeader);
    	printf("packet_size: %d\n", packet_size);
     
    	char *ptr = NULL, *paquet = NULL;
    	paquet = (char*)malloc(sizeof(packet_size));
    	memset(paquet, 0, packet_size);
     
    	ptr = paquet;
    	memcpy(ptr, ip, sizeof(struct ipHeader));
    	ptr += sizeof(struct ipHeader);
    	memcpy(ptr, tcp, sizeof(struct tcpHeader));
    	ptr += sizeof(struct tcpHeader);
     
    	//Destinataire
    	struct sockaddr_in dest;
    	dest.sin_family = AF_INET;
    	dest.sin_addr.S_un.S_addr = inet_addr("192.168.0.10");
     
    	//Envoie
    	int resultat = sendto(socketTCP, paquet, packet_size, 0, (struct sockaddr*) &dest, sizeof(struct sockaddr_in));
    	if (resultat <= 0)
    	{
    		Erreur("Erreur envoie TCP");
    		return -1;
    	}
     
    	printf("%d bytes envoye !\n", resultat);
     
    	//Liberez
    	free(ip);
    	free(tcp);
    	free(psd);
    	//free(paquet);
    	closesocket(socketTCP);
    }
    J'ai essayé pas mal de choses et ce qui est étrange c'est que si je change le protocole spécifié dans le header IP (en mettant par exemple IPPROTO_RAW), le paquet est bien envoyé (en tout cas je le vois sur WireShark) mais bien évidemment il n'a pas le bon protocole. Mais c'est le seul moyen pour moi de voir ce paquet envoyé !!
    Je précise aussi que sous la machine destinatrice (192.168.0.10) le pare feu Windows est désactivé.

    Je vous remercie pour vous réponses et vous souhaite une bonne journée .

  2. #2
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 477
    Points : 23 797
    Points
    23 797

    Par défaut

    Salut,

    qu'y a-t-il de flou dans ces headers ? Ils sont parfaitement connus et documentes partout sur le web. On en retrouve meme en francais.
    Quant au header IP, il precede le header TCP parce que TCP est construit par dessus IP (d'ou TCP/IP, UDP egalement mais pour des raisons que j'ignore je n'ai jamais vu le sigle UDP/IP, ils partagent donc bien sur le meme en-tete IP).
    Le header IP est lui aussi connu et documente http://study-ccna.com/ip-header/
    https://www.thegeekstuff.com/2012/03...otocol-header/

    L'utilite d'un checksum c'est de verifier que les donnees n'ont pas ete alteres lors du transfert.

    Sinon, manipule directement un socket TCP. Creer une appli reseau a deja son lot de challenges interessants.
    Je ne vois aucune raison de manipuler un raw socket - je n'en ai jamais eu besoin, et si j'avais commence par la en debutant, aurais peut-etre abandonne parce que c'est loin d'etre trivial -, sauf a vouloir se faire du mal.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Candidat au Club
    Homme Profil pro
    Maintenance
    Inscrit en
    avril 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Maintenance

    Informations forums :
    Inscription : avril 2015
    Messages : 4
    Points : 4
    Points
    4

    Par défaut

    Bonjour,
    Merci pour ta réponse mais je me suis mal exprimé. Ce n'est pas le Header TCP ou UDP qui me semble flou, en fait lorsque l'on remplit le Header TCP on doit aussi remplir un autre Header nommé "Pseudo Header". Cette entête comprend les champs suivant :
    - Une adresse Source
    - Une adresse destination
    - Un champ nommé...useless...
    - Le protocole
    - La longueur de l'entête TCP
    - Un pointeur vers notre entête TCP

    Dans le tuto que je suis, il explique qu'il nous faut remplir ce Header avant de calculer le checksum du TCP...Mais je ne comprend pas son utilité, tout les champs présent dans ce "Pseudo Header" ne sont pas présent normalement dans l'entête TCP mais plutôt dans l'entête IP (pour certains en tout cas).
    Donc dans le code ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // On remplit le header IP
    //On remplit le header TCP
    //On remplit le header "Pseudo-Header" 
    //On calcule le checksum
    Je ne comprend pas pourquoi....

    Concernant les raisons de manipuler un Raw Socket, j'aime juste réinventer la roue et comprendre comment les choses fonctionnent. C'est un exercice à but instructif uniquement et je comprend mieux lorsque je manipule et applique.
    Cependant je pense que mon problème initial (à savoir que le socket TCP ne s'envoie pas) est tout simplement dût à une restriction de Windows car en effet, mon code pourrait facilement être utiliser à mauvais escient .... Mais je ne trouve confirmation nul part que Windows bloque l'utilisation de Raw Socket sous Windows 10 en tout cas (car sous XP c'était le cas de ce que j'ai compris).

  4. #4
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 477
    Points : 23 797
    Points
    23 797

    Par défaut

    Le pseudo header c'est juste des infos sortis du header IP qui doivent etre utilisees dans le checksum.
    C'est juste une facon de faire pour traiter le buffer d'une traite, rien d'obligatoire.
    Et c'est le meme pour UDP et TCP puisque c'est lie q IP, donc si tu dis que tu l'as pour UDP, alors tu l'as pour TCP.
    https://stackoverflow.com/questions/...sed-in-udp-tcp
    http://www.networksorcery.com/enp/pr...p.htm#Checksum
    Quant q vouloir reinventer la roue pour mieux comprendre, bof. Mieux vaut commencer a utiliser des choses et concepts de haut niveau avant de rentrer dedans et comprendre comment ca marche. Sinon tu commences ou ? Pourquoi un raw socket et pas directement le link layer ? Ou la conductivite des cables ?
    As-tu commence par apprendre l'histoire de la roue quand tu as appris a conduire ?

    Et oui Windows pourrait ajouter des restrictions, mais y'a generalement moyen de les outrepasser.
    Sur reseau local il ne devrait pas etre limitant.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Candidat au Club
    Homme Profil pro
    Maintenance
    Inscrit en
    avril 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Maintenance

    Informations forums :
    Inscription : avril 2015
    Messages : 4
    Points : 4
    Points
    4

    Par défaut

    D'accord, merci pour tes éclaircissements et les liens.
    Je ne suis qu'un programmeur amateur mais ca fais un petit moment quand même que je développe des applications client / serveur TCP, même si ca reste à mon niveau et que je finalise rarement mes projets . Le raw socket est juste un moyen pour moi d'aller un peu plus loin .
    Donc d'après toi la source de mon problème n'est pas Windows? Je vais essayer de porter mon code sur une machine virtuel Linux pour vérifier, parce qu'honnêtement je ne vois pas d'ou peut venir le problème actuellement...
    Merci en tout cas

Discussions similaires

  1. Réponses: 2
    Dernier message: 20/08/2012, 18h56
  2. tcp syn sans reponse raw socket winpcap (c)
    Par Shark9 dans le forum Développement
    Réponses: 35
    Dernier message: 20/08/2012, 09h54
  3. requêtes http en pur raw socket TCP et UDP
    Par pam76 dans le forum Réseau
    Réponses: 2
    Dernier message: 27/10/2011, 14h13
  4. raw socket et protocole TCP/IP
    Par robertmouac dans le forum Développement
    Réponses: 3
    Dernier message: 10/03/2005, 00h09

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