2010-05-26 20 views
16

¿Alguien tiene una explicación detallada sobre cómo se pueden explotar los enteros? He leído mucho sobre el concepto, y entiendo de qué se trata, y entiendo los desbordamientos de los búfers, pero no entiendo cómo se podría modificar la memoria de manera confiable, o de alguna manera modificar el flujo de aplicaciones, haciendo un número entero mayor que su memoria definida ...¿Cómo se puede explotar el desbordamiento de enteros?

+0

Un [posible exploit que no involucra matriz/manipulación de memoria] (http://news.cnet.com/8301-17852_3-57341753-71/man-wins-$57-million-casino-says-software-glitch /). El monto de su ganancia, 43 millones de euros sospechosamente está cerca de 2^32 = 4294967296 con el que todos estamos familiarizados, y sugerimos que el fallo puede ser causado por un flujo inferior entero. –

Respuesta

14

Definitivamente es explotable, pero depende de la situación, por supuesto.

Versiones anteriores ssh tenía un desbordamiento de entero que podía explotarse de forma remota. El exploit provocó que el daemon ssh creara una tabla hash de tamaño cero y sobrescribiera la memoria cuando intentaba almacenar algunos valores allí.

Más detalles sobre el desbordamiento de enteros: ssh http://www.kb.cert.org/vuls/id/945216

más detalles sobre desbordamiento de enteros: http://projects.webappsec.org/w/page/13246946/Integer%20Overflows

+4

+1 Más información aquí http://www.owasp.org/index.php/Integer_overflow – Shaji

+1

como el ejemplo explicado más abajo por Ira Baxter, tiene que ser una situación específica como esa - donde se sobrepasa/se fluye un número entero cuando asigna un hash/buffer/array que le permite acceder a la memoria a la que no debe tener acceso, luego tiene una manera de calcular FP, etc. – wuntee

+0

@wuntee: No creo que tenga sentido tratar de limitarlo así . Cada situación es diferente. ¡La gente ingeniosa encuentra formas que uno ni siquiera puede imaginar! Recuerdo que en netscape había un solo error de uno por uno que sobrescribía un solo byte con un espacio. ¡La gente pudo explotarlo! –

3

Depende de cómo se utiliza la variable. Si nunca tomas decisiones de seguridad basadas en enteros que hayas agregado con enteros de entrada (donde un adversario podría provocar un desbordamiento), entonces no puedo pensar en cómo te meterías en problemas (pero este tipo de cosas pueden ser sutiles).

Por otra parte, he visto un montón de código como este que no valida la entrada del usuario (aunque este ejemplo es artificial):

int pricePerWidgetInCents = 3199; 
int numberOfWidgetsToBuy = int.Parse(/* some user input string */); 
int totalCostOfWidgetsSoldInCents = pricePerWidgetInCents * numberOfWidgetsToBuy; // KA-BOOM! 

// potentially much later 
int orderSubtotal = whatever + totalCostOfWidgetInCents; 

Todo es miel sobre hojuelas hasta el día en que usted vende 671,299 widgets para - $ 21,474,817.95. Jefe puede estar molesto.

+1

sí, pero ¿cómo se usa eso para su ventaja? cómo puede hacer que eso anule el puntero del marco, por ejemplo ... – wuntee

+0

un mejor ejemplo sería: int arraySize = [alguna entrada de usuario]; int array [arraySize]; – wuntee

+3

No puede usar este ejemplo para anular el puntero de marco.Sin embargo, puede usarlo para robar 42 millones de dólares, que aún explota un problema de seguridad. –

11

Utilicé APL/370 a fines de los años 60 en una IBM 360/40. APL es un lenguaje en el que esencialmente todo es una matriz multidimensional, y hay operadores increíbles para manipular matrices, incluida la remodelación de N dimensiones a M dimensiones, etc.

Como era de esperar, una matriz de N dimensiones tenía límites de índice de 1. .k con positivo diferente k para cada eje ... yk era legalmente siempre inferior a 2^31 (valores positivos en una palabra de máquina de 32 bits). Ahora, una matriz de N dimensiones tiene una ubicación asignada en la memoria. Los intentos de acceder a una ranura de matriz con un índice demasiado grande para un eje se verifican con APL en el límite superior de la matriz. Y, por supuesto, esto se aplica a una matriz de N dimensiones donde N == 1.

APL no comprobó si hizo algo increíblemente estúpido con el operador RHO (remodelación de matriz). APL solo permite un máximo de 64 dimensiones. Por lo tanto, podría hacer una matriz de 1-64 dimensiones, y APL lo haría si las dimensiones de la matriz fueran todas menores que 2^31. O bien, podría tratar de hacer una matriz de dimensiones . En este caso, APL cometió un error y, sorprendentemente, devolvió una matriz de 64 dimensiones, pero no pudo verificar los tamaños de los ejes. (Esto está en efecto donde se produjo el "desbordamiento de número entero"). Esto significaba que podía crear una matriz con tamaños de eje de 2^31 o más ... pero interpretados como enteros con signo, se trataron como números negativos.

El encantamiento de operador RHO correcto aplicado a una matriz de este tipo podría reducir la dimensionalidad a 1, con un límite superior de, obtener esto, "-1". Llama a esta matriz un "agujero de gusano" (verás por qué en el momento). Tal matriz de agujeros de gusanos tiene un lugar en la memoria, al igual que cualquier otra matriz. Pero todos los accesos a la matriz se comprueban con respecto al límite superior ... pero la verificación encuadernada del arreglo resultó ser hecha por un sin firmar comparar por APL. Entonces, puedes acceder a WORMHOLE [1], WORMHOLE [2], ... WORMHOLE [2^32-2] sin objeciones. En efecto, puede acceder a la memoria de toda la máquina.

APL también tenía una operación de asignación de matriz, en la que podía completar una matriz con un valor. WORMHOLE [] < -0 por lo tanto, se puso a cero todos de memoria.

Solo lo hice una vez, ya que borraba la memoria que contenía mi área de trabajo APL, el intérprete APL y obviamente la parte crítica de APL que permitía el tiempo compartido (en aquellos días no estaba protegido de los usuarios) ... La sala terminal pasó de su estado normal de mecánica muy ruidosa (teníamos 2741 terminales Selectric APL) a silencio absoluto en aproximadamente 2 segundos. A través del cristal en la sala de ordenadores, pude ver que el operador miraba sorprendido las luces del 370 cuando se apagaron. Se produjo un montón de vueltas.

Si bien fue divertido en ese momento, mantuve la boca cerrada.

Con un poco de cuidado, uno podría haber alterado el sistema operativo de forma arbitraria.

+0

definitivamente podría ver cómo se puede aprovechar esto (ya que puede acceder a toda la memoria de la máquina). Supongo que la idea es que todo depende de la situación específica: en esto, la aplicación no limita la asignación de una matriz, donde el tamaño de la matriz es un número entero. Mi mente estaba atrapada en el simple 'desbordamiento de búfer' y pensaba que había alguna forma de tener 'int x = y + z * w' donde yyz y w estaban todos definidos por el usuario, y en esa declaración podría escribir de alguna manera sobre la memoria de manera confiable. – wuntee

+1

Bueno, mi ejemplo tiene la aplicación * haciendo * una comprobación de límites en la asignación de matrices, pero en efecto esa comprobación se ve frustrada al tener un desbordamiento en el conjunto de matrices. Puedes hacer que tu ejemplo funcione así: x = y + z; datos [x] donde el cálculo de x se desborda. En C, no hay queja; obtienes por definición @ (& data + x). Si puede establecer x en cualquier cosa (por desbordamiento), puede acceder a cualquier cosa. –

3

Un caso común sería un código que evita el desbordamiento del búfer preguntando por el número de entradas que se proporcionarán, y luego tratando de imponer ese límite. Considere una situación en la que pretendo proporcionar 2^30 + 10 enteros. El sistema de recepción asigna un búfer de 4 * (2^30 + 10) = 40 bytes (!). Dado que la asignación de memoria tuvo éxito, puedo continuar. La verificación del búfer de entrada no me detendrá cuando envíe mi 11ª entrada, ya que 11 < 2^30 + 10. Sin embargo, desbordaré el búfer realmente asignado.

2

Solo quería resumir todo lo que descubrí sobre mi pregunta original.

La razón por la que las cosas me resultaban confusas fue porque sé cómo funcionan los desbordamientos de los búfers y puedo entender cómo puede explotarlos fácilmente. Un desbordamiento de enteros es un caso diferente: no puede explotar el desbordamiento de enteros para agregar código arbitrario y forzar un cambio en el flujo de una aplicación.

Sin embargo, es posible desbordar un entero, que se usa, por ejemplo, para indexar una matriz para acceder a partes arbitrarias de la memoria. Desde aquí, podría ser posible usar esa matriz mal indizada para anular la memoria y hacer que la ejecución de una aplicación se modifique a su intención maliciosa.

Espero que esto ayude.

Cuestiones relacionadas