Desbordamiento de búfer - terminadores canarios

2

Estoy leyendo un artículo sobre protección de desbordamiento de búfer aquí .

Para canarios terminadores, sigo la parte de que si un terminador como un cero se usa para un canario, el atacante tendría un terminador en el desbordamiento, lo que causará que el desbordamiento se detenga, evitando el desbordamiento de la dirección de retorno. p>

Pero la siguiente oración no está clara:

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.

No puedo seguir este argumento.

¿Implica que el canario terminador puede ser anulado de alguna manera?

    
pregunta Jake 03.10.2014 - 21:46
fuente

1 respuesta

7

La idea básica de un canario terminador es que cuando un atacante intenta un desbordamiento de búfer, se ve obligado a sobrescribir el valor del canario. El programa puede entonces detectar que el canario ha cambiado de valor y tomar las medidas apropiadas.

El valor 0 es algo especial en programación: muchos lenguajes lo usan como marcador de fin de texto. Si un atacante intenta desbordar un búfer de texto, el uso de 0 como canary terminador significa que el ataque fallará: para evitar que cambie el canary, deben incluir un 0 en la entrada de gran tamaño en una ubicación que hará que se ignore casi todo el exceso de entrada.

Sin embargo, esto tiene un problema: si la entrada se trata como datos binarios en lugar de como texto, el hecho de que el canario tenga un valor fijo conocido significa que el atacante simplemente puede sobreescribir el canario consigo mismo, produciendo un indetectable desbordamiento.

Editar: ejemplos de código

/* 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);
}

En un ejemplo de la vida real, el compilador puede insertar automáticamente el código de verificación de canarios y canarios en lugar de hacerlo manualmente por el programador.

    
respondido por el Mark 03.10.2014 - 22:16
fuente

Lea otras preguntas en las etiquetas