Skip to content

Instantly share code, notes, and snippets.

@BitPuffin
Created March 31, 2017 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BitPuffin/ca87af3551ad3102f9c45473992ec8b8 to your computer and use it in GitHub Desktop.
Save BitPuffin/ca87af3551ad3102f9c45473992ec8b8 to your computer and use it in GitHub Desktop.
An exploitable C program where you can get the password by reading out of bounds
./a.out
Enter password:
warning: this program uses gets(), which is unsafe.
>
> liststrs
> addstr hello there my friend
> addstr this program can be exploited
> get 0
0
> liststrs
1: 140722929936400
2: 140722930974720
> readstr 140722929936400
hello there my friend
> readstr 140722930974720
this program can be exploited
> get 64
140722934124544
> readstr 140722934124544
secretpassword
> oh shit!
> exit
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct strings_t {
char* str;
struct strings_t* next;
} strings;
typedef struct {
size_t values[64];
char* passwd;
strings* str;
} program_state;
void list_strings(program_state* st) {
strings* strs = st->str;
int idx = 1;
while(strs != NULL) {
printf("%d: %lu\n", idx, (size_t)strs->str);
strs = strs->next;
idx++;
}
}
void add_string(program_state* st, char* str) {
char* newstr = malloc(sizeof(char) * strlen(str) + 1);
strcpy(newstr, str);
strings* newobj = malloc(sizeof(strings));
newobj->next = NULL;
newobj->str = newstr;
if(st->str == NULL) {
st->str = newobj;
} else {
strings* s = st->str;
while(s->next != NULL) s = s->next;
s->next = newobj;
}
}
void read_string(program_state* st, char* str) {
size_t addr = strtoull(str, NULL, 10);
printf("%s\n", (char*)addr);
}
void get_cmd(program_state* st, char* str) {
size_t idx = strtoull(str, NULL, 10);
printf("%zu\n", st->values[idx]);
}
static const char* exitcmd = "exit";
static const char* liststrscmd = "liststrs";
static const char* readstrcmd = "readstr";
static const char* addstrcmd = "addstr";
static const char* setcmd = "set"; // would set an int at index but doesn't need to be implemented
static const char* getcmd = "get";
int main() {
program_state st;
memset(&st, 0, sizeof(program_state));
st.passwd = malloc(1024);
printf("Enter password: ");
scanf("%s", st.passwd); // Here you can overflow exploit by entering a big password
char cmd[1024];
for(;;) {
printf("\n> ");
gets(cmd);
if(strncmp(cmd, exitcmd, strlen(exitcmd)) == 0) break;
else if(strncmp(cmd, liststrscmd, strlen(liststrscmd)) == 0) list_strings(&st);
else if(strncmp(cmd, addstrcmd, strlen(addstrcmd)) == 0) add_string(&st, cmd + strlen(addstrcmd) + 1);
else if(strncmp(cmd, readstrcmd, strlen(readstrcmd)) == 0) read_string(&st, cmd + strlen(readstrcmd) + 1);
else if(strncmp(cmd, getcmd, strlen(getcmd)) == 0) get_cmd(&st, cmd + strlen(getcmd) + 1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment