it-swarm-eu.dev

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

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

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

Lo snippet specifico è:

Il fornitore aveva cercato meccanicamente il codice sorgente e trovato circa 50.000 usi dispari di funzioni di libreria C compatibili con buffer overflow come "strcpy ()" e "printf ()".

Grazie!

14
DarkMantis

È possibile avere problemi con printf(), usando come stringa di formato un argomento fornito dall'utente, ovvero printf(arg) anziché printf("%s", arg). L'ho visto fare troppo spesso. Dato che il chiamante non ha spinto argomenti extra, una stringa con alcuni specificatori spuri % Può essere usata per leggere qualunque 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à significa sprintf(), non printf().

(Potrei anche sostenere che a parte gets(), non esiste una funzione C intrinsecamente vulnerabile; solo funzioni che devono essere utilizzate con care. I cosiddetti sostituti "sicuri" 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.)

18
Tom Leek

Oltre alla risposta di @Tom, vorrei anche guidarti alle linee guida per la revisione del codice OWASP , in cui sono evidenziati alcuni problemi sull'uso di printf () e this answer a una domanda simile sul sito Web cs.stackexchange.

6
Jor-el

Ecco un esempio che mostra come questo overflow può aiutarti. Immagina di non avere accesso ai membri privati ​​(pwd per esempio), quindi printf ti aiuterà 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;
}

Produzione:

Pwd = ijk

3
Gabriel

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

2
ddyer