Ret2csu
https://www.scs.stanford.edu/brop/bittau-brop.pdfInformación Básica
ret2csu es una técnica de hacking utilizada cuando intentas tomar el control de un programa pero no puedes encontrar los gadgets que sueles usar para manipular el comportamiento del programa.
Cuando un programa utiliza ciertas bibliotecas (como libc), tiene algunas funciones integradas para gestionar cómo se comunican entre sí diferentes partes del programa. Entre estas funciones hay algunas joyas ocultas que pueden actuar como nuestros gadgets faltantes, especialmente una llamada __libc_csu_init
.
Los Gadgets Mágicos en __libc_csu_init
En __libc_csu_init
, hay dos secuencias de instrucciones (gadgets) para destacar:
La primera secuencia nos permite configurar valores en varios registros (rbx, rbp, r12, r13, r14, r15). Estos son como espacios donde podemos almacenar números o direcciones que queremos usar más tarde.
Este gadget nos permite controlar estos registros sacando valores de la pila y colocándolos en ellos.
La segunda secuencia utiliza los valores que configuramos para hacer un par de cosas:
Mover valores específicos a otros registros, preparándolos para que los utilicemos como parámetros en funciones.
Realizar una llamada a una ubicación determinada sumando los valores en r15 y rbx, luego multiplicando rbx por 8.
Tal vez no conozcas ninguna dirección para escribir allí y necesites una instrucción
ret
. Ten en cuenta que el segundo gadget también terminará en unret
, pero deberás cumplir con algunas condiciones para poder alcanzarlo:
Las condiciones serán:
[r12 + rbx*8]
debe apuntar a una dirección que almacene una función callable (si no hay idea y no hay pie, simplemente puedes usar la función_init
):Si _init está en
0x400560
, usa GEF para buscar un puntero en la memoria hacia él y haz que[r12 + rbx*8]
sea la dirección con el puntero a _init:
rbp
yrbx
deben tener el mismo valor para evitar el saltoHay algunas instrucciones
pop
omitidas que debes tener en cuenta
RDI y RSI
Otra forma de controlar rdi
y rsi
desde el gadget ret2csu es accediendo a desplazamientos específicos:
Consulta esta página para más información:
Ejemplo
Utilizando la llamada
Imagina que deseas hacer una llamada al sistema o llamar a una función como write()
pero necesitas valores específicos en los registros rdx
y rsi
como parámetros. Normalmente, buscarías gadgets que establezcan directamente estos registros, pero no puedes encontrar ninguno.
Aquí es donde entra en juego ret2csu:
Configurar los Registros: Utiliza el primer gadget mágico para sacar valores de la pila y colocarlos en rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) y r15.
Utilizar el Segundo Gadget: Con esos registros configurados, utilizas el segundo gadget. Esto te permite mover los valores elegidos a
rdx
yrsi
(desde r14 y r13, respectivamente), preparando los parámetros para una llamada de función. Además, controlandor15
yrbx
, puedes hacer que el programa llame a una función ubicada en la dirección que calculas y colocas en[r15 + rbx*8]
.
Tienes un ejemplo utilizando esta técnica y explicándola aquí, y este es el exploit final que se utilizó:
Ten en cuenta que el exploit anterior no está destinado a realizar un RCE
, sino que simplemente llama a una función llamada win
(tomando la dirección de win
desde stdin llamando a gets en la cadena ROP y almacenándola en r15) con un tercer argumento con el valor 0xdeadbeefcafed00d
.
Saltando la llamada y alcanzando ret
El siguiente exploit fue extraído de esta página donde se utiliza ret2csu pero en lugar de usar la llamada, se está saltando las comparaciones y alcanzando el ret
después de la llamada:
¿Por qué no usar directamente libc?
Normalmente estos casos también son vulnerables a ret2plt + ret2lib, pero a veces necesitas controlar más parámetros de los que se pueden controlar fácilmente con los gadgets que encuentras directamente en libc. Por ejemplo, la función write()
requiere tres parámetros, y puede que no sea posible encontrar gadgets para establecer todos estos directamente.
Última actualización