From 1756a9958003dd8a57848a2dc7dc2f9cdd942e9a Mon Sep 17 00:00:00 2001 From: "Nicholas.Ni" Date: Fri, 2 Jul 2021 00:49:48 +0800 Subject: [PATCH 01/11] Add reply status code match in http service --- hydra-http.c | 104 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/hydra-http.c b/hydra-http.c index a0769b9..f2b27e6 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -9,6 +9,7 @@ char *http_buf = NULL; #define END_CONDITION_MAX_LEN 100 static char end_condition[END_CONDITION_MAX_LEN]; int end_condition_type = -1; +int match_status_code = 0; int32_t webport; int32_t http_auth_mechanism = AUTH_UNASSIGNED; @@ -248,6 +249,25 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha ptr = ((char *)strchr(http_buf, ' ')); if (ptr != NULL) ptr++; + // check status + if (match_status_code != 0) { + char *status_code; + memset(status_code, 0, 3); + + for (int i = 0; i < 3; i++) { + *(status_code + i) = *(ptr + i); + } + + if (match_status_code == atoi(status_code)) { + if (end_condition == -1) { + if (debug) + hydra_report(stderr, "Status code condition %d match.\n", status_code); + hydra_report_found_host(port, ip, "www", fp); + hydra_completed_pair_found(); + } + } + } + if (ptr != NULL && (*ptr == '2' || *ptr == '3' || strncmp(ptr, "403", 3) == 0 || strncmp(ptr, "404", 3) == 0)) { #ifdef HAVE_PCRE if (end_condition_type >= 0 && hydra_string_match(http_buf, end_condition) != end_condition_type) { @@ -426,37 +446,67 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis // -1 error, hydra will exit, so print a good error message here /*POU CODE */ - char *start = strstr(miscptr, "F="); - if (start == NULL) - start = strstr(miscptr, "S="); - if (start != NULL) { - if (start[0] == 'F') - end_condition_type = 0; - else - end_condition_type = 1; + char *delim = ":"; + strtok(miscptr, delim); + char *p; - int condition_len = strlen(start); - memset(end_condition, 0, END_CONDITION_MAX_LEN); - if (condition_len >= END_CONDITION_MAX_LEN) { - hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); - return -1; + while ((p = strtok(NULL, delim))) { + if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { + char *match_text_start = strstr(p, "F="); + if (match_text_start == NULL) + match_text_start = strstr(p, "S="); + + if (match_text_start != NULL) { + if (match_text_start[0] == 'F') + end_condition_type = 0; + else + end_condition_type = 1; + + int condition_len = strlen(match_text_start); + memset(end_condition, 0, END_CONDITION_MAX_LEN); + if (condition_len >= END_CONDITION_MAX_LEN) { + hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); + return -1; + } + // copy condition witout starting string (F= or S= 2char) + strncpy(end_condition, match_text_start + 2, condition_len - 2); + if (debug) + hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); + + if (*(match_text_start - 1) == ' ') + match_text_start--; + memset(match_text_start, '\0', condition_len); + if (debug) + hydra_report(stderr, "Modificated options:%s\n", miscptr); + } else { + if (debug) + hydra_report(stderr, "Condition not found\n"); + } } - // copy condition witout starting string (F= or S= 2char) - strncpy(end_condition, start + 2, condition_len - 2); - if (debug) - hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); - if (*(start - 1) == ' ') - start--; - memset(start, '\0', condition_len); - if (debug) - hydra_report(stderr, "Modificated options:%s\n", miscptr); - } else { - if (debug) - hydra_report(stderr, "Condition not found\n"); + if (strstr(p, "c=") != NULL || strstr(p, 'C=') != NULL) { + if (strlen(p) != 2 + 3) { + hydra_report(stderr, "Invalid status code, eg: 200."); + return -1; + } + + char *status_code; + memset(status_code, 0, 3); + + strncpy(status_code, p + 2, 3); + + for (int i = 0; i < strlen(status_code); i++) { + if (!isdigit(*(status_code + i))) { + hydra_report(stderr, "Invalid status code, eg: 200"); + return -1; + } + } + + match_status_code = atoi(status_code); + free(status_code); + } } - return 0; } @@ -467,6 +517,8 @@ void usage_http(const char *service) { "NTLM or MD5\n" " (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each " "request\n" + " (c|C)=check for status code in the HTTP reply. If the reply status " + " code matches it, it is judged as successful \n" " (F|S)=check for text in the HTTP reply. S= means if this text is " "found, a\n" " valid account has been found, F= means if this string is " From a69c5d87d61b9db9e90952a7cd3fc1a4899ad988 Mon Sep 17 00:00:00 2001 From: "Nicholas.Ni" Date: Fri, 2 Jul 2021 09:34:25 +0800 Subject: [PATCH 02/11] fix hydra telnet in some terminals, login failure will be accompanied by %, for example:% Authenticate failed --- hydra-http.c | 9 ++++++--- hydra-telnet.c | 14 ++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/hydra-http.c b/hydra-http.c index f2b27e6..933cb14 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -504,7 +504,10 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis } match_status_code = atoi(status_code); - free(status_code); + + if (debug) { + hydra_report(stdout, "Find match reply status code: %d", match_status_code); + } } } return 0; @@ -517,8 +520,8 @@ void usage_http(const char *service) { "NTLM or MD5\n" " (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each " "request\n" - " (c|C)=check for status code in the HTTP reply. If the reply status " - " code matches it, it is judged as successful \n" + " (c|C)=check for status code in the HTTP reply. If the reply status code\n" + " matches it, it is judged as successful \n" " (F|S)=check for text in the HTTP reply. S= means if this text is " "found, a\n" " valid account has been found, F= means if this string is " diff --git a/hydra-telnet.c b/hydra-telnet.c index 39908f9..de6f541 100644 --- a/hydra-telnet.c +++ b/hydra-telnet.c @@ -37,12 +37,14 @@ int32_t start_telnet(int32_t s, char *ip, int32_t port, unsigned char options, c return 1; if (strchr(buf, '/') != NULL || strchr(buf, '>') != NULL || strchr(buf, '%') != NULL || strchr(buf, '$') != NULL || strchr(buf, '#') != NULL) { - hydra_report_found_host(port, ip, "telnet", fp); - hydra_completed_pair_found(); - free(buf); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 3; - return 1; + if (strstr(buf, "ailed") == NULL) { + hydra_report_found_host(port, ip, "telnet", fp); + hydra_completed_pair_found(); + free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) + return 3; + return 1; + } } (void)make_to_lower(buf); From a218726dbc04722e330dee90a96059b9cbd80b84 Mon Sep 17 00:00:00 2001 From: "Nicholas.Ni" Date: Mon, 5 Jul 2021 23:25:46 +0800 Subject: [PATCH 03/11] fix: Optimize the code --- .gitignore | 2 + hydra-http.c | 264 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 159 insertions(+), 107 deletions(-) diff --git a/.gitignore b/.gitignore index 4cf0c32..d325b29 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ pw-inspector pw-inspector.exe hydra.restore *~ +.vscode/ +build/ diff --git a/hydra-http.c b/hydra-http.c index 933cb14..489d8ff 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -9,11 +9,22 @@ char *http_buf = NULL; #define END_CONDITION_MAX_LEN 100 static char end_condition[END_CONDITION_MAX_LEN]; int end_condition_type = -1; -int match_status_code = 0; + +#define MAX_STATUS_CODE_SIZE 10 +int match_status_code[MAX_STATUS_CODE_SIZE]; int32_t webport; int32_t http_auth_mechanism = AUTH_UNASSIGNED; +void freeMemory(void **ptr) { + if (ptr != NULL && *ptr != NULL) { + free(*ptr); + *ptr = NULL; + } +} + +#define freeM(p) freeMemory((void **)(&(p))) + int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp, char *type, ptr_header_node ptr_head) { char *empty = ""; char *login, *pass, *buffer, buffer2[500]; @@ -34,7 +45,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha buffer_size = strlen(header) + 500; if (!(buffer = malloc(buffer_size))) { - free(header); + freeM(header); return 3; } @@ -86,8 +97,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha fooptr = buffer2; result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header); if (result == NULL) { - free(buffer); - free(header); + frefreeM(buffer); + freeM(header); return 3; } @@ -129,21 +140,21 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha } if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - free(buffer); - free(header); + freeM(buffer); + freeM(header); return 1; } // receive challenge if (http_buf != NULL) - free(http_buf); + freeM(http_buf); http_buf = hydra_receive_line(s); if (http_buf == NULL) { if (verbose) hydra_report(stderr, "[ERROR] Server did not answer\n"); - free(buffer); - free(header); + freeM(buffer); + freeM(header); return 3; } @@ -165,8 +176,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha // recover challenge from64tobits((char *)buf1, pos); - free(http_buf); - http_buf = NULL; + freeM(http_buf); // Send response buildAuthResponse((tSmbNtlmAuthChallenge *)buf1, (tSmbNtlmAuthResponse *)buf2, 0, login, pass, NULL, NULL); @@ -198,13 +208,13 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha } if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - free(buffer); - free(header); + freeM(buffer); + freeM(header); return 1; } if (http_buf != NULL) - free(http_buf); + freeM(http_buf); http_buf = hydra_receive_line(s); complete_line = 0; tmpreplybuf[0] = 0; @@ -215,20 +225,20 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha if (tmpreplybuf[0] == 0 && strstr(http_buf, "HTTP/1.") != NULL) { strncpy(tmpreplybuf, http_buf, sizeof(tmpreplybuf) - 1); tmpreplybuf[sizeof(tmpreplybuf) - 1] = 0; - free(http_buf); + freeM(http_buf); http_buf = hydra_receive_line(s); } else if (tmpreplybuf[0] != 0) { complete_line = 1; if ((tmpreplybufptr = malloc(strlen(tmpreplybuf) + strlen(http_buf) + 1)) != NULL) { strcpy(tmpreplybufptr, tmpreplybuf); strcat(tmpreplybufptr, http_buf); - free(http_buf); + freeM(http_buf); http_buf = tmpreplybufptr; if (debug) printf("http_buf now: %s\n", http_buf); } } else { - free(http_buf); + freeM(http_buf); http_buf = hydra_receive_line(s); } } @@ -238,8 +248,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha if (http_buf == NULL) { if (verbose) hydra_report(stderr, "[ERROR] Server did not answer\n"); - free(buffer); - free(header); + freeM(buffer); + freeM(header); return 3; } @@ -249,21 +259,19 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha ptr = ((char *)strchr(http_buf, ' ')); if (ptr != NULL) ptr++; + // check status - if (match_status_code != 0) { - char *status_code; - memset(status_code, 0, 3); + if (match_status_code != NULL) { + for (int i = 0; match_status_code[i]; i++) { + if (match_status_code[i] == atoi(ptr)) { + if (end_condition_type == -1) { + if (debug) + hydra_report(stderr, "Status code condition %d match.\n", match_status_code[i]); + hydra_report_found_host(port, ip, "www", fp); + hydra_completed_pair_found(); - for (int i = 0; i < 3; i++) { - *(status_code + i) = *(ptr + i); - } - - if (match_status_code == atoi(status_code)) { - if (end_condition == -1) { - if (debug) - hydra_report(stderr, "Status code condition %d match.\n", status_code); - hydra_report_found_host(port, ip, "www", fp); - hydra_completed_pair_found(); + goto finish; + } } } } @@ -284,8 +292,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha hydra_completed_pair_found(); } if (http_buf != NULL) { - free(http_buf); - http_buf = NULL; + freeM(http_buf); } } else { if (ptr != NULL && *ptr != '4') @@ -310,8 +317,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha if (find_auth) { // free(http_buf); // http_buf = NULL; - free(buffer); - free(header); + freeM(buffer); + freeM(header); return 1; } } @@ -319,9 +326,9 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha } // free(http_buf); // http_buf = NULL; - - free(buffer); - free(header); +finish: + freeM(buffer); + freeM(header); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; @@ -447,88 +454,131 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis /*POU CODE */ + + + char *misc = (char *)malloc(strlen(miscptr)); + memset(misc, '\0', strlen(miscptr)); + strcpy(misc, miscptr); + char *delim = ":"; - strtok(miscptr, delim); - char *p; + char *p = NULL; + char *match_text_start = NULL; + memset(match_status_code, '\0', MAX_STATUS_CODE_SIZE); - while ((p = strtok(NULL, delim))) { - if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { - char *match_text_start = strstr(p, "F="); - if (match_text_start == NULL) - match_text_start = strstr(p, "S="); +#if defined __APPLE__ || __linux__ || __unix__ + while ((p = strtok_r(NULL, delim, &misc))) { +#endif - if (match_text_start != NULL) { - if (match_text_start[0] == 'F') - end_condition_type = 0; - else - end_condition_type = 1; +#ifdef _WIN32 + while ((p = strtok_s(NULL, delim, &misc))) { +#endif - int condition_len = strlen(match_text_start); - memset(end_condition, 0, END_CONDITION_MAX_LEN); - if (condition_len >= END_CONDITION_MAX_LEN) { - hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); + if (strstr(p, "r=") != NULL || strstr(p, "R=") != NULL) { + if (strlen(p) < 3) { + hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); + free(misc); + misc = NULL; return -1; } - // copy condition witout starting string (F= or S= 2char) - strncpy(end_condition, match_text_start + 2, condition_len - 2); - if (debug) - hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); - if (*(match_text_start - 1) == ' ') - match_text_start--; - memset(match_text_start, '\0', condition_len); - if (debug) - hydra_report(stderr, "Modificated options:%s\n", miscptr); - } else { - if (debug) - hydra_report(stderr, "Condition not found\n"); + char tmp; + int value, n; + int pos = 0; + + p += 2; + + while (p) { + n = sscanf(p, "%3d%c", &value, &tmp); + + if ((n != 1 && tmp != '|') || value > 1000) { + hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); + free(misc); + return -1; + } + + match_status_code[pos++] = value; + + if (pos > MAX_STATUS_CODE_SIZE) { + hydra_report(stderr, "Match up to %d status codes.", MAX_STATUS_CODE_SIZE); + free(misc); + return -1; + } + + if (n == 1) { + break; + } + + p = strchr(p, '|'); + + if (p) { + ++p; + } + } + } + if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { + int size = 0; + if (misc != NULL) { + size += strlen(misc) + 1; + } + size += strlen(p); + match_text_start = (char *)malloc(size); + memset(match_text_start, '\0', strlen(match_text_start)); + strcat(match_text_start, p); + if (misc != NULL) { + strcat(match_text_start, ":"); + strcat(match_text_start, misc); + } + break; } } - if (strstr(p, "c=") != NULL || strstr(p, 'C=') != NULL) { - if (strlen(p) != 2 + 3) { - hydra_report(stderr, "Invalid status code, eg: 200."); + if (match_text_start != NULL) { + if (match_text_start[0] == 'F') + end_condition_type = 0; + else + end_condition_type = 1; + + int condition_len = strlen(match_text_start); + memset(end_condition, 0, END_CONDITION_MAX_LEN); + + if (condition_len >= END_CONDITION_MAX_LEN) { + hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); + free(misc); + free(match_text_start); return -1; } - char *status_code; - memset(status_code, 0, 3); + // copy condition witout starting string (F= or S= 2char) + strncpy(end_condition, match_text_start + 2, condition_len - 2); + if (debug) + hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); - strncpy(status_code, p + 2, 3); + free(match_text_start); + match_text_start = NULL; - for (int i = 0; i < strlen(status_code); i++) { - if (!isdigit(*(status_code + i))) { - hydra_report(stderr, "Invalid status code, eg: 200"); - return -1; - } - } - - match_status_code = atoi(status_code); - - if (debug) { - hydra_report(stdout, "Find match reply status code: %d", match_status_code); - } + if (debug) + hydra_report(stderr, "Modificated options:%s\n", miscptr); } - } - return 0; -} -void usage_http(const char *service) { - printf("Module %s requires the page to authenticate.\n" - "The following parameters are optional:\n" - " (a|A)=auth-type specify authentication mechanism to use: BASIC, " - "NTLM or MD5\n" - " (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each " - "request\n" - " (c|C)=check for status code in the HTTP reply. If the reply status code\n" - " matches it, it is judged as successful \n" - " (F|S)=check for text in the HTTP reply. S= means if this text is " - "found, a\n" - " valid account has been found, F= means if this string is " - "present the\n" - " combination is invalid. Note: this must be the last option " - "supplied.\n" - "For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: " - "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n", - service); -} + return 0; + } + + void usage_http(const char *service) { + printf("Module %s requires the page to authenticate.\n" + "The following parameters are optional:\n" + " (a|A)=auth-type specify authentication mechanism to use: BASIC, " + "NTLM or MD5\n" + " (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each " + "request\n" + " (r|R)=check for status code in the HTTP reply. If the reply status code\n" + " matches it, it is judged as successful \n" + " (F|S)=check for text in the HTTP reply. S= means if this text is " + "found, a\n" + " valid account has been found, F= means if this string is " + "present the\n" + " combination is invalid. Note: this must be the last option " + "supplied.\n" + "For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: " + "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n", + service); + } From eaa8f297d800388f7b3b6cf8476454d55d292feb Mon Sep 17 00:00:00 2001 From: "Nicholas.Ni" Date: Mon, 5 Jul 2021 23:40:14 +0800 Subject: [PATCH 04/11] fix freeM --- hydra-http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hydra-http.c b/hydra-http.c index 489d8ff..f7a46a7 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -97,7 +97,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha fooptr = buffer2; result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header); if (result == NULL) { - frefreeM(buffer); + freeM(buffer); freeM(header); return 3; } From cd814fe6afeba24b75448ffdf86149b4eac25508 Mon Sep 17 00:00:00 2001 From: "Nicholas.ni" Date: Wed, 7 Jul 2021 09:51:57 +0800 Subject: [PATCH 05/11] fix Out of memory --- hydra-http-form.c | 14 ++++++++++++-- hydra-http.c | 35 ++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index f675beb..025581c 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -386,6 +386,7 @@ char *stringify_headers(ptr_header_node *ptr_head) { } } + return headers_str; } @@ -509,8 +510,17 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { hydra_report(stderr, "[ERROR] Out of memory for HTTP headers (H).\n"); return 0; default: - hydra_report(stderr, "[ERROR] no valid optional parameter type given: %c\n", miscptr[0]); - return 0; + while (*ptr != 0 && *ptr != ':') + ptr++; + + if (*ptr != 0) { + *ptr = 0; + ptr += 1; + } + + miscptr = ptr; + // hydra_report(stderr, "[ERROR] no valid optional parameter type given: %c\n", miscptr[0]); + // return 0; } } return 1; diff --git a/hydra-http.c b/hydra-http.c index f7a46a7..b2e8db8 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -263,6 +263,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha // check status if (match_status_code != NULL) { for (int i = 0; match_status_code[i]; i++) { + if(match_status_code[i] == 0) + continue; if (match_status_code[i] == atoi(ptr)) { if (end_condition_type == -1) { if (debug) @@ -456,13 +458,14 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis - char *misc = (char *)malloc(strlen(miscptr)); + char *misc = (char *)malloc(strlen(miscptr) + 1); + char *cp = misc; memset(misc, '\0', strlen(miscptr)); strcpy(misc, miscptr); char *delim = ":"; char *p = NULL; - char *match_text_start = NULL; + char* match_text_start = NULL; memset(match_status_code, '\0', MAX_STATUS_CODE_SIZE); #if defined __APPLE__ || __linux__ || __unix__ @@ -476,7 +479,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (strstr(p, "r=") != NULL || strstr(p, "R=") != NULL) { if (strlen(p) < 3) { hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); - free(misc); + free(cp); misc = NULL; return -1; } @@ -492,7 +495,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if ((n != 1 && tmp != '|') || value > 1000) { hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); - free(misc); + free(cp); return -1; } @@ -500,7 +503,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (pos > MAX_STATUS_CODE_SIZE) { hydra_report(stderr, "Match up to %d status codes.", MAX_STATUS_CODE_SIZE); - free(misc); + free(cp); return -1; } @@ -517,14 +520,17 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis } if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { int size = 0; - if (misc != NULL) { + if (misc != NULL && strlen(misc) != 0) { size += strlen(misc) + 1; } size += strlen(p); - match_text_start = (char *)malloc(size); - memset(match_text_start, '\0', strlen(match_text_start)); - strcat(match_text_start, p); - if (misc != NULL) { + if(size == strlen(p)) { + match_text_start = p; + } else { + match_text_start = (char *) realloc(p, size); + } + + if (misc != NULL && strlen(misc) != 0) { strcat(match_text_start, ":"); strcat(match_text_start, misc); } @@ -543,8 +549,8 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (condition_len >= END_CONDITION_MAX_LEN) { hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); - free(misc); - free(match_text_start); + free(cp); + return -1; } @@ -553,13 +559,12 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (debug) hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); - free(match_text_start); - match_text_start = NULL; - if (debug) hydra_report(stderr, "Modificated options:%s\n", miscptr); } + free(cp); + return 0; } From c771c6397bd4ec0da7fbf5a2ab4ce39a809e980a Mon Sep 17 00:00:00 2001 From: "Nicholas.ni" Date: Wed, 7 Jul 2021 10:42:36 +0800 Subject: [PATCH 06/11] fix some problems --- hydra-http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hydra-http.c b/hydra-http.c index b2e8db8..31fbb1f 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -501,8 +501,8 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis match_status_code[pos++] = value; - if (pos > MAX_STATUS_CODE_SIZE) { - hydra_report(stderr, "Match up to %d status codes.", MAX_STATUS_CODE_SIZE); + if (pos >= MAX_STATUS_CODE_SIZE) { + hydra_report(stderr, "Status code quantity must be less than %d", MAX_STATUS_CODE_SIZE); free(cp); return -1; } From 9feb2d9ec25998f136d513c1ba8a37c1952e1646 Mon Sep 17 00:00:00 2001 From: "Nicholas.ni" Date: Thu, 8 Jul 2021 23:25:27 +0800 Subject: [PATCH 07/11] fix: Skip when status codes do not match --- hydra-http.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hydra-http.c b/hydra-http.c index 31fbb1f..584f440 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -261,7 +261,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha ptr++; // check status - if (match_status_code != NULL) { + if (match_status_code != NULL && match_status_code[0] != 0) { for (int i = 0; match_status_code[i]; i++) { if(match_status_code[i] == 0) continue; @@ -272,10 +272,23 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha hydra_report_found_host(port, ip, "www", fp); hydra_completed_pair_found(); + if (http_buf != NULL) { + freeM(http_buf); + } + goto finish; } } } + + if (end_condition_type == -1) { + // Skip when status codes do not match + hydra_completed_pair(); + if (http_buf != NULL) { + freeM(http_buf); + } + goto finish; + } } if (ptr != NULL && (*ptr == '2' || *ptr == '3' || strncmp(ptr, "403", 3) == 0 || strncmp(ptr, "404", 3) == 0)) { From 0776e47741bfd3e6f4d437b9aa333c582d445c81 Mon Sep 17 00:00:00 2001 From: "Nicholas.Ni" Date: Sun, 25 Jul 2021 23:01:27 +0800 Subject: [PATCH 08/11] fix hydra-http.c --- hydra-http.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/hydra-http.c b/hydra-http.c index f7a46a7..10fe197 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -11,7 +11,7 @@ static char end_condition[END_CONDITION_MAX_LEN]; int end_condition_type = -1; #define MAX_STATUS_CODE_SIZE 10 -int match_status_code[MAX_STATUS_CODE_SIZE]; +int *match_status_code; int32_t webport; int32_t http_auth_mechanism = AUTH_UNASSIGNED; @@ -44,7 +44,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha header = stringify_headers(&ptr_head); buffer_size = strlen(header) + 500; - if (!(buffer = malloc(buffer_size))) { + if (!(buffer = (char *)malloc(buffer_size))) { freeM(header); return 3; } @@ -229,7 +229,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha http_buf = hydra_receive_line(s); } else if (tmpreplybuf[0] != 0) { complete_line = 1; - if ((tmpreplybufptr = malloc(strlen(tmpreplybuf) + strlen(http_buf) + 1)) != NULL) { + if ((tmpreplybufptr = (char *) malloc(strlen(tmpreplybuf) + strlen(http_buf) + 1)) != NULL) { strcpy(tmpreplybufptr, tmpreplybuf); strcat(tmpreplybufptr, http_buf); freeM(http_buf); @@ -262,7 +262,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha // check status if (match_status_code != NULL) { - for (int i = 0; match_status_code[i]; i++) { + for (int i = 0; i < sizeof(*match_status_code) / sizeof(int); i++) { if (match_status_code[i] == atoi(ptr)) { if (end_condition_type == -1) { if (debug) @@ -358,7 +358,7 @@ void service_http(char *ip, int32_t sp, unsigned char options, char *miscptr, FI webport = mysslport; /* normalise the webtarget for ipv6/port number */ - webtarget = malloc(strlen(hostname) + 1 /* null */ + 6 /* :65535 */ + webtarget = (char *) malloc(strlen(hostname) + 1 /* null */ + 6 /* :65535 */ #ifdef AF_INET6 + 2 /* [] */ #endif @@ -460,10 +460,9 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis memset(misc, '\0', strlen(miscptr)); strcpy(misc, miscptr); - char *delim = ":"; + const char *delim = ":"; char *p = NULL; char *match_text_start = NULL; - memset(match_status_code, '\0', MAX_STATUS_CODE_SIZE); #if defined __APPLE__ || __linux__ || __unix__ while ((p = strtok_r(NULL, delim, &misc))) { @@ -476,10 +475,11 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (strstr(p, "r=") != NULL || strstr(p, "R=") != NULL) { if (strlen(p) < 3) { hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); - free(misc); - misc = NULL; + freeM(misc); return -1; } + + int *status_tmp = (int *) malloc(MAX_STATUS_CODE_SIZE * sizeof(int)); char tmp; int value, n; @@ -492,15 +492,15 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if ((n != 1 && tmp != '|') || value > 1000) { hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); - free(misc); + freeM(misc); return -1; } - match_status_code[pos++] = value; + status_tmp[pos++] = value; if (pos > MAX_STATUS_CODE_SIZE) { hydra_report(stderr, "Match up to %d status codes.", MAX_STATUS_CODE_SIZE); - free(misc); + freeM(misc); return -1; } @@ -514,7 +514,14 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis ++p; } } + + match_status_code = (int *) malloc(pos * sizeof(int)); + for(int i = 0; i < pos; i++) { + match_status_code[i] = status_tmp[i]; + } + freeM(status_tmp); } + if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { int size = 0; if (misc != NULL) { @@ -543,8 +550,8 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (condition_len >= END_CONDITION_MAX_LEN) { hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); - free(misc); - free(match_text_start); + freeM(misc); + freeM(match_text_start); return -1; } @@ -553,8 +560,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (debug) hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); - free(match_text_start); - match_text_start = NULL; + freeM(match_text_start); if (debug) hydra_report(stderr, "Modificated options:%s\n", miscptr); From 9b7ed419c2dc2595fdb960fe45cc6e2bd3a49566 Mon Sep 17 00:00:00 2001 From: "Nicholas.ni" Date: Sat, 31 Jul 2021 18:27:21 +0800 Subject: [PATCH 09/11] fix: Parameter skip valid --- hydra-http-form.c | 13 ++----------- hydra-http.c | 15 ++++++++++----- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 025581c..d6c0b0f 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -510,17 +510,8 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { hydra_report(stderr, "[ERROR] Out of memory for HTTP headers (H).\n"); return 0; default: - while (*ptr != 0 && *ptr != ':') - ptr++; - - if (*ptr != 0) { - *ptr = 0; - ptr += 1; - } - - miscptr = ptr; - // hydra_report(stderr, "[ERROR] no valid optional parameter type given: %c\n", miscptr[0]); - // return 0; + hydra_report(stderr, "[ERROR] no valid optional parameter type given: %c\n", miscptr[0]); + return 0; } } return 1; diff --git a/hydra-http.c b/hydra-http.c index 9ae4c1c..3dc12d7 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -477,6 +477,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis const char *delim = ":"; char *p = NULL; char *match_text_start = NULL; + int trun_flag = 0; #if defined __APPLE__ || __linux__ || __unix__ while ((p = strtok_r(NULL, delim, &misc))) { @@ -485,7 +486,6 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis #ifdef _WIN32 while ((p = strtok_s(NULL, delim, &misc))) { #endif - if (strstr(p, "r=") != NULL || strstr(p, "R=") != NULL) { if (strlen(p) < 3) { hydra_report(stderr, "Invalid status code, eg: 200 or 200|400."); @@ -498,6 +498,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis char tmp; int value, n; int pos = 0; + int plen = strlen(p); p += 2; @@ -534,9 +535,12 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis match_status_code[i] = status_tmp[i]; } freeM(status_tmp); - } - if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { + char *misc_tmp = (char *)malloc(strlen(miscptr) - plen); + sprintf(misc_tmp, "%.*s%.*s", trun_flag, miscptr, strlen(miscptr) - plen - trun_flag - 1, miscptr + trun_flag + plen + 1); + freeM(miscptr); + miscptr = misc_tmp; + } else if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { int size = 0; if (misc != NULL && strlen(misc) != 0) { size += strlen(misc) + 1; @@ -552,7 +556,10 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis strcat(match_text_start, ":"); strcat(match_text_start, misc); } + memset(miscptr + trun_flag + 1, '\0', size); break; + } else { + trun_flag += strlen(p); } } @@ -568,7 +575,6 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (condition_len >= END_CONDITION_MAX_LEN) { hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); freeM(misc); - freeM(match_text_start); return -1; } @@ -577,7 +583,6 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis if (debug) hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type); - freeM(match_text_start); if (debug) hydra_report(stderr, "Modificated options:%s\n", miscptr); From 1f2d63e3ee753c8a873dab367cd68c74a676c65c Mon Sep 17 00:00:00 2001 From: "Nicholas.ni" Date: Tue, 3 Aug 2021 10:57:09 +0800 Subject: [PATCH 10/11] fix: http params skip --- hydra-http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hydra-http.c b/hydra-http.c index 3dc12d7..1afb6b4 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -537,7 +537,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis freeM(status_tmp); char *misc_tmp = (char *)malloc(strlen(miscptr) - plen); - sprintf(misc_tmp, "%.*s%.*s", trun_flag, miscptr, strlen(miscptr) - plen - trun_flag - 1, miscptr + trun_flag + plen + 1); + sprintf(misc_tmp, "%.*s%.*s", trun_flag - 1, miscptr, strlen(miscptr) - plen - trun_flag - 1, miscptr + trun_flag + plen + 1); freeM(miscptr); miscptr = misc_tmp; } else if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { @@ -559,7 +559,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis memset(miscptr + trun_flag + 1, '\0', size); break; } else { - trun_flag += strlen(p); + trun_flag += strlen(p) + 1; } } From 810a7e35e408b41851ff1eb5985dd8e14e0221b9 Mon Sep 17 00:00:00 2001 From: "Nicholas.Ni" Date: Tue, 3 Aug 2021 20:33:47 +0800 Subject: [PATCH 11/11] fix --- hydra-http.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hydra-http.c b/hydra-http.c index 1afb6b4..3b3fe78 100644 --- a/hydra-http.c +++ b/hydra-http.c @@ -16,6 +16,8 @@ int *match_status_code; int32_t webport; int32_t http_auth_mechanism = AUTH_UNASSIGNED; +char *save_miscptr; + void freeMemory(void **ptr) { if (ptr != NULL && *ptr != NULL) { free(*ptr); @@ -33,6 +35,10 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha int32_t complete_line = 0, buffer_size; char tmpreplybuf[1024] = "", *tmpreplybufptr; + if (save_miscptr != miscptr) { + miscptr = save_miscptr; + } + if (strlen(login = hydra_get_next_login()) == 0) login = empty; if (strlen(pass = hydra_get_next_password()) == 0) @@ -357,6 +363,10 @@ void service_http(char *ip, int32_t sp, unsigned char options, char *miscptr, FI unsigned char addr6[sizeof(struct in6_addr)]; #endif +if (save_miscptr != miscptr) { + miscptr = save_miscptr; +} + hydra_register_socket(sp); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return; @@ -590,6 +600,8 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis free(cp); + save_miscptr = miscptr; + return 0; }