From 2a6debf2431f617fd4bbedd40c4b7be82e080cca Mon Sep 17 00:00:00 2001 From: Angus Hudson <ahudson1@student.unimelb.edu.au> Date: Mon, 14 Oct 2019 00:52:50 +1100 Subject: [PATCH] Introduced 5 vulnerabilities and PoC's --- poc/vuln-1.poc | 2 ++ poc/vuln-2.poc | 3 +++ poc/vuln-3.poc | 5 +++++ poc/vuln-4.poc | 4 ++++ poc/vuln-5.poc | 14 +++++++++++++ src/.DS_Store | Bin 0 -> 6148 bytes src/original/passbook.c | 44 ++++++++++++++++++++-------------------- src/vuln-1/passbook.c | 15 +++++++------- src/vuln-2/passbook.c | 10 +++++---- src/vuln-3/passbook.c | 2 +- src/vuln-4/passbook.c | 9 ++++---- src/vuln-5/passbook.c | 20 ++++++++++++++---- 12 files changed, 86 insertions(+), 42 deletions(-) create mode 100644 src/.DS_Store diff --git a/poc/vuln-1.poc b/poc/vuln-1.poc index e69de29..23df6ef 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 e69de29..51200a0 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 e69de29..2ab5420 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 e69de29..9650611 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 e69de29..f7134ab 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 GIT binary patch literal 6148 zcmZQzU|@7AO)+F(5MW?n;9!8zOq>i@0Z1N%F(jFwA|RR(Y(^$S9z!BSPEvVs0aR|3 z8r&fOiaQR5e1;;1Oons@r1(q9$xmWnU^tmnkds+lVqkEck%^gwm5rT)gNuWUmn$|n zBfmVjB(bEl*eS6n8pI1oEXhcMvP1IobKva6q_E7?@^}Fe=lr~q#LT?ZB9QXn%#_rm z#G;t+%)FHRa;N;#yp&?FIZz1>4o(ivcmav(Y9mt<9R(wE(^?&cYIAb~9R(9(v)Wot z4slgOThD~t%Bt#`+PayLaAstL&<y-g8b-|mr*t%rmIW8(<>cq3gE9n6;V3;C0;3@? z8Un*V1fWGF2lw#z>ZlJ#Ltr!nNDKi``Je!88aY7e1_%w3Vqj!o05u;$Gz-jVNI!r9 zBnHw7qCr|gG)OB0BZvhy1FV&SkpZHW5!?*{=>v61Kr~o810w@iI|CyFSUUr(ea8sV z&cF!K&cF!mp)f+UGcZE5GcZE5!<;utkA}c#2tY%C8A1zy>VH=T23-Arh^kR?Gz3ON zU|5C#Ba2J0ixap~#_m5*T??vD6QI(d+8<OMGlJ@Agc!IgW`YbTN<f7{)jdcnhz3{1 Vj0}*Pe6%3|3!zbZGz91$0sx(rQ$_#) literal 0 HcmV?d00001 diff --git a/src/original/passbook.c b/src/original/passbook.c index 2a2ae56..b9446a7 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 2a2ae56..554fea3 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 2a2ae56..a4a1acd 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 2a2ae56..73509fe 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 2a2ae56..2628d75 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 2a2ae56..41447f7 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); } -- GitLab