Thursday, January 10, 2013

exploit-exercises Protostar: Net 0, Net 1, Net 2 and Net 3

This blog post will be a sum-up for Net 0, Net 1, Net 2 and Net 3 challenges of exploit-exercises' Protostar wargame.
In the first challenge we have to read a  random integer's decimal representation off the network and send it back. We parse the received data, we convert into an integer value and send it back.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define RPORT 2999
#define BUF_SIZE 255
#define RHOST "192.168.23.5"

int main (int argc, char **argv)
{
    int sd, wanted;
    char buf[BUF_SIZE];
    char *ptr;
    struct sockaddr_in target;

    /* Prepare structures and socket */
    memset (&target, 0, sizeof (target));
    target.sin_family = AF_INET;
    target.sin_port = htons (RPORT);
    if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
      {
        printf("inet_pton()");
        return -1;
      }
    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
      {
        printf("socket()");
        return -1;
      }

    /* Connect to the target host */
    if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
      {
        printf("connect()");
        return -1;
      }
    /* Read the message */
    if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
      {
        printf("recv()");
        return -1;
      }
    printf ("%s\n", buf);

    /* Extract the value */

    ptr = (char *) buf + 14;
    while ((*ptr++ != '\'') && (ptr < buf + BUF_SIZE));

    wanted = atoi (buf + 13);
    /* Send it back in little endian */
    if (send (sd, &wanted, sizeof (wanted), 0) != sizeof (wanted))
      {
        printf("send()");
        return -1;
      }

    memset (buf, 0, BUF_SIZE);
    if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
      {
        printf("recv()");
        return -1;
      }
    printf ("%s\n", buf);

    return 0;
}
kroosec@doj:~/protostar$ ./a.out
Please send '217873919' as a little endian 32bit int

Thank you sir/madam
The second challenge is mostly the inverse of the first. We read an integer over
the network and send back its decimal representation.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define RPORT 2998
#define BUF_SIZE 255
#define RHOST "192.168.23.5"

int main (int argc, char **argv)
{
    int sd;
    char buf[BUF_SIZE];
    char tmp[BUF_SIZE];
    char *ptr;
    struct sockaddr_in target;

    /* Prepare structures and socket */
    memset (&target, 0, sizeof (target));
    target.sin_family = AF_INET;
    target.sin_port = htons (RPORT);
    if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
      {
        printf("inet_pton()");
        return -1;
      }
    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
      {
        printf("socket()");
        return -1;
      }

    /* Connect to the target host */
    if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
      {
        printf("connect()");
        return -1;
      }
    /* Read the message */
    if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
      {
        printf("recv()");
        return -1;
      }

    memset (tmp, 0, BUF_SIZE);
    sprintf (tmp, "%d", *(int *)buf);

    if (send (sd, tmp, strlen (tmp), 0) != strlen (tmp))
      {
        printf("send()");
        return -1;
      }

    memset (buf, 0, BUF_SIZE);
    if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
      {
        printf("recv()");
        return -1;
      }
    printf ("%s\n", buf);

    return 0;
}

kroosec@doj:~/protostar$ ./a.out
you correctly sent the data
The third challenge is about sending back the sum 4 unsigned integers received
over the wire.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define RPORT 2997
#define BUF_SIZE 255
#define RHOST "192.168.23.5"

int main (int argc, char **argv)
{
    unsigned int sd, wanted, i;
    char buf[BUF_SIZE];
    struct sockaddr_in target;

    /* Prepare structures and socket */
    memset (&target, 0, sizeof (target));
    target.sin_family = AF_INET;
    target.sin_port = htons (RPORT);
    if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
      {
        printf("inet_pton()");
        return -1;
      }
    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
      {
        printf("socket()");
        return -1;
      }

    /* Connect to the target host */
    if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
      {
        printf("connect()");
        return -1;
      }

    wanted = 0;
    /* Read 4 unsigned integers and sum them up. */
    for (i = 0; i < 4; i++)
      {
        if (recv (sd, buf, sizeof (int), 0) == -1)
          {
            printf("recv()");
            return -1;
          }
        wanted += *(int *) buf;
      }

    if (send (sd, &wanted, sizeof (int), 0) != sizeof (int))
      {
        printf("send()");
        return -1;
      }

    memset (buf, 0, BUF_SIZE);
    if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
      {
        printf("recv()");
        return -1;
      }
    printf ("%s\n", buf);

    return 0;
}
kroosec@doj:~/protostar$ ./a.out
you added them correctly
The last challenge of the networking category emulates a networking protocol. It starts by reading the total length of the data on 2 bytes which will be 31. Following is 23 on one byte, which signifies login command. After that the resource net3, the username awesomesauce and the password each terminated with a null byte and prepended with its length (+1 for null byte).
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define RPORT 2996
#define BUF_SIZE 500
#define RHOST "192.168.23.5"

int main (int argc, char **argv)
{
    int sd;
    char buf[BUF_SIZE];
    struct sockaddr_in target;

    /* Prepare structures and socket */
    memset (&target, 0, sizeof (target));
    target.sin_family = AF_INET;
    target.sin_port = htons (RPORT);
    if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
      {
        printf("inet_pton()");
        return -1;
      }
    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
      {
        printf("socket()");
        return -1;
      }

    /* Connect to the target host */
    if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
      {
        printf("connect()");
        return -1;
      }

    /* Prepend with payload size == 31 */
    if (send (sd, "\x00\x1f", 2, 0) != 2)
      {
        printf("send()");
        return -1;
      }

    /* Start with 23 */
    if (send (sd, "\x17", 1, 0) != 1)
      {
        printf("send()");
        return -1;
      }

    /* resource */
    if (send (sd, "\x05net3\x00", 6, 0) != 6)
      {
        printf("send()");
        return -1;
      }

    /* login */
    if (send (sd, "\x0d""awesomesauce\x00", 14, 0) != 14)
      {
        printf("send()");
        return -1;
      }

    /* password */
    if (send (sd, "\x09password\x00", 10, 0) != 10)
      {
        printf("send()");
        return -1;
      }

    memset (buf, 0, BUF_SIZE);
    if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
      {
        printf("recv()");
        return -1;
      }
    printf ("%s\n", buf+2);

    return 0;
}
kroosec@doj:~/protostar$ ./a.out
!successful
And that is it with the Networking challenges of Protostar.

No comments:

Post a Comment