In che modo l'utilizzo di interi senza segno protegge dagli attacchi di overflow di interi?

4

Per evitare problemi con l'overflow di interi in C o C ++, alcune persone hanno suggerito di utilizzare numeri interi senza segno. Come può proteggere da possibili attacchi di overflow? Un numero intero senza segno non può ancora traboccare quando incrementato oltre il suo valore massimo?

    
posta Fumerian Gaming 20.02.2017 - 22:32
fonte

1 risposta

9

L'utilizzo di numeri interi senza segno non impedisce l'overflow. Una variabile k -bit può rappresentare solo 2 valori k . Non importa come interpretate i bit.

Ciò a cui probabilmente ti riferisci è il fatto che l'overflow firmato integer in C e C ++ è comportamento non definito . Ciò significa che lo standard internazionale C o C ++ non specifica alcun comportamento del programma che innesca tale overflow. Racchiudere il valore attorno o causare un'eccezione run-time sono opzioni valide tanto quanto aprire una shell di exploit. (Naturalmente, nessuna implementazione sana opterebbe per la seconda scelta, ma un exploit può diventare possibile con ulteriori conseguenze.) Inoltre, il compilatore può ottimizzare in base all'assunzione che l'overflow con segno non si verifichi e potrebbe, ad esempio, ottimizzare controlli di overflow errati come if (x + 3 < x) .

Per gli interi non firmati , d'altra parte, gli standard internazionali C e C ++ richiedono che il valore vada a capo come se l'aritmetica su un intero non firmato k -bit fosse fatta modulo 2 k . Ciò significa che il tuo programma può contare sul wraparound e usarlo a suo vantaggio. (O per spararsi nel piede.)

Altri linguaggi come Java richiedono un wraparound affidabile anche per interi con segno. (Java non ha nemmeno i tipi interi senza segno.)

A proposito di sicurezza, la più grande minaccia posta dall'overflow, tuttavia, è che la logica dell'applicazione non anticipa il wraparound. E questo è un problema indipendentemente dal fatto che si stiano utilizzando tipi di interi con segno o senza segno. Se la logica dell'applicazione presuppone che per una richiesta di n byte, è necessario allocare un buffer di n + m byte (per una piccola costante m usato per, diciamo, contabilità) e n sembra essere inferiore a m sotto il valore massimo che il tuo intero può contenere, wraparound causerà il tuo programma per allocare un buffer troppo piccolo che, a sua volta, sarà sovraccaricato. Ecco l'exploit.

Se vuoi essere sicuro, invece di usare l'aritmetica dei numeri interi senza segno, ti consiglio di fare l'esatto opposto: usa l'aritmetica dei numeri interi firmati e compila con UbSan . A meno che la vostra applicazione non sia pesantemente calcolata, avrà solo un leggero sovraccarico di runtime, ma se si verifica un evento imprevisto e l'applicazione supera un numero intero, il codice aggiunto dal disinfettante ucciderà la vostra applicazione prima che un malintenzionato possa sfruttarla. Un disinfettante simile per i tipi interi non firmati traboccanti non può essere scritto perché lo standard richiede un comportamento ben definito per farlo ei programmi si basano su di esso in modo legittimo. Questo è in realtà un caso in cui un comportamento non definito nella lingua può aiutare a rendere più sicuro la tua applicazione.

    
risposta data 21.02.2017 - 00:12
fonte

Leggi altre domande sui tag