Come spiegare l'overflow del buffer a un profano

51

Ogni tanto (quando penso a voce alta e le persone mi ascoltano) sono costretto a spiegare cos'è un overflow del buffer. Poiché non riesco davvero a pensare a una buona metafora, finisco per spendere circa 10 minuti per spiegare come funzionano i programmi (vulnerabili) e l'allocazione della memoria, e quindi avere circa 2 frasi sull'effettivo exploit ("così un buffer overflow riempie il buffer con sciocchezze e sovrascrive il puntatore per puntare a ciò che voglio che punti a "). A questo punto, la maggior parte delle persone si è suicidata ... Qual è un buon modo per spiegare un eccesso di buffer ai profani? Se possibile, ti preghiamo di includere un componente "overflow", ma anche di inserire il motivo per cui questo significa che l'attaccante può ottenere ciò che vuole. Ricorda, le persone dell'intelligenza media (e al di sotto della media) dovrebbero essere in grado di farsi un'idea di ciò di cui sto parlando, quindi mentre dovresti assolutamente sentirti libero (incoraggiato, in realtà) a spiegare che ogni parte della tua metafora (analogia?) Rappresenta , non fare affidamento su descrizioni super-tecniche ...

PS, una domanda correlata che spiega in termini tecnici cosa fa l'overflow del buffer: Che cos'è un buffer overflow?

    
posta KnightOfNi 22.03.2014 - 00:57
fonte

7 risposte

109

Immagina di avere una lista di persone a cui devi dei soldi.

Inoltre,haiunastranapennaconunfluidodicorrezioneincorporato,inmodochesescriviqualcosainunpuntoparticolareepoiscriviqualcos'altro,cancellalaprimacosachehaiscritto.Eccocomefunzionalamemoriadelcomputer,cheèunpo'diversadacomefunzionanormalmentelascrittura.

Paghiaqualcunoundepositodi$500suun'autoda$5000,quindioradeviloro$4500.TidiconocheilloronomeèJohnSmith.Scrivil'importo(4500)eilnome(JohnSmith)nellatabella.Latuatabellaoraapparecosì:

Più tardi il tuo tavolo ti ricorda di restituirli. Paghi $ 4500 (più interessi) e cancellalo dalla tabella, quindi ora la tua tabella è di nuovo bianca.

Quindi ricevi un prestito di $ 1000 da qualcun altro. Ti dicono che il loro nome è "John Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx999999999999". Scrivi la somma (1000) e il nome (John Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9999999999) nella tabella. La tua tabella ora appare così:

(l'ultimo0da1000nonèstatoscrittosopra.Questononèimportante.)

Durantelascritturadelnome,nontiseifermatoquandoseiarrivatoallafinedellacolonna"nome" e hai continuato a scrivere nella colonna "importo dovuto"! Questo è un buffer overflow.

Successivamente, la tabella ti ricorda che devi $ 99999999990 a John Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Lo trovi di nuovo e gli paghi quasi 100 miliardi di dollari.

    
risposta data 22.03.2014 - 03:00
fonte
15

L'idea di utilizzare più spazio di quello che ti è stato dato, e quindi riversare in un campo diverso è abbastanza semplice da visualizzare. Ma probabilmente non è chiaro come questo possa portare a un cattivo ragazzo che esegue il proprio codice.

Questo è abbastanza semplice da spiegare se lo capisci abbastanza bene. Assicurati di colpire sullo sfondo importante. Più o meno in questo ordine:

  • Lo "stack" è un luogo in cui è possibile memorizzare informazioni temporanee. Il "puntatore dello stack" determina dove si trova la fine della pila. Quando una funzione viene eseguita, sposta il puntatore dello stack per darsi da solo la memoria con cui lavorare e, una volta terminato, sposta il puntatore sul punto in cui è stato trovato.

  • Lo stack cresce all'indietro. Quindi, per darti 100 byte nello stack, sottrarre 100 dal puntatore dello stack piuttosto che aggiungerlo. Se lo stack della funzione precedente è iniziato a 1000 e voglio 100 byte, il mio stack inizia a 900.

  • Ciò significa che se usi più spazio di quello che hai dato tu stesso, non continuerai a scrivere nello spazio vuoto, in realtà inizierai a sovrascrivendo i precedenti valori dello stack.

  • Quando inizia la mia funzione, il valore massimo rimasto nella pila per me dalla funzione precedente è indirizzo di ritorno dove dovrei andare quando la mia funzione è terminata.

  • Questo significa che se la mia funzione supera il suo stack, la prima cosa che sta per sovrascrivere è l'indirizzo di ritorno. Se l'attaccante è attento a ciò con cui riempie la pila, può specificare qualsiasi indirizzo di ritorno che desidera.

  • Quando esiste la mia funzione, qualunque codice si trovi in quell'indirizzo di ritorno è ciò che verrà eseguito successivamente.

Esempio semplice

In Smashing the Stack for Fun and Profit , dove questa tecnica è stata originariamente descritta, la più semplice e diretta la tecnica è stata introdotta. Immagina che la funzione legga il tuo nome e poi ritorni. Quindi lo stack è simile a questo:

Stack Pointer                                      Prev. Stack Ptr
+----------------------------------+--------------+................
| Your Name Here                   | Return Addr  |  Old stack ...
+----------------------------------+--------------+................

Ma il cattivo si fa il nome abbastanza a lungo da traboccare lo spazio. E non solo, invece di digitare un vero nome, digita un codice malvagio, un po 'di padding e l'indirizzo di quel codice malvagio.

+----------------------------------+--------------+................
| [ Evil Code ]xxxxxxxxxxxxxxxxxxxxxxEvil Address |  Old stack ...
+----------------------------------+--------------+................
  ▲──────────────────────────────────┘

Ora invece di tornare al precedente chiamante, vai direttamente a [Evil Code] . Ora stai eseguendo il suo codice invece del tuo programma. Da lì è praticamente game over.

Mitigazione e altre tecniche

Due delle tecniche utilizzate per ridurre l'efficacia dello smash stack sono DEP e ASLR.

DEP ("Data Execution Prevention") funziona contrassegnando lo stack non eseguibile. Ciò significa che [Evil Code] sullo stack non verrà eseguito, poiché il codice in esecuzione nello stack non è più consentito. Per aggirare questo problema, l'attaccante trova frammenti di codice esistente che farà pezzi di ciò che vuole. E invece di sovrascrivere il proprio indirizzo di ritorno, crea una catena di indirizzi di ritorno attraverso lo stack per tutte le funzioni che desidera eseguire a turno. Chiamano questa "programmazione orientata al rendimento" o ROP. La catena di rendimenti è chiamata "catena ROP". Questo è davvero difficile da fare. Ma ci sono strumenti per aiutare.

ASLR ("Randomizzazione dello spazio degli indirizzi") funziona randomizzando le posizioni di tutte le funzioni interessanti. La creazione di una catena ROP non è così semplice: ogni volta che si esegue il programma, tutti gli indirizzi si trovano in luoghi diversi. Quindi, quando l'autore dell'attacco va a sovrascrivere l'indirizzo di ritorno con il proprio indirizzo malvagio, non saprà quali numeri usare perché il codice è sempre in posti diversi.

Né DEP né ASLR da solo offrono molta protezione, ma entrambi rendono lo sfruttamento molto difficile. Mentre alcune volte esistono alcune circostanze, non esiste una soluzione alternativa che funzioni ovunque . Se riesci a superare DEP + ASLR, è un successo unico.

    
risposta data 22.03.2014 - 05:35
fonte
3

Ci proverò senza utilizzare alcuna analogia.

Un computer è fondamentalmente tutta memoria, questa è la parte importante, i contenuti della memoria sono istruzioni, che dicono al computer cosa fare e dati, che le istruzioni usano e possono usare o modificare. Spesso è necessario memorizzare i dati che hanno una lunghezza variabile. Ad esempio, se un programma deve tenere traccia dell'indirizzo email di qualcuno che potrebbe essere molto breve ([email protected]) o molto lungo ([email protected]). Alcuni programmi non tengono traccia della lunghezza massima dei loro record di dati molto bene. Quindi, se un programma è stato progettato con un massimo di, ad esempio, 100 caratteri per un indirizzo e-mail e qualcuno gli ha fornito un indirizzo e-mail con più di 100 caratteri, il programma continuerà a scrivere il resto dell'indirizzo in memoria oltre la fine del suo pre spazio allocato La parte importante da ricordare è che la memoria è tutto, il programma stesso è in memoria proprio accanto ai record di dati.

Qualcuno che sapeva esattamente come funzionava questo programma poteva dargli un indirizzo email molto elaborato che era molto lungo e aveva caratteri speciali alla fine. L'idea era che quando il programma memorizzava l'indirizzo e-mail in memoria scriveva quei caratteri speciali in una parte della memoria dove il programma pensava che fossero altre parti di se stesso, e poi quando eseguiva quelle parti avrebbe invece eseguito qualsiasi cosa programmare quei caratteri speciali tradotti in, nel codice del computer. In questo modo sarebbe possibile per qualcuno ottenere che il computer eseguisse tutto ciò che volevano, semplicemente creando con cura i dati che davano al programma.

    
risposta data 24.03.2014 - 15:37
fonte
2

Le altre risposte sono ancora piuttosto tecniche, quindi le sto offrendo.

Immaginiamo che tu abbia una scuola materna. Ci sono dei fori per ogni studente in cui inserire le scarpe. Ogni buca contiene una scarpa. Quindi, per ogni studente, fornisci due buche.

A ogni studente vengono assegnati due cubicoli adiacenti. L'insegnante chiama quindi gli studenti a caso per mettere le scarpe nei fori del cubo a cui sono assegnati.

Quando l'insegnante richiama Bad Billy Bad Billy vuole pasticciare con Stupid Sally . I cubby di Billy sono numeri 5 e 6 e Sally sono numeri 7 e 8 . Billy mette i suoi spettacoli in 5 e 6 e poi trabocca il limite definito e inserisce un rospo viscido in il numero di cubby di Sally 7 .

Poiché l'insegnante non applica alcuna protezione sul limite definito per l'utilizzo dei cubby nell'ordine adiacente, Billy è in grado di oltrepassare il limite e interferire con lo spazio di Sally . Ora quando Sally va a prendere la sua scarpa, otterrà un rospo viscido invece yuck!

+-------------------+--------------------+-------------------+--------------------+
|      CUBBY 5      |       CUBBY 6      |      CUBBY 7      |       CUBBY 8      |
+-------------------+--------------------+-------------------+--------------------+
|                   |                    |                   |                    |
| Billy's Left Shoe | Billy's Right Shoe | Sally's Left Shoe | Sally's Right Shoe |
+-------------------+--------------------+-------------------+--------------------+

Billy inserisci tre elementi in cui è definito che dovrebbe inserire solo 2, questo è il modo in cui un overflow dello stack funziona a un livello elevato, qualcuno sta scherzando con lo storage per il quale non sono autorizzati e quindi quando la memoria viene letta, non è quello che ti aspettavi.

+-------------------+--------------------+------------+--------------------+
|      CUBBY 5      |       CUBBY 6      |   CUBBY 7  |       CUBBY 8      |
+-------------------+--------------------+------------+--------------------+
|                   |                    |            |                    |
| Billy's Left Shoe | Billy's Right Shoe | Slimy Toad | Sally's Right Shoe |
+-------------------+--------------------+------------+--------------------+

Un buffer overflow avrebbe potuto essere prevenuto se l'insegnante prestasse più attenzione e assicurasse che ogni studente usasse solo la quantità di memoria che ci si aspettava.

    
risposta data 22.03.2014 - 16:48
fonte
1

Buona domanda. Ecco un'analogia che non è la più accurata dal punto di vista tecnico, ma dovrebbe avere l'idea.

Immagina un ricettario su carta perforata a 3 fori in un raccoglitore (memoria) e un cuoco molto stupido (il processore, cioè la CPU).

  • Le persone possono aggiungere o rimuovere pagine dal raccoglitore (caricare o scaricare programmi e dati in memoria)
  • Il cuoco segue tutte le istruzioni sulla pagina in cui si trovano
  • Il cuoco inizia all'inizio (bootloader) e continua fino a quando l'istruzione non è "close book"
    • Anche se l'istruzione è di passare a un'altra pagina (Vai a pagina 394)

Quindi, normalmente, scriveresti alla prima pagina "Vai a pagina 200 (waffle)", apri il raccoglitore e inserisci i waffles a pagina 200. Quindi avvia il cuoco - il cuoco dovrebbe preparare dei waffles!

Ma aspetta ... c'è un attaccante! Hanno scritto note a margine della tua ricetta waffle (fuori dal buffer) e il cuoco esegue queste istruzioni anche se sono ovviamente scritte a mano.

Al cuoco non è mai stato detto di fare solo ciò che è stampato sul foglio originale (nel normale spazio del buffer) - anche il cuoco farà qualcosa dopo quello (in memoria dopo il buffer).

Forse il cuoco aggiunge l'aceto alle cialde (corrompe i tuoi file). Forse il cuoco gira a pagina trecentonovantaquattro e lascia l'uovo crudo seduto lì, inutilizzato, finché non marcisce e si placa (spegne il tuo antivirus). Forse il cuoco butta via tutto in cucina (cancella tutti i file), o mette un lucchetto sulla porta della cucina per tenerti fuori (ransomware), o apre la finestra (installa un trojan / backdoor) in modo che l'attaccante possa arrampicarsi nel finestra.

    
risposta data 22.03.2014 - 03:07
fonte
1

Lo spiego sempre come se stessi scoppiando un secchio. Il secchio è lì per proteggere i contenuti dall'esterno e viceversa, ma stai usando i contenuti per arrivare all'esterno del bucket, e quindi accedere alle aree del sistema a cui non dovresti altrimenti avere accesso.

    
risposta data 24.03.2014 - 20:36
fonte
0

Come si fa?

I dati in un computer sono memorizzati come una lunga lista di numeri, come i brani di un musicassetto. A differenza della musica, che viene riprodotta dall'inizio alla fine, i computer devono saltare da una traccia all'altra, quindi hanno bisogno di un 'elenco delle tracce' per dire loro dove inizia ciascuna.

Gli elenchi traccia sono facili per la musica, poiché ogni canzone ha una lunghezza nota. Con un computer, la quantità di dati che dobbiamo memorizzare potrebbe non essere ancora nota, ad esempio se arriva da Internet. Se la traccia che stiamo utilizzando si riempie, dobbiamo passare a una diversa, non usata. Se non lo facciamo, per esempio se assumiamo erroneamente che non ci sarà mai data più di una certa quantità di dati, potremmo consumare troppo nastro e "registrare" la traccia successiva. Quando un programma prova a leggere la traccia successiva, recupererà parte dei nostri dati invece di qualsiasi cosa ci fosse prima.

Questo può essere pericoloso, perché i dati sovrascritti potrebbero essere stati un insieme di istruzioni da eseguire. In tal caso, il computer eseguirà le istruzioni scaricate direttamente da Internet!

    
risposta data 24.03.2014 - 15:53
fonte

Leggi altre domande sui tag