Tu carga útil de exploits termina en la pila porque estás desbordando un búfer en la pila, y así es como obtienes el control de la dirección de retorno también.
ESP apunta directamente al inicio de su carga útil (después de la ejecución del ret
en la función que está atacando) porque coloca la carga útil justo después de los 4 bytes que sobrescriben la dirección de retorno en la pila. ret
coloca 4 (u 8) bytes en EIP, dejando que ESP apunte a la carga útil que sigue directamente.
Pero no sabe qué valor tendrá ESP en ese momento , debido al ASLR de la pila y porque una profundidad diferente de la pila de llamadas que conduce hasta este punto podría cambiar la dirección. Por lo tanto, no puede codificar una dirección de retorno correcta .
Pero si hay bytes que se decodifican como jmp esp
o call esp
en cualquier lugar en una dirección fija (no ASLRed) en la memoria del proceso , puede codificar que address como la dirección de retorno en tu exploit. La ejecución irá allí, luego a tu carga útil.
De hecho, este es a menudo el caso: algunas DLL no tienen ASLR habilitado para su código, y el código del ejecutable principal puede que tampoco esté ASLRed.
El código de
ASLR para el código de todos anula un ataque jmp esp
, a menos que el atacante pueda hacer que el proceso de destino pierda direcciones.
Tenga en cuenta que para el código de 64 bits, es poco probable que pueda utilizar jmp rsp
para los desbordamientos de búfer basados en cadenas, porque las direcciones de código contendrán algunos 0
bytes líderes .
Por lo tanto, jmp esp
te ofrece un exploit mucho más confiable que adivinar repetidamente una dirección de retorno (con un gran trineo NOP).
Las adivinanzas repetidas bloquearán el proceso de destino cada vez que te equivoques, pero un jmp esp
puede darte una alta probabilidad de éxito en el primer intento. Esto evitará dejar registros de fallos. También podría derrotar a un sistema de detección de intrusiones que busca procesos de servidor que fallan y bloquea las conexiones de su dirección IP o similar.
Tenga en cuenta que la instrucción de 2 bytes que está buscando puede aparecer como parte de otra instrucción cuando el programa se ejecuta normalmente o como datos estáticos (especialmente los datos de solo lectura en las páginas ejecutables). Así que solo necesita buscar la secuencia de 2 bytes, no el jmp esp
en el desmontaje del programa. Los compiladores nunca usarán jmp esp
, por lo que no encontrarás uno de esa manera.
Más generalmente , cualquier función que termine con un puntero de búfer en cualquier registro (por ejemplo, desde un memcpy
o especialmente strcpy
) puede permitir un ataque ret2reg , buscando una instrucción jmp eax
.
Esto puede funcionar en modo de 64 bits, donde las direcciones tienen algunos bytes de alto cero; Si strcpy
's al final de la escritura escribe ese byte de dirección alto para usted, el final de su cadena de explotación podría ser los bytes de dirección distintos a cero que sobrescriben la dirección de retorno en la pila.
En este caso, la carga útil ejecutable iría antes de la dirección de retorno, en el lugar del búfer donde la función deja un registro apuntando. (Por lo general, el comienzo del búfer si hay algún puntero útil al búfer en los registros).