Buffer overflow - canister terminatore

2

Sto leggendo un articolo sulla protezione da sovraccarico del buffer qui .

Per i canidi di terminazione, seguo la parte che se un terminatore come uno zero viene utilizzato per un canarino, l'utente malintenzionato avrebbe un terminatore nell'overflow, che causerà l'interruzione dell'overflow, impedendo l'overflow dell'indirizzo di ritorno.

Ma la frase successiva non è chiara:

The undesirable result is that the canary is known. Even with the protection, 
an attacker could potentially overwrite the canary with its known value, and 
control information with mismatched values, thus passing the canary check code, 
this latter being executed soon before the specific processor's 
return-from-call instruction.

Non sono in grado di seguire questo argomento.

Ciò implica che il canarino del terminatore può essere ignorato in qualsiasi modo?

    
posta Jake 03.10.2014 - 21:46
fonte

1 risposta

7

L'idea di base di un terminatore è che quando un utente malintenzionato tenta un buffer overflow, è costretto a sovrascrivere il valore delle canarie. Il programma può quindi rilevare che il canarino ha cambiato valore e intraprendere le azioni appropriate.

Il valore 0 è un po 'speciale nella programmazione: molte lingue lo usano come marcatore di fine testo. Se un utente malintenzionato sta tentando di sovraccaricare un buffer di testo, l'uso di un 0 come un terminatore può significare che l'attacco fallirà: per impedire al canarino di cambiare, è necessario includere un 0 nell'input sovradimensionato in una posizione che causerà la quasi totalità dell'ingresso in eccesso da ignorare.

Questo ha un problema, tuttavia: se l'input è gestito come dati binari anziché come testo, il fatto che il canarino abbia un valore fisso noto significa che l'attaccante può semplicemente sovrascrivere il canarino con se stesso, producendo un non rilevabile trabocco.

Modifica: esempi di codice

/* This reads a length-tagged packet of up to 16 bytes length from an input stream.
 *
 * Note that since the programmer forgot to check the length of the input,
 * a packet of more than 20 bytes (give or take alignment) will overflow onto
 * sensitive parts of the stack.  If bytes 17 through 20 of the outsized packet
 * are 0s, this overflow won't be detected.
 */
size_t readPacket(char *stream)
{
    size_t length;
    char packet[16];
    uint32_t canary = 0;

    length = (size_t)(*stream++);
    memcpy(packet, stream, length);
    processPacket(packet, length);

    if(canary != 0)
        exit(0);
    return length;
}


/* This reads a username from an input stream.
 * 
 * Note that since the programmer used strcpy() rather than strlcpy(), a
 * string of more than 20 bytes (give or take alignment) will overflow onto
 * sensitive parts of the stack.  However, since strcpy() stops copying once
 * it encounters a byte with the value 0, in order for overflow to reach a 
 * sensitive part of the stack, it must change the value of the canary.  If
 * this happens, exit() is called and the changed stack is never used.
 */
size_t readName(char *stream)
{
    char userName[16];
    uint32_t canary = 0;

    strcpy(userName, stream);
    processUserName(userName);

    if(canary != 0)
        exit(0);
    return strlen(userName);
}

In un esempio di vita reale, i canarini e il codice di controllo del canarino possono essere inseriti automaticamente dal compilatore anziché manualmente dal programmatore.

    
risposta data 03.10.2014 - 22:16
fonte

Leggi altre domande sui tag