Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Hacking a Test Sever C code

Options
  • 25-04-2011 4:18pm
    #1
    Closed Accounts Posts: 6


    Apologies for previously posting this in the wrong forum.


    Hi, 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....
    For the challenge ASLR is enabled, but if I could get it to work with it disabled I would be very happy.

    I use the following to return a list of address's :

    /* Transfer response to greeting */
    (void) snprintf(greeting, BLENGTH, buffer);

    I then have some shellcode that I inject in a return string, but when I attempt to use any of the addresses I keep getting seg faults...

    any ideas / help appreciated... client and server code below.


    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:
    ``````````

    /*
    * 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:
    ```````


    /*
    * 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);
    }


Comments

Advertisement