web-dev-qa-db-fra.com

En quoi printf () en C / C ++ est-il une vulnérabilité de débordement de tampon?

Selon un article que je viens de lire, les fonctions printf et strcpy sont considérées comme des failles de sécurité dues aux débordements de tampon. Je comprends comment strcpy est vulnérable, mais est-ce que quelqu'un pourrait expliquer comment/si printf est vraiment vulnérable, ou je comprends mal.

Voici l'article: https://www.digitalbond.com/blog/2012/09/06/100000-vulnerabilities/#more-11658

L'extrait spécifique est:

Le vendeur avait mécaniquement recherché le code source et trouvé quelque 50 000 utilisations étranges de fonctions de bibliothèque C capables de débordement de tampon telles que "strcpy ()" et "printf ()".

Merci!

14
DarkMantis

Il est possible d'avoir des problèmes avec printf(), en utilisant comme chaîne de format un argument fourni par l'utilisateur, c'est-à-dire printf(arg) au lieu de printf("%s", arg). Je l'ai vu faire trop souvent. Comme l'appelant n'a pas poussé d'arguments supplémentaires, une chaîne contenant des spécificateurs % Parasites peut être utilisée pour lire tout ce qui se trouve sur la pile, et avec %n Certaines valeurs peuvent être écrites en mémoire (%n signifie: "l'argument suivant est un int *; allez y écrire le nombre de caractères émis jusqu'ici).

Cependant, je trouve plus plausible que l'article que vous citez contienne une simple erreur typographique et signifie vraiment sprintf(), pas printf().

(Je pourrais également faire valoir qu'en dehors de gets(), il n'y a pas de fonction C intrinsèquement vulnérable; seules les fonctions qui doivent être utilisées avec care. Les remplacements soi-disant "sûrs" comme snprintf() ne résout pas réellement le problème; ils le cachent en remplaçant un débordement de tampon par une troncature silencieuse, ce qui est moins bruyant mais pas nécessairement meilleur.)

18
Tom Leek

En plus de la réponse de @Tom, je voudrais également vous guider vers les OWASP code review guidelines , où certains problèmes liés à l'utilisation de printf () sont mis en évidence et this answer à une question similaire sur le site Web cs.stackexchange.

6
Jor-el

Voici un exemple qui montre comment ce débordement peut vous aider. Imaginez que vous n'ayez pas accès aux membres privés (pwd par exemple) donc printf vous aidera à voir le contenu de cette variable

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

struct SecureLogin{
    SecureLogin(const char * login_)
    {
        strcpy(login,login_);
        strcpy(pwd,"ijk");//the user does not see this part of the source code as it is in a DLL
    }
    char login[8];
private:
    char pwd[8];

};


int main() {
    // your code goes here
    SecureLogin log("abc");
    printf("Pwd = %s\n",(&log.login[0])+8);
    // Pass a string address which is the base address of the login
    // field, but add 8 bytes, which skips onto the pwd field (we know
    // login is 8 bytes)
    return 0;
}

Production:

Pwd = ijk

3
Gabriel

Certaines directives printf (ie;% n) ont des effets secondaires sur les adresses trouvées sur la pile, donc les directives print peuvent être dangereuses, même si la sortie explicite est implémentée correctement.

2
ddyer