Buffer Overflows

Smashing the Stack for Fun and Profit - Aleph One

~ Zachary Trent Kaplan - ztk4@njit.edu

Repository for this Presentation: Buffer Overflow Presentation

Made with reveal.js - Repository

What is a Buffer?

Contiguous Memory

Memory in C

Command Line Input (CLI):  ./agree "Yes"
agree.c

#include <stdio.h>
#include <string.h>

int bad_code(char *arg1) {
    char cpy[16]; 
    strcpy(cpy, arg1);
    cpy[15] = '\0';
    
    return strcmp(cpy, "Yes");
}

int main(int argc, char **argv) {
    if(argc != 2) {
        printf("Usage: %s reply\n", *argv);
        return 1;
    }

    if(bad_code(argv[1]) == 0)
        printf("Thanks for agreeing!\n");
    else
        printf("I'm sorry, I don't understand\n");

    return 0;
}
                                   
Stack
Increasing Addresses →
 
Parent Frame (main)
Return Address
Saved Frame Pointer
char *arg1
char cpy[16]
\0seY
Unused Stack Space
 

Memory in C

Command Line Input (CLI):  ./agree $(python -c "print 'A'*36")
agree.c

#include <stdio.h>
#include <string.h>

int bad_code(char *arg1) {
    char cpy[16]; 
    strcpy(cpy, arg1);
    cpy[15] = '\0';
    
    return strcmp(cpy, "Yes");
}

int main(int argc, char **argv) {
    if(argc != 2) {
        printf("Usage: %s reply\n", *argv);
        return 1;
    }

    if(bad_code(argv[1]) == 0)
        printf("Thanks for agreeing!\n");
    else
        printf("I'm sorry, I don't understand\n");

    return 0;
}
                                   
Stack
Increasing Addresses →
 
Parent Frame (main)
Return Address\0AAAA
AAAAAAAA
AAAAAAAA
AAAAAAAA
AAAAAAAA
Unused Stack Space
 

An Example Attack

All the files shown can be found in this directory

Remember to use the Makefile to compile overflow with symbols on and stack protection off
to change the owner of overflow and it's privelages to u=rwxs; g=rx; o=r,
and to disable aslr on your machine before compiling.

overflow.c


#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <openssl/md5.h>

void grant_shell() {
    printf("Welcome back superuser!\nHere's your shell:\n");
    setuid(geteuid());
    char *const args[] = {"/bin/sh",  NULL};
    execv(args[0], args);
}

//easy way of storing hash in source file 
//(16 bytes represented as 16 uint8's)
uint8_t valid_hash[] = {193, 179, 147, 105, 178, 122, 16, 111,
                        31, 197, 119, 133, 91, 193, 217, 252}; 

int verify(char *argv1) {
    char passwd[21];        //holds 20 characters plus a null byte
    strcpy(passwd, argv1);
    passwd[20] = '\0';      //set the last char to null

    uint8_t hash[16];       //enough space for 16 byte hash
    MD5(passwd, strlen(passwd), (char *)hash);

    return !memcmp(hash, valid_hash, 16);
}
                                

int main(int argc, char **argv) {
    if(argc != 2) {
        printf("Usage: %s passwd\n", *argv);
        return 1;
    }

    if(verify(argv[1])) { //if password is okay
        grant_shell();
    } else {
        printf("You're not the superuser, "
                "you don't know the password!!\n");
    }
    
    return 0;
}
                                

GDB

The GNU Project Debugger

Success!

We now have a shell with root privelages

Thank You!



Questions?