Hacking Test Server Code

Discussion in 'Meet and Greet' started by mreilly2008, Apr 23, 2011.

  1. mreilly2008

    mreilly2008 New Member

    Joined:
    Apr 23, 2011
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Hi guys, I came across this code below recently and have being trying to hack it...
    I am not having much luck with it and was wondering if anyone has any experience with hacking code that could lend a hand or give me some tips... This is a genuine request and I can give the url of the site when I found the challenge, just wasn't sure if it was o.k to post the url....

    The TEST :
    ``````````
    A remote, multi threaded server sits listening on port 8001. The server runs on an x86 machine running Linux . The server was built with gcc 3.3.5 (i.e. the older gcc version available off the lab machines under /usr/local/bin).

    When we connect to it, the server prompts us to enter our name. After receiving our name the server welcomes us and asks us to enter a message. After receiving our message the server exits. the server has been built as follows:

    $/usr/local/bin/gcc -mpreferred-stack-boundary=2 -o server server.c -lpthread


    THE MISSION :
    `````````````
    Exploit the vulnerable server in order to gain remote control of the host on which the server resides.
    1. Study the server to understand what it does, how it does it and identify any flaws
    2. Determine what your payload needs to do, write the payload in C and test it
    3. Translate the payload into assembly
    4. Convert the assembly into hexadecimal opcodes
    5. Write and test the exploit



    THE SERVER:
    ``````````

    Code:
    /*
    * Our vulnerable server. It simply reads a name and a message from a client
    * before exiting.
    */
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <netdb.h>
    #include <time.h>
    
    #define PORTNUM 8001
    #define BLENGTH 256
    #define MLENGTH 128
    
    /* Read the name of a client */
    static void
    read_name(int s, char *buffer, char *greeting)
    {
    char *p;
    
    /* Construct a prompt */
    (void) snprintf(buffer, BLENGTH, "Please enter your name:\n");
    
    /* Send the prompt to the client */
    (void) send(s, (void *)buffer, BLENGTH, 0);
    
    /* Receive a response from the client */
    (void) recv(s, (void *)buffer, BLENGTH, MSG_WAITALL);
    
    /* Remove trailing '\n' from the response */
    p = buffer + strlen(buffer) - 1;
    *p = '\0';
    
    /* Transfer response to greeting */
    (void) snprintf(greeting, BLENGTH, buffer);
    
    /* Construct greeting */
    (void) strncat(greeting, ", you are most welcome!\n", BLENGTH);
    
    /* Send greeting to client */
    (void) send(s, greeting, BLENGTH, 0);
    }
    
    
    /* Read a message from a client */
    static void
    read_message(int s, char *buffer, char *message)
    {
    /* Construct a prompt */
    (void) snprintf(buffer, BLENGTH, "Please enter your message:\n");
    
    /* Send the prompt to the client */
    (void) send(s, (void *)buffer, BLENGTH, 0);
    
    /* Receive a response from the client */
    (void) recv(s, (void *)buffer, BLENGTH, MSG_WAITALL);
    
    /* Copy the response to a local buffer */
    (void) strcpy(message, buffer);
    }
    
    /* Make an introduction */
    static void
    do_first_bit(int s)
    {
    char greeting[BLENGTH];
    char buffer[BLENGTH];
    
    read_name(s, buffer, greeting);
    }
    
    /* Do the work */
    static void
    do_second_bit(int s)
    {
    char message[MLENGTH];
    char buffer[BLENGTH];
    
    read_message(s, buffer, message);
    } 
    
    /* One thread per connection */
    void *
    handler(void *n)
    {
    int s;
    
    /* Detach */
    (void) pthread_detach(pthread_self());
    
    /* Cast parameter */
    s = *((int *)n);
    
    /* Make an introduction */
    do_first_bit(s);
    
    /* Do the work */
    do_second_bit(s);
    
    /* Close the socket */
    (void) close(s);
    
    /* Free memory */
    free(n);
    
    return ((void *)NULL);
    }
    
    
    /* Connect and talk to a client */
    int
    main(void)
    {
    struct sockaddr_in socketname, client;
    struct hostent *host;
    socklen_t clientlen = sizeof (client);
    pthread_t tid;
    int s, n, *c, optval = 1;
    
    /* We will always be localhost */
    if ((host = gethostbyname("localhost")) == NULL) {
    perror("gethostbyname()");
    exit(EXIT_FAILURE);
    }
    
    /* Fill in the socket address structure */
    (void) memset((char *)&socketname, '\0', sizeof (socketname));
    socketname.sin_family = AF_INET;
    socketname.sin_port = htons(PORTNUM);
    (void) memcpy((char *)&socketname.sin_addr, host->h_addr_list[0],
    host->h_length);
    
    /* Create an Internet family, stream socket */
    s = socket(AF_INET, SOCK_STREAM, 0);
    
    /* Did that work? */
    if (s < 0) {
    perror("socket()");
    exit(EXIT_FAILURE);
    }
    
    /* Allow binding if waiting on kernel to clean up */
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
    (char *)&optval, sizeof (optval)) < 0) {
    perror("setsockopt()");
    exit(EXIT_FAILURE);
    }
    
    /* Now bind the address to our socket so it becomes visible */
    if (bind(s, (struct sockaddr *)&socketname,
    sizeof (socketname)) < 0) {
    perror("bind()");
    exit(EXIT_FAILURE);
    }
    
    /* Make our now visible socket available for connections */
    if (listen(s, 5)) {
    perror("listen()");
    exit(EXIT_FAILURE);
    } 
    
    /* Loop forever */
    while (1) {
    
    /* Accept a connection */
    n = accept(s, (struct sockaddr *)&client, &clientlen);
    
    /* Did that work? */
    if (n < 0) {
    perror("accept()");
    exit(EXIT_FAILURE);
    }
    
    /* Allocate room for socket for this thread */
    c = malloc(sizeof (*c));
    
    /* Check we got some memory */
    if (!c) {
    perror("malloc()");
    exit(EXIT_FAILURE);
    }
    
    /* Initialise */
    *c = n;
    
    /* Have a conversation */
    (void) pthread_create(&tid, NULL, handler, (void *)c);
    }
    
    /* Close socket */
    (void) close(s);
    
    return (0);
    } 
    
    CLIENT:
    ```````

    Code:
    /*
    * Simple demonstration of talking to our vulnerable server
    */
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <netdb.h>
    #include <time.h>
    
    #define PORTNUM 8001
    #define BLENGTH 256
    
    /* Send our name to the server */
    static void
    send_name(int s)
    {
    char buffer[BLENGTH];
    
    /* Receive a prompt from the server */
    (void) recv(s, (void *)buffer, BLENGTH, MSG_WAITALL);
    
    /* Display the prompt to the user */
    (void) fputs(buffer, stdout);
    
    /* Read a response from the user */
    (void) fgets(buffer, BLENGTH, stdin);
    
    /* Send the response to the server */
    (void) send(s, (void *)buffer, BLENGTH, 0);
    
    /* Receive a reply from the server */
    (void) recv(s, (void *)buffer, BLENGTH, MSG_WAITALL);
    
    /* Display the reply to the user */
    (void) fputs(buffer, stdout);
    }
    
    /* Send our message to the server */
    static void
    send_message(int s)
    {
    char buffer[BLENGTH];
    
    /* Receive a prompt from the server */
    (void) recv(s, (void *)buffer, BLENGTH, MSG_WAITALL);
    
    /* Display the prompt to the user */
    (void) fputs(buffer, stdout);
    
    /* Read a response from the user */
    (void) fgets(buffer, BLENGTH, stdin);
    
    /* Send the response to the server */
    (void) send(s, (void *)buffer, BLENGTH, 0);
    } 
    /* Connect and talk to the server */
    int
    main(void)
    {
    struct sockaddr_in server;
    struct hostent *host;
    int s;
    
    /* Create an Internet family, stream socket */
    s = socket(AF_INET, SOCK_STREAM, 0);
    
    /* Did that work? */
    if (s < 0) {
    perror("socket()");
    exit(EXIT_FAILURE);
    }
    
    /* We are running the server on localhost for the minute */
    if ((host = gethostbyname("localhost")) == NULL) {
    perror("gethostbyname()");
    exit(EXIT_FAILURE);
    }
    
    /* Fill in the socket address structure */
    (void) memset((char *)&server, '\0', sizeof (server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORTNUM);
    (void) memcpy((char *)&server.sin_addr, host->h_addr_list[0],
    host->h_length);
    
    /* Connect to the server */
    if (connect(s, (struct sockaddr *)&server, sizeof (server)) < 0) {
    perror("connect()");
    exit(EXIT_FAILURE);
    }
    
    /* Send our name first */
    send_name(s);
    
    /* Now send a message */
    send_message(s);
    
    /* Close the socket */
    (void) close(s);
    
    return (0);
    }
     
    Last edited by a moderator: Apr 23, 2011

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice