Come faccio a disinfettare e controllare i grandi numeri che verranno inviati a una libreria BigNum non gestita come GMP?

1

Ho bisogno di elaborare i dati inviati dagli utenti in un formato LargeNumber. Le mie scelte attuali sono

Poiché il trattamento di grandi numeri ha la possibilità di creare alcuni errori in virgola mobile e il codice non gestito ha la capacità di creare buffer overflow:

  • C'è qualcosa che posso fare per scansionare in modo proattivo e convalidare numeri grandi che verranno utilizzati in queste librerie?

  • Alcune operazioni sono più rischiose di altre? (mult vs add)

  • Alcune librerie sono migliori di altre? (Il codice gestito è più sicuro a causa del controllo dei limiti? .. ha importanza, è solo un numero?)

  • È anche possibile scansionare un numero elevato per casi insoliti che potrebbero causare un overflow? Cosa dovrei cercare?

posta random65537 05.03.2013 - 07:20
fonte

2 risposte

1

Un numero è un numero. Quando si tratta di numeri, ci sono tre passaggi:

  1. Decodifica i valori di una rappresentazione esterna (ad esempio un gruppo di byte che, nel tuo protocollo, seguono una determinata convenzione).
  2. Applicare operazioni matematiche sui valori.
  3. Codifica i risultati.

Gli overflow del buffer a causa di dati dannosi si verificano solo nelle fasi 1 e 3, e quindi molto raramente. Durante la fase 2, non ci sono problemi di questo tipo (se c'è è un overflow, allora è un bug nella libreria stessa, ma non si conoscono tali bug per le implementazioni esistenti - di regola, gli sviluppatori per le librerie matematiche sono maniache nel tracciare e distruggere i bug).

Come utente della libreria, devi occuparti delle seguenti due cose:

  • Quando codifica , non dare per scontato che il valore "si adatti ad una determinata lunghezza del buffer". Usa la libreria per vedere la lunghezza effettiva del valore.
  • Quando si usano molte moltiplicazioni, gli interi possono raggiungere dimensioni illimitate, portando a enormi allocazioni di memoria e un consumo elevato di CPU. Potresti voler controllare la lunghezza dei numeri interi in vari punti del tuo codice, per vedere se hai a che fare con valori che sono molto più grandi di quanto dovrebbero.

Ti suggerisco di iniziare con BigInteger (da .NET) perché è la più semplice ed è già lì. Immagina di passare a qualcos'altro solo se incontri un problema di prestazioni reali, debitamente misurato e quantificato.

(Non avrai alcun "errore in virgola mobile" quando usi gli interi, per definizione. Il punto mobile è un altro dominio.)

    
risposta data 05.03.2013 - 13:38
fonte
1

Come altri hanno già detto, la lettura / stampa è la principale area di rischio per i buffer overflow.

Tuttavia, è possibile utilizzare la libreria bignum per spruzzare l'heap. Ad esempio, MPIR / GMP usa una struttura bignum che assomiglia un po 'a questo:

typedef struct
{
    off_t count;
    mpn_limb_t* limbs;
} mpz+t;

Dove off_t descrive il numero di arti e il suo segno descrive il segno del numero complessivo. Quindi ogni mpn_limb_t viene tipizzato in dimensioni appropriate per la tua piattaforma.

Chiaramente, questo non può essere e non è assegnato allo stack, quindi stai praticamente scrivendo tutti questi numeri ( mpn_limb_t ) nell'heap, permettendoti di heap spray che non sfrutterà direttamente la libreria, ma potrebbe facilitare un altro exploit.

Il processo di sanitizzazione per questo è quello di non fidarsi di una serializzazione binaria del tuo numero, poiché ogni bit è usato per memorizzare il numero in forma grezza e metterlo in memoria che ti offre l'intera gamma di codici operativi. Hai davvero bisogno di leggere il numero da un formato leggibile dall'uomo, che sebbene meno efficiente, rende un po 'più difficile la produzione di shellcode utili (a meno che tu non possa scrivere qualcosa con gli opcode rappresentati dall'asci di 0-9, che dubito ).

L'aggiunta, la moltiplicazione ecc. "non possono" eccedere, nel senso che gmp / mpir almeno non riuscirà ad allocare memoria sufficiente per il% target% di co_de e si fermerà qui.

Ci dovrebbe essere (c'è sicuramente una funzione di stampa) una funzione per leggere gli interi dalla rappresentazione del testo. Mi piacerebbe che tu lo usassi e usassi la corrispondente funzione di stampa per l'output. Sarai quindi in grado di gestire numeri fino ai limiti imposti dalla tua memoria mentre non scrivi assurdità arbitrarie alla memoria. Potresti voler controllare la documentazione di queste funzioni per verificare il loro comportamento su caratteri non interi / decimali.

Le eccezioni a virgola mobile non dovrebbero essere causate da alcuna libreria float mp, perché la dimensione interna / rappresentazione del float in questione non può comunque essere gestita dal processore. Se dai un'occhiata agli algoritmi (vedi algoritmi per APFPA usati in questo tipo di codice, vedrai che usano le normali operazioni di virgola mobile di precisione. Qualsiasi libreria decente dovrebbe davvero garantire che non causino un'eccezione di virgola mobile quando si lavora su "arti".

    
risposta data 05.03.2013 - 14:12
fonte

Leggi altre domande sui tag