Potrebbero esserci ancora buffer overflow in es .: C?

-1

Recentemente ho letto sull'argomento $.

D: Perché un linguaggio di programmazione ha insicurezza insignificante? O .. era solo nei vecchi tempi? Come potrebbe essere?

    
posta gasko peter 29.08.2013 - 10:24
fonte

3 risposte

3

C è stato progettato in un momento in cui la potenza della CPU disponibile era una risorsa scarsa e anche la programmazione era molto inferiore. I tempi moderni hanno cambiato il contesto:

  • Al giorno d'oggi, la maggior parte del tempo di elaborazione in una CPU viene spesa in attesa di RAM, poiché la velocità della CPU è aumentata molto più rapidamente della diminuzione della latenza della RAM. Quindi la CPU ha un po 'di "tempo libero" e quindi può permettersi controlli extra, ad es. controlli ai limiti sugli array.

  • Di questi tempi si fa molta più programmazione, il che significa che sono coinvolti molti più programmatori e la competenza media è quindi, meccanicamente, diminuita.

  • La competenza media dell'attore , d'altra parte, è abbastanza aumentata. Gli exploit di overflow del buffer sono passati, dagli anni '70, da "debolezza teorica" a "attacco generico che può essere regolato automaticamente e programmato".

Questo è il motivo per cui quasi tutti i linguaggi di programmazione più recenti includono "protezioni" intrinseche contro il buffer overflow, ma anche attacchi di cross-typing (quando alcuni byte sono fatti per essere interpretati con un tipo diverso, ad esempio facendo in modo che un codice consideri un intero come se fosse era un puntatore) e problemi di allocazione della memoria ("use-after-free"). Per buffer overflow, la protezione è duplice:

  • Le lingue più recenti offrono gestione automatica della memoria , che consente di gestire stringhe di caratteri come valori immutabili. Ciò rimuove un sacco di occasioni per un programmatore disattento per consentire il verificarsi di un buffer overflow.
  • Gli accessi alla memoria sono limitati a verificarsi solo con gli oggetti matrice correttamente digitati, che applicano controlli sistematici sui limiti dell'array. Quando si verifica un overflow del buffer, viene emessa un'eccezione invece di che consente l'overflow effettivo dei dati. Questo è ancora un bug, che può causare l'arresto anomalo dell'applicazione, ma questo non consente più l'esecuzione di codice arbitrario.

Sfortunatamente, tali protezioni non possono essere genericamente trasferite su C. Ad esempio, la specifica C consente di scrivere un valore di puntatore in un file e poi, in seguito, di leggerlo di nuovo e il puntatore DEVE essere ancora valido. È matematicamente impossibile scrivere un garbage collector in grado di gestire questo caso. Lì è un GC per C e C ++ , ma (per sua natura) non può davvero supportare ogni programma C "legale".

In altre parole, se "modifichi" C in modo che sia più robusto contro i buffer overflow, allora non è più "C", ma qualcos'altro (che potresti chiamare "Java" o "C #"). Il C originale è ancora ampiamente utilizzato, a volte per una buona ragione tecnica (ad esempio per scrivere codice su una piattaforma molto piccola, come una smart card), ma soprattutto per tradizione e per una più facile integrazione con tutte le librerie esistenti.

    
risposta data 29.08.2013 - 16:18
fonte
2

C è un linguaggio semplice che è abbastanza facile da tradurre in Assembly / Machine Language (rispetto ai linguaggi moderni) quando si trascurano le ottimizzazioni.

C non è tanto incrinato dalle insicurezze, ma solo C non ti obbliga a fare sempre le cose in un modo più sicuro come in altre lingue moderne. Un programma eseguito su un Bell Labs PDP-10 negli anni '70 da ingegneri esperti aveva requisiti diversi rispetto a un moderno server web connesso a Internet che poteva essere attaccato da abili avversari. Allora, volevi che il linguaggio fosse veloce e semplice e che così tanti controlli di sanità fossero lasciati al programmatore.

Una delle parti "insicuri" principali di C è la mancanza di controllo dei limiti. Se vuoi copiare una stringa di caratteri in un nuovo array, la funzione strcpy copierà una stringa da un buffer ad un altro buffer finché non vedrà un byte NULL che indica la fine della prima stringa. Ciò consente attacchi di buffer overflow se si tenta di spremere 500 caratteri di input in un buffer da 256 byte (il programma continuerà a copiare fino a raggiungere il carattere null). La memoria successiva a quella stringa potrebbe aver avuto dati importanti per l'esecuzione dei programmi, consentendo eventualmente a un utente malintenzionato di immettere nuovi comandi a livello macchina nel programma. Tuttavia, ci sono modi più sicuri per programmare all'interno di C, ad esempio, usa strlcpy che prende come parametro la dimensione del buffer di destinazione e copia solo fino a quel numero di caratteri (e quindi null termina la stringa).

(Inoltre, i moderni sistemi operativi forniscono aiuto attraverso funzionalità come la non esecuzione, i bit senza scrittura e la randomizzazione del layout dello spazio degli indirizzi.)

Certo, è ancora possibile che i programmatori commettano errori.

    
risposta data 29.08.2013 - 14:52
fonte
2

Quando C fu progettato nei primi anni '70, furono diversi tempi.

  • I sistemi di solito erano solo parte di reti piccole, affidabili o non collegate in rete.
  • Stavano raramente elaborando dati da fonti sconosciute
  • L'hardware era lento e costoso

A causa di queste circostanze, le prestazioni elevate erano molto più preoccupanti della sicurezza. Ecco perché C omette molti controlli di integrità sulle operazioni e si aspetta che i programmatori li implementino quando ne sentono il bisogno e possono risparmiare le risorse che costa.

Ma al giorno d'oggi, la situazione è cambiata

  • È difficile trovare un sistema che non in qualche modo sia connesso a Internet
  • I sistemi interagiscono spesso con utenti non fidati o addirittura anonimi
  • I programmi elaborano le informazioni ottenute da fonti non attendibili e potenzialmente dannose.
  • Anche le applicazioni diventano sempre più complesse, lasciando più spazio per errori critici per la sicurezza.

D'altro canto, le risorse hardware sono diventate molto più abbondanti. I più grandi supercomputer degli anni '70 avevano una potenza di elaborazione che era di diverse grandezze inferiore a quella dei telefoni cellulari di oggi.

Per questi motivi, l'attenzione dei linguaggi di programmazione si è spostata dall'efficienza alla sicurezza.

    
risposta data 29.08.2013 - 15:40
fonte

Leggi altre domande sui tag