Quali sono i rischi / le vulnerabilità di sicurezza di cui ogni programmatore C deve essere a conoscenza? [chiuso]

11

Ci sono molti rischi per la sicurezza derivanti dall'avere contatti ravvicinati con l'hardware piuttosto che utilizzare API collaudate e provate da linguaggi di programmazione di alto livello. È molto più facile causare un overflow del buffer in C rispetto a un linguaggio come Java.

Quali sono i rischi o le vulnerabilità (ad es. buffer overflow) di cui ogni programmatore C dovrebbe essere a conoscenza (vulnerabilità I.E. rilevanti per i programmatori C)? A quali problemi potrebbero portare? Come evitarli e quali sono gli errori più comuni che causano questi problemi nei programmi?

    
posta Anto 27.04.2011 - 19:20
fonte

4 risposte

13

Gli overflow del buffer sono grandi. Nulla in C viene controllato in base all'impostazione predefinita, quindi è molto semplice sovrascrivere un buffer. Esiste una funzione di libreria standard, gets() , che non può essere interrotta a causa del sovraccarico del buffer e non dovrebbe quasi mai essere utilizzata.

Esistono alcune tecniche a livello di implementazione per ostacolare lo sfruttamento, come scrambling heap blocks, ma ciò non fermerà il buffer overflow nei buffer locali, che spesso possono fare cose interessanti come cambiare l'indirizzo a cui una funzione ritornerà.

Non c'è una buona soluzione generale in C. Molte funzioni di libreria hanno versioni che limiteranno la quantità che scriveranno. anche se il calcolo può essere goffo. Esiste un software in grado di rilevare gli overflow del buffer heap durante il test, a condizione che venga eseguito il test appropriato e che l'overflow dello stack spesso si verifichi come un arresto anomalo nei test. Oltre a questo, è una questione di attenta codifica e revisione del codice.

Un problema correlato è il problema di scrivere in un buffer troppo piccolo di un carattere, dimenticando che una stringa C che ha n caratteri richiede n + 1 caratteri in memoria, a causa del terminatore 'printf()' . Se l'utente malintenzionato riesce a memorizzare una stringa senza il terminatore, qualsiasi funzione C in attesa di una stringa continuerà a essere elaborata fino a raggiungere un byte zero, che potrebbe comportare la copia o l'output di più informazioni di quanto desiderato (o la memoria protetta per un attacco DOS ). La soluzione, ancora una volta, è la consapevolezza, la cura e la revisione del codice.

C'è un altro rischio con la famiglia char * str; ... printf(str); . Se scrivi mai str , ti stai preparando per i problemi se %n contiene un '%' quando stampato. La direttiva di formato printf() consente a printf("%s", str); di scrivere in memoria. La soluzione è puts(str); o snprintf() . (Inoltre, usa il C99 sprintf() invece di strncpy() .)

L'utilizzo di numeri interi non firmati, in particolare come indici di loop, può causare problemi. Se assegni un piccolo valore negativo a un non firmato, ottieni un valore positivo elevato. Ciò può minare cose come l'elaborazione di solo N istanze di qualcosa o in funzioni limitate come unsigned short . Esamina tutti gli interi senza segno. Potresti voler evitare int , poiché un valore elevato in uno di questi convertirà in un valore positivo elevato in int .

Non dimenticare che una costante di carattere, in C, è in realtà un char c; while((c = getchar()) != EOF) ... . Scrivere qualcosa come EOF può facilmente fallire, poiché char non sarà rappresentabile in %code% .

Ci sono molti più errori C caratteristici che posso pensare, ma questi potrebbero causare problemi di sicurezza.

    
risposta data 27.04.2011 - 20:16
fonte
5

Alcuni dei rischi specifici di C includono: buffer overflow , attacco di stringhe di formattazione e integer overflow .

    
risposta data 27.04.2011 - 19:34
fonte
4

Ecco un rischio facile da perdere che può causare problemi che richiedono ore per risolverlo.

Considera il seguente codice, che verrà compilato senza problemi.

if(lpstr_current_state = CONST_EMERGENCY_STATE_HOLY_CRAP)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

Quando controlli di vedere se lpstr_current_state è in CONST_EMERGENCY_STATE_HOLY_CRAP in realtà stai assegnando. È meglio mettere sempre la variabile costante a sinistra. Quando metti la costante a sinistra, il compilatore fallirà perché non puoi assegnare un valore a una variabile.

if(CONST_EMERGENCY_STATE_HOLY_CRAP = lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

Quindi puoi facilmente dire a te stesso, "Santo schifo, che avrebbe potuto essere cattivo", mentre fissava il codice da leggere ...

if(CONST_EMERGENCY_STATE_HOLY_CRAP == lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}
    
risposta data 27.04.2011 - 19:29
fonte
0

C'è solo un uno rischio di sicurezza: il fatto che ci siano persone esterne che faranno del loro meglio per cogliere eventuali vulnerabilità nel tuo software e sfruttarlo per il proprio guadagno. Tutto il resto segue da lì.

Quindi quando pensi che "nessuno sano di mente ...", allora devi pensare immediatamente "eccetto che qualcuno che vuole hackerare nei computer degli altri farebbe esattamente questo".

La più grande conseguenza è che ogni volta che reagisci agli eventi esterni (ad esempio, elaborando i dati forniti dall'esterno), devi presupporre che questi dati siano sotto il controllo del tuo peggior nemico.

    
risposta data 12.01.2016 - 10:31
fonte

Leggi altre domande sui tag