2010-04-24 8 views
6

Dans quelle direction dois-je aller (bibliothèques, documents)?Comment pirater toute requête HTTP locale et extraire l'URL en utilisant c?

MISE À JOUR

Quelqu'un peut-il illustrer comment utiliser winpcap pour faire le travail?

MISE À JOUR 2

Comment puis-je vérifier si un paquet est un HTTP un?

+2

Vous n'avez pas besoin d'écrire un logiciel pour cela. Utilisez un [proxy] (http://www.squid-cache.org/) qui a [logging] (http://www.squid-cache.org/Doc/config/access_log/). –

+0

Notez que les réponses données vous permettent d'enregistrer ou de contrôler les URLs mais certainement pas de détourner: "Pour modifier les paramètres du logiciel à l'insu de l'utilisateur afin de forcer cet utilisateur à visiter un certain site web" (wiktionary). Vous avez peut-être abusé du terme ou en vouliez dire un autre. –

+0

Désolé de contester Matt, mais le calmar "détournement" en effet. Je veux dire par là qu'il vous permet de substituer une URL différente à celle que l'utilisateur a saisie (si c'est ce que vous voulez faire en tant que programmeur). La fonction principale est de mettre en cache des choses, mais cela peut faire plus que si vous le souhaitez. – Hotei

Répondre

15

Si par « pirater » vous vouliez dire renifler les paquets alors ce que vous devez faire pour le faire avec WinPcap est le suivant:

  1. Trouver l'appareil que vous souhaitez utiliser - See WinPcap tutorial.

  2. Ouvrir un dispositif utilisant pcap_open

    // Open the device 
    char errorBuffer[PCAP_ERRBUF_SIZE]; 
    pcap_t *pcapDescriptor = pcap_open(source,    // name of the device 
                snapshotLength,  // portion of the packet to capture 
                      // 65536 guarantees that the whole packet will be captured on all the link layers 
                attributes,   // 0 for no flags, 1 for promiscuous 
                readTimeout,   // read timeout 
                NULL,     // authentication on the remote machine 
                errorBuffer);   // error buffer 
    
  3. Utiliser une fonction qui lit les paquets à partir du descripteur comme pcap_loop

    int result = pcap_loop(pcapDescriptor, count, functionPointer, NULL); 
    

    Cette boucle de volonté jusqu'à ce que quelque chose de mal est arrivé ou la boucle a été brisée à l'aide un appel de méthode spéciale. Il appellera le functionPointer pour chaque paquet.

  4. Dans la fonction objet pointu quelque chose qui analyse les paquets, il devrait ressembler à un pcap_handler:

    typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, 
         const u_char *); 
    
  5. Maintenant, tout ce qu'il vous reste est d'analyser les paquets que leur tampon est dans le const u_char* et leur la longueur est dans le champ pcap_pkthdr structure caplen.

    En supposant que vous avez HTTP GET via TCP sur IPv4 sur les paquets Ethernet, vous pouvez:

    • Sauter 14 octets de l'en-tête Ethernet.
    • Sautez 20 octets de l'en-tête IPv4 (en supposant qu'il n'y ait pas d'options IPv4, si vous pensez que les options IPv4 sont possibles, vous pouvez lire les 5-8 bits de l'en-tête IPv4, multipliez cela par 4 et ce serait le nombre d'octets l'en-tête IPv4 prend).
    • Sauter 20 octets de l'en-tête TCP (en supposant qu'il n'y a pas d'options TCP, si vous pensez que les options TCP sont possibles, vous pouvez lire les 96-99 bits de l'en-tête TCP, multiplier par 4 et ce serait le nombre d'octets l'en-tête TCP prend).
    • Le reste du paquet doit être le texte HTTP. Le texte entre le premier et le deuxième espace devrait être l'URI. Si c'est trop long, vous devrez peut-être faire une reconstruction TCP, mais la plupart des URI sont suffisamment petits pour tenir dans un paquet.

      MISE À JOUR: Dans le code ceci ressemblera à ce que (je l'ai écrit sans le tester):

      int tcp_len, url_length; 
      uchar *url, *end_url, *final_url, *tcp_payload; 
      
      ... /* code in http://www.winpcap.org/docs/docs_40_2/html/group__wpcap__tut6.html */ 
      
      /* retireve the position of the tcp header */ 
      ip_len = (ih->ver_ihl & 0xf) * 4; 
      
      /* retireve the position of the tcp payload */ 
      tcp_len = (((uchar*)ih)[ip_len + 12] >> 4) * 4; 
      tcpPayload = (uchar*)ih + ip_len + tcp_len; 
      
      /* start of url - skip "GET " */ 
      url = tcpPayload + 4; 
      
      /* length of url - lookfor space */ 
      end_url = strchr((char*)url, ' '); 
      url_length = end_url - url; 
      
      /* copy the url to a null terminated c string */ 
      final_url = (uchar*)malloc(url_length + 1); 
      strncpy((char*)final_url, (char*)url, url_length); 
      final_url[url_length] = '\0'; 
      

Vous pouvez également filtrer uniquement le trafic HTTP en utilisant la création et la fixation d'un BPF. See WinPcap tutorial. Vous devriez probablement utiliser le filtre "tcp and dst port 80" qui ne vous donnerait que la requête envoyée par votre ordinateur au serveur. Si cela ne vous dérange pas d'utiliser C#, vous pouvez essayer d'utiliser Pcap.Net, qui ferait tout cela pour vous beaucoup plus facilement, y compris l'analyse des parties Ethernet, IPv4 et TCP du paquet.

+1

Est-il possible d'automatiser l'étape 1? Il semble que le tutoriel nécessite de spécifier un périphérique manuellement. – Gtker

+0

Bien sûr, vous devez toujours en choisir un ou simplement le faire pour tous les appareils. Souvent, vous n'avez qu'un seul appareil, vous pouvez donc simplement choisir le premier. Vous pouvez également automatiser le choix en utilisant leurs propriétés (comme leur adresse IP). Voir une autre partie du didacticiel WinPcap: http://www.winpcap.org/docs/docs_411/html/group__wpcap__tut2.html – brickner

+0

@ brickner, pouvez-vous également expliquer comment vérifier si un paquet est un paquet HTTP dans 'pcap_handler' ? – Gtker

0

Vous pouvez regarder le code source de tcpdump pour voir comment cela fonctionne. tcpdump est un utilitaire de ligne de commande Linux qui surveille et imprime l'activité réseau. Cependant, vous avez besoin d'un accès root à la machine pour l'utiliser.

+0

Est-ce que cela fonctionne également pour Windows? – Gtker

+0

@Runner: Si vous êtes intéressé par les solutions Windows uniquement, vous pouvez ajouter une balise [windows]. –

+0

Non seulement les fenêtres, mais aussi Windows et Linux. – Gtker

1

Cela peut sembler exagéré, mais le proxy Web/cache serveur Squid fait exactement cela. Il y a quelques années, mon entreprise l'a utilisé et j'ai dû modifier le code localement pour fournir des avertissements spéciaux lorsque certaines URL étaient accédées, donc je sais qu'il peut faire ce que vous voulez. Vous avez juste besoin de trouver le code que vous voulez et le retirer pour votre projet. J'ai utilisé la version 2.X et je vois qu'ils sont à 3.X maintenant mais je soupçonne que cet aspect du code n'a pas beaucoup changé en interne.

Vous n'avez pas dit si Windows est une 'exigence' ou une 'préférence' mais selon le site: http://www.squid-cache.org/ ils peuvent faire les deux.

+0

Non, je veux l'implémenter moi-même. – Gtker

+2

Vous ne voulez pas commencer une guerre de flamme, mais le fait que vous venez de demander à quelqu'un d'autre comment le faire pour vous dans le commentaire winpcap me fait me demander ... – Hotei