diff --git a/poc/vuln-1.poc b/poc/vuln-1.poc index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..23df6ef572ae6eebbb09f92fb170c0fe06c303e9 100644 --- a/poc/vuln-1.poc +++ b/poc/vuln-1.poc @@ -0,0 +1,2 @@ +put http://example.com/adflasdgalsdghaljnsdgdslajkhgndsaljkghdsajklghadnsjlkgadjklsgadjklsgadjklsghadklnsghadklsjghdsakljgadjlsghkdalsgadjklsghadjklsghadklsghadjklsgndasjklghadklssdlfhladjslhnadlskghadlnsghadlsghjadnslkgnadsklghadklnsghadklnsghdsaklgnhkasdhgnkljadsghlnasdkjghlkdsaghnadklsghadklsghnadklsghadjklsgnadklsgadlnsgadlnsjghnadklsjghnaklsghjadjfhgdajkgnadslghadnlsghadklsjghadjlsghadlskghadklnsghadjklsgnasdjklghnlkjadsghadlsghadslnkgjhdsalkgnasdkljghaslknghasddlkgndsakjghadnslkjgnadsklghdnsdhasglnkdsahgkldsaghlaghldaksajklghadslkgnadsjklghadkls username password +save master_password passwords.txt \ No newline at end of file diff --git a/poc/vuln-2.poc b/poc/vuln-2.poc index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..51200a00576c83a7b8bd69df874291d880951845 100644 --- a/poc/vuln-2.poc +++ b/poc/vuln-2.poc @@ -0,0 +1,3 @@ +put h u cGKZu2X69wXHiGZJfWpsXsT8NmxVWKl2f29XwrfgSXhGmm82f9xJLedi8CrHGYDsHkSi5Ep1Y66A1igqmccAPtUSdMPzkCZnxPbqkaIZ9ZRK81N6hUVGzlokSTDSmKKavX0YdG0KyB7kGOQwKvzmGHUkcnULUDU5Un8JGtN3iic5klcNWXSGpNUMWTgWJ7O5eGy8t45WQ8zj1yr9zS1ZTUPnAyHYlhl9wyaLvdV0ijHfwl24MLmA7GZlg6eIcSKJIq7KFyyGcsLXNWQnPpbBjuhni78CAyz7iL8LlwlNPCcqlJ8JYuWljtzQzQqViLmdTbcdz4XcR3f0iCGqZ9rcbT4NW4lhnWLCjtvRIVbCG9W5CoHbPjHmJw8kTRnge0ywkIIfPHpSKSARDfmCr82Ri9swi96RnqbAcPQmqBtfFPLuohlWlAVluJJlg0U1301FGkBABX63LO5FWGMKaCDFaY0ZOSK3BhoJQZKo83XS48XIEsz2fMQVJfLI083AKqe2kgihq8vw1DctMW0I2MkeoRB1ZTaAXIPedyEDjLKK70subPH68rWb9zfYPv7bT7qm7sJkcnAp6t6unffJzr5wpmkf44IyNVTSBG90PlDf2jgsObag0c7iaypswu9pjccqkPBdFTOXAfyT7rNS8iLhhopMo5Zl6BeXUEeegbUiLKiXNiZmDM1zv07eSvvDlvnCNNPEi2vDb7VWzXp3azoj96UOvRH4u6ZitRJDY3TnzW7muke6a9E027iD4uujCKxJ5uLbmdRVHp2YbC1WObR9x4mxMOt4oIPtG405NkPrxQvgp7vPQKPEPLFdGT8vn03Qz5EXw2IRddmc3EDUWNvFSCvdupKXLONpuPVolC5Qbg2EN450a8ASIwt5B0Kb2RfOpIk1OVWMtHi36Pmnd3QHLTIELfF33c3psxJFg4qHgmKS5vM0x7d4B5qZyV3ag5znCPOz13W6I78MF3gE0GvePKWe5O4bqzkirFqKhppc1ylzmFQiGqWeL +put h u cGKZu2X69wXHiGZJfWpsXsT8NmxVWKl2f29XwrfgSXhGmm82f9xJLedi8CrHGYDsHkSi5Ep1Y66A1igqmccAPtUSdMPzkCZnxPbqkaIZ9ZRK81N6hUVGzlokSTDSmKKavX0YdG0KyB7kGOQwKvzmGHUkcnULUDU5Un8JGtN3iic5klcNWXSGpNUMWTgWJ7O5eGy8t45WQ8zj1yr9zS1ZTUPnAyHYlhl9wyaLvdV0ijHfwl24MLmA7GZlg6eIcSKJIq7KFyyGcsLXNWQnPpbBjuhni78CAyz7iL8LlwlNPCcqlJ8JYuWljtzQzQqViLmdTbcdz4XcR3f0iCGqZ9rcbT4NW4lhnWLCjtvRIVbCG9W5CoHbPjHmJw8kTRnge0ywkIIfPHpSKSARDfmCr82Ri9swi96RnqbAcPQmqBtfFPLuohlWlAVluJJlg0U1301FGkBABX63LO5FWGMKaCDFaY0ZOSK3BhoJQZKo83XS48XIEsz2fMQVJfLI083AKqe2kgihq8vw1DctMW0I2MkeoRB1ZTaAXIPedyEDjLKK70subPH68rWb9zfYPv7bT7qm7sJkcnAp6t6unffJzr5wpmkf44IyNVTSBG90PlDf2jgsObag0c7iaypswu9pjccqkPBdFTOXAfyT7rNS8iLhhopMo5Zl6BeXUEeegbUiLKiXNiZmDM1zv07eSvvDlvnCNNPEi2vDb7VWzXp3azoj96UOvRH4u6ZitRJDY3TnzW7muke6a9E027iD4uujCKxJ5uLbmdRVHp2YbC1WObR9x4mxMOt4oIPtG405NkPrxQvgp7vPQKPEPLFdGT8vn03Qz5EXw2IRddmc3EDUWNvFSCvdupKXLONpuPVolC5Qbg2EN450a8ASIwt5B0Kb2RfOpIk1OVWMtHi36Pmnd3QHLTIELfF33c3psxJFg4qHgmKS5vM0x7d4B5qZyV3ag5znCPOz13W6I78MF3gE0GvePKWe5O4bqzkirFqKhppc1ylzmFQiGqWeL +save master_pw password.txt \ No newline at end of file diff --git a/poc/vuln-3.poc b/poc/vuln-3.poc index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2ab5420671ac020625f0ccf2d4118a027b078bef 100644 --- a/poc/vuln-3.poc +++ b/poc/vuln-3.poc @@ -0,0 +1,5 @@ +put http://example.com u p +put http://example.com.au u p +put http://example.co.uk u p +list +save master_pw passwords.txt \ No newline at end of file diff --git a/poc/vuln-4.poc b/poc/vuln-4.poc index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9650611e0023f8836bb7e36e00740d3548a36a0a 100644 --- a/poc/vuln-4.poc +++ b/poc/vuln-4.poc @@ -0,0 +1,4 @@ +put h user p +put h user cGKZu2X69wXHiGZJfWpsXsT8NmxVWKl2f29XwrfgSXhGmm82f9xJLedi8CrHGYDsHkSi5Ep1Y66A1igqmccAPtUSdMPzkCZnxPbqkaIZ9ZRK81N6hUVGzlokSTDSmKKavX0YdG0KyB7kGOQwKvzmGHUkcnULUDU5Un8JGtN3iic5klcNWXSGpNUMWTgWJ7O5eGy8t45WQ8zj1yr9zS1ZTUPnAyHYlhl9wyaLvdV0ijHfwl24MLmA7GZlg6eIcSKJIq7KFyyGcsLXNWQnPpbBjuhni78CAyz7iL8LlwlNPCcqlJ8JYuWljtzQzQqViLmdTbcdz4XcR3f0iCGqZ9rcbT4NW4lhnWLCjtvRIVbCG9W5CoHbPjHmJw8kTRnge0ywkIIfPHpSKSARDfmCr82Ri9swi96RnqbAcPQmqBtfFPLuohlWlAVluJJlg0U1301FGkBABX63LO5FWGMKaCDFaY0ZOSK3BhoJQZKo83XS48XIEsz2fMQVJfLI083AKqe2kgihq8vw1DctMW0I2MkeoRB1ZTaAXIPedyEDjLKK70subPH68rWb9zfYPv7bT7qm7sJkcnAp6t6unffJzr5wpmkf44IyNVTSBG90PlDf2jgsObag0c7iaypswu9pjccqkPBdFTOXAfyT7rNS8iLhhopMo5Zl6BeXUEeegbUiLKiXNiZmDM1zv07eSvvDlvnCNNPEi2vDb7VWzXp3azoj96UOvRH4u6ZitRJDY3TnzW7muke6a9E027iD4uujCKxJ5uLbmdRVHp2YbC1WObR9x4mxMOt4oIPtG405NkPrxQvgp7vPQKPEPLFdGT8vn03Qz5EXw2IRddmc3EDUWNvFSCvdupKXLONpuPVolC5Qbg2EN450a8ASIwt5B0Kb2RfOpIk1OVWMtHi36Pmnd3QHLTIELfF33c3psxJFg4qHgmKS5vM0x7d4B5qZyV3ag5znCPOz13W6I78MF3gE0GvePKWe5O4bqzkirFqKhppc1ylzmFQiGqW +list +save master_pw password.txt \ No newline at end of file diff --git a/poc/vuln-5.poc b/poc/vuln-5.poc index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f7134abcb30ab89a97ff024718d728d5d3c44f19 100644 --- a/poc/vuln-5.poc +++ b/poc/vuln-5.poc @@ -0,0 +1,14 @@ +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com u p +put http://example.com user password +list +save master_pw passwords.txt \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3711711efdc43ef14f1b0c35010ba42af722a536 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/original/passbook.c b/src/original/passbook.c index 2a2ae56b90e1190bb5c4f554e48fa41c928ab935..b9446a73bbf763967c58bd0214d7a632bf6123b5 100644 --- a/src/original/passbook.c +++ b/src/original/passbook.c @@ -67,7 +67,7 @@ static node_t *node_new(const char *url, const cred_t cred){ new->url = strdup(url); assert(new->url != NULL && "new: strdup url failed"); new->cred.username = strdup(cred.username); - assert(new->cred.username != NULL && "new: strdup username failed"); + assert(new->cred.username != NULL && "new: strdup username failed"); new->cred.password = strdup(cred.password); assert(new->cred.password != NULL && "new: strdup password failed"); new->left = NULL; @@ -75,7 +75,7 @@ static node_t *node_new(const char *url, const cred_t cred){ return new; } -/* updates a node's credential in place: +/* updates a node's credential in place: replaces p's credential with that from q and frees q */ static void node_edit_cred(node_t * p, node_t *q){ free(p->cred.username); @@ -105,7 +105,7 @@ static node_t * node_insert(node_t *p, node_t *q){ if (q == NULL){ return p; } - /* we store a pointer to a node pointer that remembers where in the + /* we store a pointer to a node pointer that remembers where in the tree the new node needs to be added */ node_t ** new = NULL; node_t * const start = p; @@ -193,11 +193,11 @@ const char WHITESPACE[] = " \t\r\n"; unsigned int tokenise(char *str, char * toks[], unsigned int toksLen){ unsigned numToks = 0; while (numToks < toksLen){ - /* strip leading whitespace */ + /* strip leading whitespace */ size_t start = strspn(str,WHITESPACE); if (str[start] != '\0'){ - toks[numToks] = &(str[start]); - + toks[numToks] = &(str[start]); + /* compute the length of the token */ const size_t tokLen = strcspn(toks[numToks],WHITESPACE); if (tokLen > 0){ @@ -249,7 +249,7 @@ nodeptr_list_t list_push(nodeptr_list_t lst, const node_t *p){ assert(n != NULL && "push: malloc failed"); n->p = p; n->next = lst.head; - n->prev = NULL; + n->prev = NULL; if (lst.head != NULL){ assert(lst.last != NULL); lst.head->prev = n; @@ -258,7 +258,7 @@ nodeptr_list_t list_push(nodeptr_list_t lst, const node_t *p){ lst.last = n; } lst.head = n; - + return lst; } @@ -314,7 +314,7 @@ void print_inorder(const node_t *p){ lst = list_push(lst,p->left); p = p->left; } - + // pop from the stack to simulate the return const node_t *q; lst = list_pop(lst,&q); @@ -338,14 +338,14 @@ void node_save(const node_t *p, FILE *f){ fprintf(f,"%s",INSTRUCTION_PUT); fprintf(f," "); fprintf(f,"%s",p->url); - fprintf(f," "); - fprintf(f,"%s",p->cred.username); - fprintf(f," "); + fprintf(f," "); + fprintf(f,"%s",p->cred.username); + fprintf(f," "); fprintf(f,"%s",p->cred.password); fprintf(f,"\n"); } -/* save the master password to the given file. We save a "masterpw" +/* save the master password to the given file. We save a "masterpw" instruction that will cause the passbook to prompt the user for the given master password the next time the file is read */ void masterpw_save(const char *pw, FILE *f){ @@ -396,12 +396,12 @@ int save_levelorder(const node_t *p, const char *masterpw, static int execute(void){ char * toks[4]; /* these are pointers to start of different tokens */ const unsigned int numToks = tokenise(inst,toks,4); - + if (numToks == 0){ /* blank line */ return 0; } - + if (strcmp(toks[0],INSTRUCTION_GET) == 0){ if (numToks != 2){ debug_printf("Expected 1 argument to %s instruction but instead found %u\n",INSTRUCTION_GET,numToks-1); @@ -422,7 +422,7 @@ static int execute(void){ } debug_printf("Removing: %s\n",toks[1]); map = rem(map,toks[1]); - + } else if (strcmp(toks[0],INSTRUCTION_PUT) == 0){ if (numToks != 4){ debug_printf("Expected 3 arguments to %s instruction but instead found %u\n",INSTRUCTION_PUT,numToks-1); @@ -456,8 +456,8 @@ static int execute(void){ exit(1); // exit immediately } #else - return -1; -#endif + return -1; +#endif } else if (strcmp(toks[0],INSTRUCTION_LIST) == 0){ if (numToks != 1){ @@ -470,7 +470,7 @@ static int execute(void){ debug_printf("Unrecognised instruction %s\n",toks[0]); return -1; } - + return 0; } @@ -478,7 +478,7 @@ static int execute(void){ is returned. Returns < 0 on failure. */ static int run(FILE *f){ assert(f != NULL); - + int instructionCount = 0; while (instructionCount < MAX_INSTRUCTIONS){ memset(inst,0,sizeof(inst)); @@ -522,7 +522,7 @@ static int run(FILE *f){ return instructionCount; }else{ /* see if we are at end of file by trying to do one more read. - this is necessary if the final line of the file ends in a + this is necessary if the final line of the file ends in a newline '\n' character */ char c; int res = fread(&c,1,1,f); @@ -561,7 +561,7 @@ int main(const int argc, const char * argv[]){ fprintf(stderr," use - to read from standard input\n"); exit(0); } - + for (int i = 1; i<argc; i++){ printf("Running on input file %s\n",argv[i]); FILE *f; diff --git a/src/vuln-1/passbook.c b/src/vuln-1/passbook.c index 2a2ae56b90e1190bb5c4f554e48fa41c928ab935..554fea388771e342db8ac709d902f25b049d336a 100644 --- a/src/vuln-1/passbook.c +++ b/src/vuln-1/passbook.c @@ -7,6 +7,11 @@ #include "debug.h" +#define MAX_LINE_LENGTH 1022 +#define MAX_INSTRUCTIONS 1024 +/* two extra chars in each line: the newline '\n' and NUL '\0' */ +#define INSTRUCTION_LENGTH (MAX_LINE_LENGTH + 2) + #ifdef PASSBOOK_LIBFUZZER #include <stdint.h> const char LIBFUZZER_INPUT_FILE[] = "libFuzzerInput.tmp"; @@ -64,7 +69,9 @@ static void node_print(const node_t *p){ static node_t *node_new(const char *url, const cred_t cred){ node_t *new = malloc(sizeof(node_t)); assert(new != NULL && "new: malloc failed"); - new->url = strdup(url); + new->url = malloc(200); // Vulnerability, almost all commercial lengths are < 100, so 200 seems safe + // But URLs exist with length > 200, so this is reasonable error + strcpy(new->url, url); assert(new->url != NULL && "new: strdup url failed"); new->cred.username = strdup(cred.username); assert(new->cred.username != NULL && "new: strdup username failed"); @@ -214,12 +221,6 @@ unsigned int tokenise(char *str, char * toks[], unsigned int toksLen){ return numToks; } -#define MAX_LINE_LENGTH 1022 -#define MAX_INSTRUCTIONS 1024 -/* two extra chars in each line: the newline '\n' and NUL '\0' */ -#define INSTRUCTION_LENGTH (MAX_LINE_LENGTH+2) - - /* a global instruction buffer */ char inst[INSTRUCTION_LENGTH]; diff --git a/src/vuln-2/passbook.c b/src/vuln-2/passbook.c index 2a2ae56b90e1190bb5c4f554e48fa41c928ab935..a4a1acd7fdb4d7d23e33e7b9ed12bd5df5d8d1b1 100644 --- a/src/vuln-2/passbook.c +++ b/src/vuln-2/passbook.c @@ -78,11 +78,13 @@ static node_t *node_new(const char *url, const cred_t cred){ /* updates a node's credential in place: replaces p's credential with that from q and frees q */ static void node_edit_cred(node_t * p, node_t *q){ - free(p->cred.username); - free(p->cred.password); - p->cred.username = q->cred.username; - p->cred.password = q->cred.password; + p->cred.username = realloc(p->cred.username, 1013); // Vulnerability here + p->cred.password = realloc(p->cred.password, 1013); + + strcpy(p->cred.username, q->cred.username); + strcpy(p->cred.password, q->cred.password); + free(q->url); free(q); } diff --git a/src/vuln-3/passbook.c b/src/vuln-3/passbook.c index 2a2ae56b90e1190bb5c4f554e48fa41c928ab935..73509fe3b384897ea31addbbe281e0cb732605ad 100644 --- a/src/vuln-3/passbook.c +++ b/src/vuln-3/passbook.c @@ -274,7 +274,7 @@ nodeptr_list_t list_pop(nodeptr_list_t lst, const node_t **out){ lst.head = NULL; lst.last = NULL; }else{ - nodeptr_list_elem_t *ret = lst.head->next; + nodeptr_list_elem_t *ret = lst.head; // Vulnerability free(lst.head); lst.head = ret; } diff --git a/src/vuln-4/passbook.c b/src/vuln-4/passbook.c index 2a2ae56b90e1190bb5c4f554e48fa41c928ab935..2628d75b76d8f8b32e3c04af13a9c35db6e9c24b 100644 --- a/src/vuln-4/passbook.c +++ b/src/vuln-4/passbook.c @@ -78,11 +78,12 @@ static node_t *node_new(const char *url, const cred_t cred){ /* updates a node's credential in place: replaces p's credential with that from q and frees q */ static void node_edit_cred(node_t * p, node_t *q){ - free(p->cred.username); - free(p->cred.password); + p->cred.username = realloc(p->cred.username, sizeof(char)*(strlen(p->cred.username)+1002)); // Vulnerability + p->cred.password = realloc(p->cred.password, sizeof(char)*(strlen(p->cred.password)+1002)); + + strcpy(p->cred.username, q->cred.username); + strcpy(p->cred.password, q->cred.password); - p->cred.username = q->cred.username; - p->cred.password = q->cred.password; free(q->url); free(q); } diff --git a/src/vuln-5/passbook.c b/src/vuln-5/passbook.c index 2a2ae56b90e1190bb5c4f554e48fa41c928ab935..41447f797d456fe8c673f2b318c31414b14b2898 100644 --- a/src/vuln-5/passbook.c +++ b/src/vuln-5/passbook.c @@ -15,6 +15,10 @@ const char LIBFUZZER_INPUT_FILE[] = "libFuzzerInput.tmp"; #define fprintf(...) #endif +#define MAX_UPDATE 10 + +int g_curr_update = 0; + const char INSTRUCTION_PUT[] = "put"; const char INSTRUCTION_REM[] = "rem"; @@ -78,11 +82,19 @@ static node_t *node_new(const char *url, const cred_t cred){ /* updates a node's credential in place: replaces p's credential with that from q and frees q */ static void node_edit_cred(node_t * p, node_t *q){ - free(p->cred.username); - free(p->cred.password); - p->cred.username = q->cred.username; - p->cred.password = q->cred.password; + fprintf(stderr, "%d\n", g_curr_update); + if (++g_curr_update > MAX_UPDATE) { + p->cred.username = realloc(p->cred.username, sizeof(char)*(strlen(p->cred.username))); // Vulnerability + p->cred.password = realloc(p->cred.password, sizeof(char)*(strlen(p->cred.password))); + + strcpy(p->cred.username, q->cred.username); + strcpy(p->cred.password, q->cred.password); + } + else { + p->cred.username = q->cred.username; + p->cred.password = q->cred.password; + } free(q->url); free(q); }