Question:
Code délicat pour sécuriser la mémoire
D.W.
2013-12-10 14:12:49 UTC
view on stackexchange narkive permalink

Je conçois un défi de devoirs pour les étudiants qui apprennent la sécurité de la mémoire et l'écriture de code C sécurisé. Dans le cadre de cela, je recherche une petite tâche de programmation où il n'est pas trivial d'écrire du code C sans dépassements de tampon, erreurs de tableau hors limites et / ou autres erreurs de sécurité de la mémoire. Quel serait un bon exemple d'une telle tâche?

En d'autres termes: je spécifie la fonctionnalité souhaitée; ils l'implémentent en C; et s'ils ne font pas attention lors de l'implémentation, il y a de fortes chances que leur code présente une vulnérabilité de sécurité de la mémoire. Idéalement, je préférerais quelque chose qui puisse être implémenté de manière concise (quelques centaines de lignes de code, tout au plus) pour garder la tâche d'une taille gérable, et ce serait extra-cool si la tâche était en quelque sorte industriellement ou pratiquement pertinente ou réaliste. ou représentatif de la programmation du monde réel.

Pour donner un exemple d'un domaine différent, la mise en œuvre de la recherche binaire sur une liste triée est un exemple classique d'une tâche de programmation facilement spécifiée où si vous ne faites pas attention lors de la mise en œuvre il, il y a une chance significative que vous ayez une sorte de bogue logique (par exemple, une erreur de décalage, une boucle infinie sur certaines entrées, ce genre de chose). Y a-t-il une bonne tâche correspondante, pour la sécurité, et en particulier les vulnérabilités de sécurité de la mémoire?

Si vous êtes cruel, utilisez un analyseur ASN.1.
Quatre réponses:
CL.
2013-12-10 19:18:13 UTC
view on stackexchange narkive permalink

Un exemple typique de gestion de tampon non trivial est l'analyse de fichiers binaires (ou de paquets réseau) qui peuvent contenir des chaînes de longueur arbitraire (y a-t-il un analyseur ASN.1 qui n'a pas eu de bogues de débordement de tampon à un moment donné ?)

Par exemple, considérons le format des blocs de données textuelles dans les fichiers PNG:

Le mot-clé et la chaîne de texte sont séparés par un zéro byte (caractère nul). Ni le mot clé ni la chaîne de texte ne peuvent contenir un caractère nul. La chaîne de texte n'est pas terminée par un zéro (la longueur du morceau définit la fin).

Le devoir pourrait donc être un outil qui génère toutes les données textuelles dans un fichier PNG.

Même du texte brut peut ne pas être tout à fait trivial si vous avez besoin de gérer arbitrairement de longues lignes, et donc de redimensionner un tampon de manière dynamique.Par exemple:

Implémentez tail sans paramètres. (Les lignes peuvent être plus longues que n'importe quel tampon statique. Le fichier entier peut être plus volumineux que la mémoire disponible.)

John Deters
2013-12-10 21:33:13 UTC
view on stackexchange narkive permalink

Je vois beaucoup de problèmes lorsque les gens ont besoin d'analyser des données de caractères hors de structures, en particulier lorsqu'il s'agit d'un tampon normalement terminé par null, mais qui peut avoir la taille du tampon sans terminateur.

  short canary = 0x5678; struct customer {char name [4]; char suffix [3];}; short fencepost = 0x1234;  

Demandez-leur de remplir le client avec des données comme "Joe" et "Jr". Demandez-leur de sortir toutes les données dans ce format exact:

  canary: 0x5678name: Joesuffix: Jrfencepost: 0x1234  

Puis demandez-leur de remplir le client avec "John "et" Esq ". Leur sortie devrait ressembler à ceci:

  canary: 0x5678name: Johnsuffix: Esqfencepost: 0x1234  

C'est une tâche simple et courante. Cela devrait leur apprendre qu'ils ne peuvent pas se contenter de strcpy ("Esq") dans le tampon, car cela tuera le canari. Il devrait les obliger à copier les données du tampon afin de le terminer pour l'imprimer.

Je vous recommande de tester d'abord ceci et de vérifier les paramètres du compilateur. Dans les anciennes versions de Microsoft de Visual C ++, une version de débogage serait liée à une version de débogage de l'allocateur de mémoire qui ajoutait des bornes autour de la mémoire allouée. Cela permettrait au débogueur de signaler une erreur de mémoire écrasée. Je ne sais pas si les versions les plus récentes font toujours cela, mais je sais que les versions de version ne le font pas.

Si vous voulez leur donner un "pourquoi", montrez comment saisir un nom comme Fred @@ @@@@@@ peut provoquer un plantage et permettre à un pirate de prendre le contrôle du programme.

ndp
2013-12-16 22:08:16 UTC
view on stackexchange narkive permalink

c'est difficile car les noyaux Linux modernes afaik n'ont pas de piles exécutables, ils ne pourront donc pas tester leurs programmes sur une distribution linux normale. (Je me souviens avoir des difficultés à tester le code listé dans l'article Alef One sur ma machine Debian)

Ce que vous pourriez faire, c'est leur fournir une VM personnalisée (comme un sacré Linux vulnérable) dont les paramètres de sécurité sont désactivés et leur dire de tester leur code là-bas.

Plus précisément, une solution serait de leur faire écrire un programme qui contient un nom de fichier comme argument de ligne de commande ou comme entrée utilisateur

  • ouvre le fichier
  • lit certains configuration à partir de celui-ci
  • l'analyse / recherche quelque chose de spécifique
  • pousse la partie appropriée dans une prise réseau
  • un autre processus lit les données et doit imprimer certaines parties pertinentes .

Votre scénario pourrait être:

Vous devez écrire un programme en c qui lit les horaires des vols des compagnies aériennes à partir d'un fichier fourni par l'utilisateur et le pousse via une socket tcp vers anoth er processus qui l'affiche ensuite.

Afin de pimenter un peu les choses, vous pouvez fournir une structure dans laquelle tout doit être géré.

C'est simple puisque la plupart du code peut être trouvé en ligne (lecture depuis un fichier, écriture sur socket) et les étudiants n'ont qu'à gérer la mémoire

* "les noyaux Linux modernes n'ont pas de piles exécutables, donc ils ne pourront pas tester leurs programmes sur une distribution Linux normale" * - Je soupçonne que cela représente une mauvaise compréhension de la question, ou des dépassements de tampon. Je ne cherche pas à demander aux étudiants d'exploiter une vulnérabilité dans un programme existant. Je veux plutôt leur demander d'écrire du code sécurisé - ou du code qui, espérons-le, sera sécurisé. (De plus, une pile non exécutable n'est pas une solution miracle qui rend les dépassements de tampon non exploitables.)
Je suis entièrement d'accord, et je suis désolé pour la mauvaise formulation de la réponse.Ce que je voulais dire, c'est que je suppose que les étudiants aimeraient se tester si / comment ils peuvent obtenir un shell de leur programme ou l'exploiter en général et fournir avec un moyen simple de le faire leur donnerait une bonne expérience bonus: -). (Un professeur de l'université a fait quelque chose de similaire et il s'est avéré que de nombreux étudiants ont opté pour le bonus)
AviD
2013-12-23 15:22:28 UTC
view on stackexchange narkive permalink

En fonction des contraintes de votre plate-forme, je suggérerais qu’ils implémentent certains DCOM.

La mise en œuvre des appels DCOM implique de nombreux domaines problématiques: appels réseau, gestion des interfaces, marshalling , le comptage de références distribuées et la gestion de la durée de vie des objets, la sécurité de la mémoire partagée, et plus encore - si cela est bien fait, cela inclut également une vérification d'ACL de bas niveau, etc. Beaucoup de petits morceaux et de structures complexes volent.

Je n'ai jamais vu de code DCOM - que ce soit en appelant le client ou le serveur - PAS de bogues significatifs (à moins d'être implémentés dans un langage "sûr", comme VB, et même alors c'est commun).



Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...