Determinar la dirección de destino en un desbordamiento de montón

1

Para que se produzca un desbordamiento del montón y se ejecute un código arbitrario, la función free() realiza el paso:

hdr->next->next->prev = hdr->next->prev

Entiendo que la dirección de hdr->next->next->prev se calcula como hdr->next->next + 4 . Bastante claro.

Ahora, este valor será sobrescrito por la dirección hdr- > next- > prev que está controlada por el atacante y que contiene el código de shell posiblemente en el mismo montón (asumiendo que es ejecutable)

La dirección de destino, es decir, el valor en hdr->next->next en un desbordamiento de pila de vainilla debe ser la dirección en la pila que almacena la dirección de retorno después de que free() haya completado su trabajo.

Q1. ¿Cómo determina un atacante la dirección Exacta del puntero de retorno de free() en la pila?

Q2. La razón principal por la que ocurre esto es porque el puntero agrega 4 al valor hdr->next->next para escribir el puntero prev . ¿Se ha solucionado esto o sigue siendo uno de los motivos de los desbordamientos actuales del montón? (La razón por la que pregunto esto es que estoy al tanto de otras explotaciones de pilas, como el doble gratuito, etc., solo quiero asegurarme de que la razón primitiva haya sido corregida)

    
pregunta sudhacker 29.09.2012 - 20:01
fuente

1 respuesta

2

Un gran recurso en profundidad sobre un ataque de desbordamiento de búfer es el Aplastando la pila tutorial de Aleph One. Si bien el desbordamiento de pila y el desbordamiento de pila son sutilmente diferentes, las técnicas son similares / relacionadas.

Felix "FX" Lindner escribe un excelente artículo (2006) en The H Security que describe en profundidad tu exploit. Versión condensada a continuación; Recomiendo encarecidamente el artículo completo para mayor claridad.

En la respuesta a Q1, la determinación del puntero de dirección exacto para la pila es la captura. A menudo, debido a la asignación de pila, la duración variable de los programas y los datos, etc., no puede detectar la posición exacta sin un conocimiento significativo del diseño de la memoria. En cambio, una técnica común es rellenar una serie de instrucciones alrededor del código de carga útil en un intento de "golpear" el puntero de la pila. Una serie de instrucciones NOP se escriben antes del código de la carga útil, de modo que "si" el SP queda atrapado en el desbordamiento del búfer resultante, el SP avanzará hasta que ejecute su carga útil. En el caso de que el SP esté "después" de su código de carga útil, puede escribir una serie de instrucciones JMP que apunten al jefe de la carga útil. (Vea el tutorial; Aleph cubre este proceso en detalle).

El objetivo de este desbordamiento del montón es corromper los metadatos del registro del montón justo antes de la operación de "escritura" implícita en la asignación de hdr->next->prev a hdr->next->next->prev . Con la lista enlazada dañada, es posible sobrescribir la dirección de retorno utilizada al final de free en la pila.

En respuesta a la Q2, asumiré que está preguntando acerca de la implementación de GNU Libc de free() . Otras implementaciones probablemente tendrán un código diferente. Ahora existen múltiples controles de integridad para evitar objetos de tamaño no válido y doble libertad, etc. (Consulte _int_free() y las funciones relacionadas en Git ). Esto no quiere decir (definitivamente) que el vector es imposible por otros medios, pero ahora es más difícil.

Una tercera fuente de información (¿borrador?) sobre este tema es un documento técnico de Justin Ferguson: Entendiendo el montón rompiéndolo

    
respondido por el Jeff Stice-Hall 06.02.2013 - 16:56
fuente

Lea otras preguntas en las etiquetas