Mostrando entradas con la etiqueta c. Mostrar todas las entradas
Mostrando entradas con la etiqueta c. Mostrar todas las entradas

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.