¿Cómo protege el uso de enteros sin signo contra ataques de desbordamiento de enteros?

4

Para evitar problemas con el desbordamiento de enteros en C o C ++, algunas personas han sugerido usar enteros sin signo. ¿Cómo puede esto proteger contra posibles ataques de desbordamiento? ¿Un entero sin signo todavía no se desborda cuando se incrementa más allá de su valor máximo?

    
pregunta Fumerian Gaming 20.02.2017 - 22:32
fuente

1 respuesta

9

El uso de enteros sin signo no evita el desbordamiento. Una variable k -bit solo puede representar 2 valores k diferentes. No importa cómo interpretas los bits.

A lo que probablemente te refieres es al hecho de que el desbordamiento de enteros firmado en C y C ++ es comportamiento indefinido . Lo que significa que el estándar internacional C o C ++ no especifica ningún comportamiento del programa que active dicho desbordamiento. Ajustar el valor alrededor o causar una excepción en tiempo de ejecución son opciones válidas tanto como abrir un shell de explotación. (Por supuesto, ninguna implementación sensata optaría por la última opción. Pero un exploit puede ser posible a través de consecuencias adicionales). Además, el compilador puede optimizar basándose en el supuesto de que no se produce un desbordamiento firmado y podría, por ejemplo, optimizar controles de desbordamiento equivocados, como if (x + 3 < x) .

Para los enteros unsigned , por otro lado, los estándares internacionales C y C ++ requieren que el valor se ajuste como si fuera aritmética en un entero k -bit sin signo modulo 2 k . Esto significa que su programa puede confiar en el envoltorio y usarlo en su beneficio. (O dispararse en el pie).

Otros lenguajes como Java requieren un envolvente confiable también para enteros con signo. (Java ni siquiera tiene tipos de enteros sin signo).

Hablando de seguridad, la mayor amenaza planteada por el desbordamiento, sin embargo, es que la lógica de su aplicación no anticipa el entorno. Y este es un problema independientemente de si está utilizando tipos de enteros con o sin signo. Si la lógica de su aplicación supone que para una solicitud de n bytes, debe asignar un búfer de n + m bytes (para una pequeña constante m utilizado para, por ejemplo, contabilidad) y n es inferior a m por debajo del valor máximo que su entero puede contener, el wraparound causará su programa para asignar un búfer demasiado pequeño que, a su vez, será superado. Ahí va la hazaña.

Si desea estar seguro, en lugar de utilizar la aritmética de enteros sin signo en todo el proceso, le recomiendo que haga exactamente lo contrario: use signed aritmética de enteros y compile con UbSan . A menos que su computación sea pesada, tendrá solo una sobrecarga de tiempo de ejecución menor, pero si el evento no anticipado ocurre y su aplicación se desborda en un número entero, el código adicional agregado por el desinfectante eliminará su aplicación antes de que un atacante pueda explotarla. No se puede escribir un desinfectante similar para los tipos enteros sin signo que desbordan porque el estándar requiere un comportamiento bien definido para hacerlo y los programas confían legítimamente en él. Este es realmente un caso en el que un comportamiento indefinido en el idioma puede ayudar a que su aplicación more sea segura.

    
respondido por el 5gon12eder 21.02.2017 - 00:12
fuente

Lea otras preguntas en las etiquetas