martes, 26 de febrero de 2013

Solución al reto overthewire vortex level 0

Hoy por twitter gracias a @loopback1984 y a @neosysforensics, me he enterado que los wargames de intruded.net, que en su momento estuve haciendo, y que hace más de dos años se les jodió la plataforma y desaparecieron, han vuelto a ver la luz gracias a la gente de overthewire :).

No he podido resistir la tentación y he empezado a hacerlos :P. Aquí vamos cómo se puede resolver el nivel 0 de vortex. Lo cierto es que hace muchos años que lo había resuelto, estos retos estaban en otra web llamada pulltheplug y que también desapareció hace años.

El enunciado:
Your goal is to connect to port 5842 on vortex.labs.overthewire.org and read in 4 unsigned integers in host byte order. Add these integers together and send back the results to get a username and password for vortex1. This information can be used to log in using SSH.
Note: vortex is on an 32bit x86 machine (meaning, a little endian architecture) 

Pues esta bastante claro:
  1. Conectarse a la máquina.
  2. Recoger 4 enteros sin signo.
  3. Sumarlos.
  4. Devolver al servidor la suma.
  5. Leer usuario y contraseña.
Un programa que hace esto es el siguiente:

#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#include <netinet/in.h>
#include <netdb.h>

#define MACHINE_NAME ("vortex.labs.overthewire.org")
#define PORT (5842)

int main(int argc, char *argv[]) {
    struct sockaddr_in addr;
    struct hostent *resolver;
    unsigned int v1, v2, v3, v4;
    int sfd;
    char c;
    ssize_t bytes_read;

    if ((sfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        exit(-1);

    if ((resolver = gethostbyname(MACHINE_NAME)) == NULL)
        exit(-1);

    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    bcopy(resolver->h_addr,
          &addr.sin_addr.s_addr,
          sizeof(uint32_t));

    if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
        exit(-1);

    read(sfd, &v1, sizeof(unsigned int));
    read(sfd, &v2, sizeof(unsigned int));
    read(sfd, &v3, sizeof(unsigned int));
    read(sfd, &v4, sizeof(unsigned int));


    v1 += v2 + v3 + v4;

    write(sfd, &v1, sizeof(unsigned int));

    while (0x01ec0ded) {
        bytes_read = read(sfd, &c, sizeof(char));
        if (bytes_read == sizeof(char))
            printf("%c", c);
        else {
            printf("\n");
            break;
        }
    }

    return 0;
}


En negrita está lo más interesante, si ya sabías manejarte con sockets no tiene mucha chicha.

Por cierto, este programa funciona "por casualidad" }:-), he dejado un pequeño bug a propósito (aparte de que no controlo si los 4 read() de los enteros realmente se hacen bien). ¿Eres capaz de verlo? (Nota: puede que haya más de un bug xD).

Saludos.

No hay comentarios:

Publicar un comentario