/ / Sockets UDP: recvfrom et adresse de réception - c ++, c, sécurité, udp

Sockets UDP: recvfrom et adresse de réception - c ++, c, sécurité, udp

L'API de socket BSD / POSIX recvfrom() appel (mis à la disposition des programmeurs C ou C ++ via le <sys/socket.h> fichier d’en-tête) fournit un paramètre "out" d’adresse source, struct sockaddr *src_addr, qui stocke l'adresse IP du serveur distant qui a envoyé le datagramme reçu.

Pour toute application qui envoie Datagrammes UDP à un point de terminaison distant, puisreçoit une réponse (par exemple, un résolveur DNS), est-il considéré comme une mesure de sécurité nécessaire de toujours s'assurer que tout datagramme reçu provient de la même adresse IP que le dernier envoyé datagramme (c'est-à-dire l'adresse utilisée dans le précédent sendto appel?)

En d'autres termes, si nous appelons sendto et envoyer un datagramme à une adresse, devons-nous toujours nous assurer qu'un correspondant recvfrom l'appel est de la même adresse?

Il semble que cela pourrait ne pas être réalisable,considérer qu'un datagramme de réponse peut légitimement provenir d'une adresse IP différente si le serveur distant est protégé par un pare-feu ou fait partie d'un système distribué comportant plusieurs adresses IP.

Mais, si nous ne vérifions pas qu’un datagramme reçu provient de la même Adresse IP comme adresse du dernier sendto appel, quoi d’empêcher un attaquant d’intercepter des datagrammes, puis d’envoyer des datagrammes malveillants au client?

Réponses:

2 pour la réponse № 1

Comment savez-vous que le paquet reçu est une réponse? Normalement, cela est fait en utilisant l’adresse source et le port du paquet reçu.

Cependant, il est impossible de vérifier la sourceadresse dans un paquet UDP. Un expéditeur peut placer l'adresse source de son choix. La vérification ne suffit donc que si vous faites confiance à tous les paquets qui circulent sur Internet, ce qui est évidemment impossible.

Il vous faut donc un mécanisme supplémentaire: cookies aléatoires, numéros de séquence, etc.


1 pour la réponse № 2

Pour toute application qui envoie des datagrammes UDP à un point d'extrémité distant, puis reçoit une réponse (telle que, par exemple, un résolveur DNS),

Vous pouvez utiliser un numéro de port sortant aléatoire. C'est ainsi Le DNS peut atténuer les attaques d'usurpation d'identité.

est-il considéré comme une mesure de sécurité nécessairede toujours s'assurer que tout datagramme reçu provient de la même adresse IP que le dernier datagramme envoyé (c'est-à-dire l'adresse utilisée lors de l'appel sendto précédent?)

En d'autres termes, si nous appelons sendto et envoyons un datagramme à une adresse donnée, devons-nous toujours nous assurer qu'un appel recvfrom correspondant provient de la même adresse?

Pas seulement pour la sécurité, mais pour la fonctionnalité. Si vous avez plusieurs connexions sortantes, vous devez savoir quelles réponses UDP correspondent à chaque connexion. Ceci peut être réalisé via une combinaison adresse IP / port du côté distant.

Il semble que cela pourrait ne pas être réalisable,considérant qu'une réponse le datagramme pourrait légitimement provenir d'une adresse IP différente si le le serveur distant est derrière un pare-feu ou fait partie d'un système distribué avec plusieurs adresses IP.

Un système distant doit envoyer la réponse via lemême interface qu'il l'a reçu. Si ce n'est pas le cas, ce sera "non standard" et ne fonctionnera pas avec votre application, ni avec d'autres applications nécessitant de recevoir et de répondre aux paquets UDP.

Mais, si nous ne vérifions pas qu’un datagramme reçuest de la même adresse IP adresse comme adresse du dernier appel sendto, que faut-il empêcher un attaquant d’intercepter des datagrammes, puis d’envoyer des programmes malveillants datagrammes au client?

Rien. Si un attaquant peut MITM une connexion UDP, il peut alors intercepter et modifier tout ce qu'il veut. Ils pourraient simplement envoyer des paquets UDP avec des adresses IP usurpées à votre service.

Si vous devez préserver l'intégrité et la confidentialité des paquets, vous devez implémenter une sorte de cryptage. Par exemple. check-out DTLS si vous avez besoin de supporter les datagrammes.


0 pour la réponse № 3

Certains NAT prennent en charge la perforation UDP qui effectue également la validation IP que vous avez mentionnée. Il n’est donc pas nécessaire de le faire dans l’application.

Pour un protocole personnalisé, vous souhaiterez peut-être implémenter une sorte de numéro de séquence dans votre charge utile pour augmenter encore le niveau de sécurité.


0 pour la réponse № 4

Dans le cas général, il n’est pas vrai qu’un datagramme reçu arbitrairement est une réponse à la requête précédente. Vous devez filtrer, par exemple, via connect(), pour vous assurer de ne traiter que les réponses qui sont des réponses.