/* fzem/fzem_fuzz.c 02.25.2009 fzem Krakow Labs Development [www.krakowlabs.com] -> fzem "MUA security just met its match" rush@KL (Jeremy Brown) [rush[at]krakowlabs[dot]com] Fuzzing Module -> fzem.tar.gz Associated Files & Information: http://www.krakowlabs.com/dev/fuz/fzem/fzem http://www.krakowlabs.com/dev/fuz/fzem/fzem.c.txt http://www.krakowlabs.com/dev/fuz/fzem/fzem_fuzz.c.txt http://www.krakowlabs.com/dev/fuz/fzem/core.h.txt http://www.krakowlabs.com/dev/fuz/fzem/fuzz.h.txt http://www.krakowlabs.com/dev/fuz/fzem/Makefile.txt http://www.krakowlabs.com/dev/fuz/fzem/fzem_doc.txt http://www.krakowlabs.com/dev/fuz/fzem/fzem.tar.gz http://www.krakowlabs.com/dev/fuz/fzem/fzem.jpeg fzem/fzem_fuzz.c */ #include #include #include #include #include #include #include #include #include "core.h" #include "fuzz.h" void fzem_pop_hdrs_stage_hlpr(char *buf, int cli, char *data, int len) { if(strstr(buf, "retr") || strstr(buf, "RETR")) { send(cli, data, len, 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "dele") || strstr(buf, "DELE")) { send(cli, POP_OK_DELE_RESP, strlen(POP_OK_DELE_RESP), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "quit") || strstr(buf, "QUIT")) { send(cli, POP_OK_QUIT_RESP, strlen(POP_OK_QUIT_RESP), 0); memset(buf, 0, BUFSIZE); return; } } void fzem_pop_hdrs_stage1(char *buf, int cli, int n) { fzem_fzof_gen(); int len = (strlen(fuzz[n].data)*MAILHDRTLONE)+512; char stage1[len]; snprintf(stage1, len, "+OK 100 octets\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n\r\nfzem :)\r\n.\r\n", mail[0].header, fuzz[n].data, mail[1].header, fuzz[n].data, mail[2].header, fuzz[n].data, mail[3].header, fuzz[n].data, mail[4].header, fuzz[n].data, mail[5].header, fuzz[n].data, mail[6].header, fuzz[n].data, mail[7].header, fuzz[n].data, mail[8].header, fuzz[n].data, mail[9].header, fuzz[n].data, mail[10].header, fuzz[n].data); fzem_pop_hdrs_stage_hlpr(buf, cli, stage1, strlen(stage1)); memset(buf, 0, BUFSIZE); recv(cli, buf, BUFSIZE, 0); fzem_pop_hdrs_stage_hlpr(buf, cli, stage1, strlen(stage1)); memset(buf, 0, BUFSIZE); memset(stage1, 0, len); } void fzem_pop_hdrs_stage2(char *buf, int cli, int n) { fzem_fzof_gen(); int len = (strlen(fuzz[n].data)*MAILHDRTLTWO)+512; char stage2[len]; snprintf(stage2, len, "+OK 100 octets\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n\r\nfzem :)\r\n.\r\n", mail[11].header, fuzz[n].data, mail[12].header, fuzz[n].data, mail[13].header, fuzz[n].data, mail[14].header, fuzz[n].data, mail[15].header, fuzz[n].data, mail[16].header, fuzz[n].data, mail[17].header, fuzz[n].data, mail[18].header, fuzz[n].data, mail[19].header, fuzz[n].data); fzem_pop_hdrs_stage_hlpr(buf, cli, stage2, strlen(stage2)); memset(buf, 0, BUFSIZE); recv(cli, buf, BUFSIZE, 0); fzem_pop_hdrs_stage_hlpr(buf, cli, stage2, strlen(stage2)); memset(buf, 0, BUFSIZE); memset(stage2, 0, len); } void fzem_pop_hdrs_stage3(char *buf, int cli, int n) { fzem_fzof_gen(); int len = (strlen(fuzz[n].data)*MIMEHDRTL)+512; char stage3[len]; snprintf(stage3, len, "+OK 100 octets\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n%s %s\r\n\r\nfzem :)\r\n.\r\n", mime[0].header, fuzz[n].data, mime[1].header, fuzz[n].data, mime[2].header, fuzz[n].data, mime[3].header, fuzz[n].data, mime[4].header, fuzz[n].data, mime[5].header, fuzz[n].data, mime[6].header, fuzz[n].data, mime[7].header, fuzz[n].data, mime[8].header, fuzz[n].data, mime[9].header, fuzz[n].data, mime[10].header, fuzz[n].data, mime[11].header, fuzz[n].data, mime[12].header, fuzz[n].data); fzem_pop_hdrs_stage_hlpr(buf, cli, stage3, strlen(stage3)); memset(buf, 0, BUFSIZE); recv(cli, buf, BUFSIZE, 0); fzem_pop_hdrs_stage_hlpr(buf, cli, stage3, strlen(stage3)); memset(buf, 0, BUFSIZE); memset(stage3, 0, len); } int fzem_engine(int port, int mode, int debug, char *cfd, char *chd, int r) { char buf[BUFSIZE], fzdt[16+1], *md; int cli, serv, reuse = 1, cnum = -1, hnum = -1; struct sockaddr_in client, server; socklen_t len; if((mode == 1) && (r == 1)) md = "SMTP/OK Responses"; if((mode == 1) && (r == 2)) md = "SMTP/ERROR Responses"; if((mode == 1) && (r == 1) && (cfd != NULL)) md = "SMTP/Custom OK Responses"; if((mode == 1) && (r == 2) && (cfd != NULL)) md = "SMTP/Custom ERROR Responses"; if((mode == 2) && (cfd == NULL) && (chd == NULL)) md = "Headers"; if((mode == 2) && (cfd != NULL) && (chd == NULL)) md = "Headers/Custom Fuzz Data"; if((mode == 2) && (cfd == NULL) && (chd != NULL)) md = "Headers/Custom Header"; if((mode == 2) && (cfd != NULL) && (chd != NULL)) md = "Headers/Custom Fuzz Data & Headers"; if((mode == 3) && (r == 1)) md = "POP3/OK Responses"; if((mode == 3) && (r == 2)) md = "POP3/ERROR Responses"; if((mode == 3) && (r == 1) && (cfd != NULL)) md = "POP3/Custom OK Responses"; if((mode == 3) && (r == 2) && (cfd != NULL)) md = "POP3/Custom ERROR Responses"; if((mode == 4) && (r == 1)) md = "IMAP4/OK Responses"; if((mode == 4) && (r == 2)) md = "IMAP4/ERROR Responses"; if((mode == 4) && (r == 1) && (cfd != NULL)) md = "IMAP4/Custom OK Responses"; if((mode == 4) && (r == 2) && (cfd != NULL)) md = "IMAP4/Custom ERROR Responses"; printf("\n********** [%s] Mode **********\n\nKrakow Labs Development [www.krakowlabs.com] -> fzem\n\n********** [%s] Mode **********\n\n", md, md); printf("INFO: fzem server is starting\n"); server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = INADDR_ANY; fflush(stdout); if(debug == 1) printf("DEBUG: Creating Socket... "); if((serv = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("fzem_error: socket()\n"); return -1; } fflush(stdout); if(setsockopt(serv, SOL_SOCKET, SO_REUSEADDR, &reuse, (socklen_t)sizeof(reuse)) < 0) { printf("fzem_error: setsockopt()\n"); return -1; } fflush(stdout); if(debug == 1) printf("SUCCESS\nDEBUG: Binding to PORT %d... ", port); if(bind(serv, (struct sockaddr *)&server, sizeof(struct sockaddr)) < 0) { printf("fzem_error: bind(%d)\n", port); return -1; } fflush(stdout); if(listen(serv, 10) < 0) { printf("fzem_error: listen()\n"); return -1; } fflush(stdout); if(debug == 1) printf("SUCCESS\nDEBUG: listen() OK\n"); printf("INFO: fzem server is running\n"); while(1) { if((cli = accept(serv, (struct sockaddr *)&client, &len)) < 0) { printf("fzem_error: accept()\n"); return -1; } fflush(stdout); if(getpeername(cli, (struct sockaddr *)&client, &len) < 0) { printf("fzem_error: getpeername()\n"); return -1; } fflush(stdout); fzem_counter(&cnum); if(cnum == FZTL) cnum = 0; fzem_counter(&hnum); if(hnum == HDRTL) hnum = 0; if(cfd != NULL) { snprintf(fzdt, 16+1, "%s", cfd); } if(debug == 1) { if((mode == 1) && (r == 1) && (cfd == NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc); } if((mode == 1) && (r == 2) && (cfd == NULL)) { printf("DEBUG: [%d] Client %s connected --> ERROR RESPONSE FUZZING WITH: (%s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc); } if((mode == 1) && (r == 1) && (cfd != NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s [%d bytes])\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd)); } if((mode == 1) && (r == 2) && (cfd != NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s [%d bytes])\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd)); } if((mode == 2) && (cfd == NULL) && (chd == NULL)) { printf("DEBUG: [%d] Client %s connected --> FUZZING HEADERS WITH: (FUZZING ORACLE)\n", cnum+1, inet_ntoa(client.sin_addr)); } if((mode == 2) && (cfd != NULL) && (chd == NULL)) { if(hnum <= 19) printf("DEBUG: [%d] Client %s connected --> CUSTOM FUZZING DATA WITH: (%s [%d bytes] + %s)\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd), mail[hnum].header); if(hnum >= 20) printf("DEBUG: [%d] Client %s connected --> CUSTOM FUZZING DATA WITH: (%s [%d bytes] + %s)\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd), mime[hnum-20].header); } if((mode == 2) && (cfd == NULL) && (chd != NULL)) { printf("DEBUG: [%d] Client %s connected --> CUSTOM HEADER FUZZING WITH: (%s + %s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc, chd); } if((mode == 2) && (cfd != NULL) && (chd != NULL)) { printf("DEBUG: [%d] Client %s connected --> CUSTOM FUZZING WITH: (%s [%d bytes] + %s)\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd), chd); } if((mode == 3) && (r == 1) && (cfd == NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc); } if((mode == 3) && (r == 2) && (cfd == NULL)) { printf("DEBUG: [%d] Client %s connected --> ERROR RESPONSE FUZZING WITH: (%s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc); } if((mode == 3) && (r == 1) && (cfd != NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s [%d bytes])\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd)); } if((mode == 3) && (r == 2) && (cfd != NULL)) { printf("DEBUG: [%d] Client %s connected --> ERROR RESPONSE FUZZING WITH: (%s [%d bytes])\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd)); } if((mode == 4) && (r == 1) && (cfd == NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc); } if((mode == 4) && (r == 2) && (cfd == NULL)) { printf("DEBUG: [%d] Client %s connected --> ERROR RESPONSE FUZZING WITH: (%s)\n", cnum+1, inet_ntoa(client.sin_addr), fuzz[cnum].desc); } if((mode == 4) && (r == 1) && (cfd != NULL)) { printf("DEBUG: [%d] Client %s connected --> OK RESPONSE FUZZING WITH: (%s [%d bytes])\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd)); } if((mode == 4) && (r == 2) && (cfd != NULL)) { printf("DEBUG: [%d] Client %s connected --> ERROR RESPONSE FUZZING WITH: (%s [%d bytes])\n", cnum+1, inet_ntoa(client.sin_addr), fzdt, strlen(cfd)); } } fflush(stdout); if(mode == 1) { fzem_smtp_resp(buf, cli, cnum, cfd, r); } if((mode == 2) && (cfd == NULL) && (chd == NULL)) { send(cli, POP_OK_BEGIN, strlen(POP_OK_BEGIN), 0); fzem_pop_hdrs(buf, cli); } if((mode == 2) && (cfd != NULL) || (chd != NULL)) { send(cli, POP_OK_BEGIN, strlen(POP_OK_BEGIN), 0); fzem_pop_hdrs_custom(buf, cli, cnum, hnum, cfd, chd); } if(mode == 3) { fzem_pop_resp(buf, cli, cnum, cfd, r); } if(mode == 4) { fzem_imap_resp(buf, cli, cnum, cfd, r); } } return 0; } void fzem_pop_hdrs_hlpr_one(char *buf, int cli, int z) { char list[32*FZTL*3], uidl[32*FZTL*3]; int i; if(strstr(buf, "auth") || strstr(buf, "AUTH")) { send(cli, POP_ERR_AUTH_RESP, strlen(POP_ERR_AUTH_RESP), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "capa") || strstr(buf, "CAPA")) { send(cli, POP_OK_CAPA_RESP, strlen(POP_OK_CAPA_RESP), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "user") || strstr(buf, "USER")) { send(cli, POP_OK_LOGIN_RESP, strlen(POP_OK_LOGIN_RESP), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "pass") || strstr(buf, "PASS") || strstr(buf, "apop") || strstr(buf, "APOP") || strstr(buf, "APop")) // balsa does "APop" { send(cli, POP_OK_LOGIN_SUCCESS, strlen(POP_OK_LOGIN_SUCCESS), 0); memset(buf, 0, BUFSIZE); } if(z == 1) { if(strstr(buf, "stat") || strstr(buf, "STAT")) { send(cli, POP_OK_STAT_RESP, strlen(POP_OK_STAT_RESP), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "list") || strstr(buf, "LIST") || strstr(buf, "List")) // balsa does "List" { send(cli, POP_OK_LIST_RESPA, strlen(POP_OK_LIST_RESPA), 0); for(i = 1; i <= (FZTL*3); i++) { snprintf(list, sizeof(list)-1, "%d 100\r\n", i); send(cli, list, strlen(list), 0); } send(cli, POP_OK_LIST_RESPB, strlen(POP_OK_LIST_RESPB), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "uidl") || strstr(buf, "UIDL")) { send(cli, POP_OK_UIDL_RESPA, strlen(POP_OK_UIDL_RESPA), 0); for(i = 1; i <= (FZTL*3); i++) { snprintf(uidl, sizeof(uidl)-1, "%d w00t00w00t00w00t00w00t00w\r\n", i); send(cli, uidl, strlen(uidl), 0); } send(cli, POP_OK_UIDL_RESPB, strlen(POP_OK_UIDL_RESPB), 0); memset(buf, 0, BUFSIZE); } } if(z == 2) { if(strstr(buf, "stat") || strstr(buf, "STAT")) { send(cli, POP_HDR_ST_CUSTOM, strlen(POP_HDR_ST_CUSTOM), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "list") || strstr(buf, "LIST")) { send(cli, POP_HDR_LT_CUSTOM, strlen(POP_HDR_LT_CUSTOM), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "uidl") || strstr(buf, "UIDL")) { send(cli, POP_HDR_UL_CUSTOM, strlen(POP_HDR_UL_CUSTOM), 0); memset(buf, 0, BUFSIZE); } } } void fzem_pop_hdrs_hlpr_two(char *buf, int cli) { if(strstr(buf, "dele") || strstr(buf, "DELE")) { send(cli, POP_OK_DELE_RESP, strlen(POP_OK_DELE_RESP), 0); memset(buf, 0, BUFSIZE); } if(strstr(buf, "stls") || strstr(buf, "STLS")) { send(cli, POP_ERR_STLS_RESP, strlen(POP_ERR_STLS_RESP), 0); memset(buf, 0, BUFSIZE); } } void fzem_pop_hdrs(char *buf, int cli) { int n; while(recv(cli, buf, BUFSIZE, 0)) { fzem_pop_hdrs_hlpr_one(buf, cli, POP_HDRS); if(strstr(buf, "retr") || strstr(buf, "RETR")) { for(n = 0; n <= (FZTL-1); n++) { fzem_pop_hdrs_stage1(buf, cli, n); recv(cli, buf, BUFSIZE, 0); fzem_pop_hdrs_stage2(buf, cli, n); recv(cli, buf, BUFSIZE, 0); fzem_pop_hdrs_stage3(buf, cli, n); recv(cli, buf, BUFSIZE, 0); } } fzem_pop_hdrs_hlpr_two(buf, cli); if(strstr(buf, "quit") || strstr(buf, "QUIT")) { send(cli, POP_OK_QUIT_RESP, strlen(POP_OK_QUIT_RESP), 0); memset(buf, 0, BUFSIZE); close(cli); return; } } } void fzem_pop_hdrs_custom(char *buf, int cli, int cnum, int hnum, char *cfd, char *chd) { fzem_fzof_gen(); int len = 0; if((cfd == NULL) && (chd != NULL)) { len = strlen(fuzz[cnum].data)+strlen(chd)+64; } if((cfd != NULL) && (chd == NULL)) { len = strlen(cfd)+16+64; } if((cfd != NULL) && (chd != NULL)) { len = strlen(cfd)+strlen(chd)+64; } char msg[len]; while(recv(cli, buf, BUFSIZE, 0)) { fzem_pop_hdrs_hlpr_one(buf, cli, POP_HDRS_CUSTOM); if(strstr(buf, "retr") || strstr(buf, "RETR")) { memset(msg, 0, len); if((cfd != NULL) && (chd == NULL) && (hnum <= 19)) { snprintf(msg, len, "+OK 100 octets\r\n%s %s\r\n\r\nfzem :)\r\n.\r\n", mail[hnum].header, cfd); } if((cfd != NULL) && (chd == NULL) && (hnum >= 20)) { snprintf(msg, len, "+OK 100 octets\r\n%s %s\r\n\r\nfzem :)\r\n.\r\n", mime[hnum-20].header, cfd); } if((cfd == NULL) && (chd != NULL)) { snprintf(msg, len, "+OK 100 octets\r\n%s: %s\r\n\r\nfzem :)\r\n.\r\n", chd, fuzz[cnum].data); } if((cfd != NULL) && (chd != NULL)) { snprintf(msg, len, "+OK 100 octets\r\n%s: %s\r\n\r\nfzem :)\r\n.\r\n", chd, cfd); } fzem_pop_hdrs_stage_hlpr(buf, cli, msg, strlen(msg)); memset(buf, 0, BUFSIZE); recv(cli, buf, BUFSIZE, 0); fzem_pop_hdrs_stage_hlpr(buf, cli, msg, strlen(msg)); memset(buf, 0, BUFSIZE); memset(msg, 0, len); } fzem_pop_hdrs_hlpr_two(buf, cli); if(strstr(buf, "quit") || strstr(buf, "QUIT")) { send(cli, POP_OK_QUIT_RESP, strlen(POP_OK_QUIT_RESP), 0); memset(buf, 0, BUFSIZE); close(cli); return; } } } void fzem_smtp_resp_hlpr(char *buf, int cli, char *resp, int len, char *data, int r) { int rr; if(r == 1) rr = SMTP_OK; if(r == 2) rr = SMTP_ERR; while(recv(cli, buf, BUFSIZE, 0)) { if(strstr(buf, "helo") || strstr(buf, "HELO") || strstr(buf, "ehlo") || strstr(buf, "EHLO")) { memset(resp, 0, len); snprintf(resp, len, "%d %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "data") || strstr(buf, "DATA")) { memset(resp, 0, len); snprintf(resp, len, "%d %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "quit") || strstr(buf, "QUIT")) { memset(resp, 0, len); snprintf(resp, len, "%d %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); close(cli); return; } if(!strstr(buf, "quit") && !strstr(buf, "QUIT") && !strstr(buf, "helo") && !strstr(buf, "HELO") && !strstr(buf, "ehlo") && !strstr(buf, "EHLO") && !strstr(buf, "data") && !strstr(buf, "DATA")) { memset(resp, 0, len); snprintf(resp, len, "%d %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } } } void fzem_smtp_resp(char *buf, int cli, int cnum, char *cfd, int r) { fzem_fzof_gen(); if(cfd == NULL) { int len = strlen(fuzz[cnum].data)+64; char resp[len]; memset(buf, 0, BUFSIZE); memset(resp, 0, len); snprintf(resp, len, "%d %s\r\n", SMTP_BEGIN_RESP, fuzz[cnum].data); send(cli, resp, strlen(resp), 0); fzem_smtp_resp_hlpr(buf, cli, resp, len, fuzz[cnum].data, r); } if(cfd != NULL) { int len = strlen(cfd)+64; char resp[len]; memset(buf, 0, BUFSIZE); memset(resp, 0, len); snprintf(resp, len, "%d %s\r\n", SMTP_BEGIN_RESP, cfd); send(cli, resp, strlen(resp), 0); fzem_smtp_resp_hlpr(buf, cli, resp, strlen(resp), cfd, r); } } void fzem_pop_resp_hlpr(char *buf, int cli, char *resp, int len, char *data, int r) { char *rr; if(r == 1) rr = POP_OK; if(r == 2) rr = POP_ERR; while(recv(cli, buf, BUFSIZE, 0)) { if(strstr(buf, "auth") || strstr(buf, "AUTH")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", POP_ERR, data); // thunderbird love send(cli, resp, strlen(resp), 0); } if(strstr(buf, "stls") || strstr(buf, "STLS")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "capa") || strstr(buf, "CAPA")) { memset(resp, 0, len); snprintf(resp, len, "%s\r\n%s\r\n.\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "user") || strstr(buf, "USER")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "pass") || strstr(buf, "PASS") || strstr(buf, "apop") || strstr(buf, "APOP")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "stat") || strstr(buf, "STAT")) { memset(resp, 0, len); snprintf(resp, len, "%s %s 100\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "list") || strstr(buf, "LIST")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n1 100\r\n.\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "retr") || strstr(buf, "RETR")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\nfzem :)\r\n.\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "uidl") || strstr(buf, "UIDL")) { memset(resp, 0, len); snprintf(resp, len, "%s\r\n1 %s\r\n.\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "dele") || strstr(buf, "DELE")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "quit") || strstr(buf, "QUIT")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", rr, data); send(cli, resp, strlen(resp), 0); close(cli); return; } } } void fzem_pop_resp(char *buf, int cli, int cnum, char *cfd, int r) { fzem_fzof_gen(); if(cfd == NULL) { int len = strlen(fuzz[cnum].data)+64; char resp[len]; memset(buf, 0, BUFSIZE); memset(resp, 0, len); snprintf(resp, len, "+OK %s\r\n", fuzz[cnum].data); send(cli, resp, strlen(resp), 0); fzem_pop_resp_hlpr(buf, cli, resp, len, fuzz[cnum].data, r); } if(cfd != NULL) { int len = strlen(cfd)+64; char resp[len]; memset(buf, 0, BUFSIZE); memset(resp, 0, len); snprintf(resp, len, "+OK %s\r\n", cfd); send(cli, resp, strlen(resp), 0); fzem_pop_resp_hlpr(buf, cli, resp, len, cfd, r); } } void fzem_imap_resp_hlpr(char *buf, int cli, char *resp, int len, char *data, int r) { char *rr, *token, *tag; if(r == 1) rr = IMAP_OK; if(r == 2) rr = IMAP_ERR; while(recv(cli, buf, BUFSIZE, 0)) { char buffer[strlen(buf)+1]; sprintf(buffer, "%s", buf); token = strtok(buffer, " "); tag = token; if(strstr(buf, "capability") || strstr(buf, "CAPABILITY")) { memset(resp, 0, len); snprintf(resp, len, "* CAPABILITY IMAP4rev1 %s\r\n%s %s CAPABILITY completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "login") || strstr(buf, "LOGIN")) { memset(resp, 0, len); snprintf(resp, len, "%s %s LOGIN completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "authenticate") || strstr(buf, "AUTHENTICATE")) { memset(resp, 0, len); snprintf(resp, len, "+ %s\r\n", data); send(cli, resp, strlen(resp), 0); recv(cli, buf, BUFSIZE, 0); send(cli, resp, strlen(resp), 0); recv(cli, buf, BUFSIZE, 0); memset(resp, 0, len); snprintf(resp, len, "%s %s AUTHENTICATE completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "append") || strstr(buf, "APPEND")) { memset(resp, 0, len); snprintf(resp, len, "%s %s APPEND completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "check") || strstr(buf, "CHECK")) { memset(resp, 0, len); snprintf(resp, len, "%s %s CHECK completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "close") || strstr(buf, "CLOSE")) { memset(resp, 0, len); snprintf(resp, len, "%s %s CLOSE completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "copy") || strstr(buf, "COPY")) { memset(resp, 0, len); snprintf(resp, len, "%s %s COPY completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "create") || strstr(buf, "CREATE")) { memset(resp, 0, len); snprintf(resp, len, "%s %s CREATE completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "delete") || strstr(buf, "DELETE")) { memset(resp, 0, len); snprintf(resp, len, "%s %s DELETE completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "examine") || strstr(buf, "EXAMINE")) // fuzzes flags { memset(resp, 0, len); snprintf(resp, len, "* 1 EXISTS\r\n* FLAGS (\\Answered \\%s \\Deleted \\Seen \\Draft)\r\n* 1 RECENT\r\n%s %s EXAMINE completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "expunge") || strstr(buf, "EXPUNGE")) { memset(resp, 0, len); snprintf(resp, len, "* %s EXPUNGE\r\n%s %s EXPUNGE completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "fetch") || strstr(buf, "FETCH")) { memset(resp, 0, len); snprintf(resp, len, "* 1 FETCH %s\r\n%s %s FETCH completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "list") || strstr(buf, "LIST")) { memset(resp, 0, len); snprintf(resp, len, "* LIST () \".\" \"/%s\" fzem\r\n%s %s LIST completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "lsub") || strstr(buf, "LSUB")) { memset(resp, 0, len); snprintf(resp, len, "* LSUB () \".\" %s\r\n%s %s LSUB completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "noop") || strstr(buf, "NOOP")) { memset(resp, 0, len); snprintf(resp, len, "%s %s NOOP completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "rename") || strstr(buf, "RENAME")) { memset(resp, 0, len); snprintf(resp, len, "%s %s RENAME completed %s\r\n", tag, rr, data); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "search") || strstr(buf, "SEARCH")) { memset(resp, 0, len); snprintf(resp, len, "* SEARCH 1 2 %s\r\n%s %s SEARCH completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "select") || strstr(buf, "SELECT")) // fuzzes flags { memset(resp, 0, len); snprintf(resp, len, "* 1 EXISTS\r\n* FLAGS (\\Answered \\%s \\Deleted \\Seen \\Draft)\r\n* 1 RECENT\r\n%s %s SELECT completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "status") || strstr(buf, "STATUS")) { memset(resp, 0, len); snprintf(resp, len, "* STATUS fzem (%s)\r\n%s %s STATUS completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "store") || strstr(buf, "STORE")) { memset(resp, 0, len); snprintf(resp, len, "* 1 FETCH FLAGS (\\Deleted \\%s)\r\n%s %s STORE completed\r\n", data, tag, rr); send(cli, resp, strlen(resp), 0); } if(strstr(buf, "subscribe") || strstr(buf, "SUBSCRIBE")) { char *tok; memset(resp, 0, len); tok = strtok(buf, " "); tok = strtok(NULL, " "); if(strcmp(tok, "SUBSCRIBE") == 0) { snprintf(resp, len, "%s %s SUBSCRIBE completed %s\r\n", tag, rr, data); } if(strcmp(tok, "UNSUBSCRIBE") == 0) { snprintf(resp, len, "%s %s UNSUBSCRIBE completed %s\r\n", tag, rr, data); } send(cli, resp, strlen(resp), 0); } if(strstr(buf, "logout") || strstr(buf, "LOGOUT")) { memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n%s %s LOGOUT completed\r\n", IMAP_QUIT, data, tag, rr); send(cli, resp, strlen(resp), 0); close(cli); return; } } } /* Interesting quote from rfc2060: "The client MUST be prepared to accept any response at all times." */ void fzem_imap_resp(char *buf, int cli, int cnum, char *cfd, int r) { fzem_fzof_gen(); if(cfd == NULL) { int len = strlen(fuzz[cnum].data)+64; char resp[len]; memset(buf, 0, BUFSIZE); memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", IMAP_BEGIN, fuzz[cnum].data); send(cli, resp, strlen(resp), 0); fzem_imap_resp_hlpr(buf, cli, resp, len, fuzz[cnum].data, r); } if(cfd != NULL) { int len = strlen(cfd)+64; char resp[len]; memset(buf, 0, BUFSIZE); memset(resp, 0, len); snprintf(resp, len, "%s %s\r\n", IMAP_BEGIN, cfd); send(cli, resp, strlen(resp), 0); fzem_imap_resp_hlpr(buf, cli, resp, len, cfd, r); } } void fzem_list_hdr(void) { int i; printf("\nMAIL Headers\n------------\n"); for(i = 0; i <= 19; i++) { printf("[%d] %s\n", i+1, mail[i].header); } printf("\nMIME Headers\n------------\n"); for(i = 0; i <= 12; i++) { printf("[%d] %s\n", i+1, mime[i].header); } } void fzem_list_fzorc(void) { int i; printf("\nFUZZING ORACLE\n--------------\n"); for(i = 0; i <= (FZTL-1); i++) { printf("[%d] %s\n", i+1, fuzz[i].desc); } } void fzem_fzof_gen(void) { memset(of1, 'A', sizeof(of1)); fuzz[0].data = of1; memset(of2, 'A', sizeof(of2)); fuzz[1].data = of2; memset(of3, 'A', sizeof(of3)); fuzz[2].data = of3; memset(of4, 'A', sizeof(of4)); fuzz[3].data = of4; memset(of5, 'A', sizeof(of5)); fuzz[4].data = of5; memset(of6, 'A', sizeof(of6)); fuzz[5].data = of6; memset(of7, 'A', sizeof(of7)); fuzz[6].data = of7; memset(of8, 'A', sizeof(of8)); fuzz[7].data = of8; memset(of9, 'A', sizeof(of9)); fuzz[8].data = of9; memset(of10, 'A', sizeof(of10)); fuzz[9].data = of10; }