9
votes

Reconstruction de paquets HTTP

Si j'ai un grand paquet HTTP qui a été divisé en plusieurs paquets TCP, comment puis-je les reconstruire dans un seul paquet HTTP? Fondamentalement, où dans le paquet, dois-je dire quand un paquet HTTP commence / se terminer? Je ne peux pas sembler voir des drapeaux / champs de l'en-tête TCP qui indiquent le début ou la fin du paquet HTTP.

edit: dans le suivi des réponses. Si TCP gère le flux, comment sait-il quand le flux commence et se termine? Est-ce déterminé par l'ouverture et la fermeture de la prise? Un certain protocole, à un certain niveau, doit pouvoir savoir lorsque le flux / paquet HTTP a commencé et s'est terminé. C'est ce que j'aimerais savoir.

La situation que je suis dans est que j'utilise un sniffer de paquet en C # qui se lit dans des paquets TCP et j'aimerais pouvoir reconstruire les demandes / réponses HTTP / etc. Passez à travers l'interface comme comment Wifrehark et divers autres renifleurs parviennent à. Alternativement y a-t-il des bibliothèques C # qui vous permettent d'exploiter dans les flux HTTP au niveau supérieur, ce qui vous permet d'économiser de reconstruire le flux / paquets HTTP moi-même?

merci.


0 commentaires

6 Réponses :


8
votes

Vous ne devez utiliser aucune information du niveau TCP pour déterminer les limites de la requête HTTP. TCP fournit un service de flux d'octets fiable; Vous ne pouvez pas voir de champs ni de drapeaux dans TCP qui aident à cela parce qu'ils ne sont pas là.

Pour déterminer où se trouvent les limites dans une demande HTTP, vous devez suivre la RFC 2616. Les limites sont bien définies et vous pouvez les déterminer en analysant les données que vous recevez.


0 commentaires

3
votes

TCP est un protocole flux , pas un protocole de paquets. La couche d'application (c'est-à-dire que vous) reçoit un flux de données, pas un tas de paquets. Vous continuez de lire des octets dans le flux et vous obtiendrez toute votre charge utile HTTP, tandis que TCP effectue la vérification des erreurs, la résenuture, etc. en dessous.


0 commentaires

5
votes

Dans chaque paquet TCP, le début des données de la charge utile est immédiatement après l'en-tête TCP et la fin des données de charge utile est la fin du paquet IP.

La fin de l'en-tête TCP est facilement trouvée - le décalage est un champ 4 bits dans l'en-tête contenant la longueur de l'en-tête en mots 32 bits (ainsi de multiplication par 4 obtenir la longueur en octets de 8 bits).

Utilisez les numéros de séquence TCP à partir du champ SEQUENCE pour chaîner les charges utiles dans le bon ordre. Notez qu'il pourrait y avoir des duplicats, dans le cas de retransmissions.


0 commentaires

14
votes

OK, j'ai travaillé sur la façon de faire cela (dodgy mais ça fait le travail).

Il est simple de supprimer les en-têtes Ethernet, IP et TCP vous laissant avec le message de données 'brut'. En regardant dans le message, il est facile de détecter s'il s'agit du démarrage d'un paquet HTTP en recherchant le "http / 1.1 ..." au début du paquet. Cela indique que le paquet est le début d'un flux http / packet plus grand / autre. Vous pouvez également effectuer une analyse simple pour lire le champ "longueur de contenu" qui est la longueur totale de l'ensemble du paquet HTTP.

Vous pouvez également utiliser les numéros IP et Port Source / Destination pour former un identifiant unique pour le lien. Ainsi, après avoir reçu le paquet d'en-tête, prenez note de ces 4 choses (SRCIP, SRCPORT, DESTIP, DETTPORT). La prochaine fois que vous recevez un paquet correspondant à ce combo port / IP, vous pouvez vérifier si la partie suivante du paquet HTTP. Vous pouvez utiliser les numéros de séquence pour effectuer une certaine validation et probablement d'autres choses, mais généralement les paquets sont en ordre afin que ce soit correct. Je pense qu'un nouveau port est ouvert pour chaque courant HTTP afin de ne pas recevoir de paquets aléatoires qui ne font pas partie du flux, mais cela pourrait être une zone sujette à l'erreur.

Quoi qu'il en soit, une fois que vous avez reçu ce paquet, débarrasserez à nouveau les en-têtes et obtenez le message RAW. Ajoutez-le sur la partie déjà connue du message. Si la longueur du message total reçu jusqu'à présent est égale à la longueur lue à partir du champ "longueur de contenu", le paquet est complet!

Cette méthode est évidemment sujette à une énorme quantité d'erreurs, mais je ne suis pas après une manière extrêmement robuste de le faire. Je pensais que je répondrais à ma propre question au cas où quelqu'un d'autre apparaît dans le même problème à l'avenir! Bonne chance avec votre renifle: D


2 commentaires

Si le champ de longueur de contenu n'est pas spécifié, il existe également d'autres moyens de résoudre la longueur. par exemple. httpwatch.com/httpgallery/chunked


Peut-être un peu de retard, mais l'en-tête Longueur de contenu ne spécifie pas la longueur totale de paquets. Il spécifie simplement la taille du contenu, donc le corps, qui vient après les en-têtes. Les en-têtes et le corps sont séparés par \ r \ n \ r \ n .