Created
March 31, 2017 17:49
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
./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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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