Hay dos tipos de problemas que creo que podrías estar confundiendo. Una es la dirección de las funciones a las que llama su código de shell que proporciona la aplicación vulnerable o las bibliotecas cargadas, y la otra es saltos absolutos frente a los saltos relativos dentro de su código de cáscara.
Llamadas de biblioteca
Supongamos, por un segundo, que está intentando un exploit de estilo de retorno a libc en un simple binario. Así que quieres la dirección de system
para muchas de estas hazañas. Construyamos un pequeño binario que imprima la dirección de system
.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
printf("system @%p\n", system);
return 0;
}
Compila y ejecuta esto varias veces:
% gcc -o getsystem getsystem.c
% ./getsystem
system @0x7fdc54419d40
% ./getsystem
system @0x7fbc15b61d40
% ./getsystem
system @0x7fbeacfb6d40
Observe que cada vez que se ejecuta, la dirección de system
ha cambiado. Esto se debe a una mitigación de seguridad moderna llamada ASLR: la biblioteca C se carga en una dirección base diferente, por lo que system
se cargará en una dirección diferente. En consecuencia, su código de shell debe ubicar primero libc, luego llamar a system
en una dirección relativa al inicio de la biblioteca. (Llamada la "dirección base").
Saltos
En shellcode más complejo, es posible que necesites hacer un jmp
o call
dentro de la propia carga útil. En tales casos, usted debe tener saltos y llamadas relativas, porque no sabe la dirección exacta donde se cargará su código de shell. En lugar de decir "saltar a 0x0804abcd
", debería tener "saltar 5 bytes hacia adelante". Esto es lo que se entiende por "Código independiente de la posición": puede funcionar cuando se carga en cualquier posición, y no solo en una dirección de inicio fija.
Debido a que Shellcode generalmente se carga en la pila o en el montón, los cuales están sujetos a varias manipulaciones (ASLR, otros datos que usan la pila / pila, subprocesos, etc.), es imposible predecir una dirección absoluta donde su Shellcode tierra.