Le bug heartbleed est-il une manifestation de l’exploit classique de débordement de tampon en C?

Lors de l’une de nos premières conférences sur la sécurité, nous avons abordé le problème de C, qui ne vérifiait pas la longueur supposée des mémoires tampons et présentait quelques exemples des différentes manières dont cette vulnérabilité pourrait être exploitée.

Dans ce cas, il semble qu’il s’agisse d’une opération de lecture malveillante, l’application ne lisant que le nombre d’octets de mémoire

  1. Ai-je raison d’affirmer que le bogue Heartbleed est une manifestation du problème de vérification de la longueur de la mémoire tampon C?

  2. Pourquoi l’utilisation malveillante n’a-t-elle pas causé une erreur de segmentation lorsqu’elle a tenté de lire la mémoire d’une autre application?

  3. Est-ce que le fait de simplement mettre à zéro la mémoire avant d’écrire (puis de la lire par la suite) aurait provoqué une erreur de segmentation? Ou cela varie-t-il entre les systèmes d’exploitation? Ou entre un autre facteur environnemental?

  4. Apparemment, les exploitations du bug ne peuvent pas être identifiées. Est-ce parce que la fonction de pulsation ne se connecte pas lorsqu’elle est appelée? Sinon, toute requête pour une chaîne de ~ 64k risque d’être malveillante.

Ai-je raison d’affirmer que le bogue Heartbleed est une manifestation du problème de vérification de la longueur de la mémoire tampon C?

Oui.

Le bug heartbleed est-il une manifestation de l’exploit classique de débordement de tampon en C?

Non. Le dépassement de tampon “classique” est celui où vous écrivez plus de données dans un tampon alloué par stack qu’il ne peut en contenir, où les données écrites sont fournies par l’agent hostile. Les données hostiles débordent de la mémoire tampon et écrasent l’adresse de retour de la méthode en cours. Lorsque la méthode se termine, elle retourne ensuite à une adresse contenant le code choisi par l’attaquant et commence à l’exécuter.

Au contraire, le défaut heartbleed n’écrase pas un tampon et n’exécute pas de code arbitraire; il lit simplement les limites du code dans lequel il est fort probable que des données sensibles se trouvent à proximité en mémoire.

Pourquoi l’utilisation malveillante n’a-t-elle pas causé une erreur de segmentation lorsqu’elle a tenté de lire la mémoire d’une autre application?

Il n’a pas essayé de lire la mémoire d’une autre application. L’exploit lit la mémoire du processus en cours, pas un autre processus.

Pourquoi l’utilisation malveillante n’a-t-elle pas causé une erreur de segmentation lorsqu’elle a tenté de lire la mémoire en dehors des limites du tampon?

Ceci est un duplicata de cette question:

Pourquoi cela ne donne-t-il pas une faute de violation de segmentation?

Une erreur de segmentation signifie que vous avez touché une page que le gestionnaire de mémoire du système d’exploitation ne vous a pas alloué. Le bogue ici est que vous avez touché des données sur une page valide que le gestionnaire de tas ne vous a pas alloué . Tant que la page est valide, vous n’obtiendrez pas de erreur de segmentation. Généralement, le gestionnaire de tas demande au système d’exploitation un gros morceau de mémoire, puis le répartit entre différentes allocations. Toutes ces affectations sont alors sur des pages de mémoire valides en ce qui concerne le système d’exploitation.

Le déréférencement de null est une erreur de segmentation simplement parce que le système d’exploitation ne fait jamais de la page valide la page contenant le pointeur zéro.

Plus généralement: le compilateur et le moteur d’exécution ne sont pas obligés de s’assurer qu’un comportement non défini entraîne un segfault; UB peut entraîner n’importe quel comportement, y compris ne rien faire. Pour plus de reflections sur ce sujet, voir:

Peut-on accéder à la mémoire d’une variable locale en dehors de sa scope?

Pour les deux, je me suis plaint qu’UB devait toujours être l’équivalent d’une erreur de segmentation dans un code critique pour la sécurité, ainsi que de quelques pistes pour une discussion sur l’parsing statique de la vulnérabilité, voir l’article du blog d’aujourd’hui:

http://ericlippert.com/2014/04/15/heartbleed-and-static-analysis/

Est-ce que le fait de simplement mettre à zéro la mémoire avant d’écrire (puis de la lire par la suite) aurait provoqué une erreur de segmentation?

Peu probable. Si lire hors des limites ne cause pas de erreur de segmentation, il est peu probable que l’écriture en dehors des limites. Il est possible qu’une page de mémoire soit en lecture seule, mais dans ce cas, cela semble peu probable.

Bien sûr, les conséquences ultérieures de la remise à zéro de toutes sortes de mémoire que vous ne devriez pas commettre sont des erreurs de segmentation partout dans la série. S’il y a un pointeur dans cette mémoire mise à zéro que vous déréférencerez plus tard, c’est le déréférencement de null qui produira une erreur de segmentation.

cela varie-t-il entre les systèmes d’exploitation?

La question est vague. Permettez-moi de reformuler.

Différents systèmes d’exploitation et différentes bibliothèques d’exécution C / C ++ proposent-ils des stratégies différentes pour allouer de la mémoire virtuelle, allouer de la mémoire de segment de mémoire et identifier le moment où l’access à la mémoire sort des sentiers battus?

Oui; des choses différentes sont différentes .

Ou entre un autre facteur environnemental?

Tel que?

Apparemment, les exploitations du bug ne peuvent pas être identifiées. Est-ce parce que la fonction de pulsation ne se connecte pas lorsqu’elle est appelée?

Correct.

sûrement toute demande pour une chaîne de ~ 64k est susceptible d’être malveillante?

Je ne suis pas votre train de pensée. Ce qui rend la demande probablement malveillante est une discordance entre les octets envoyés et les octets dont l’écho doit être répercuté, et non la taille des données dont l’écho est demandé.

Une erreur de segmentation ne se produit pas car les données auxquelles on accède sont directement adjacentes aux données demandées et se trouvent généralement dans la mémoire du même processus. Cela pourrait provoquer une exception si la demande était suffisamment volumineuse, je suppose, mais cela n’est pas dans l’intérêt de l’exploitant, puisqu’un échec du processus les empêcherait d’obtenir les données.

Pour une explication claire, il est difficile d’améliorer cette bande dessinée XKCD :

entrez la description de l'image ici