¿Por qué un ataque ret2libc debe seguir el orden "system (), exit (), command?

4

En un ataque ret2libc, entiendo que la dirección de retorno se puede sobrescribir con la dirección del comando del sistema, que toma una cadena de comandos como argumento. En este caso, ¿no debería la dirección de la cadena de comando ir directamente después de la dirección del sistema ()? Sin embargo, la mayoría de los tutoriales que he visto siguen el formato: dirección de system (). Address of exit (). Address de la cadena de comandos.

¿Por qué es obligatorio incluir la dirección de exit ()? ¿Seguirá funcionando el ataque si se excluye exit ()?

    
pregunta Lew Wei Hao 12.09.2016 - 23:31
fuente

2 respuestas

5

La técnica ret2libc (y la programación orientada al retorno (ROP)) se basa en sobrescribir la pila para crear un nuevo marco de pila que llama a la función del sistema. Este artículo de wikipedia explica los marcos de pila con gran detalle: enlace

El marco de pila determina el orden en que se escriben la función de llamada y los parámetros:

function address return address parameters

Entonces, en tu ejemplo, quieres llamar a system() con cmdstring y regresar a la función exit() cuando la llamada system() vuelva. Entonces escribes el siguiente marco de pila:

system_addr exit_addr cmdstring_addr

Si elimina la dirección de salida, cambie el marco de pila a lo siguiente:

system_addr cmdstring_addr existingdataonstack_aka_junk

Así que ahora estás llamando a system() con un argumento de dirección de correo no deseado e intentas volver a ingresar a la cadena de comandos una vez que la función se complete. Es por eso que falla. Puede reemplazar la dirección exit() con otros datos, como 0x41414141 , lo que causará un segfault una vez que se complete la llamada system() . O puede reemplazarlo con la dirección de una ubicación pop pop ret y luego escribir más marcos de pila debajo. Esto es ahora una carga útil ROP . Este es un ejemplo básico de cómo se vería en la pila:

system_addr poppopret_addr cmdstring_addr printf_addr exit_addr addr_of_string_to_printf

Esto le permitiría imprimir algo como You got hacked antes de salir.

    
respondido por el wireghoul 13.09.2016 - 02:08
fuente
1

El motivo exit() está incluido es terminar el programa con gracia . Si no tiene exit() al final de su cadena, el programa continuará ejecutándose de forma extraña o lo más probable es que termine con una falla de segmentación. No es obligatorio incluir una llamada a exit() . Lo ideal es que construyas tu exploit de tal manera que luego el programa continúe ejecutándose como siempre, para que nadie sospeche porque su servicio ya no se está ejecutando.

    
respondido por el mroman 13.09.2016 - 12:23
fuente

Lea otras preguntas en las etiquetas