Come è printf () in C / C ++ una vulnerabilità di overflow del buffer?

13

Secondo un articolo che ho appena letto, le funzioni printf e strcpy sono considerate vulnerabilità di sicurezza a causa di overflow del buffer. Capisco quanto strcpy sia vulnerabile, ma qualcuno potrebbe spiegare come / se printf è veramente vulnerabile, o sto solo capendo male.

Questo è l'articolo: link

Lo snippet specifico è:

The vendor had mechanically searched the source code and found some 50,000-odd uses of buffer-overflow-capable C library functions such as “strcpy()” and “printf().”

Grazie!

    
posta DarkMantis 09.10.2013 - 17:53
fonte

4 risposte

17

È possibile avere problemi con printf() , utilizzando come stringa di formattazione un argomento fornito dall'utente, cioè printf(arg) invece di printf("%s", arg) . L'ho visto fare troppo spesso. Dato che il chiamante non ha spinto argomenti extra, una stringa con alcuni specificatori spuri di % può essere usata per leggere qualsiasi cosa sia nello stack, e con %n alcuni valori possono essere scritti in memoria ( %n significa: "l'argomento successivo è un int * ; vai a scrivere lì il numero di caratteri emessi finora).

Tuttavia, trovo più plausibile che l'articolo che citi contenga un semplice errore tipografico, e in realtà significhi sprintf() , non printf() .

(Potrei anche obiettare che a parte gets() , non esiste una funzione C intrinsecamente vulnerabile, solo funzioni che devono essere usate con care . Le cosiddette sostituzioni "sicure" come snprintf() in realtà non risolve il problema, lo nasconde sostituendo un buffer overflow con un troncamento silenzioso, che è meno rumoroso ma non necessariamente migliore.)

    
risposta data 09.10.2013 - 18:54
fonte
5

Oltre alla risposta di @ Tom, vorrei anche guidarti alle Linee guida per la revisione del codice OWASP , dove alcuni problemi sull'uso di printf () sono evidenziati e questo rispondono a una domanda simile sul sito web cs.stackexchange.

    
risposta data 09.10.2013 - 19:08
fonte
3

Ecco un esempio che mostra come questo overflow può aiutarti. Immagina di non avere accesso ai membri privati (pwd per esempio) in modo che printf ti aiuti a vedere il contenuto di questa variabile

#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;
}

Output:

Pwd = ijk

    
risposta data 03.12.2014 - 22:18
fonte
2

Alcune direttive printf (cioè% n) hanno effetti collaterali sugli indirizzi trovati nello stack, quindi le direttive di stampa possono essere pericolose, anche se l'output esplicito è implementato correttamente.

    
risposta data 09.10.2013 - 19:15
fonte

Leggi altre domande sui tag