En este artículo, resolveremos la tarea número 24 del sitio
pwnable.kr y aprenderemos sobre cómo apilar el marco de la pila.
Información organizacionalEspecialmente para aquellos que quieran aprender algo nuevo y desarrollarse en cualquiera de las áreas de información y seguridad informática, escribiré y hablaré sobre las siguientes categorías:
- PWN;
- criptografía (criptografía);
- tecnologías de red (Red);
- inversa (ingeniería inversa);
- esteganografía (Stegano);
- búsqueda y explotación de vulnerabilidades WEB.
Además de esto, compartiré mi experiencia en informática forense, análisis de malware y firmware, ataques a redes inalámbricas y redes de área local, realización de pentests y escritura de exploits.
Para que pueda conocer nuevos artículos, software y otra información, creé un
canal en Telegram y un
grupo para discutir cualquier problema en el campo de ICD. Además, consideraré personalmente sus solicitudes personales, preguntas, sugerencias y recomendaciones
personalmente y responderé a todos .
Toda la información se proporciona solo con fines educativos. El autor de este documento no tiene ninguna responsabilidad por los daños causados a alguien como resultado del uso de los conocimientos y métodos obtenidos como resultado de estudiar este documento.
Solución de trabajo de inicio de sesión simple
Continuamos la segunda sección. Diré de inmediato que es más difícil que el primero y que no tenemos el código fuente de las aplicaciones. No te olvides de la discusión
aquí . Empecemos
Haga clic en el icono con el inicio de sesión simple de la firma. Se nos da la dirección y el puerto para la conexión y el programa en sí.

Descarga todo lo que nos dan, revisa el binario.

Este es un elfo de 32 bits con una pila canaria y no ejecutable instalada. Descompilamos en IDA Pro.

En el programa, los datos del usuario se decodifican desde base64. La variable v7 almacena la longitud de la cadena decodificada. A continuación, se compara v7 con 12. Si se pasa la prueba, la cadena decodificada se copia a la variable de entrada, y luego se llama a la función de autenticación, en la que se pasa la longitud de la cadena decodificada como parámetro. Y si pasamos la autenticación, se llama a la función correcta. Veamos la función de autenticación.

Parece un desbordamiento de búfer. Echa un vistazo a la pila.

No No podemos desbordar el búfer, ya que esto requiere más de 12 bytes. Las direcciones donde se almacena el valor de las variables son interesantes, especialmente la variable v4 a la que se realiza la copia.

Esta es la dirección [ESP + 32]. Eche un vistazo al código para esto en forma desmontada.

Las siguientes instrucciones son necesarias para guardar el marco de la pila.
push ebp
mov ebp, esp
Para restaurar la pila, use la instrucción leave. El cual realizamos las operaciones inversas.

Lo más interesante es la tercera instrucción
sub esp, 28h
.
Por lo tanto, se produce una superposición: esp disminuye en 40 y la variable v2 se encuentra en esp + 32 y ocupa 12 bytes. Es decir, después de mover el valor de esp a ebp, la dirección de los últimos cuatro bytes de la variable v2 se guardará en ebp. Cuando se ejecutan las instrucciones de abandono y retiro, los últimos cuatro bytes de la variable v2 estarán ahora en el marco superior de la pila.
Verifiquemos y demos la línea de entrada QUFBQUFBQUFCQkJC.

Si nuestra suposición es correcta, luego de ejecutar retn en la función de autenticación, la parte superior de la pila será la dirección "BBBB".

Ahora ejecuta licencia.

Hay "BBBB" en EBP y ahora después de ejecutar la licencia en la función principal principal, el programa se bloqueará. Por lo tanto, podemos delante de la dirección de la parte superior de la pila en la que se ubicará la dirección a la que queremos ir. Entonces la carga será así: 4 bytes + dirección donde vamos + dirección al comienzo de la carga.
Primero, escribe una plantilla.
from pwn import * from base64 import * r = remote('pwnable.kr', 9003) r.recv() r.interactive()
Ahora descubrimos la dirección a la que queremos ir: esto es 0x8049284 dentro de la función correcta.

Esta dirección será la segunda parte de nuestra carga. La tercera parte de la carga será la dirección de la variable de entrada (dirección de carga).

Componemos la carga en el código. No olvides codificar en base64:
payload = "A"*4 + p32(0x8049284) + p32(0x811EB40) payload = b64encode(payload)
Código completo
from pwn import * from base64 import * r = remote('pwnable.kr', 9003) r.recv() payload = "A"*4 + p32(0x8049284) + p32(0x811EB40) payload = b64encode(payload) r.send(payload+"\n") r.interactive()

Y consigue tus puntos. Honestamente, esta tarea no fue muy fácil para mí.

Y continuamos: en el próximo artículo: forense. Puedes unirte a nosotros en
Telegram .