Partage
  • Partager sur Facebook
  • Partager sur Twitter

Socket

    19 février 2017 à 22:55:09

    Bonsoir,

    J'ai récemment acheté le livre "Techniques de Hacking" de Jon Erickson, au combien passionant !
    La partie réseau est introduite (après 2 pages très résumées sur le modèle OSI) par la notion de sockets en C.
    J'en  suis arrivé à réaliser un petit programme qui est censé identifier un serveur web ( en autre afficher la réponse qu'il me renvoie lorsque que je lui envoie la commande "HEAD / HTTP/1.0\r\n\r\n"

    Mon problème est le suivant : contrairement aux exemples du livre dans lequel le serveur  renvoie bien une réponse, chez moi ça ne 'fonctionne' pas.. Après quelques recherches, en tentant nottament l'expérience sur un serveur local, j'obtiens (sur le serveur) la sortie suivante :

    192.168.2.114 - - [19/Feb/2017 22:47:15] code 501, message Unsupported method ('HEAD')
    192.168.2.114 - - [19/Feb/2017 22:47:15] "HEAD / HTTP/1.0" 501 -

    Je précise que le livre a été publié en 2012 donc certains protcoles ont peut-être changé ( ? ).

    Je vous mets le code source si jamais :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h> // pour struct hostent
    
    #include "hacking.h"
    #include "hacking-network.h"
    
    #define HTTP_PORT 80
    
    int main(int argc, char const *argv[])
    {	
    	int sockfd;
    
    	struct hostent *host_info;
    	struct sockaddr_in target_addr;
    
    	unsigned char buffer[4096];
    
    	if (argc < 2)
    	{
    		printf("Usage : %s <hostname>\n", argv[0]);
    		exit(EXIT_FAILURE);
    	}
    
    	host_info = gethostbyname(argv[1]);
    	if(host_info == NULL)
    	{
    		printf("%s does'nt exist\n", argv[1]);
    		exit(EXIT_FAILURE);
    	}
    
    	if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    	{
    		perror("Failed socket");
    		exit(EXIT_FAILURE);
    	}
    		
    	target_addr.sin_addr = *((struct in_addr*) (host_info->h_addr));
    	target_addr.sin_port = htons(HTTP_PORT);
    	target_addr.sin_family = AF_INET;
    	memset(&(target_addr.sin_zero), '\0', 8);
    
    	if (connect(sockfd, (struct sockaddr*)&target_addr, sizeof(target_addr)) == -1)
    	{
    		perror("Connect failed");
    		exit(EXIT_FAILURE);
    	}
    
    	send_string(sockfd, "HEAD / HTTP/1.0\r\n\r\n");
    	while(recv_line(sockfd, buffer))
    	{
    		if(strncasecmp(buffer, "Server:", 7) == 0)
    		{
    			printf("The web server for %s is %s\n", argv[1], buffer+8);
    			exit(EXIT_SUCCESS);
    		}
    	}
    
    	printf("Server line not found\n");
    
    	return EXIT_SUCCESS;
    }

    En théorie si je fais par exemple ./webserver_id www.microsoft.com

    Je suis censé avoir The web server for www.microsoft.com is Microsoft-IIS/7.0. (ou un truc semblable quoi..)

    Je ne sais pas vraiment si je dois mettre ce sujet en langage C ou en réseaux donc dites le moi s'il faut que je le bouge.

    Merci d'avance ! :D

    • Partager sur Facebook
    • Partager sur Twitter
      20 février 2017 à 9:41:58

      J'aimerais bien voir l'implémentation de recv_line.

      • Partager sur Facebook
      • Partager sur Twitter

      git is great because Linus did it, mercurial is better because he didn't.

        20 février 2017 à 12:08:50

        Merci de me venir en aide !

        Voila le code de recv_line (et de send_string) :

        /*	Cette fonction accepte un descripteur de socket et un pointeur sur la chaîne à envoyer.
         *	Elle s'assure que tous les octets de la chaîne sont émis. Elle retourne 1 en cas de succès
         *	et 0 en cas d'échec.
         */
        
        int send_string(int sockfd, unsigned char *buffer)
        {
        	int sent_bytes, bytes_to_send;
        	bytes_to_send = strlen(buffer);
        	while(bytes_to_send > 0)
        	{
        		sent_bytes = send(sockfd, buffer, bytes_to_send, 0);
        		if(sent_bytes == -1)
        			return 0;
        		bytes_to_send -= sent_bytes;
        		buffer += sent_bytes;
        	}
        
        	return 1;
        }
        
        /*	Cette fonction accepete un descripteur de socket et un pointeur sur le tampon de destination.
         *	Elle lit les données depuis la socket jusqu'à ce qu'elle rencontre la suite d'octets de fin de ligne
         *	(EOL). Ces octets snt lus depuis la socket mais le tamon de destination est clos avant ces octets.
         *	Elle retourne la taille de la ligne lue (sans les octets de fin)
         */
        int recv_line(int sockfd, char* dest_buffer)
        {
        	#define EOL "\r\n"
        	#define EOL_SIZE 2
        
        	unsigned char* ptr;
        	int eol_matched = 0;
        
        	ptr = dest_buffer;
        
        	while(recv(sockfd, ptr, 1, 0)) // On lit les octets un par un
        	{
        		if(*ptr == EOL[eol_matched])
        		{
        			eol_matched++;
        			if (eol_matched == EOL_SIZE)
        			{
        				*(ptr + 1 - EOL_SIZE) = '\0';	// On enlève les \r\n
        				return strlen(dest_buffer);		// On retourne la taille
        			}
        			else
        				eol_matched = 0;
        		}
        
        		ptr++;
        	}
        
        	return 0;
        }
        • Partager sur Facebook
        • Partager sur Twitter
          20 février 2017 à 12:24:59

          Xenoliss a écrit:

          192.168.2.114 - - [19/Feb/2017 22:47:15] code 501, message Unsupported method ('HEAD')

          192.168.2.114 - - [19/Feb/2017 22:47:15] "HEAD / HTTP/1.0" 501 -


          Bon c'est ok: tu as une un serveur qui n'implemente pas cette fonction c'est tout! (bien que normalement d'après https://issues.apache.org/jira/browse/OLINGO-840 cela doit être une fonction obligatoire) 

          http://stackoverflow.com/questions/8524014/correct-response-to-http-head-request-on-https-only-site y a un gars qui se plaint qu'il n'obtient une reponse 501 sur la requete HEAD que sur la racine ( / ) aussi!

          en bref: ca vient pas de ton programme, mais du serveur. Testes sur un autre serveur?

          -
          Edité par breizhbugs 20 février 2017 à 12:28:08

          • Partager sur Facebook
          • Partager sur Twitter
          ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
            20 février 2017 à 13:00:48

            Je ne sais pas vraiment si j'en ai les droits mais j'ai tester sur plusieurs serveur tel que, microsoft, facebook, gmail etc ... Sans réponse à chaque fois >_< 

            Je regarde les liens que tu m'as donné en espérant trouver des réponses  !

            • Partager sur Facebook
            • Partager sur Twitter
              20 février 2017 à 14:25:51

              As tu essayé sur autre chose que la racine?
              • Partager sur Facebook
              • Partager sur Twitter
              ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                20 février 2017 à 18:00:28

                Je viens de tester, le résultat ne change pas
                • Partager sur Facebook
                • Partager sur Twitter

                Socket

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown