Comment valider la longueur de tableau d'octets reçus, qui est non nulle terminée?
-
25-09-2019 - |
Question
I ai un code C \ C ++ qui reçoit une structure sur le réseau, à partir de la forme suivante:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
Le code je passe sur Data
dans une boucle de temps de DataLen
et traite les données.
... Le problème:
Une fois le code est venu à des experts de sécurité pour les tests de pénétration, ils ont préparé une fausse application qui envoie ce struct avec DataLen
plus grand que la longueur réelle de Data
. Cela provoque, bien sûr, une exception de violation d'accès.
Alors, la question est - comment puis-je valider la longueur réelle de la Data
reçue? Est-il possible sans changer la structure?
Merci d'avance.
La solution
Nice experts de la sécurité! Je souhaite que ma compagnie avait un département comme ça.
Chaque fois que des données sont reçues du réseau, le réseau IO indique le nombre d'octets écrit dans la mémoire tampon, si vous avez utilisé read(2)
, recv(2)
ou boost::asio::async_read
ou toute autre chose que j'ai vu. cas d'utilisation typique quand il y a un « nombre d'octets à suivre » champ dans l'en-tête de votre structure de données, est d'appeler à plusieurs reprises en lecture / recv / etc jusqu'à ce que le nombre d'octets ont été reçus (ou jusqu'à ce que l'erreur a eu lieu), et seulement alors il doit construire et retourner votre DataStruct (ou rapport d'erreur).
Autres conseils
Vous savez combien d'octets que vous avez reçu, pour comparer juste avec DataLen
.
Il est impossible sans changer la structure. Les données reçues de socket TCP / IP est simple flux. Logiquement, il ne se divise pas en paquets. paquet physique peut contenir une ou plusieurs instances de DataStruct, une instance DataStruct peut être divisée en deux ou plusieurs paquets physiques. la structure actuelle de l'information peut être utilisée que s'il n'y a pas d'erreurs de communication ou des paquets non valides.
La corruption est facile si vous avez pas de limitation intrinsèque.
Certains mécanismes de protection seraient:
- Essayez de
realloc()
la mémoire tampon, dans une certaine taille acceptable (siData
est dynamique) - Exceptions sont amis: utilisation
SIGSEGV
àsignal(2)
,signal(7)
etsetjmp(2)
de faire un peu utile try / catch structure du code. Voir La combinaison setjmp () / longjmp ( ) et de traitement des signaux pour une introduction rapide sur ce sujet. Utilisezsigaction(2)
pour aller plus loin (en obtenant l'adresse défectueuse;).