From d273cb4807dce5eebebecd8fab51892ad5c046e8 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Wed, 21 May 2014 12:53:08 +0200 Subject: [PATCH 01/20] Created linked list for HTTP headers. --- hydra-http-form.c | 152 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 29 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 69fa064..3b13f0b 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -56,6 +56,12 @@ extern char *HYDRA_EXIT; char *buf; char *cond; +typedef struct header_node { + char *header; + char *value; + struct header_node *next; +}t_header_node, *ptr_header_node; + int success_cond = 0; int getcookie = 1; int auth_flag = 0; @@ -72,6 +78,68 @@ extern char *slash; int webport, freemischttpform = 0; char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1; +ptr_header_node ptr_head = NULL; + +/* + * Returns 1 if success, or 0 otherwise (out of memory). + */ +int add_header(char *header, char *value){ + ptr_header_node cur_ptr = NULL; + + // get to the last header + for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); + + ptr_header_node new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); + if(new_ptr){ + // create a new item and append it to the list + new_ptr->header = header; + new_ptr->value = value; + new_ptr->next = NULL; + }else{ + // we're out of memory, so forcefully end + return 0; + } + + if(cur_ptr) + cur_ptr->next = new_ptr; + else + // head is NULL, so the list is empty + ptr_head = new_ptr; + + hydra_report_debug(stdout, "[add_header] Added header %s: %s", header, value); + hydra_report_debug(stdout, "[add_header] len(header) = %d", strlen(header)); + hydra_report_debug(stdout, "[add_header] len(value) = %d", strlen(value)); + + return 1; +} + +/* + * List layout: + * +----------+ +--------+ +--------+ +--------+ + * | ptr_head | --> | next | --> | next | --> | NULL | + * | | | header | | header | | NULL | + * | | | value | | value | | NULL | + * +----------+ +--------+ +--------+ +--------+ + * + * Returns 1 if success, or 0 otherwise (out of memory). + */ +int add_or_replace_header(char *header, char *value){ + ptr_header_node cur_ptr = NULL; + + for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if(strcmp(cur_ptr->header, header) == 0){ + free(cur_ptr->value); + cur_ptr->value = value; + break; + } + } + + if(cur_ptr == NULL) + return add_header(header, value); + + return 1; +} + int strpos(char *str, char *target) { char *res = strstr(str, target); @@ -382,8 +450,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc if ((endloc = strchr(startloc, '\n')) != NULL) { startloc[endloc - startloc] = 0; } - strncpy(str, startloc, sizeof(str)); - str[sizeof(str) - 1] = 0; + strcpy(str, startloc); endloc = strchr(str, '/'); if (endloc != NULL) { @@ -395,12 +462,11 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc if (strlen(str) - strlen(str2) == 0) { strcpy(str3, "/"); } else { - strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2)); - str3[strlen(str) - strlen(str2)] = 0; + strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) - 1); + str3[strlen(str) - strlen(str2) - 1] = 0; } } else { - strncpy(str2, webtarget, sizeof(str2) - 1); - str2[sizeof(str2) - 1] = 0; + strncpy(str2, webtarget, sizeof(str2)); if (redirected_url_buff[0] != '/') { //it's a relative path, so we have to concatenate it //with the path from the first url given @@ -526,20 +592,20 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F *ptr++ = 0; optional1 = ptr; if (strstr(url, "\\:") != NULL) { - if ((ptr = malloc(strlen(url))) != NULL) { // no need for +1 + if ((ptr = malloc(strlen(url))) != NULL) { strcpy(ptr, hydra_strrep(url, "\\:", ":")); url = ptr; } } if (strstr(variables, "\\:") != NULL) { - if ((ptr = malloc(strlen(variables))) != NULL) { // no need for +1 + if ((ptr = malloc(strlen(variables))) != NULL) { strcpy(ptr, hydra_strrep(variables, "\\:", ":")); variables = ptr; } } if (strstr(cond, "\\:") != NULL) { - if ((ptr = malloc(strlen(cond))) != NULL) { // no need for +1 - strcpy(ptr, hydra_strrep(cond, "\\:", ":")); + if ((ptr = malloc(strlen(cond))) != NULL) { + strcpy(ptr, hydra_strrep(cond, "\\:", ":")); cond = ptr; } } @@ -567,6 +633,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F success_cond = 0; } + char *header = NULL, *value = NULL; while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { switch (optional1[0]) { case 'c': // fall through @@ -579,24 +646,49 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F sprintf(cookieurl, "%.1000s", hydra_strrep(optional1 + 2, "\\:", ":")); optional1 = ptr; break; - case 'h': // fall through + case 'h': + // add a new header at the end + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - optional1 contains the header's name + * - ptr contains the header's value + */ + header = (char *) malloc(strlen(optional1 + 2)); + value = (char *) malloc(strlen(ptr)); + if(header && value){ + strcpy(header, optional1 + 2); + strcpy(value, hydra_strrep(ptr, "\\:", ":")); + hydra_report_debug(stdout, "Adding header: %s: %s", header, value); + hydra_report_debug(stdout, "\tlen(header): %d", strlen(header)); + hydra_report_debug(stdout, "\tlen(value): %d", strlen(value)); + if(add_header(header, value)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + hydra_child_exit(1); + break; case 'H': - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - ptr2 = ptr; - while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) - ptr2++; - if (*ptr2 != 0) - *ptr2++ = 0; - if (sizeof(userheader) - strlen(userheader) > 4) { - strncat(userheader, optional1 + 2, sizeof(userheader) - strlen(userheader) - 4); - strcat(userheader, ":"); - strncat(userheader, hydra_strrep(ptr, "\\:", ":"), sizeof(userheader) - strlen(userheader) - 3); - strcat(userheader, "\r\n"); - } + // add a new header, or replace an existing one's value +// if (sizeof(userheader) - strlen(userheader) > 4) { +// strncat(userheader, optional1 + 2, sizeof(userheader) - strlen(userheader) - 4); +// strcat(userheader, ":"); +// strncat(userheader, hydra_strrep(ptr, "\\:", ":"), sizeof(userheader) - strlen(userheader) - 3); +// strcat(userheader, "\r\n"); +// } optional1 = ptr2; break; // no default @@ -671,11 +763,13 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F } void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { - service_http_form(ip, sp, options, miscptr, fp, port, "GET"); + //// + service_http_form(ip, sp, options, miscptr, fp, port, "GET"); } void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { - service_http_form(ip, sp, options, miscptr, fp, port, "POST"); + //// + service_http_form(ip, sp, options, miscptr, fp, port, "POST"); } int service_http_form_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { From c46665749646672a361781335d8e15cb6321cbb2 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Thu, 22 May 2014 09:51:35 +0200 Subject: [PATCH 02/20] Added function to stringify headers from linked list. --- hydra-http-form.c | 194 ++++++++++++++++++++++++++++------------------ 1 file changed, 119 insertions(+), 75 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 3b13f0b..2a5517a 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -84,33 +84,34 @@ ptr_header_node ptr_head = NULL; * Returns 1 if success, or 0 otherwise (out of memory). */ int add_header(char *header, char *value){ - ptr_header_node cur_ptr = NULL; + ptr_header_node cur_ptr = NULL; - // get to the last header - for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); + // get to the last header + for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); - ptr_header_node new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); - if(new_ptr){ - // create a new item and append it to the list - new_ptr->header = header; - new_ptr->value = value; - new_ptr->next = NULL; - }else{ - // we're out of memory, so forcefully end - return 0; - } + ptr_header_node new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); + if(new_ptr){ + // create a new item and append it to the list + new_ptr->header = header; + new_ptr->value = value; + new_ptr->next = NULL; + }else{ + // we're out of memory, so forcefully end + return 0; + } - if(cur_ptr) - cur_ptr->next = new_ptr; - else - // head is NULL, so the list is empty - ptr_head = new_ptr; + if(cur_ptr) + cur_ptr->next = new_ptr; + else + // head is NULL, so the list is empty + ptr_head = new_ptr; - hydra_report_debug(stdout, "[add_header] Added header %s: %s", header, value); - hydra_report_debug(stdout, "[add_header] len(header) = %d", strlen(header)); - hydra_report_debug(stdout, "[add_header] len(value) = %d", strlen(value)); - - return 1; + // TODO Remove the debug messages + hydra_report_debug(stdout, "[add_header] Added header %s: %s", header, value); + hydra_report_debug(stdout, "[add_header] len(header) = %d", strlen(header)); + hydra_report_debug(stdout, "[add_header] len(value) = %d", strlen(value)); + + return 1; } /* @@ -124,20 +125,59 @@ int add_header(char *header, char *value){ * Returns 1 if success, or 0 otherwise (out of memory). */ int add_or_replace_header(char *header, char *value){ - ptr_header_node cur_ptr = NULL; + ptr_header_node cur_ptr = NULL; - for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ - if(strcmp(cur_ptr->header, header) == 0){ - free(cur_ptr->value); - cur_ptr->value = value; - break; - } - } + for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if(strcmp(cur_ptr->header, header) == 0){ + free(cur_ptr->value); + cur_ptr->value = value; + break; + } + } - if(cur_ptr == NULL) - return add_header(header, value); + if(cur_ptr == NULL) + return add_header(header, value); - return 1; + // TODO Remove the debug messages + hydra_report_debug(stdout, "[add_or_replace_header] Added header %s: %s", header, value); + hydra_report_debug(stdout, "[add_or_replace_header] len(header) = %d", strlen(header)); + hydra_report_debug(stdout, "[add_or_replace_header] len(value) = %d", strlen(value)); + + return 1; +} + +/* + * Concat all the headers in the list in a single string, and clean the whole list. + */ +char * stringify_headers_and_clean(){ + char * headers_str = NULL; + ptr_header_node cur_ptr = ptr_head, tmp_ptr = NULL; + int ttl_size = 0; + + while(cur_ptr){ + if(cur_ptr->header && cur_ptr->value){ // Check for NULLs + ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 1; + headers_str = (char *) realloc(headers_str, sizeof(char) * ttl_size); + if(headers_str){ // Check for errors + strcat(headers_str, cur_ptr->header); + strcat(headers_str, ": "); + strcat(headers_str, cur_ptr->value); + strcat(headers_str, "\r\n"); + }else{ + // Error: out of memory + hydra_report(stderr, "Out of memory for HTTP headers"); + hydra_child_exit(1); + } + } + // Clean it up and get to the next header + tmp_ptr = cur_ptr; + cur_ptr = cur_ptr->next; + free(tmp_ptr->header); + free(tmp_ptr->value); + free(tmp_ptr); + } + + return headers_str; } int strpos(char *str, char *target) { @@ -647,49 +687,53 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F optional1 = ptr; break; case 'h': - // add a new header at the end - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - ptr2 = ptr; - while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) - ptr2++; - if (*ptr2 != 0) - *ptr2++ = 0; - /* - * At this point: - * - optional1 contains the header's name - * - ptr contains the header's value - */ - header = (char *) malloc(strlen(optional1 + 2)); - value = (char *) malloc(strlen(ptr)); - if(header && value){ - strcpy(header, optional1 + 2); - strcpy(value, hydra_strrep(ptr, "\\:", ":")); - hydra_report_debug(stdout, "Adding header: %s: %s", header, value); - hydra_report_debug(stdout, "\tlen(header): %d", strlen(header)); - hydra_report_debug(stdout, "\tlen(value): %d", strlen(value)); - if(add_header(header, value)){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } + // add a new header at the end + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ + header = (char *) malloc(strlen(optional1 + 2)); + value = (char *) malloc(strlen(ptr)); + if(header && value){ + strcpy(header, optional1 + 2); + strcpy(value, hydra_strrep(ptr, "\\:", ":")); + if(add_header(hydra_trim(header), hydra_trim(value))){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; } - // Error: abort execution - hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - hydra_child_exit(1); - break; + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + hydra_child_exit(1); + break; case 'H': - // add a new header, or replace an existing one's value -// if (sizeof(userheader) - strlen(userheader) > 4) { -// strncat(userheader, optional1 + 2, sizeof(userheader) - strlen(userheader) - 4); -// strcat(userheader, ":"); -// strncat(userheader, hydra_strrep(ptr, "\\:", ":"), sizeof(userheader) - strlen(userheader) - 3); -// strcat(userheader, "\r\n"); -// } - optional1 = ptr2; + // add a new header, or replace an existing one's value + header = (char *) malloc(strlen(optional1 + 2)); + value = (char *) malloc(strlen(ptr)); + if(header && value){ + strcpy(header, optional1 + 2); + strcpy(value, hydra_strrep(ptr, "\\:", ":")); + if(add_or_replace_header(hydra_trim(header), hydra_trim(value))){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + hydra_child_exit(1); break; // no default } From 8ebbde3223643ce359742a30d2afa15a4b68317d Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Thu, 22 May 2014 09:51:59 +0200 Subject: [PATCH 03/20] Added function to trim strings. --- hydra-mod.c | 23 +++++++++++++++++++++++ hydra-mod.h | 1 + 2 files changed, 24 insertions(+) diff --git a/hydra-mod.c b/hydra-mod.c index a9cefab..c8aa999 100644 --- a/hydra-mod.c +++ b/hydra-mod.c @@ -1285,3 +1285,26 @@ int hydra_memsearch(char *haystack, int hlen, char *needle, int nlen) { return i; return -1; } + +char * hydra_trim(char * str) { + size_t len = strlen(str); + char * str_ptr[] = {str, NULL}; + + // Truncate leading spaces + for(; *str_ptr[0] == ' ' && len > 0; str_ptr[0]++) + len--; + + if(len == 0) + return NULL; + + // Truncate trailing spaces + str_ptr[1] = str + len; + for(; *str_ptr[1] == ' '; str_ptr[1]--) + len--; + *(str_ptr[1] + 1) = 0; + + char * trimmed_str = strndup(str_ptr[0], len); + free(str); + + return trimmed_str; +} diff --git a/hydra-mod.h b/hydra-mod.h index 5330e5c..5830607 100644 --- a/hydra-mod.h +++ b/hydra-mod.h @@ -38,6 +38,7 @@ extern char *hydra_strcasestr(const char *haystack, const char *needle); extern void hydra_dump_data(unsigned char *buf, int len, char *text); extern int hydra_memsearch(char *haystack, int hlen, char *needle, int nlen); extern char *hydra_strrep(char *string, char *oldpiece, char *newpiece); +extern char * hydra_trim(char * str); #ifdef HAVE_PCRE int hydra_string_match(char *str, const char *regex); From 70c598ee3293bf97d532c10e5a7c610b3a42b224 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Sun, 29 Jun 2014 03:28:12 +0200 Subject: [PATCH 04/20] Added -h and -H options support for direct HTTP GET/POST requests. --- hydra-http-form.c | 476 ++++++++++++++++++++-------------------------- 1 file changed, 207 insertions(+), 269 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 2a5517a..7971752 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -52,10 +52,24 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da #include "hydra-mod.h" +/* HTTP Request Options */ +#define OPT_PROXY_AUTH 1 +#define OPT_PROXY_NOAUTH 2 +#define OPT_NOPROXY 4 +#define OPT_GETCOOKIES 8 + +/* Default HTTP Headers */ +#define DEFAULT_HOST 1 +#define DEFAULT_USER_AGENT 2 +#define DEFAULT_CONTENT_TYPE 4 + +#define MAX_REQ_LEN 1030 + extern char *HYDRA_EXIT; char *buf; char *cond; +char http_request[MAX_REQ_LEN]; typedef struct header_node { char *header; char *value; @@ -76,10 +90,40 @@ char cookie[4096] = "", cmiscptr[1024]; extern char *webtarget; extern char *slash; int webport, freemischttpform = 0; +int http_opts; char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1; ptr_header_node ptr_head = NULL; +void prepare_httpreq(char * method, char * path){ + char tail[] = " HTTP/1.0"; + int req_len = (strlen(method) + strlen(path) + 1) <= MAX_REQ_LEN ? (strlen(method) + strlen(path) + 1) : MAX_REQ_LEN; + + memset(http_request, 0, MAX_REQ_LEN); + + if(strcmp(method, "GET") == 0) + strcat(http_request, "GET "); + else if(strcmp(method, "POST") == 0) + strcat(http_request, "POST "); + + strncat(http_request, path, MAX_REQ_LEN - sizeof(tail) - 5); + strcat(http_request, tail); +} + +/* + * Returns 1 if specified header exists, or 0 otherwise. + */ +int header_exists(char * header){ + ptr_header_node cur_ptr = NULL; + int header_exists = 0; + + for(cur_ptr = ptr_head; cur_ptr && !header_exists; cur_ptr = cur_ptr->next) + if(cur_ptr->header && strcmp(cur_ptr->header, header) == 0) + header_exists = 1; + + return header_exists; +} + /* * Returns 1 if success, or 0 otherwise (out of memory). */ @@ -107,9 +151,9 @@ int add_header(char *header, char *value){ ptr_head = new_ptr; // TODO Remove the debug messages - hydra_report_debug(stdout, "[add_header] Added header %s: %s", header, value); - hydra_report_debug(stdout, "[add_header] len(header) = %d", strlen(header)); - hydra_report_debug(stdout, "[add_header] len(value) = %d", strlen(value)); +// hydra_report(stdout, "[add_header] Added header %s: %s\n", header, value); +// hydra_report(stdout, "[add_header] len(header) = %d", strlen(header)); +// hydra_report(stdout, "[add_header] len(value) = %d", strlen(value)); return 1; } @@ -129,7 +173,7 @@ int add_or_replace_header(char *header, char *value){ for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ if(strcmp(cur_ptr->header, header) == 0){ - free(cur_ptr->value); + //free(cur_ptr->value); cur_ptr->value = value; break; } @@ -139,42 +183,101 @@ int add_or_replace_header(char *header, char *value){ return add_header(header, value); // TODO Remove the debug messages - hydra_report_debug(stdout, "[add_or_replace_header] Added header %s: %s", header, value); - hydra_report_debug(stdout, "[add_or_replace_header] len(header) = %d", strlen(header)); - hydra_report_debug(stdout, "[add_or_replace_header] len(value) = %d", strlen(value)); +// hydra_report(stdout, "[add_or_replace_header] Added header %s: %s\n", header, value); +// hydra_report(stdout, "[add_or_replace_header] len(header) = %d", strlen(header)); +// hydra_report(stdout, "[add_or_replace_header] len(value) = %d", strlen(value)); return 1; } +/* + * Replace in all headers' values every occurrence of oldvalue by newvalue. + */ +void hdrrep(char * oldvalue, char * newvalue){ + ptr_header_node cur_ptr = NULL; + + for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if(strstr(cur_ptr->value, oldvalue)){ + cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(newvalue)); + if(cur_ptr->value) + strcpy(cur_ptr->value, newvalue); + else{ + hydra_report(stderr, "[ERROR] Out of memory."); + hydra_child_exit(1); + } + } + } +} + +int add_default_headers(int default_header_opts){ + int retval = 0; + + char * header = (char *) malloc(sizeof(char) * 80); + char * value = (char *) malloc(sizeof(char) * 80); + + if(header && value){ + if((default_header_opts & OPT_PROXY_AUTH) == OPT_PROXY_AUTH){ + memset(header, 0, 80); + memset(value, 0, 80); + strcpy(header, "Proxy-Authorization"); + strcpy(value, "Basic "); + strncat(value, proxy_authentication, 73); + retval &= add_header(header, value); + retval &= add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy Auth)"); + } + + if((default_header_opts & OPT_PROXY_NOAUTH) == OPT_PROXY_NOAUTH){ + retval &= add_or_replace_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)"); + } + + if((default_header_opts & OPT_NOPROXY) == OPT_NOPROXY){ + + } + + if((default_header_opts & OPT_GETCOOKIES) == OPT_GETCOOKIES){ + + } + } + + return retval; +} + /* * Concat all the headers in the list in a single string, and clean the whole list. */ char * stringify_headers_and_clean(){ char * headers_str = NULL; ptr_header_node cur_ptr = ptr_head, tmp_ptr = NULL; - int ttl_size = 0; + int ttl_size = strlen(http_request); while(cur_ptr){ if(cur_ptr->header && cur_ptr->value){ // Check for NULLs ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 1; - headers_str = (char *) realloc(headers_str, sizeof(char) * ttl_size); + if(headers_str) + headers_str = (char *) realloc(headers_str, sizeof(char) * ttl_size); + else{ + // Garbage appears when strcat()-ing, if we don't blank newly allocated memory + headers_str = (char *) malloc(sizeof(char) * ttl_size); + if(headers_str) + memset(headers_str, 0, sizeof(char) * ttl_size); + } if(headers_str){ // Check for errors - strcat(headers_str, cur_ptr->header); - strcat(headers_str, ": "); - strcat(headers_str, cur_ptr->value); - strcat(headers_str, "\r\n"); + strcat(headers_str, cur_ptr->header); + strcat(headers_str, ": "); + strcat(headers_str, cur_ptr->value); + strcat(headers_str, "\r\n"); }else{ - // Error: out of memory - hydra_report(stderr, "Out of memory for HTTP headers"); - hydra_child_exit(1); + // Error: out of memory + hydra_report(stderr, "Out of memory for HTTP headers"); + hydra_child_exit(1); } } // Clean it up and get to the next header tmp_ptr = cur_ptr; cur_ptr = cur_ptr->next; - free(tmp_ptr->header); - free(tmp_ptr->value); - free(tmp_ptr); + //free(tmp_ptr->header); + //free(tmp_ptr->value); + //free(tmp_ptr); } return headers_str; @@ -328,250 +431,38 @@ void hydra_reconnect(int s, char *ip, int port, unsigned char options) { int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type) { char *empty = ""; - char *login, *pass, buffer[9000], clogin[256], cpass[256]; + char *login, *pass, clogin[256], cpass[256]; + char *buffer; // Buffer for HTTP headers char header[8096], *upd3variables, cuserheader[1024]; int found = !success_cond, i, j; memset(header, 0, sizeof(header)); cookie[0] = 0; // reset cookies from potential previous attempt + // Take the next login/pass pair if (strlen(login = hydra_get_next_login()) == 0) - login = empty; - if (strlen(pass = hydra_get_next_password()) == 0) - pass = empty; - strncpy(clogin, html_encode(login), sizeof(clogin) - 1); - clogin[sizeof(clogin) - 1] = 0; - strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); - cpass[sizeof(cpass) - 1] = 0; - upd3variables = hydra_strrep(variables, "^USER^", clogin); - upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); - if (strstr(userheader, "^USER^") == NULL && strstr(userheader, "^PASS^") == NULL) { - strcpy(cuserheader, userheader); - } else { // we use the encoded version - strncpy(cuserheader, hydra_strrep(userheader, "^USER^", clogin), sizeof(cuserheader) - 1); - cuserheader[sizeof(cuserheader) - 1] = 0; - strncpy(cuserheader, hydra_strrep(cuserheader, "^PASS^", cpass), sizeof(cuserheader) - 1); - cuserheader[sizeof(cuserheader) - 1] = 0; - } + login = empty; + if (strlen(pass = hydra_get_next_password()) == 0) + pass = empty; + strncpy(clogin, html_encode(login), sizeof(clogin) - 1); + clogin[sizeof(clogin) - 1] = 0; + strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); + cpass[sizeof(cpass) - 1] = 0; - /* again: no snprintf to be portable. dont worry, buffer cant overflow */ - if (use_proxy == 1 && proxy_authentication != NULL) { - // proxy with authentication - if (getcookie) { - //doing a GET to save cookies - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla 5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", - webtarget, webport, cookieurl, webtarget, proxy_authentication, header, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - i = analyze_server_response(s); // return value ignored - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } - hydra_reconnect(s, ip, port, options); - } + // Replace the user/pass placeholders in the command line options + upd3variables = hydra_strrep(variables, "^USER^", clogin); + upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); - if (strcmp(type, "POST") == 0) { - sprintf(buffer, - "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy Auth)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", - webtarget, webport, url, webtarget, proxy_authentication, (int) strlen(upd3variables), header, cuserheader, upd3variables); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } else { - sprintf(buffer, - "GET http://%s:%d%.600s?%s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", - webtarget, webport, url, upd3variables, webtarget, proxy_authentication, header, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } - } else { - if (use_proxy == 1) { - // proxy without authentication - if (getcookie) { - //doing a GET to get cookies - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy)\r\n%s%s\r\n", webtarget, webport, cookieurl, webtarget, header, - cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } - hydra_reconnect(s, ip, port, options); - } + // Replace the user/pass placeholders in the user-supplied headers + hdrrep("^USER^", clogin); + hdrrep("^PASS^", cpass); - if (strcmp(type, "POST") == 0) { - sprintf(buffer, - "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", - webtarget, webport, url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } else { - sprintf(buffer, "GET http://%s:%d%.600s?%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s%s\r\n", webtarget, webport, url, upd3variables, webtarget, - header, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } - } else { - // direct web server, no proxy - if (getcookie) { - //doing a GET to save cookies - sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s\r\n", cookieurl, webtarget, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } - hydra_reconnect(s, ip, port, options); - } +////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (strcmp(type, "POST") == 0) { - sprintf(buffer, - "POST %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", - url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } else { - sprintf(buffer, "GET %.600s?%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s%s\r\n", url, upd3variables, webtarget, header, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } - } - } + buffer = stringify_headers_and_clean(); + hydra_report(stdout, "HTTP headers:\n%s\r\n%s", http_request, buffer); - found = analyze_server_response(s); - if (auth_flag) { // we received a 401 error - user using wrong module - hydra_report(stderr, "[ERROR] the target is using HTTP auth, not a web form, received HTTP error code 401. Use module \"http%s-get\" instead.\n", - (options & OPTION_SSL) > 0 ? "s" : ""); - return 4; - } - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %.1000s\r\n", cookie); - } - //if page was redirected, follow the location header - redirected_cpt = MAX_REDIRECT; - if (debug) - printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); - while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { - //we have to split the location - char *startloc, *endloc; - char str[2048]; - char str2[2048]; - char str3[2048]; - - redirected_cpt--; - redirected_flag = 0; - //check if the redirect page contains the fail/success condition -#ifdef HAVE_PCRE - if (hydra_string_match(redirected_url_buff, cond) == 1) { -#else - if (strstr(redirected_url_buff, cond) != NULL) { -#endif - found = success_cond; - } else { - //location could be either absolute http(s):// or / something - //or relative - startloc = strstr(redirected_url_buff, "://"); - if (startloc != NULL) { - startloc += strlen("://"); - - if ((endloc = strchr(startloc, '\r')) != NULL) { - startloc[endloc - startloc] = 0; - } - if ((endloc = strchr(startloc, '\n')) != NULL) { - startloc[endloc - startloc] = 0; - } - strcpy(str, startloc); - - endloc = strchr(str, '/'); - if (endloc != NULL) { - strncpy(str2, str, endloc - str); - str2[endloc - str] = 0; - } else - strncpy(str2, str, sizeof(str)); - - if (strlen(str) - strlen(str2) == 0) { - strcpy(str3, "/"); - } else { - strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) - 1); - str3[strlen(str) - strlen(str2) - 1] = 0; - } - } else { - strncpy(str2, webtarget, sizeof(str2)); - if (redirected_url_buff[0] != '/') { - //it's a relative path, so we have to concatenate it - //with the path from the first url given - char *urlpath; - char urlpath_extracted[2048]; - - memset(urlpath_extracted, 0, sizeof(urlpath_extracted)); - - urlpath = strrchr(url, '/'); - if (urlpath != NULL) { - strncpy(urlpath_extracted, url, urlpath - url); - sprintf(str3, "%.1000s/%.1000s", urlpath_extracted, redirected_url_buff); - } else { - sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff); - } - } else - strncpy(str3, redirected_url_buff, sizeof(str3)); - if (debug) - hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url); - } - if (str3[0] != '/') { - j = strlen(str3); - str3[j + 1] = 0; - for (i = j; i > 0; i--) - str3[i] = str3[i - 1]; - str3[0] = '/'; - } - - if (verbose) - hydra_report(stderr, "[VERBOSE] Page redirected to http://%s%s\n", str2, str3); - - //re-use the code above to check for proxy use - if (use_proxy == 1 && proxy_authentication != NULL) { - // proxy with authentication - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", - webtarget, webport, str3, str2, proxy_authentication, header); - } else { - if (use_proxy == 1) { - // proxy without authentication - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", webtarget, webport, str3, str2, header); - } else { - //direct web server, no proxy - sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); - } - } - - hydra_reconnect(s, ip, port, options); - - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - found = analyze_server_response(s); - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } - } - } - - //if the last status is still 3xx, set it as a false - if (found != -1 && found == success_cond && redirected_flag == 0 && redirected_cpt >= 0) { - hydra_report_found_host(port, ip, "www-form", fp); - hydra_completed_pair_found(); - } else { - hydra_completed_pair(); - } + hydra_child_exit(1); return 1; } @@ -673,6 +564,34 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F success_cond = 0; } + // Prepare the HTTP requests that will follow + http_opts = 0; + if(use_proxy == 1 && proxy_authentication != NULL){ + // proxy with authentication + http_opts = OPT_PROXY_AUTH; + if(getcookie) + http_opts |= OPT_GETCOOKIES; + }else if(use_proxy == 1){ + // proxy without authentication + http_opts = OPT_PROXY_NOAUTH; + if(getcookie) + http_opts |= OPT_GETCOOKIES; + }else{ + // direct web server, no proxy +// char * header = (char *) malloc(255); +// char * value = (char *) malloc(255); +// strcpy(header, "User-Agent"); +// strcpy(value, "Mozilla/5.0 (Hydra)"); +// add_header(header, value); + add_header("Host", webtarget); + add_header("User-Agent", "Mozilla/5.0 (Hydra)"); + http_opts = OPT_NOPROXY; + if(getcookie) + http_opts |=OPT_GETCOOKIES; + } + + prepare_httpreq(type, url); + char *header = NULL, *value = NULL; while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { switch (optional1[0]) { @@ -690,14 +609,14 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F // add a new header at the end ptr = optional1 + 2; while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; + ptr++; if (*ptr != 0) - *ptr++ = 0; + *ptr++ = 0; ptr2 = ptr; while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) - ptr2++; + ptr2++; if (*ptr2 != 0) - *ptr2++ = 0; + *ptr2++ = 0; /* * At this point: * - (optional1 + 2) contains the header's name @@ -706,13 +625,15 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F header = (char *) malloc(strlen(optional1 + 2)); value = (char *) malloc(strlen(ptr)); if(header && value){ - strcpy(header, optional1 + 2); - strcpy(value, hydra_strrep(ptr, "\\:", ":")); - if(add_header(hydra_trim(header), hydra_trim(value))){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } + strcpy(header, optional1 + 2); + strcpy(value, hydra_strrep(ptr, "\\:", ":")); + hydra_report(stdout, "Header: %s\n", header); + hydra_report(stdout, "Value: %s\n", value); + if(add_header(header, value)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } } // Error: abort execution hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); @@ -720,16 +641,33 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F break; case 'H': // add a new header, or replace an existing one's value + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ header = (char *) malloc(strlen(optional1 + 2)); value = (char *) malloc(strlen(ptr)); if(header && value){ - strcpy(header, optional1 + 2); - strcpy(value, hydra_strrep(ptr, "\\:", ":")); - if(add_or_replace_header(hydra_trim(header), hydra_trim(value))){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } + strcpy(header, optional1 + 2); + strcpy(value, hydra_strrep(ptr, "\\:", ":")); + hydra_report(stdout, "Header: %s\n", header); + hydra_report(stdout, "Value: %s\n", value); + if(add_or_replace_header(header, value)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } } // Error: abort execution hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); From db0a25f60163a3bb88f4d6fd1ca9f182943f5de1 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Mon, 30 Jun 2014 21:03:40 +0200 Subject: [PATCH 05/20] HTTP headers now get freed when they're no longer needed. --- hydra-http-form.c | 137 ++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 97 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 7971752..0663ebd 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -134,10 +134,13 @@ int add_header(char *header, char *value){ for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); ptr_header_node new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); - if(new_ptr){ + char * new_header = strdup(header); + char * new_value = strdup(value); + + if(new_ptr && new_header && new_value){ // create a new item and append it to the list - new_ptr->header = header; - new_ptr->value = value; + new_ptr->header = new_header; + new_ptr->value = new_value; new_ptr->next = NULL; }else{ // we're out of memory, so forcefully end @@ -150,11 +153,6 @@ int add_header(char *header, char *value){ // head is NULL, so the list is empty ptr_head = new_ptr; - // TODO Remove the debug messages -// hydra_report(stdout, "[add_header] Added header %s: %s\n", header, value); -// hydra_report(stdout, "[add_header] len(header) = %d", strlen(header)); -// hydra_report(stdout, "[add_header] len(value) = %d", strlen(value)); - return 1; } @@ -169,25 +167,30 @@ int add_header(char *header, char *value){ * Returns 1 if success, or 0 otherwise (out of memory). */ int add_or_replace_header(char *header, char *value){ - ptr_header_node cur_ptr = NULL; + int ret = 1; - for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ - if(strcmp(cur_ptr->header, header) == 0){ - //free(cur_ptr->value); - cur_ptr->value = value; - break; - } + ptr_header_node cur_ptr = NULL; + char * new_header = strdup(header); + char * new_value = strdup(value); + + if(new_header && new_value){ + for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if(strcmp(cur_ptr->header, new_header) == 0){ + free(cur_ptr->value); + cur_ptr->value = new_value; + break; + } + } } - if(cur_ptr == NULL) - return add_header(header, value); + if(cur_ptr == NULL){ + ret = add_header(header, value); + // add_header() will create a new copy so we can safely free them + free(new_header); + free(new_value); + } - // TODO Remove the debug messages -// hydra_report(stdout, "[add_or_replace_header] Added header %s: %s\n", header, value); -// hydra_report(stdout, "[add_or_replace_header] len(header) = %d", strlen(header)); -// hydra_report(stdout, "[add_or_replace_header] len(value) = %d", strlen(value)); - - return 1; + return ret; } /* @@ -209,39 +212,6 @@ void hdrrep(char * oldvalue, char * newvalue){ } } -int add_default_headers(int default_header_opts){ - int retval = 0; - - char * header = (char *) malloc(sizeof(char) * 80); - char * value = (char *) malloc(sizeof(char) * 80); - - if(header && value){ - if((default_header_opts & OPT_PROXY_AUTH) == OPT_PROXY_AUTH){ - memset(header, 0, 80); - memset(value, 0, 80); - strcpy(header, "Proxy-Authorization"); - strcpy(value, "Basic "); - strncat(value, proxy_authentication, 73); - retval &= add_header(header, value); - retval &= add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy Auth)"); - } - - if((default_header_opts & OPT_PROXY_NOAUTH) == OPT_PROXY_NOAUTH){ - retval &= add_or_replace_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)"); - } - - if((default_header_opts & OPT_NOPROXY) == OPT_NOPROXY){ - - } - - if((default_header_opts & OPT_GETCOOKIES) == OPT_GETCOOKIES){ - - } - } - - return retval; -} - /* * Concat all the headers in the list in a single string, and clean the whole list. */ @@ -275,9 +245,9 @@ char * stringify_headers_and_clean(){ // Clean it up and get to the next header tmp_ptr = cur_ptr; cur_ptr = cur_ptr->next; - //free(tmp_ptr->header); - //free(tmp_ptr->value); - //free(tmp_ptr); + free(tmp_ptr->header); + free(tmp_ptr->value); + free(tmp_ptr); } return headers_str; @@ -565,29 +535,18 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F } // Prepare the HTTP requests that will follow + // Add the default HTTP headers http_opts = 0; if(use_proxy == 1 && proxy_authentication != NULL){ // proxy with authentication - http_opts = OPT_PROXY_AUTH; - if(getcookie) - http_opts |= OPT_GETCOOKIES; + // TODO Add default headers here }else if(use_proxy == 1){ // proxy without authentication - http_opts = OPT_PROXY_NOAUTH; - if(getcookie) - http_opts |= OPT_GETCOOKIES; + // TODO Add default headers here }else{ // direct web server, no proxy -// char * header = (char *) malloc(255); -// char * value = (char *) malloc(255); -// strcpy(header, "User-Agent"); -// strcpy(value, "Mozilla/5.0 (Hydra)"); -// add_header(header, value); - add_header("Host", webtarget); - add_header("User-Agent", "Mozilla/5.0 (Hydra)"); - http_opts = OPT_NOPROXY; - if(getcookie) - http_opts |=OPT_GETCOOKIES; + add_header("Host", webtarget); + add_header("User-Agent", "Mozilla/5.0 (Hydra)"); } prepare_httpreq(type, url); @@ -622,18 +581,10 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F * - (optional1 + 2) contains the header's name * - ptr contains the header's value */ - header = (char *) malloc(strlen(optional1 + 2)); - value = (char *) malloc(strlen(ptr)); - if(header && value){ - strcpy(header, optional1 + 2); - strcpy(value, hydra_strrep(ptr, "\\:", ":")); - hydra_report(stdout, "Header: %s\n", header); - hydra_report(stdout, "Value: %s\n", value); - if(add_header(header, value)){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } + if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"))){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; } // Error: abort execution hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); @@ -656,19 +607,11 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F * - (optional1 + 2) contains the header's name * - ptr contains the header's value */ - header = (char *) malloc(strlen(optional1 + 2)); - value = (char *) malloc(strlen(ptr)); - if(header && value){ - strcpy(header, optional1 + 2); - strcpy(value, hydra_strrep(ptr, "\\:", ":")); - hydra_report(stdout, "Header: %s\n", header); - hydra_report(stdout, "Value: %s\n", value); - if(add_or_replace_header(header, value)){ + if(add_or_replace_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"))){ // Success: break the switch and go ahead optional1 = ptr2; break; - } - } + } // Error: abort execution hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); hydra_child_exit(1); From 31b021acda9e196b233b7f2e039b8775c541846b Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Tue, 8 Jul 2014 01:44:22 +0200 Subject: [PATCH 06/20] Changed scope for better performance. --- hydra-http-form.c | 395 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 305 insertions(+), 90 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 0663ebd..7308f6b 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -63,16 +63,19 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da #define DEFAULT_USER_AGENT 2 #define DEFAULT_CONTENT_TYPE 4 -#define MAX_REQ_LEN 1030 +/* HTTP Header Types */ +#define HEADER_TYPE_USERHEADER 'h' +#define HEADER_TYPE_USERHEADER_REPL 'H' +#define HEADER_TYPE_DEFAULT 'D' extern char *HYDRA_EXIT; char *buf; char *cond; -char http_request[MAX_REQ_LEN]; typedef struct header_node { char *header; char *value; + char type; struct header_node *next; }t_header_node, *ptr_header_node; @@ -90,26 +93,10 @@ char cookie[4096] = "", cmiscptr[1024]; extern char *webtarget; extern char *slash; int webport, freemischttpform = 0; -int http_opts; char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1; ptr_header_node ptr_head = NULL; -void prepare_httpreq(char * method, char * path){ - char tail[] = " HTTP/1.0"; - int req_len = (strlen(method) + strlen(path) + 1) <= MAX_REQ_LEN ? (strlen(method) + strlen(path) + 1) : MAX_REQ_LEN; - - memset(http_request, 0, MAX_REQ_LEN); - - if(strcmp(method, "GET") == 0) - strcat(http_request, "GET "); - else if(strcmp(method, "POST") == 0) - strcat(http_request, "POST "); - - strncat(http_request, path, MAX_REQ_LEN - sizeof(tail) - 5); - strcat(http_request, tail); -} - /* * Returns 1 if specified header exists, or 0 otherwise. */ @@ -125,9 +112,16 @@ int header_exists(char * header){ } /* - * Returns 1 if success, or 0 otherwise (out of memory). + * List layout: + * +----------+ +--------+ +--------+ +--------+ + * | ptr_head | --> | next | --> | next | --> | NULL | + * | | | header | | header | | NULL | + * | | | value | | value | | NULL | + * +----------+ +--------+ +--------+ +--------+ + * + * Returns 1 if success, or 0 otherwise (out of memory). */ -int add_header(char *header, char *value){ +int add_header(char *header, char *value, char type){ ptr_header_node cur_ptr = NULL; // get to the last header @@ -141,6 +135,7 @@ int add_header(char *header, char *value){ // create a new item and append it to the list new_ptr->header = new_header; new_ptr->value = new_value; + new_ptr->type = type; new_ptr->next = NULL; }else{ // we're out of memory, so forcefully end @@ -156,51 +151,15 @@ int add_header(char *header, char *value){ return 1; } -/* - * List layout: - * +----------+ +--------+ +--------+ +--------+ - * | ptr_head | --> | next | --> | next | --> | NULL | - * | | | header | | header | | NULL | - * | | | value | | value | | NULL | - * +----------+ +--------+ +--------+ +--------+ - * - * Returns 1 if success, or 0 otherwise (out of memory). - */ -int add_or_replace_header(char *header, char *value){ - int ret = 1; - - ptr_header_node cur_ptr = NULL; - char * new_header = strdup(header); - char * new_value = strdup(value); - - if(new_header && new_value){ - for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ - if(strcmp(cur_ptr->header, new_header) == 0){ - free(cur_ptr->value); - cur_ptr->value = new_value; - break; - } - } - } - - if(cur_ptr == NULL){ - ret = add_header(header, value); - // add_header() will create a new copy so we can safely free them - free(new_header); - free(new_value); - } - - return ret; -} - /* * Replace in all headers' values every occurrence of oldvalue by newvalue. + * Only user-defined headers are considered. */ void hdrrep(char * oldvalue, char * newvalue){ ptr_header_node cur_ptr = NULL; for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ - if(strstr(cur_ptr->value, oldvalue)){ + if((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)){ cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(newvalue)); if(cur_ptr->value) strcpy(cur_ptr->value, newvalue); @@ -215,7 +174,7 @@ void hdrrep(char * oldvalue, char * newvalue){ /* * Concat all the headers in the list in a single string, and clean the whole list. */ -char * stringify_headers_and_clean(){ +char * stringify_headers_and_clean(char * http_request){ char * headers_str = NULL; ptr_header_node cur_ptr = ptr_head, tmp_ptr = NULL; int ttl_size = strlen(http_request); @@ -245,14 +204,41 @@ char * stringify_headers_and_clean(){ // Clean it up and get to the next header tmp_ptr = cur_ptr; cur_ptr = cur_ptr->next; - free(tmp_ptr->header); +/* free(tmp_ptr->header); free(tmp_ptr->value); - free(tmp_ptr); + free(tmp_ptr);*/ } return headers_str; } +char * prepare_http_request(char * method, char * path){ + char * request = NULL, *headers = NULL; + char tail[] = " HTTP/1.0", + http_request[1030]; + int req_len = (strlen(method) + strlen(path) + 1) <= 1030 ? (strlen(method) + strlen(path) + 1) : 1030; + + memset(http_request, 0, 1030); + + if(strcmp(method, "GET") == 0) + strcat(http_request, "GET "); + else if(strcmp(method, "POST") == 0) + strcat(http_request, "POST "); + + strncat(http_request, path, 1030 - sizeof(tail) - 5); + strcat(http_request, tail); + + headers = stringify_headers_and_clean(http_request); + request = (char *) malloc(strlen(http_request) + strlen(headers) + 3); + if(request && headers){ + strcpy(request, http_request); + strcat(request, "\r\n"); + strcat(request, headers); + } + + return request; +} + int strpos(char *str, char *target) { char *res = strstr(str, target); @@ -400,17 +386,18 @@ void hydra_reconnect(int s, char *ip, int port, unsigned char options) { } int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type) { - char *empty = ""; + char *empty = ""; + char *buffer, // Buffer for HTTP headers + *proxy_string; char *login, *pass, clogin[256], cpass[256]; - char *buffer; // Buffer for HTTP headers char header[8096], *upd3variables, cuserheader[1024]; int found = !success_cond, i, j; memset(header, 0, sizeof(header)); cookie[0] = 0; // reset cookies from potential previous attempt - // Take the next login/pass pair - if (strlen(login = hydra_get_next_login()) == 0) + // Take the next login/pass pair + if (strlen(login = hydra_get_next_login()) == 0) login = empty; if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; @@ -418,19 +405,264 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc clogin[sizeof(clogin) - 1] = 0; strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); cpass[sizeof(cpass) - 1] = 0; - - // Replace the user/pass placeholders in the command line options - upd3variables = hydra_strrep(variables, "^USER^", clogin); - upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); + upd3variables = hydra_strrep(variables, "^USER^", clogin); + upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); // Replace the user/pass placeholders in the user-supplied headers hdrrep("^USER^", clogin); hdrrep("^PASS^", cpass); +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* again: no snprintf to be portable. dont worry, buffer cant overflow */ + if (use_proxy == 1 && proxy_authentication != NULL) { + // proxy with authentication + add_header("Host", webtarget, HEADER_TYPE_DEFAULT); + add_header("User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); + proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); + if(proxy_string) { + strcpy(proxy_string, "Basic "); + strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); + add_header("Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); + }else{ + hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); + hydra_child_exit(1); + } + if (getcookie) { + //doing a GET to save cookies +// sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla 5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", +// webtarget, webport, cookieurl, webtarget, proxy_authentication, header, cuserheader); + buffer = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", buffer); +/* if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + i = analyze_server_response(s); // return value ignored + if (strlen(cookie) > 0) { + sprintf(header, "Cookie: %s\r\n", cookie); + } + hydra_reconnect(s, ip, port, options);*/ + } + buffer = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers (Proxy Auth): %s", buffer); + /*if (strcmp(type, "POST") == 0) { + sprintf(buffer, + "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy Auth)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", + webtarget, webport, url, webtarget, proxy_authentication, (int) strlen(upd3variables), header, cuserheader, upd3variables); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + } else { + sprintf(buffer, + "GET http://%s:%d%.600s?%s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", + webtarget, webport, url, upd3variables, webtarget, proxy_authentication, header, cuserheader); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + }*/ + } else { + if (use_proxy == 1) { + // proxy without authentication + add_header("Host", webtarget, HEADER_TYPE_DEFAULT); + add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); + if (getcookie) { + //doing a GET to get cookies + buffer = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", buffer); + +// sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy)\r\n%s%s\r\n", webtarget, webport, cookieurl, webtarget, header, +// cuserheader); +/* if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + i = analyze_server_response(s); // ignore result + if (strlen(cookie) > 0) { + sprintf(header, "Cookie: %s\r\n", cookie); + } + hydra_reconnect(s, ip, port, options);*/ + } + buffer = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", buffer); + /*if (strcmp(type, "POST") == 0) { + sprintf(buffer, + "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", + webtarget, webport, url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + } else { + sprintf(buffer, "GET http://%s:%d%.600s?%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s%s\r\n", webtarget, webport, url, upd3variables, webtarget, + header, cuserheader); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + }*/ + } else { + // direct web server, no proxy + add_header("Host", webtarget, HEADER_TYPE_DEFAULT); + add_header("User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); + if (getcookie) { + //doing a GET to save cookies +/* sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s\r\n", cookieurl, webtarget, cuserheader); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + i = analyze_server_response(s); // ignore result + if (strlen(cookie) > 0) { + sprintf(header, "Cookie: %s\r\n", cookie); + } + hydra_reconnect(s, ip, port, options);*/ + buffer = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers (Direct Cookies): %s", buffer); + } + buffer = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers (Direct): %s", buffer); + /*if (strcmp(type, "POST") == 0) { + sprintf(buffer, + "POST %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", + url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + } else { + sprintf(buffer, "GET %.600s?%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s%s\r\n", url, upd3variables, webtarget, header, cuserheader); + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + }*/ + } + } + + /*found = analyze_server_response(s); + if (auth_flag) { // we received a 401 error - user using wrong module + hydra_report(stderr, "[ERROR] the target is using HTTP auth, not a web form, received HTTP error code 401. Use module \"http%s-get\" instead.\n", + (options & OPTION_SSL) > 0 ? "s" : ""); + return 4; + } + if (strlen(cookie) > 0) { + sprintf(header, "Cookie: %.1000s\r\n", cookie); + } + //if page was redirected, follow the location header + redirected_cpt = MAX_REDIRECT; + if (debug) + printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); + while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { + //we have to split the location + char *startloc, *endloc; + char str[2048]; + char str2[2048]; + char str3[2048]; + + redirected_cpt--; + redirected_flag = 0; + //check if the redirect page contains the fail/success condition + #ifdef HAVE_PCRE + if (hydra_string_match(redirected_url_buff, cond) == 1) { + #else + if (strstr(redirected_url_buff, cond) != NULL) { + #endif + found = success_cond; + } else { + //location could be either absolute http(s):// or / something + //or relative + startloc = strstr(redirected_url_buff, "://"); + if (startloc != NULL) { + startloc += strlen("://"); + + if ((endloc = strchr(startloc, '\r')) != NULL) { + startloc[endloc - startloc] = 0; + } + if ((endloc = strchr(startloc, '\n')) != NULL) { + startloc[endloc - startloc] = 0; + } + strcpy(str, startloc); + + endloc = strchr(str, '/'); + if (endloc != NULL) { + strncpy(str2, str, endloc - str); + str2[endloc - str] = 0; + } else + strncpy(str2, str, sizeof(str)); + + if (strlen(str) - strlen(str2) == 0) { + strcpy(str3, "/"); + } else { + strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) - 1); + str3[strlen(str) - strlen(str2) - 1] = 0; + } + } else { + strncpy(str2, webtarget, sizeof(str2)); + if (redirected_url_buff[0] != '/') { + //it's a relative path, so we have to concatenate it + //with the path from the first url given + char *urlpath; + char urlpath_extracted[2048]; + + memset(urlpath_extracted, 0, sizeof(urlpath_extracted)); + + urlpath = strrchr(url, '/'); + if (urlpath != NULL) { + strncpy(urlpath_extracted, url, urlpath - url); + sprintf(str3, "%.1000s/%.1000s", urlpath_extracted, redirected_url_buff); + } else { + sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff); + } + } else + strncpy(str3, redirected_url_buff, sizeof(str3)); + if (debug) + hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url); + } + if (str3[0] != '/') { + j = strlen(str3); + str3[j + 1] = 0; + for (i = j; i > 0; i--) + str3[i] = str3[i - 1]; + str3[0] = '/'; + } + + if (verbose) + hydra_report(stderr, "[VERBOSE] Page redirected to http://%s%s\n", str2, str3); + + //re-use the code above to check for proxy use + if (use_proxy == 1 && proxy_authentication != NULL) { + // proxy with authentication + sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", + webtarget, webport, str3, str2, proxy_authentication, header); + } else { + if (use_proxy == 1) { + // proxy without authentication + sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", webtarget, webport, str3, str2, header); + } else { + //direct web server, no proxy + sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); + } + } + + hydra_reconnect(s, ip, port, options); + + if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + return 1; + } + found = analyze_server_response(s); + if (strlen(cookie) > 0) { + sprintf(header, "Cookie: %s\r\n", cookie); + } + } + } + + //if the last status is still 3xx, set it as a false + if (found != -1 && found == success_cond && redirected_flag == 0 && redirected_cpt >= 0) { + hydra_report_found_host(port, ip, "www-form", fp); + hydra_completed_pair_found(); + } else { + hydra_completed_pair(); + } + return 1;*/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////// - buffer = stringify_headers_and_clean(); - hydra_report(stdout, "HTTP headers:\n%s\r\n%s", http_request, buffer); +/* char * http_request = prepare_http_request(type, url); + hydra_report(stdout, "HTTP headers:\n%s\r\n", http_request);*/ hydra_child_exit(1); return 1; @@ -534,23 +766,6 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F success_cond = 0; } - // Prepare the HTTP requests that will follow - // Add the default HTTP headers - http_opts = 0; - if(use_proxy == 1 && proxy_authentication != NULL){ - // proxy with authentication - // TODO Add default headers here - }else if(use_proxy == 1){ - // proxy without authentication - // TODO Add default headers here - }else{ - // direct web server, no proxy - add_header("Host", webtarget); - add_header("User-Agent", "Mozilla/5.0 (Hydra)"); - } - - prepare_httpreq(type, url); - char *header = NULL, *value = NULL; while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { switch (optional1[0]) { @@ -581,7 +796,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F * - (optional1 + 2) contains the header's name * - ptr contains the header's value */ - if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"))){ + if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)){ // Success: break the switch and go ahead optional1 = ptr2; break; @@ -607,7 +822,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F * - (optional1 + 2) contains the header's name * - ptr contains the header's value */ - if(add_or_replace_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"))){ + if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)){ // Success: break the switch and go ahead optional1 = ptr2; break; From f5e74749f802d1ba95e8faaf242a25e0fdfdf066 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Sat, 12 Jul 2014 19:41:30 +0200 Subject: [PATCH 07/20] Now we don't blank the headers' memory space after stringifying them. --- hydra-http-form.c | 71 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 7308f6b..eaa6136 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -100,15 +100,15 @@ ptr_header_node ptr_head = NULL; /* * Returns 1 if specified header exists, or 0 otherwise. */ -int header_exists(char * header){ - ptr_header_node cur_ptr = NULL; - int header_exists = 0; +ptr_header_node header_exists(char * header_name, char type){ + ptr_header_node cur_ptr = NULL, + found_header = NULL; - for(cur_ptr = ptr_head; cur_ptr && !header_exists; cur_ptr = cur_ptr->next) - if(cur_ptr->header && strcmp(cur_ptr->header, header) == 0) - header_exists = 1; + for(cur_ptr = ptr_head; cur_ptr && !found_header; cur_ptr = cur_ptr->next) + if(cur_ptr->header && strcmp(cur_ptr->header, header_name) == 0 && cur_ptr->type == type) + found_header = cur_ptr; - return header_exists; + return found_header; } /* @@ -132,11 +132,41 @@ int add_header(char *header, char *value, char type){ char * new_value = strdup(value); if(new_ptr && new_header && new_value){ - // create a new item and append it to the list - new_ptr->header = new_header; - new_ptr->value = new_value; - new_ptr->type = type; - new_ptr->next = NULL; + if(type == HEADER_TYPE_USERHEADER){ + // create a new item and append it to the list + new_ptr->header = new_header; + new_ptr->value = new_value; + new_ptr->type = type; + new_ptr->next = NULL; + hydra_report(stdout, "[DEBUG] Added header (HEADER_TYPE_USERHEADER) %s: %s\n", new_header, new_value); + }else if(type == HEADER_TYPE_DEFAULT && !header_exists(new_header, HEADER_TYPE_USERHEADER_REPL)){ + // It's a default header and there are no user headers that replace it, + // so we create a new item and append it to the list + new_ptr->header = new_header; + new_ptr->value = new_value; + new_ptr->type = type; + new_ptr->next = NULL; + hydra_report(stdout, "[DEBUG] Added header (HEADER_TYPE_DEFAULT) %s: %s\n", new_header, new_value); + }else if(type == HEADER_TYPE_USERHEADER_REPL){ + // It's a user-supplied header that must replace a default one + ptr_header_node hdr_val = header_exists(new_header, HEADER_TYPE_DEFAULT); + if(!hdr_val){ + // There are no headers with the same name, so we act + // as if it was a normal header + new_ptr->header = new_header; + new_ptr->value = new_value; + new_ptr->type = type; + new_ptr->next = NULL; + hydra_report(stdout, "[DEBUG] Added header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", new_header, new_value); + }else{ + // Replace the default header's value with this new value + free(hdr_val->value); + hdr_val->value = new_value; + hdr_val->type = type; + hydra_report(stdout, "[DEBUG] Replaced header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", hdr_val->header, hdr_val->value); + return 1; + } + } }else{ // we're out of memory, so forcefully end return 0; @@ -172,11 +202,12 @@ void hdrrep(char * oldvalue, char * newvalue){ } /* - * Concat all the headers in the list in a single string, and clean the whole list. + * Concat all the headers in the list in a single string. + * Leave the list itself intact: do not clean it here. */ -char * stringify_headers_and_clean(char * http_request){ +char * stringify_headers(char * http_request){ char * headers_str = NULL; - ptr_header_node cur_ptr = ptr_head, tmp_ptr = NULL; + ptr_header_node cur_ptr = ptr_head; int ttl_size = strlen(http_request); while(cur_ptr){ @@ -185,7 +216,7 @@ char * stringify_headers_and_clean(char * http_request){ if(headers_str) headers_str = (char *) realloc(headers_str, sizeof(char) * ttl_size); else{ - // Garbage appears when strcat()-ing, if we don't blank newly allocated memory + // Garbage appears when strcat()-ing, if we don't blank the newly allocated memory headers_str = (char *) malloc(sizeof(char) * ttl_size); if(headers_str) memset(headers_str, 0, sizeof(char) * ttl_size); @@ -201,12 +232,8 @@ char * stringify_headers_and_clean(char * http_request){ hydra_child_exit(1); } } - // Clean it up and get to the next header - tmp_ptr = cur_ptr; + // Get to the next header cur_ptr = cur_ptr->next; -/* free(tmp_ptr->header); - free(tmp_ptr->value); - free(tmp_ptr);*/ } return headers_str; @@ -228,7 +255,7 @@ char * prepare_http_request(char * method, char * path){ strncat(http_request, path, 1030 - sizeof(tail) - 5); strcat(http_request, tail); - headers = stringify_headers_and_clean(http_request); + headers = stringify_headers(http_request); request = (char *) malloc(strlen(http_request) + strlen(headers) + 3); if(request && headers){ strcpy(request, http_request); From 4186a3ad4321f1cc3994c788e5780105093a4cd5 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Sat, 12 Jul 2014 20:25:08 +0200 Subject: [PATCH 08/20] Removed repeated code. --- hydra-http-form.c | 63 ++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index eaa6136..9b10cce 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -127,57 +127,48 @@ int add_header(char *header, char *value, char type){ // get to the last header for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); - ptr_header_node new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); + ptr_header_node existing_hdr, + new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); + char * new_header = strdup(header); char * new_value = strdup(value); if(new_ptr && new_header && new_value){ - if(type == HEADER_TYPE_USERHEADER){ - // create a new item and append it to the list + if((type == HEADER_TYPE_USERHEADER) || + (type == HEADER_TYPE_DEFAULT && !header_exists(new_header, HEADER_TYPE_USERHEADER_REPL)) || + (type == HEADER_TYPE_USERHEADER_REPL && !header_exists(new_header, HEADER_TYPE_DEFAULT))){ + /* + * We are in one of the following scenarios: + * 1. A default header with no user-supplied headers that replace it. + * 2. A user-supplied header that must be appended (option 'h'). + * 3. A user-supplied header that must replace a default header (option 'h'), + * but no default headers exist with that name. + * + * In either case we just add the header to the list. + */ new_ptr->header = new_header; new_ptr->value = new_value; new_ptr->type = type; new_ptr->next = NULL; - hydra_report(stdout, "[DEBUG] Added header (HEADER_TYPE_USERHEADER) %s: %s\n", new_header, new_value); - }else if(type == HEADER_TYPE_DEFAULT && !header_exists(new_header, HEADER_TYPE_USERHEADER_REPL)){ - // It's a default header and there are no user headers that replace it, - // so we create a new item and append it to the list - new_ptr->header = new_header; - new_ptr->value = new_value; - new_ptr->type = type; - new_ptr->next = NULL; - hydra_report(stdout, "[DEBUG] Added header (HEADER_TYPE_DEFAULT) %s: %s\n", new_header, new_value); - }else if(type == HEADER_TYPE_USERHEADER_REPL){ + + if(cur_ptr) + cur_ptr->next = new_ptr; + else + // head is NULL, so the list is empty + ptr_head = new_ptr; + }else if(type == HEADER_TYPE_USERHEADER_REPL && (existing_hdr = header_exists(new_header, HEADER_TYPE_DEFAULT))){ // It's a user-supplied header that must replace a default one - ptr_header_node hdr_val = header_exists(new_header, HEADER_TYPE_DEFAULT); - if(!hdr_val){ - // There are no headers with the same name, so we act - // as if it was a normal header - new_ptr->header = new_header; - new_ptr->value = new_value; - new_ptr->type = type; - new_ptr->next = NULL; - hydra_report(stdout, "[DEBUG] Added header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", new_header, new_value); - }else{ - // Replace the default header's value with this new value - free(hdr_val->value); - hdr_val->value = new_value; - hdr_val->type = type; - hydra_report(stdout, "[DEBUG] Replaced header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", hdr_val->header, hdr_val->value); - return 1; - } + // Replace the default header's value with this new value + free(existing_hdr->value); + existing_hdr->value = new_value; + existing_hdr->type = type; + hydra_report(stdout, "[DEBUG] Replaced header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", existing_hdr->header, existing_hdr->value); } }else{ // we're out of memory, so forcefully end return 0; } - if(cur_ptr) - cur_ptr->next = new_ptr; - else - // head is NULL, so the list is empty - ptr_head = new_ptr; - return 1; } From 8722f8a55c4edb9828bf839819646531f10903a8 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Sun, 27 Jul 2014 04:33:48 +0200 Subject: [PATCH 09/20] Checkpoint. HTTP request correctly implemented for plain HTTP (w/o proxy). --- hydra-http-form.c | 68 +++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 9b10cce..bbe27ba 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -87,6 +87,7 @@ char redirected_url_buff[2048] = ""; int redirected_flag = 0; #define MAX_REDIRECT 8 +#define MAX_CONTENT_LENGTH 20 int redirected_cpt = MAX_REDIRECT; char cookie[4096] = "", cmiscptr[1024]; @@ -123,17 +124,15 @@ ptr_header_node header_exists(char * header_name, char type){ */ int add_header(char *header, char *value, char type){ ptr_header_node cur_ptr = NULL; + ptr_header_node existing_hdr, new_ptr; // get to the last header for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); - ptr_header_node existing_hdr, - new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); - char * new_header = strdup(header); char * new_value = strdup(value); - if(new_ptr && new_header && new_value){ + if(new_header && new_value){ if((type == HEADER_TYPE_USERHEADER) || (type == HEADER_TYPE_DEFAULT && !header_exists(new_header, HEADER_TYPE_USERHEADER_REPL)) || (type == HEADER_TYPE_USERHEADER_REPL && !header_exists(new_header, HEADER_TYPE_DEFAULT))){ @@ -146,6 +145,9 @@ int add_header(char *header, char *value, char type){ * * In either case we just add the header to the list. */ + new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); + if(!new_ptr) + return 0; new_ptr->header = new_header; new_ptr->value = new_value; new_ptr->type = type; @@ -192,6 +194,19 @@ void hdrrep(char * oldvalue, char * newvalue){ } } +void cleanup(){ + ptr_header_node cur_ptr = ptr_head, next_ptr = cur_ptr; + + while(next_ptr){ + free(cur_ptr->header); + free(cur_ptr->value); + next_ptr = cur_ptr->next; + //free(cur_ptr); + } + + ptr_head = NULL; +} + /* * Concat all the headers in the list in a single string. * Leave the list itself intact: do not clean it here. @@ -230,7 +245,7 @@ char * stringify_headers(char * http_request){ return headers_str; } -char * prepare_http_request(char * method, char * path){ +char * prepare_http_request(char * method, char * path, char * postdata){ char * request = NULL, *headers = NULL; char tail[] = " HTTP/1.0", http_request[1030]; @@ -247,11 +262,14 @@ char * prepare_http_request(char * method, char * path){ strcat(http_request, tail); headers = stringify_headers(http_request); - request = (char *) malloc(strlen(http_request) + strlen(headers) + 3); + request = (char *) malloc(strlen(http_request) + strlen(headers) + 5 + (strcmp(method, "POST") == 0 && postdata? strlen(postdata) : 0)); if(request && headers){ strcpy(request, http_request); strcat(request, "\r\n"); strcat(request, headers); + strcat(request, "\r\n"); + if(strcmp(method, "POST") == 0 && postdata) + strcat(request, postdata); } return request; @@ -410,6 +428,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc char *login, *pass, clogin[256], cpass[256]; char header[8096], *upd3variables, cuserheader[1024]; int found = !success_cond, i, j; + char content_length[MAX_CONTENT_LENGTH]; memset(header, 0, sizeof(header)); cookie[0] = 0; // reset cookies from potential previous attempt @@ -450,7 +469,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc //doing a GET to save cookies // sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla 5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", // webtarget, webport, cookieurl, webtarget, proxy_authentication, header, cuserheader); - buffer = prepare_http_request(type, url); + buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", buffer); /* if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; @@ -461,7 +480,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc } hydra_reconnect(s, ip, port, options);*/ } - buffer = prepare_http_request(type, url); + buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Auth): %s", buffer); /*if (strcmp(type, "POST") == 0) { sprintf(buffer, @@ -485,7 +504,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); if (getcookie) { //doing a GET to get cookies - buffer = prepare_http_request(type, url); + buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", buffer); // sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy)\r\n%s%s\r\n", webtarget, webport, cookieurl, webtarget, header, @@ -499,7 +518,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc } hydra_reconnect(s, ip, port, options);*/ } - buffer = prepare_http_request(type, url); + buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", buffer); /*if (strcmp(type, "POST") == 0) { sprintf(buffer, @@ -519,35 +538,38 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc // direct web server, no proxy add_header("Host", webtarget, HEADER_TYPE_DEFAULT); add_header("User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); + if (getcookie) { //doing a GET to save cookies -/* sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s\r\n", cookieurl, webtarget, cuserheader); + buffer = prepare_http_request(type, url, NULL); + hydra_report(stdout, "HTTP headers (Direct Cookies): %s", buffer); if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; } i = analyze_server_response(s); // ignore result if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); + add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); } - hydra_reconnect(s, ip, port, options);*/ - buffer = prepare_http_request(type, url); - hydra_report(stdout, "HTTP headers (Direct Cookies): %s", buffer); + hydra_reconnect(s, ip, port, options); } - buffer = prepare_http_request(type, url); - hydra_report(stdout, "HTTP headers (Direct): %s", buffer); - /*if (strcmp(type, "POST") == 0) { - sprintf(buffer, - "POST %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", - url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables); + + // now prepare for the "real" request + if (strcmp(type, "POST") == 0) { + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); + add_header("Content-Length", content_length, HEADER_TYPE_DEFAULT); + add_header("Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + buffer = prepare_http_request(type, url, upd3variables); + hydra_report(stdout, "HTTP headers (Direct): %s", buffer); if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; } } else { - sprintf(buffer, "GET %.600s?%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s%s\r\n", url, upd3variables, webtarget, header, cuserheader); + buffer = prepare_http_request(type, url, NULL); + hydra_report(stdout, "HTTP headers (Direct): %s", buffer); if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; } - }*/ + } } } From f0fc03e53b51beb9bbc8d06e0751ed1d9893d0bf Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Tue, 29 Jul 2014 21:19:53 +0200 Subject: [PATCH 10/20] Direct HTTP working. --- hydra-http-form.c | 685 +++++++++++++++++++++++----------------------- 1 file changed, 343 insertions(+), 342 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index bbe27ba..1120243 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -96,6 +96,8 @@ extern char *slash; int webport, freemischttpform = 0; char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1; +char *cookie_request, *normal_request; // Buffers for HTTP headers + ptr_header_node ptr_head = NULL; /* @@ -194,6 +196,22 @@ void hdrrep(char * oldvalue, char * newvalue){ } } +void hdrrepv(char * hdrname, char * new_value){ + ptr_header_node cur_ptr = NULL; + + for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if((cur_ptr->type == HEADER_TYPE_DEFAULT) && strcmp(cur_ptr->header, hdrname)){ + cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(new_value)); + if(cur_ptr->value) + strcpy(cur_ptr->value, new_value); + else{ + hydra_report(stderr, "[ERROR] Out of memory"); + hydra_child_exit(1); + } + } + } +} + void cleanup(){ ptr_header_node cur_ptr = ptr_head, next_ptr = cur_ptr; @@ -211,68 +229,69 @@ void cleanup(){ * Concat all the headers in the list in a single string. * Leave the list itself intact: do not clean it here. */ -char * stringify_headers(char * http_request){ +char * stringify_headers(){ char * headers_str = NULL; ptr_header_node cur_ptr = ptr_head; - int ttl_size = strlen(http_request); + int ttl_size = 0; - while(cur_ptr){ - if(cur_ptr->header && cur_ptr->value){ // Check for NULLs - ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 1; - if(headers_str) - headers_str = (char *) realloc(headers_str, sizeof(char) * ttl_size); - else{ - // Garbage appears when strcat()-ing, if we don't blank the newly allocated memory - headers_str = (char *) malloc(sizeof(char) * ttl_size); - if(headers_str) - memset(headers_str, 0, sizeof(char) * ttl_size); - } - if(headers_str){ // Check for errors + for(; cur_ptr; cur_ptr = cur_ptr->next) + ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 3; + + headers_str = (char *) malloc(ttl_size + 1); + + if(headers_str){ + memset(headers_str, 0, ttl_size + 1); + for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ strcat(headers_str, cur_ptr->header); - strcat(headers_str, ": "); + strcat(headers_str, ":"); strcat(headers_str, cur_ptr->value); strcat(headers_str, "\r\n"); - }else{ - // Error: out of memory - hydra_report(stderr, "Out of memory for HTTP headers"); - hydra_child_exit(1); - } + } } - // Get to the next header - cur_ptr = cur_ptr->next; - } return headers_str; } -char * prepare_http_request(char * method, char * path, char * postdata){ - char * request = NULL, *headers = NULL; - char tail[] = " HTTP/1.0", - http_request[1030]; - int req_len = (strlen(method) + strlen(path) + 1) <= 1030 ? (strlen(method) + strlen(path) + 1) : 1030; +char * prepare_http_request(char * type, char * path, char * params, char * headers){ + unsigned int reqlen = 0; + char * http_request = NULL; - memset(http_request, 0, 1030); + if(type && path && headers){ + reqlen = strlen(path) + strlen(headers) + 20; + if(params) + reqlen += strlen(params); - if(strcmp(method, "GET") == 0) - strcat(http_request, "GET "); - else if(strcmp(method, "POST") == 0) - strcat(http_request, "POST "); + http_request = (char *) malloc(reqlen); + if(http_request){ + memset(http_request, 0, reqlen); - strncat(http_request, path, 1030 - sizeof(tail) - 5); - strcat(http_request, tail); + // append the request verb (GET or POST) + if(strcmp(type, "GET") == 0) + strcat(http_request, "GET "); + else + strcat(http_request, "POST "); - headers = stringify_headers(http_request); - request = (char *) malloc(strlen(http_request) + strlen(headers) + 5 + (strcmp(method, "POST") == 0 && postdata? strlen(postdata) : 0)); - if(request && headers){ - strcpy(request, http_request); - strcat(request, "\r\n"); - strcat(request, headers); - strcat(request, "\r\n"); - if(strcmp(method, "POST") == 0 && postdata) - strcat(request, postdata); + // append the request path + strcat(http_request, path); + + // if GET, append the params now + if(params && strcmp(type, "GET") == 0){ + strcat(http_request, "?"); + strcat(http_request, params); + } + + // append the headers + strcat(http_request, " HTTP/1.0\r\n"); + strcat(http_request, headers); + strcat(http_request, "\r\n"); + + // if POST, append the params now + if(params && strcmp(type, "POST") == 0) + strcat(http_request, params); + } } - return request; + return http_request; } int strpos(char *str, char *target) { @@ -352,9 +371,11 @@ int analyze_server_response(int s) { endcookie1 = strchr(str, '\n'); endcookie2 = strchr(str, ';'); //terminate string after cookie data - if (endcookie1 != NULL && endcookie1 < endcookie2) - *endcookie1 = 0; - else if (endcookie2 != NULL) + if (endcookie1 != NULL && ((endcookie1 < endcookie2) || (endcookie2 == NULL))){ + if(*(endcookie1 - 1) == '\r') + endcookie1--; + *endcookie1 = 0; + }else if (endcookie2 != NULL) *endcookie2 = 0; // is the cookie already there? if yes, remove it! if (index(startcookie, '=') != NULL && (ptr = index(startcookie, '=')) - startcookie + 1 <= sizeof(tmpname)) { @@ -423,10 +444,10 @@ void hydra_reconnect(int s, char *ip, int port, unsigned char options) { int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type) { char *empty = ""; - char *buffer, // Buffer for HTTP headers - *proxy_string; + char * buffer; char *login, *pass, clogin[256], cpass[256]; char header[8096], *upd3variables, cuserheader[1024]; + char *http_request; int found = !success_cond, i, j; char content_length[MAX_CONTENT_LENGTH]; @@ -449,106 +470,35 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc hdrrep("^USER^", clogin); hdrrep("^PASS^", cpass); -/////////////////////////////////////////////////////////////////////////////////////////////////////////// - /* again: no snprintf to be portable. dont worry, buffer cant overflow */ if (use_proxy == 1 && proxy_authentication != NULL) { - // proxy with authentication - add_header("Host", webtarget, HEADER_TYPE_DEFAULT); - add_header("User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); - proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); - if(proxy_string) { - strcpy(proxy_string, "Basic "); - strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); - add_header("Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); - }else{ - hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); - hydra_child_exit(1); - } if (getcookie) { - //doing a GET to save cookies -// sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla 5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", -// webtarget, webport, cookieurl, webtarget, proxy_authentication, header, cuserheader); - buffer = prepare_http_request(type, url, NULL); + //buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", buffer); -/* if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - i = analyze_server_response(s); // return value ignored - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } - hydra_reconnect(s, ip, port, options);*/ } - buffer = prepare_http_request(type, url, NULL); + //buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Auth): %s", buffer); - /*if (strcmp(type, "POST") == 0) { - sprintf(buffer, - "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy Auth)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", - webtarget, webport, url, webtarget, proxy_authentication, (int) strlen(upd3variables), header, cuserheader, upd3variables); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } else { - sprintf(buffer, - "GET http://%s:%d%.600s?%s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy Auth)\r\n%s%s\r\n", - webtarget, webport, url, upd3variables, webtarget, proxy_authentication, header, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - }*/ } else { if (use_proxy == 1) { // proxy without authentication - add_header("Host", webtarget, HEADER_TYPE_DEFAULT); - add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); if (getcookie) { //doing a GET to get cookies - buffer = prepare_http_request(type, url, NULL); + //buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", buffer); - -// sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra Proxy)\r\n%s%s\r\n", webtarget, webport, cookieurl, webtarget, header, -// cuserheader); -/* if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } - hydra_reconnect(s, ip, port, options);*/ } - buffer = prepare_http_request(type, url, NULL); + //buffer = prepare_http_request(type, url, NULL); hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", buffer); - /*if (strcmp(type, "POST") == 0) { - sprintf(buffer, - "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s", - webtarget, webport, url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - } else { - sprintf(buffer, "GET http://%s:%d%.600s?%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%s%s\r\n", webtarget, webport, url, upd3variables, webtarget, - header, cuserheader); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { - return 1; - } - }*/ } else { // direct web server, no proxy - add_header("Host", webtarget, HEADER_TYPE_DEFAULT); - add_header("User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); - if (getcookie) { //doing a GET to save cookies - buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Direct Cookies): %s", buffer); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + http_request = prepare_http_request("GET", cookieurl, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0) { + if (strlen(cookie) > 0){ add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(); } hydra_reconnect(s, ip, port, options); } @@ -558,34 +508,35 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); add_header("Content-Length", content_length, HEADER_TYPE_DEFAULT); add_header("Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); - buffer = prepare_http_request(type, url, upd3variables); - hydra_report(stdout, "HTTP headers (Direct): %s", buffer); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + normal_request = stringify_headers(); + http_request = prepare_http_request("POST", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } else { - buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Direct): %s", buffer); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + normal_request = stringify_headers(); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } } } - /*found = analyze_server_response(s); + found = analyze_server_response(s); + if (auth_flag) { // we received a 401 error - user using wrong module hydra_report(stderr, "[ERROR] the target is using HTTP auth, not a web form, received HTTP error code 401. Use module \"http%s-get\" instead.\n", (options & OPTION_SSL) > 0 ? "s" : ""); return 4; } - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %.1000s\r\n", cookie); - } + + if (strlen(cookie) > 0) + add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); + //if page was redirected, follow the location header redirected_cpt = MAX_REDIRECT; if (debug) printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); + while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { //we have to split the location char *startloc, *endloc; @@ -674,19 +625,21 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", webtarget, webport, str3, str2, header); } else { //direct web server, no proxy - sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); + //sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); + hdrrepv("Host", str2); + normal_request = stringify_headers(); + http_request = prepare_http_request("GET", str3, NULL, normal_request); } } hydra_reconnect(s, ip, port, options); - if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } + found = analyze_server_response(s); - if (strlen(cookie) > 0) { - sprintf(header, "Cookie: %s\r\n", cookie); - } + if (strlen(cookie) > 0) + add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); } } @@ -697,184 +650,24 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc } else { hydra_completed_pair(); } - return 1;*/ -////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/* char * http_request = prepare_http_request(type, url); - hydra_report(stdout, "HTTP headers:\n%s\r\n", http_request);*/ - - hydra_child_exit(1); - return 1; + return 1; } void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port, char *type) { int run = 1, next_run = 1, sock = -1; int myport = PORT_HTTP, mysslport = PORT_HTTP_SSL; - char *ptr, *ptr2; + // register our socket descriptor hydra_register_socket(sp); - if (webtarget != NULL && (webtarget = strstr(miscptr, "://")) != NULL) { - webtarget += strlen("://"); - if ((ptr2 = index(webtarget, ':')) != NULL) { /* step over port if present */ - *ptr2 = 0; - ptr2++; - ptr = ptr2; - if (*ptr == '/' || (ptr = index(ptr2, '/')) != NULL) - miscptr = ptr; - else - miscptr = slash; /* to make things easier to user */ - } else if ((ptr2 = index(webtarget, '/')) != NULL) { - if (freemischttpform == 0) { - freemischttpform = 1; - miscptr = malloc(strlen(ptr2) + 1); - strcpy(miscptr, ptr2); - *ptr2 = 0; - } - } else - webtarget = NULL; - } - if (cmdlinetarget != NULL && webtarget == NULL) - webtarget = cmdlinetarget; - else if (webtarget == NULL && cmdlinetarget == NULL) - webtarget = hydra_address2string(ip); - if (port != 0) - webport = port; - else if ((options & OPTION_SSL) == 0) - webport = myport; - else - webport = mysslport; - - sprintf(bufferurl, "%.1000s", miscptr); - url = bufferurl; - ptr = url; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - variables = ptr; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - cond = ptr; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - optional1 = ptr; - if (strstr(url, "\\:") != NULL) { - if ((ptr = malloc(strlen(url))) != NULL) { - strcpy(ptr, hydra_strrep(url, "\\:", ":")); - url = ptr; - } - } - if (strstr(variables, "\\:") != NULL) { - if ((ptr = malloc(strlen(variables))) != NULL) { - strcpy(ptr, hydra_strrep(variables, "\\:", ":")); - variables = ptr; - } - } - if (strstr(cond, "\\:") != NULL) { - if ((ptr = malloc(strlen(cond))) != NULL) { - strcpy(ptr, hydra_strrep(cond, "\\:", ":")); - cond = ptr; - } - } - if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */ ) - hydra_child_exit(2); - -//printf("url: %s, var: %s, cond: %s, opt: %s\n", url, variables, cond, optional1); - - if (*cond == 0) { - fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); - hydra_child_exit(2); - } - - sprintf(cookieurl, "%.1000s", url); - - //conditions now have to contain F or S to set the fail or success condition - if (*cond != 0 && (strpos(cond, "F=") == 0)) { - success_cond = 0; - cond += 2; - } else if (*cond != 0 && (strpos(cond, "S=") == 0)) { - success_cond = 1; - cond += 2; - } else { - //by default condition is a fail - success_cond = 0; - } - - char *header = NULL, *value = NULL; - while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { - switch (optional1[0]) { - case 'c': // fall through - case 'C': - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - sprintf(cookieurl, "%.1000s", hydra_strrep(optional1 + 2, "\\:", ":")); - optional1 = ptr; - break; - case 'h': - // add a new header at the end - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - ptr2 = ptr; - while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) - ptr2++; - if (*ptr2 != 0) - *ptr2++ = 0; - /* - * At this point: - * - (optional1 + 2) contains the header's name - * - ptr contains the header's value - */ - if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } - // Error: abort execution - hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - hydra_child_exit(1); - break; - case 'H': - // add a new header, or replace an existing one's value - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - ptr2 = ptr; - while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) - ptr2++; - if (*ptr2 != 0) - *ptr2++ = 0; - /* - * At this point: - * - (optional1 + 2) contains the header's name - * - ptr contains the header's value - */ - if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } - // Error: abort execution - hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - hydra_child_exit(1); - break; - // no default - } - } - + /* + * Iterate through the runs. Values are the following: + * - 1 -> Open connection to remote server. + * - 2 -> Run password attempts. + * - 3 -> Disconnect and end with success. + * - 4 -> Disconnect and end with error. + */ while (1) { if (run == 2) { if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { @@ -886,30 +679,30 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F } switch (run) { case 1: /* connect and service init function */ - { - if (sock >= 0) - sock = hydra_disconnect(sock); - if ((options & OPTION_SSL) == 0) { - if (port != 0) - myport = port; - sock = hydra_connect_tcp(ip, myport); - port = myport; - } else { - if (port != 0) - mysslport = port; - sock = hydra_connect_ssl(ip, mysslport); - port = mysslport; - } - if (sock < 0) { - hydra_report(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int) getpid()); - if (freemischttpform) - free(miscptr); - freemischttpform = 0; - hydra_child_exit(1); - } - next_run = 2; - break; - } + { + if (sock >= 0) + sock = hydra_disconnect(sock); + if ((options & OPTION_SSL) == 0) { + if (port != 0) + myport = port; + sock = hydra_connect_tcp(ip, myport); + port = myport; + } else { + if (port != 0) + mysslport = port; + sock = hydra_connect_ssl(ip, mysslport); + port = mysslport; + } + if (sock < 0) { + hydra_report(stderr, "[ERROR] Child with pid %d terminating, cannot connect\n", (int) getpid()); + if (freemischttpform) + free(miscptr); + freemischttpform = 0; + hydra_child_exit(1); + } + next_run = 2; + break; + } case 2: /* run the cracking function */ next_run = start_http_form(sock, ip, port, options, miscptr, fp, type); break; @@ -943,12 +736,10 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F } void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { - //// service_http_form(ip, sp, options, miscptr, fp, port, "GET"); } void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { - //// service_http_form(ip, sp, options, miscptr, fp, port, "POST"); } @@ -963,5 +754,215 @@ int service_http_form_init(char *ip, int sp, unsigned char options, char *miscpt // 0 all OK // -1 error, hydra will exit, so print a good error message here + char *ptr, *ptr2; + char *proxy_string; + + if (webtarget != NULL && (webtarget = strstr(miscptr, "://")) != NULL) { + webtarget += strlen("://"); + if ((ptr2 = index(webtarget, ':')) != NULL) { /* step over port if present */ + *ptr2 = 0; + ptr2++; + ptr = ptr2; + if (*ptr == '/' || (ptr = index(ptr2, '/')) != NULL) + miscptr = ptr; + else + miscptr = slash; /* to make things easier to user */ + } else if ((ptr2 = index(webtarget, '/')) != NULL) { + if (freemischttpform == 0) { + freemischttpform = 1; + miscptr = malloc(strlen(ptr2) + 1); + strcpy(miscptr, ptr2); + *ptr2 = 0; + } + } else + webtarget = NULL; + } + if (cmdlinetarget != NULL && webtarget == NULL) + webtarget = cmdlinetarget; + else if (webtarget == NULL && cmdlinetarget == NULL) + webtarget = hydra_address2string(ip); + if (port != 0) + webport = port; + else if ((options & OPTION_SSL) == 0) + webport = PORT_HTTP; + else + webport = PORT_HTTP_SSL; + + sprintf(bufferurl, "%.1000s", miscptr); + url = bufferurl; + ptr = url; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + variables = ptr; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + cond = ptr; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + optional1 = ptr; + if (strstr(url, "\\:") != NULL) { + if ((ptr = malloc(strlen(url))) != NULL) { + strcpy(ptr, hydra_strrep(url, "\\:", ":")); + url = ptr; + } + } + if (strstr(variables, "\\:") != NULL) { + if ((ptr = malloc(strlen(variables))) != NULL) { + strcpy(ptr, hydra_strrep(variables, "\\:", ":")); + variables = ptr; + } + } + if (strstr(cond, "\\:") != NULL) { + if ((ptr = malloc(strlen(cond))) != NULL) { + strcpy(ptr, hydra_strrep(cond, "\\:", ":")); + cond = ptr; + } + } + if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */ ) + hydra_child_exit(2); + + //printf("url: %s, var: %s, cond: %s, opt: %s\n", url, variables, cond, optional1); + + if (*cond == 0) { + fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); + return -1; + } + + sprintf(cookieurl, "%.1000s", url); + + //conditions now have to contain F or S to set the fail or success condition + if (*cond != 0 && (strpos(cond, "F=") == 0)) { + success_cond = 0; + cond += 2; + } else if (*cond != 0 && (strpos(cond, "S=") == 0)) { + success_cond = 1; + cond += 2; + } else { + //by default condition is a fail + success_cond = 0; + } + + char *header = NULL, *value = NULL; + while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { + switch (optional1[0]) { + case 'c': // fall through + case 'C': + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + sprintf(cookieurl, "%.1000s", hydra_strrep(optional1 + 2, "\\:", ":")); + optional1 = ptr; + break; + case 'h': + // add a new header at the end + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ + if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + return -1; + case 'H': + // add a new header, or replace an existing one's value + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ + if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + return -1; + // no default + } + } + + /* again: no snprintf to be portable. dont worry, buffer cant overflow */ + if (use_proxy == 1 && proxy_authentication != NULL) { + // proxy with authentication + add_header("Host", webtarget, HEADER_TYPE_DEFAULT); + add_header("User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); + proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); + if(proxy_string) { + strcpy(proxy_string, "Basic "); + strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); + add_header("Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); + }else{ + hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); + return -1; + } + if (getcookie) { + //doing a GET to save cookies + cookie_request = stringify_headers(); + hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", cookie_request); + } + normal_request = stringify_headers(); + hydra_report(stdout, "HTTP headers (Proxy Auth): %s", normal_request); + } else { + if (use_proxy == 1) { + // proxy without authentication + add_header("Host", webtarget, HEADER_TYPE_DEFAULT); + add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); + if (getcookie) { + //doing a GET to get cookies + cookie_request = stringify_headers(); + hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", cookie_request); + } + normal_request = stringify_headers(); + hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", normal_request); + } else { + // direct web server, no proxy + add_header("Host", webtarget, HEADER_TYPE_DEFAULT); + add_header("User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); + + if (getcookie) { + //doing a GET to save cookies + cookie_request = stringify_headers(); +// hydra_report(stdout, "HTTP headers (Direct Cookies): %s", cookie_request); + } + + normal_request = stringify_headers(); +// hydra_report(stdout, "HTTP Headers (Direct): %s", normal_request); + } + } + return 0; } From 4c0d05bba63154388a3dddcaba25a41ab3342edd Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Wed, 30 Jul 2014 18:24:39 +0200 Subject: [PATCH 11/20] Checkpoint plain HTTP. --- hydra-http-form.c | 49 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 1120243..00384ac 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -83,12 +83,6 @@ int success_cond = 0; int getcookie = 1; int auth_flag = 0; -char redirected_url_buff[2048] = ""; -int redirected_flag = 0; - -#define MAX_REDIRECT 8 -#define MAX_CONTENT_LENGTH 20 -int redirected_cpt = MAX_REDIRECT; char cookie[4096] = "", cmiscptr[1024]; extern char *webtarget; @@ -96,6 +90,14 @@ extern char *slash; int webport, freemischttpform = 0; char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1; +#define MAX_REDIRECT 8 +#define MAX_CONTENT_LENGTH 20 +#define MAX_PROXY_LENGTH 2048 // sizeof(cookieurl) * 2 + +char redirected_url_buff[2048] = ""; +int redirected_flag = 0; +int redirected_cpt = MAX_REDIRECT; + char *cookie_request, *normal_request; // Buffers for HTTP headers ptr_header_node ptr_head = NULL; @@ -446,10 +448,10 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc char *empty = ""; char * buffer; char *login, *pass, clogin[256], cpass[256]; - char header[8096], *upd3variables, cuserheader[1024]; + char header[8096], *upd3variables; char *http_request; int found = !success_cond, i, j; - char content_length[MAX_CONTENT_LENGTH]; + char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; memset(header, 0, sizeof(header)); cookie[0] = 0; // reset cookies from potential previous attempt @@ -483,11 +485,34 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc // proxy without authentication if (getcookie) { //doing a GET to get cookies - //buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", buffer); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); + http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); // ignore result + if (strlen(cookie) > 0) + add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); + hydra_reconnect(s, ip, port, options); + } + + // now prepare for the "real" request + if (strcmp(type, "POST") == 0) { + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); + add_header("Content-Length", content_length, HEADER_TYPE_DEFAULT); + add_header("Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(); + http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } else { + normal_request = stringify_headers(); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; } - //buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", buffer); } else { // direct web server, no proxy if (getcookie) { From 4f0dc05ce901a5f12073250e3581df690d0112c4 Mon Sep 17 00:00:00 2001 From: ajuaristi Date: Mon, 11 Aug 2014 15:15:14 +0200 Subject: [PATCH 12/20] Feature to specify HTTP headers manually or replace the default ones. --- hydra-http-form.c | 566 ++++++++++++++++++++++++++-------------------- 1 file changed, 316 insertions(+), 250 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 00384ac..d142f53 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -100,16 +100,19 @@ int redirected_cpt = MAX_REDIRECT; char *cookie_request, *normal_request; // Buffers for HTTP headers -ptr_header_node ptr_head = NULL; +//ptr_header_node ptr_head = NULL; + +ptr_header_node initialize(char * ip, unsigned char options, char * miscptr); /* * Returns 1 if specified header exists, or 0 otherwise. */ -ptr_header_node header_exists(char * header_name, char type){ - ptr_header_node cur_ptr = NULL, +ptr_header_node header_exists(ptr_header_node * ptr_head, char * header_name, char type){ + ptr_header_node cur_ptr = *ptr_head, found_header = NULL; - for(cur_ptr = ptr_head; cur_ptr && !found_header; cur_ptr = cur_ptr->next) +// hydra_report(stdout, "header_exists(): ptr_head = %s; cur_ptr = %s\n", ptr_head, cur_ptr); + for(cur_ptr = *ptr_head; cur_ptr && !found_header; cur_ptr = cur_ptr->next) if(cur_ptr->header && strcmp(cur_ptr->header, header_name) == 0 && cur_ptr->type == type) found_header = cur_ptr; @@ -126,20 +129,22 @@ ptr_header_node header_exists(char * header_name, char type){ * * Returns 1 if success, or 0 otherwise (out of memory). */ -int add_header(char *header, char *value, char type){ +int add_header(ptr_header_node * ptr_head, char *header, char *value, char type){ ptr_header_node cur_ptr = NULL; ptr_header_node existing_hdr, new_ptr; // get to the last header - for(cur_ptr = ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); + for(cur_ptr = *ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); + +// hydra_report(stdout, "cur_ptr = %s; ptr_head = %s", cur_ptr, *ptr_head); char * new_header = strdup(header); char * new_value = strdup(value); if(new_header && new_value){ if((type == HEADER_TYPE_USERHEADER) || - (type == HEADER_TYPE_DEFAULT && !header_exists(new_header, HEADER_TYPE_USERHEADER_REPL)) || - (type == HEADER_TYPE_USERHEADER_REPL && !header_exists(new_header, HEADER_TYPE_DEFAULT))){ + (type == HEADER_TYPE_DEFAULT && !header_exists(ptr_head, new_header, HEADER_TYPE_USERHEADER_REPL)) || + (type == HEADER_TYPE_USERHEADER_REPL && !header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))){ /* * We are in one of the following scenarios: * 1. A default header with no user-supplied headers that replace it. @@ -149,6 +154,7 @@ int add_header(char *header, char *value, char type){ * * In either case we just add the header to the list. */ +// hydra_report(stdout, "1"); new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); if(!new_ptr) return 0; @@ -157,12 +163,15 @@ int add_header(char *header, char *value, char type){ new_ptr->type = type; new_ptr->next = NULL; - if(cur_ptr) + if(cur_ptr){ cur_ptr->next = new_ptr; - else +// hydra_report(stdout, "cur_ptr appended\n"); + }else{ // head is NULL, so the list is empty - ptr_head = new_ptr; - }else if(type == HEADER_TYPE_USERHEADER_REPL && (existing_hdr = header_exists(new_header, HEADER_TYPE_DEFAULT))){ + *ptr_head = new_ptr; +// hydra_report(stdout, "ptr_head allocated\n"); + } + }else if(type == HEADER_TYPE_USERHEADER_REPL && (existing_hdr = header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))){ // It's a user-supplied header that must replace a default one // Replace the default header's value with this new value free(existing_hdr->value); @@ -175,6 +184,10 @@ int add_header(char *header, char *value, char type){ return 0; } +// if(ptr_head) +// hydra_report(stdout, "add_header(): ptr_head = %s:%s\n", (*ptr_head)->header, (*ptr_head)->value); +// if(cur_ptr) +// hydra_report(stdout, "add_header(): cur_ptr = %s:%s\n", cur_ptr->header, cur_ptr->value); return 1; } @@ -182,10 +195,10 @@ int add_header(char *header, char *value, char type){ * Replace in all headers' values every occurrence of oldvalue by newvalue. * Only user-defined headers are considered. */ -void hdrrep(char * oldvalue, char * newvalue){ +void hdrrep(ptr_header_node * ptr_head, char * oldvalue, char * newvalue){ ptr_header_node cur_ptr = NULL; - for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ if((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)){ cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(newvalue)); if(cur_ptr->value) @@ -198,11 +211,11 @@ void hdrrep(char * oldvalue, char * newvalue){ } } -void hdrrepv(char * hdrname, char * new_value){ +void hdrrepv(ptr_header_node * ptr_head, char * hdrname, char * new_value){ ptr_header_node cur_ptr = NULL; - for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ - if((cur_ptr->type == HEADER_TYPE_DEFAULT) && strcmp(cur_ptr->header, hdrname)){ + for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if((cur_ptr->type == HEADER_TYPE_DEFAULT) && strcmp(cur_ptr->header, hdrname) == 0){ cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(new_value)); if(cur_ptr->value) strcpy(cur_ptr->value, new_value); @@ -214,42 +227,45 @@ void hdrrepv(char * hdrname, char * new_value){ } } -void cleanup(){ - ptr_header_node cur_ptr = ptr_head, next_ptr = cur_ptr; +void cleanup(ptr_header_node * ptr_head){ + ptr_header_node cur_ptr = *ptr_head, next_ptr = cur_ptr; while(next_ptr){ - free(cur_ptr->header); - free(cur_ptr->value); + free(next_ptr->header); + free(next_ptr->value); next_ptr = cur_ptr->next; - //free(cur_ptr); + free(cur_ptr); } - ptr_head = NULL; + *ptr_head = NULL; } /* * Concat all the headers in the list in a single string. * Leave the list itself intact: do not clean it here. */ -char * stringify_headers(){ +char * stringify_headers(ptr_header_node * ptr_head){ char * headers_str = NULL; - ptr_header_node cur_ptr = ptr_head; + ptr_header_node cur_ptr = *ptr_head; int ttl_size = 0; +// hydra_report(stdout, "cur_ptr = %s", cur_ptr); for(; cur_ptr; cur_ptr = cur_ptr->next) ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 3; - headers_str = (char *) malloc(ttl_size + 1); +// hydra_report(stdout, "ttl_size = %d", ttl_size); + headers_str = (char *) malloc(ttl_size + 1); - if(headers_str){ - memset(headers_str, 0, ttl_size + 1); - for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ - strcat(headers_str, cur_ptr->header); - strcat(headers_str, ":"); - strcat(headers_str, cur_ptr->value); - strcat(headers_str, "\r\n"); - } - } + if(headers_str){ + memset(headers_str, 0, ttl_size + 1); + for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ +// hydra_report(stdout, "Header: \"%s: %s\"", cur_ptr->header, cur_ptr->value); + strcat(headers_str, cur_ptr->header); + strcat(headers_str, ":"); + strcat(headers_str, cur_ptr->value); + strcat(headers_str, "\r\n"); + } + } return headers_str; } @@ -444,12 +460,12 @@ void hydra_reconnect(int s, char *ip, int port, unsigned char options) { } } -int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type) { +int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type, ptr_header_node ptr_head) { char *empty = ""; char * buffer; char *login, *pass, clogin[256], cpass[256]; char header[8096], *upd3variables; - char *http_request; + char *http_request; // buffer for the HTTP request int found = !success_cond, i, j; char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; @@ -469,17 +485,44 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); // Replace the user/pass placeholders in the user-supplied headers - hdrrep("^USER^", clogin); - hdrrep("^PASS^", cpass); + hdrrep(&ptr_head, "^USER^", clogin); + hdrrep(&ptr_head, "^PASS^", cpass); /* again: no snprintf to be portable. dont worry, buffer cant overflow */ if (use_proxy == 1 && proxy_authentication != NULL) { if (getcookie) { //buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", buffer); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); + http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); + if(hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); + if(strlen(cookie) > 0) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + hydra_reconnect(s, ip, port, options); + } + // now prepare for the "real" request + if (strcmp(type, "POST") == 0) { + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); + if(header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if(!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } else { + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; } - //buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Proxy Auth): %s", buffer); } else { if (use_proxy == 1) { // proxy without authentication @@ -492,7 +535,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc return 1; i = analyze_server_response(s); // ignore result if (strlen(cookie) > 0) - add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); hydra_reconnect(s, ip, port, options); } @@ -501,14 +544,18 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc memset(proxy_string, 0, sizeof(proxy_string)); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); - add_header("Content-Length", content_length, HEADER_TYPE_DEFAULT); - add_header("Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); - normal_request = stringify_headers(); + if(header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if(!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; } else { - normal_request = stringify_headers(); + normal_request = stringify_headers(&ptr_head); http_request = prepare_http_request("GET", url, upd3variables, normal_request); if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; @@ -521,9 +568,9 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0){ - add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); - normal_request = stringify_headers(); + if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)){ + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); } hydra_reconnect(s, ip, port, options); } @@ -531,14 +578,18 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc // now prepare for the "real" request if (strcmp(type, "POST") == 0) { snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); - add_header("Content-Length", content_length, HEADER_TYPE_DEFAULT); - add_header("Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); - normal_request = stringify_headers(); + if(header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if(!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); http_request = prepare_http_request("POST", url, upd3variables, normal_request); if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; } else { - normal_request = stringify_headers(); + normal_request = stringify_headers(&ptr_head); http_request = prepare_http_request("GET", url, upd3variables, normal_request); if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; @@ -554,14 +605,16 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc return 4; } - if (strlen(cookie) > 0) - add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); + if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); //if page was redirected, follow the location header redirected_cpt = MAX_REDIRECT; if (debug) printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); + free(http_request); + while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { //we have to split the location char *startloc, *endloc; @@ -603,8 +656,8 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc if (strlen(str) - strlen(str2) == 0) { strcpy(str3, "/"); } else { - strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) - 1); - str3[strlen(str) - strlen(str2) - 1] = 0; + strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2)); + str3[strlen(str) - strlen(str2)] = 0; } } else { strncpy(str2, webtarget, sizeof(str2)); @@ -642,18 +695,21 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc //re-use the code above to check for proxy use if (use_proxy == 1 && proxy_authentication != NULL) { // proxy with authentication - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", - webtarget, webport, str3, str2, proxy_authentication, header); + hdrrepv(&ptr_head, "Host", str2); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); } else { if (use_proxy == 1) { // proxy without authentication - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", webtarget, webport, str3, str2, header); + hdrrepv(&ptr_head, "Host", str2); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); } else { //direct web server, no proxy - //sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); - hdrrepv("Host", str2); - normal_request = stringify_headers(); - http_request = prepare_http_request("GET", str3, NULL, normal_request); + hdrrepv(&ptr_head, "Host", str2); + http_request = prepare_http_request("GET", str3, NULL, cookie_request); } } @@ -663,8 +719,10 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc return 1; found = analyze_server_response(s); - if (strlen(cookie) > 0) - add_header("Cookie", cookie, HEADER_TYPE_DEFAULT); + if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + + free(http_request); } } @@ -679,7 +737,7 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc return 1; } -void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port, char *type) { +void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port, char *type, ptr_header_node * ptr_head) { int run = 1, next_run = 1, sock = -1; int myport = PORT_HTTP, mysslport = PORT_HTTP_SSL; @@ -729,7 +787,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F break; } case 2: /* run the cracking function */ - next_run = start_http_form(sock, ip, port, options, miscptr, fp, type); + next_run = start_http_form(sock, ip, port, options, miscptr, fp, type, ptr_head); break; case 3: /* clean exit */ if (sock >= 0) @@ -761,11 +819,15 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F } void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { - service_http_form(ip, sp, options, miscptr, fp, port, "GET"); + ptr_header_node ptr_head = initialize(ip, options, miscptr); + service_http_form(ip, sp, options, miscptr, fp, port, "GET", ptr_head); + cleanup(&ptr_head); } void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { - service_http_form(ip, sp, options, miscptr, fp, port, "POST"); + ptr_header_node ptr_head = initialize(ip, options, miscptr); + service_http_form(ip, sp, options, miscptr, fp, port, "POST", ptr_head); + cleanup(&ptr_head); } int service_http_form_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { @@ -779,141 +841,121 @@ int service_http_form_init(char *ip, int sp, unsigned char options, char *miscpt // 0 all OK // -1 error, hydra will exit, so print a good error message here + return 0; +} + +ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { + ptr_header_node ptr_head = NULL; char *ptr, *ptr2; char *proxy_string; if (webtarget != NULL && (webtarget = strstr(miscptr, "://")) != NULL) { - webtarget += strlen("://"); - if ((ptr2 = index(webtarget, ':')) != NULL) { /* step over port if present */ - *ptr2 = 0; - ptr2++; - ptr = ptr2; - if (*ptr == '/' || (ptr = index(ptr2, '/')) != NULL) - miscptr = ptr; - else - miscptr = slash; /* to make things easier to user */ - } else if ((ptr2 = index(webtarget, '/')) != NULL) { - if (freemischttpform == 0) { - freemischttpform = 1; - miscptr = malloc(strlen(ptr2) + 1); - strcpy(miscptr, ptr2); - *ptr2 = 0; - } - } else - webtarget = NULL; - } - if (cmdlinetarget != NULL && webtarget == NULL) - webtarget = cmdlinetarget; - else if (webtarget == NULL && cmdlinetarget == NULL) - webtarget = hydra_address2string(ip); - if (port != 0) - webport = port; - else if ((options & OPTION_SSL) == 0) - webport = PORT_HTTP; - else - webport = PORT_HTTP_SSL; + webtarget += strlen("://"); + if ((ptr2 = index(webtarget, ':')) != NULL) { /* step over port if present */ + *ptr2 = 0; + ptr2++; + ptr = ptr2; + if (*ptr == '/' || (ptr = index(ptr2, '/')) != NULL) + miscptr = ptr; + else + miscptr = slash; /* to make things easier to user */ + } else if ((ptr2 = index(webtarget, '/')) != NULL) { + if (freemischttpform == 0) { + freemischttpform = 1; + miscptr = malloc(strlen(ptr2) + 1); + strcpy(miscptr, ptr2); + *ptr2 = 0; + } + } else + webtarget = NULL; + } + if (cmdlinetarget != NULL && webtarget == NULL) + webtarget = cmdlinetarget; + else if (webtarget == NULL && cmdlinetarget == NULL) + webtarget = hydra_address2string(ip); + if (port != 0) + webport = port; + else if ((options & OPTION_SSL) == 0) + webport = PORT_HTTP; + else + webport = PORT_HTTP_SSL; - sprintf(bufferurl, "%.1000s", miscptr); - url = bufferurl; - ptr = url; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - variables = ptr; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - cond = ptr; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - optional1 = ptr; - if (strstr(url, "\\:") != NULL) { - if ((ptr = malloc(strlen(url))) != NULL) { - strcpy(ptr, hydra_strrep(url, "\\:", ":")); - url = ptr; - } - } - if (strstr(variables, "\\:") != NULL) { - if ((ptr = malloc(strlen(variables))) != NULL) { - strcpy(ptr, hydra_strrep(variables, "\\:", ":")); - variables = ptr; - } - } - if (strstr(cond, "\\:") != NULL) { - if ((ptr = malloc(strlen(cond))) != NULL) { - strcpy(ptr, hydra_strrep(cond, "\\:", ":")); - cond = ptr; - } - } - if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */ ) - hydra_child_exit(2); + sprintf(bufferurl, "%.1000s", miscptr); + url = bufferurl; + ptr = url; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + variables = ptr; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + cond = ptr; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + optional1 = ptr; + if (strstr(url, "\\:") != NULL) { + if ((ptr = malloc(strlen(url))) != NULL) { + strcpy(ptr, hydra_strrep(url, "\\:", ":")); + url = ptr; + } + } + if (strstr(variables, "\\:") != NULL) { + if ((ptr = malloc(strlen(variables))) != NULL) { + strcpy(ptr, hydra_strrep(variables, "\\:", ":")); + variables = ptr; + } + } + if (strstr(cond, "\\:") != NULL) { + if ((ptr = malloc(strlen(cond))) != NULL) { + strcpy(ptr, hydra_strrep(cond, "\\:", ":")); + cond = ptr; + } + } + if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */ ) + hydra_child_exit(2); //printf("url: %s, var: %s, cond: %s, opt: %s\n", url, variables, cond, optional1); - if (*cond == 0) { - fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); - return -1; - } + if (*cond == 0) { + fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); + return -1; + } - sprintf(cookieurl, "%.1000s", url); + sprintf(cookieurl, "%.1000s", url); - //conditions now have to contain F or S to set the fail or success condition - if (*cond != 0 && (strpos(cond, "F=") == 0)) { - success_cond = 0; - cond += 2; - } else if (*cond != 0 && (strpos(cond, "S=") == 0)) { - success_cond = 1; - cond += 2; - } else { - //by default condition is a fail - success_cond = 0; - } + //conditions now have to contain F or S to set the fail or success condition + if (*cond != 0 && (strpos(cond, "F=") == 0)) { + success_cond = 0; + cond += 2; + } else if (*cond != 0 && (strpos(cond, "S=") == 0)) { + success_cond = 1; + cond += 2; + } else { + //by default condition is a fail + success_cond = 0; + } - char *header = NULL, *value = NULL; - while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { - switch (optional1[0]) { - case 'c': // fall through - case 'C': - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - sprintf(cookieurl, "%.1000s", hydra_strrep(optional1 + 2, "\\:", ":")); - optional1 = ptr; - break; - case 'h': - // add a new header at the end - ptr = optional1 + 2; - while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - ptr2 = ptr; - while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) - ptr2++; - if (*ptr2 != 0) - *ptr2++ = 0; - /* - * At this point: - * - (optional1 + 2) contains the header's name - * - ptr contains the header's value - */ - if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)){ - // Success: break the switch and go ahead - optional1 = ptr2; - break; - } - // Error: abort execution - hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - return -1; - case 'H': - // add a new header, or replace an existing one's value - ptr = optional1 + 2; + char *header = NULL, *value = NULL; + while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { + switch (optional1[0]) { + case 'c': // fall through + case 'C': + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + sprintf(cookieurl, "%.1000s", hydra_strrep(optional1 + 2, "\\:", ":")); + optional1 = ptr; + break; + case 'h': + // add a new header at the end + ptr = optional1 + 2; while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) ptr++; if (*ptr != 0) @@ -928,66 +970,90 @@ int service_http_form_init(char *ip, int sp, unsigned char options, char *miscpt * - (optional1 + 2) contains the header's name * - ptr contains the header's value */ - if(add_header(optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)){ + if(add_header(&ptr_head, optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)){ // Success: break the switch and go ahead optional1 = ptr2; break; } - // Error: abort execution - hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - return -1; - // no default - } - } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + return -1; + case 'H': + // add a new header, or replace an existing one's value + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ + if(add_header(&ptr_head, optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + return -1; + // no default + } + } - /* again: no snprintf to be portable. dont worry, buffer cant overflow */ - if (use_proxy == 1 && proxy_authentication != NULL) { - // proxy with authentication - add_header("Host", webtarget, HEADER_TYPE_DEFAULT); - add_header("User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); - proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); - if(proxy_string) { - strcpy(proxy_string, "Basic "); - strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); - add_header("Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); - }else{ - hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); - return -1; - } - if (getcookie) { - //doing a GET to save cookies - cookie_request = stringify_headers(); - hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", cookie_request); - } - normal_request = stringify_headers(); - hydra_report(stdout, "HTTP headers (Proxy Auth): %s", normal_request); - } else { - if (use_proxy == 1) { - // proxy without authentication - add_header("Host", webtarget, HEADER_TYPE_DEFAULT); - add_header("User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); - if (getcookie) { - //doing a GET to get cookies - cookie_request = stringify_headers(); - hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", cookie_request); - } - normal_request = stringify_headers(); - hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", normal_request); - } else { - // direct web server, no proxy - add_header("Host", webtarget, HEADER_TYPE_DEFAULT); - add_header("User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); + /* again: no snprintf to be portable. dont worry, buffer cant overflow */ + if (use_proxy == 1 && proxy_authentication != NULL) { + // proxy with authentication + add_header(ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(ptr_head, "User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); + proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); + if(proxy_string) { + strcpy(proxy_string, "Basic "); + strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); + add_header(ptr_head, "Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); + }else{ + hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); + return -1; + } + if (getcookie) { + //doing a GET to save cookies + cookie_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", cookie_request); + } + normal_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Auth): %s", normal_request); + } else { + if (use_proxy == 1) { + // proxy without authentication + add_header(ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(ptr_head, "User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); + if (getcookie) { + //doing a GET to get cookies + cookie_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", cookie_request); + } + normal_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", normal_request); + } else { + // direct web server, no proxy + add_header(&ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); - if (getcookie) { - //doing a GET to save cookies - cookie_request = stringify_headers(); -// hydra_report(stdout, "HTTP headers (Direct Cookies): %s", cookie_request); - } + if (getcookie) { + //doing a GET to save cookies + cookie_request = stringify_headers(&ptr_head); +// hydra_report(stdout, "HTTP headers (Direct Cookies): %s", cookie_request); + } - normal_request = stringify_headers(); -// hydra_report(stdout, "HTTP Headers (Direct): %s", normal_request); - } - } - - return 0; + normal_request = stringify_headers(&ptr_head); +// hydra_report(stdout, "HTTP Headers (Direct): %s", normal_request); + } + } + return ptr_head; } From 8a26ec58d41a5308ce56ffbcbe2e13399decb96b Mon Sep 17 00:00:00 2001 From: Ander Juaristi Date: Tue, 12 Aug 2014 16:40:02 +0200 Subject: [PATCH 13/20] Trim no longer needed. --- hydra-mod.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/hydra-mod.c b/hydra-mod.c index c8aa999..a9cefab 100644 --- a/hydra-mod.c +++ b/hydra-mod.c @@ -1285,26 +1285,3 @@ int hydra_memsearch(char *haystack, int hlen, char *needle, int nlen) { return i; return -1; } - -char * hydra_trim(char * str) { - size_t len = strlen(str); - char * str_ptr[] = {str, NULL}; - - // Truncate leading spaces - for(; *str_ptr[0] == ' ' && len > 0; str_ptr[0]++) - len--; - - if(len == 0) - return NULL; - - // Truncate trailing spaces - str_ptr[1] = str + len; - for(; *str_ptr[1] == ' '; str_ptr[1]--) - len--; - *(str_ptr[1] + 1) = 0; - - char * trimmed_str = strndup(str_ptr[0], len); - free(str); - - return trimmed_str; -} From 01eaf27ea0d8727abd29ea7f2695769648a17856 Mon Sep 17 00:00:00 2001 From: Ander Juaristi Date: Tue, 12 Aug 2014 16:40:36 +0200 Subject: [PATCH 14/20] Trim no longer needed. --- hydra-mod.h | 1 - 1 file changed, 1 deletion(-) diff --git a/hydra-mod.h b/hydra-mod.h index 5830607..5330e5c 100644 --- a/hydra-mod.h +++ b/hydra-mod.h @@ -38,7 +38,6 @@ extern char *hydra_strcasestr(const char *haystack, const char *needle); extern void hydra_dump_data(unsigned char *buf, int len, char *text); extern int hydra_memsearch(char *haystack, int hlen, char *needle, int nlen); extern char *hydra_strrep(char *string, char *oldpiece, char *newpiece); -extern char * hydra_trim(char * str); #ifdef HAVE_PCRE int hydra_string_match(char *str, const char *regex); From abac14d5d56f5f0447d9f41b7fad349d2b9dfa6d Mon Sep 17 00:00:00 2001 From: strunk Date: Wed, 3 Sep 2014 16:13:53 +0200 Subject: [PATCH 15/20] Merged changes from upstream. --- hydra-http-form.c | 1026 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1026 insertions(+) create mode 100644 hydra-http-form.c diff --git a/hydra-http-form.c b/hydra-http-form.c new file mode 100644 index 0000000..53e1a94 --- /dev/null +++ b/hydra-http-form.c @@ -0,0 +1,1026 @@ + +/* + +Hydra Form Module +----------------- + +The hydra form can be used to carry out a brute-force attack on simple +web-based login forms that require username and password variables via +either a GET or POST request. + +The module works similarly to the HTTP basic auth module and will honour +proxy mode (with authenticaion) as well as SSL. The module can be invoked +with the service names of "http-get-form", "http-post-form", +"https-get-form" and "https-post-form". + +Here's a couple of examples: - + +./hydra -l "" -P pass.txt 10.221.64.12 http-post-form +"/irmlab2/testsso-auth.do:ID=^USER^&Password=^PASS^:Invalid Password" + +./hydra -S -s 443 -l "" -P pass.txt 10.221.64.2 https-get-form +"/irmlab1/vulnapp.php:username=^USER^&pass=^PASS^:incorrect" + +The option field (following the service field) takes three ":" separated +values and an optional fourth value, the first is the page on the server +to GET or POST to, the second is the POST/GET variables (taken from either +the browser, or a proxy such as PAROS) with the varying usernames and passwords +in the "^USER^" and "^PASS^" placeholders, the third is the string that it +checks for an *invalid* or *valid* login - any exception to this is counted +as a success. +So please: + * invalid condition login should be preceded by "F=" + * valid condition login should be preceded by "S=". +By default, if no header is found the condition is assume to be a fail, +so checking for *invalid* login. +The fourth optional value, can be a 'C' to define a different page to GET +initial cookies from. + +If you specify the verbose flag (-v) it will show you the response from the +HTTP server which is useful for checking the result of a failed login to +find something to pattern match against. + +Module initially written by Phil Robinson, IRM Plc (releases@irmplc.com), +rewritten by David Maciejak + +Fix and issue with strtok use and implement 1 step location follow if HTTP +3xx code is returned (david dot maciejak at gmail dot com) + +Added fail or success condition, getting cookies, and allow 5 redirections by david + +*/ + +#include "hydra-mod.h" + +/* HTTP Request Options */ +#define OPT_PROXY_AUTH 1 +#define OPT_PROXY_NOAUTH 2 +#define OPT_NOPROXY 4 +#define OPT_GETCOOKIES 8 + +/* Default HTTP Headers */ +#define DEFAULT_HOST 1 +#define DEFAULT_USER_AGENT 2 +#define DEFAULT_CONTENT_TYPE 4 + +/* HTTP Header Types */ +#define HEADER_TYPE_USERHEADER 'h' +#define HEADER_TYPE_USERHEADER_REPL 'H' +#define HEADER_TYPE_DEFAULT 'D' + +extern char *HYDRA_EXIT; +char *buf; +char *cond; + +typedef struct header_node { + char *header; + char *value; + char type; + struct header_node *next; +}t_header_node, *ptr_header_node; + +int success_cond = 0; +int getcookie = 1; +int auth_flag = 0; + +char cookie[4096] = "", cmiscptr[1024]; + +extern char *webtarget; +extern char *slash; +int webport, freemischttpform = 0; +char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1; + +#define MAX_REDIRECT 8 +#define MAX_CONTENT_LENGTH 20 +#define MAX_PROXY_LENGTH 2048 // sizeof(cookieurl) * 2 + +char redirected_url_buff[2048] = ""; +int redirected_flag = 0; +int redirected_cpt = MAX_REDIRECT; + +char *cookie_request, *normal_request; // Buffers for HTTP headers + +//ptr_header_node ptr_head = NULL; + +ptr_header_node initialize(char * ip, unsigned char options, char * miscptr); + +/* + * Returns 1 if specified header exists, or 0 otherwise. + */ +ptr_header_node header_exists(ptr_header_node * ptr_head, char * header_name, char type){ + ptr_header_node cur_ptr = *ptr_head, + found_header = NULL; + +// hydra_report(stdout, "header_exists(): ptr_head = %s; cur_ptr = %s\n", ptr_head, cur_ptr); + for(cur_ptr = *ptr_head; cur_ptr && !found_header; cur_ptr = cur_ptr->next) + if(cur_ptr->header && strcmp(cur_ptr->header, header_name) == 0 && cur_ptr->type == type) + found_header = cur_ptr; + + return found_header; +} + +/* + * List layout: + * +----------+ +--------+ +--------+ +--------+ + * | ptr_head | --> | next | --> | next | --> | NULL | + * | | | header | | header | | NULL | + * | | | value | | value | | NULL | + * +----------+ +--------+ +--------+ +--------+ + * + * Returns 1 if success, or 0 otherwise (out of memory). + */ +int add_header(ptr_header_node * ptr_head, char *header, char *value, char type){ + ptr_header_node cur_ptr = NULL; + ptr_header_node existing_hdr, new_ptr; + + // get to the last header + for(cur_ptr = *ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); + +// hydra_report(stdout, "cur_ptr = %s; ptr_head = %s", cur_ptr, *ptr_head); + + char * new_header = strdup(header); + char * new_value = strdup(value); + + if(new_header && new_value){ + if((type == HEADER_TYPE_USERHEADER) || + (type == HEADER_TYPE_DEFAULT && !header_exists(ptr_head, new_header, HEADER_TYPE_USERHEADER_REPL)) || + (type == HEADER_TYPE_USERHEADER_REPL && !header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))){ + /* + * We are in one of the following scenarios: + * 1. A default header with no user-supplied headers that replace it. + * 2. A user-supplied header that must be appended (option 'h'). + * 3. A user-supplied header that must replace a default header (option 'h'), + * but no default headers exist with that name. + * + * In either case we just add the header to the list. + */ +// hydra_report(stdout, "1"); + new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); + if(!new_ptr) + return 0; + new_ptr->header = new_header; + new_ptr->value = new_value; + new_ptr->type = type; + new_ptr->next = NULL; + + if(cur_ptr){ + cur_ptr->next = new_ptr; +// hydra_report(stdout, "cur_ptr appended\n"); + }else{ + // head is NULL, so the list is empty + *ptr_head = new_ptr; +// hydra_report(stdout, "ptr_head allocated\n"); + } + }else if(type == HEADER_TYPE_USERHEADER_REPL && (existing_hdr = header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))){ + // It's a user-supplied header that must replace a default one + // Replace the default header's value with this new value + free(existing_hdr->value); + existing_hdr->value = new_value; + existing_hdr->type = type; + hydra_report(stdout, "[DEBUG] Replaced header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", existing_hdr->header, existing_hdr->value); + } + }else{ + // we're out of memory, so forcefully end + return 0; + } + +// if(ptr_head) +// hydra_report(stdout, "add_header(): ptr_head = %s:%s\n", (*ptr_head)->header, (*ptr_head)->value); +// if(cur_ptr) +// hydra_report(stdout, "add_header(): cur_ptr = %s:%s\n", cur_ptr->header, cur_ptr->value); + return 1; +} + +/* + * Replace in all headers' values every occurrence of oldvalue by newvalue. + * Only user-defined headers are considered. + */ +void hdrrep(ptr_header_node * ptr_head, char * oldvalue, char * newvalue){ + ptr_header_node cur_ptr = NULL; + + for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if((cur_ptr->type == HEADER_TYPE_USERHEADER || cur_ptr->type == HEADER_TYPE_USERHEADER_REPL) && strstr(cur_ptr->value, oldvalue)){ + cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(newvalue)); + if(cur_ptr->value) + strcpy(cur_ptr->value, newvalue); + else{ + hydra_report(stderr, "[ERROR] Out of memory."); + hydra_child_exit(1); + } + } + } +} + +void hdrrepv(ptr_header_node * ptr_head, char * hdrname, char * new_value){ + ptr_header_node cur_ptr = NULL; + + for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ + if((cur_ptr->type == HEADER_TYPE_DEFAULT) && strcmp(cur_ptr->header, hdrname) == 0){ + cur_ptr->value = (char *) realloc(cur_ptr->value, strlen(new_value)); + if(cur_ptr->value) + strcpy(cur_ptr->value, new_value); + else{ + hydra_report(stderr, "[ERROR] Out of memory"); + hydra_child_exit(1); + } + } + } +} + +void cleanup(ptr_header_node * ptr_head){ + ptr_header_node cur_ptr = *ptr_head, next_ptr = cur_ptr; + + while(next_ptr){ + free(cur_ptr->header); + free(cur_ptr->value); + next_ptr = cur_ptr->next; + //free(cur_ptr); + } + + *ptr_head = NULL; +} + +/* + * Concat all the headers in the list in a single string. + * Leave the list itself intact: do not clean it here. + */ +char * stringify_headers(ptr_header_node * ptr_head){ + char * headers_str = NULL; + ptr_header_node cur_ptr = *ptr_head; + int ttl_size = 0; + +// hydra_report(stdout, "cur_ptr = %s", cur_ptr); + for(; cur_ptr; cur_ptr = cur_ptr->next) + ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 3; + +// hydra_report(stdout, "ttl_size = %d", ttl_size); + headers_str = (char *) malloc(ttl_size + 1); + + if(headers_str){ + memset(headers_str, 0, ttl_size + 1); + for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ +// hydra_report(stdout, "Header: \"%s: %s\"", cur_ptr->header, cur_ptr->value); + strcat(headers_str, cur_ptr->header); + strcat(headers_str, ":"); + strcat(headers_str, cur_ptr->value); + strcat(headers_str, "\r\n"); + } + } + + return headers_str; +} + +char * prepare_http_request(char * type, char * path, char * params, char * headers){ + unsigned int reqlen = 0; + char * http_request = NULL; + + if(type && path && headers){ + reqlen = strlen(path) + strlen(headers) + 20; + if(params) + reqlen += strlen(params); + + http_request = (char *) malloc(reqlen); + if(http_request){ + memset(http_request, 0, reqlen); + + // append the request verb (GET or POST) + if(strcmp(type, "GET") == 0) + strcat(http_request, "GET "); + else + strcat(http_request, "POST "); + + // append the request path + strcat(http_request, path); + + // if GET, append the params now + if(params && strcmp(type, "GET") == 0){ + strcat(http_request, "?"); + strcat(http_request, params); + } + + // append the headers + strcat(http_request, " HTTP/1.0\r\n"); + strcat(http_request, headers); + strcat(http_request, "\r\n"); + + // if POST, append the params now + if(params && strcmp(type, "POST") == 0) + strcat(http_request, params); + } + } + + return http_request; +} + +int strpos(char *str, char *target) { + char *res = strstr(str, target); + + if (res == NULL) + return -1; + else + return res - str; +} + +char *html_encode(char *string) { + char *ret = string; + + if (ret == NULL) + return NULL; + + if (index(ret, '%') != NULL) + ret = hydra_strrep(ret, "%", "%25"); + if (index(ret, ' ') != NULL) + ret = hydra_strrep(ret, " ", "%20"); + if (index(ret, '&') != NULL) + ret = hydra_strrep(ret, "&", "%26"); + if (index(ret, '#') != NULL) + ret = hydra_strrep(ret, "&", "%23"); + + return ret; +} + + +/* +int analyze_server_response(int socket) +return 0 or 1 when the cond regex is matched +return -1 if no response from server +*/ +int analyze_server_response(int s) { + int runs = 0; + + while ((buf = hydra_receive_line(s)) != NULL) { + runs++; + //check for http redirection + if (strstr(buf, "HTTP/1.1 3") != NULL || strstr(buf, "HTTP/1.0 3") != NULL || strstr(buf, "Status: 3") != NULL) { + redirected_flag = 1; + } else if (strstr(buf, "HTTP/1.1 401") != NULL || strstr(buf, "HTTP/1.0 401") != NULL) { + auth_flag = 1; + } else if ((strstr(buf, "HTTP/1.1 403") != NULL) || (strstr(buf, "HTTP/1.1 404") != NULL) || (strstr(buf, "HTTP/1.0 403") != NULL) || (strstr(buf, "HTTP/1.0 404") != NULL)) { + return 0; + } + + if (hydra_strcasestr(buf, "Location: ") != NULL) { + char *startloc, *endloc; + char str[2048]; + + startloc = hydra_strcasestr(buf, "Location: ") + strlen("Location: "); + strncpy(str, startloc, sizeof(str) - 1); + str[sizeof(str) - 1] = 0; + endloc = strchr(str, '\n'); + if (endloc != NULL) + *endloc = 0; + endloc = strchr(str, '\r'); + if (endloc != NULL) + *endloc = 0; + strcpy(redirected_url_buff, str); + } + //there can be multiple cookies + if (hydra_strcasestr(buf, "Set-Cookie: ") != NULL) { + char *cookiebuf = buf; + + do { + char *startcookie, *endcookie1, *endcookie2; + char str[1024], tmpcookie[4096] = "", tmpname[128] = "", *ptr, *ptr2; + + memset(str, 0, sizeof(str)); + startcookie = hydra_strcasestr(cookiebuf, "Set-Cookie: ") + strlen("Set-Cookie: "); + strncpy(str, startcookie, sizeof(str) - 1); + str[sizeof(str) - 1] = 0; + endcookie1 = strchr(str, '\n'); + endcookie2 = strchr(str, ';'); + //terminate string after cookie data + if (endcookie1 != NULL && ((endcookie1 < endcookie2) || (endcookie2 == NULL))){ + if(*(endcookie1 - 1) == '\r') + endcookie1--; + *endcookie1 = 0; + }else if (endcookie2 != NULL) + *endcookie2 = 0; + // is the cookie already there? if yes, remove it! + if (index(startcookie, '=') != NULL && (ptr = index(startcookie, '=')) - startcookie + 1 <= sizeof(tmpname)) { + strncpy(tmpname, startcookie, sizeof(tmpname) - 2); + tmpname[sizeof(tmpname) - 2] = 0; + ptr = index(tmpname, '='); + *(++ptr) = 0; + // is the cookie already in the cookiejar? (so, does it have to be replaced?) + if ((ptr = hydra_strcasestr(cookie, tmpname)) != NULL) { + // yes it is. + // if the cookie is not in the beginning of the cookiejar, copy the ones before + if (ptr != cookie && *(ptr - 1) == ' ') { + strncpy(tmpcookie, cookie, ptr - cookie - 2); + tmpcookie[ptr - cookie - 2] = 0; + } + ptr += strlen(tmpname); + // if there are any cookies after this one in the cookiejar, copy them over + if ((ptr2 = strstr(ptr, "; ")) != NULL) { + ptr2 += 2; + strncat(tmpcookie, ptr2, sizeof(tmpcookie) - strlen(tmpcookie) - 1); + } + if (debug) + printf("[DEBUG] removing cookie %s in jar\n before: %s\n after: %s\n", tmpname, cookie, tmpcookie); + strcpy(cookie, tmpcookie); + } + } + ptr = index(str, '='); + // only copy the cookie if it has a value (otherwise the server wants to delete the cookie + if (ptr != NULL && *(ptr + 1) != ';' && *(ptr + 1) != 0 && *(ptr + 1) != '\n' && *(ptr + 1) != '\r') { + if (strlen(cookie) > 0) + strncat(cookie, "; ", sizeof(cookie) - strlen(cookie) - 1); + strncat(cookie, str, sizeof(cookie) - strlen(cookie) - 1); + } + cookiebuf = startcookie; + } while (hydra_strcasestr(cookiebuf, "Set-Cookie: ") != NULL); + } +#ifdef HAVE_PCRE + if (hydra_string_match(buf, cond) == 1) { +#else + if (strstr(buf, cond) != NULL) { +#endif + free(buf); +// printf("DEBUG: STRING %s FOUND!!:\n%s\n", cond, buf); + return 1; + } +// else printf("DEBUG: STRING %s NOT FOUND:\n%s\n", cond, buf); + free(buf); + } + if (runs == 0) { + if (debug) + hydra_report(stderr, "DEBUG: no response from server\n"); + return -1; + } + return 0; +} + +void hydra_reconnect(int s, char *ip, int port, unsigned char options) { + if (s >= 0) + s = hydra_disconnect(s); + if ((options & OPTION_SSL) == 0) { + s = hydra_connect_tcp(ip, port); + } else { + s = hydra_connect_ssl(ip, port); + } +} + +int start_http_form(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp, char *type, ptr_header_node ptr_head) { + char *empty = ""; + char * buffer; + char *login, *pass, clogin[256], cpass[256]; + char header[8096], *upd3variables; + char *http_request; + int found = !success_cond, i, j; + char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; + + memset(header, 0, sizeof(header)); + cookie[0] = 0; // reset cookies from potential previous attempt + + // Take the next login/pass pair + if (strlen(login = hydra_get_next_login()) == 0) + login = empty; + if (strlen(pass = hydra_get_next_password()) == 0) + pass = empty; + strncpy(clogin, html_encode(login), sizeof(clogin) - 1); + clogin[sizeof(clogin) - 1] = 0; + strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); + cpass[sizeof(cpass) - 1] = 0; + upd3variables = hydra_strrep(variables, "^USER^", clogin); + upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); + + // Replace the user/pass placeholders in the user-supplied headers + hdrrep(&ptr_head, "^USER^", clogin); + hdrrep(&ptr_head, "^PASS^", cpass); + + /* again: no snprintf to be portable. dont worry, buffer cant overflow */ + if (use_proxy == 1 && proxy_authentication != NULL) { + if (getcookie) { + //buffer = prepare_http_request(type, url, NULL); + hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", buffer); + } + //buffer = prepare_http_request(type, url, NULL); + hydra_report(stdout, "HTTP headers (Proxy Auth): %s", buffer); + } else { + if (use_proxy == 1) { + // proxy without authentication + if (getcookie) { + //doing a GET to get cookies + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); + http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); // ignore result + if (strlen(cookie) > 0) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + hydra_reconnect(s, ip, port, options); + } + + // now prepare for the "real" request + if (strcmp(type, "POST") == 0) { + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); + if(header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if(!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } else { + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } + } else { + // direct web server, no proxy + if (getcookie) { + //doing a GET to save cookies + http_request = prepare_http_request("GET", cookieurl, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); // ignore result + if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)){ + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); + } + hydra_reconnect(s, ip, port, options); + } + + // now prepare for the "real" request + if (strcmp(type, "POST") == 0) { + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); + if(header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if(!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("POST", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } else { + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } + } + } + + found = analyze_server_response(s); + + if (auth_flag) { // we received a 401 error - user using wrong module + hydra_report(stderr, "[ERROR] the target is using HTTP auth, not a web form, received HTTP error code 401. Use module \"http%s-get\" instead.\n", + (options & OPTION_SSL) > 0 ? "s" : ""); + return 4; + } + + if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + + //if page was redirected, follow the location header + redirected_cpt = MAX_REDIRECT; + if (debug) + printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); + + while (found == 0 && redirected_flag && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { + //we have to split the location + char *startloc, *endloc; + char str[2048]; + char str2[2048]; + char str3[2048]; + + redirected_cpt--; + redirected_flag = 0; + //check if the redirect page contains the fail/success condition + #ifdef HAVE_PCRE + if (hydra_string_match(redirected_url_buff, cond) == 1) { + #else + if (strstr(redirected_url_buff, cond) != NULL) { + #endif + found = success_cond; + } else { + //location could be either absolute http(s):// or / something + //or relative + startloc = strstr(redirected_url_buff, "://"); + if (startloc != NULL) { + startloc += strlen("://"); + + if ((endloc = strchr(startloc, '\r')) != NULL) { + startloc[endloc - startloc] = 0; + } + if ((endloc = strchr(startloc, '\n')) != NULL) { + startloc[endloc - startloc] = 0; + } + strcpy(str, startloc); + + endloc = strchr(str, '/'); + if (endloc != NULL) { + strncpy(str2, str, endloc - str); + str2[endloc - str] = 0; + } else + strncpy(str2, str, sizeof(str)); + + if (strlen(str) - strlen(str2) == 0) { + strcpy(str3, "/"); + } else { + strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) - 1); + str3[strlen(str) - strlen(str2) - 1] = 0; + } + } else { + strncpy(str2, webtarget, sizeof(str2)); + if (redirected_url_buff[0] != '/') { + //it's a relative path, so we have to concatenate it + //with the path from the first url given + char *urlpath; + char urlpath_extracted[2048]; + + memset(urlpath_extracted, 0, sizeof(urlpath_extracted)); + + urlpath = strrchr(url, '/'); + if (urlpath != NULL) { + strncpy(urlpath_extracted, url, urlpath - url); + sprintf(str3, "%.1000s/%.1000s", urlpath_extracted, redirected_url_buff); + } else { + sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff); + } + } else + strncpy(str3, redirected_url_buff, sizeof(str3)); + if (debug) + hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url); + } + if (str3[0] != '/') { + j = strlen(str3); + str3[j + 1] = 0; + for (i = j; i > 0; i--) + str3[i] = str3[i - 1]; + str3[0] = '/'; + } + + if (verbose) + hydra_report(stderr, "[VERBOSE] Page redirected to http://%s%s\n", str2, str3); + + //re-use the code above to check for proxy use + if (use_proxy == 1 && proxy_authentication != NULL) { + // proxy with authentication + sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", + webtarget, webport, str3, str2, proxy_authentication, header); + } else { + if (use_proxy == 1) { + // proxy without authentication + hdrrepv(&ptr_head, "Host", str2); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); + } else { + //direct web server, no proxy + //sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); + hdrrepv(&ptr_head, "Host", str2); + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("GET", str3, NULL, normal_request); + } + } + + hydra_reconnect(s, ip, port, options); + + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + + found = analyze_server_response(s); + if (strlen(cookie) > 0 && !header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + } + } + + //if the last status is still 3xx, set it as a false + if (found != -1 && found == success_cond && (redirected_flag == 0 || success_cond == 1) && redirected_cpt >= 0) { + hydra_report_found_host(port, ip, "www-form", fp); + hydra_completed_pair_found(); + } else { + hydra_completed_pair(); + } + + return 1; +} + +void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port, char *type, ptr_header_node * ptr_head) { + int run = 1, next_run = 1, sock = -1; + int myport = PORT_HTTP, mysslport = PORT_HTTP_SSL; + + // register our socket descriptor + hydra_register_socket(sp); + + /* + * Iterate through the runs. Values are the following: + * - 1 -> Open connection to remote server. + * - 2 -> Run password attempts. + * - 3 -> Disconnect and end with success. + * - 4 -> Disconnect and end with error. + */ + while (1) { + if (run == 2) { + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { + if (freemischttpform) + free(miscptr); + freemischttpform = 0; + hydra_child_exit(1); + } + } + switch (run) { + case 1: /* connect and service init function */ + { + if (sock >= 0) + sock = hydra_disconnect(sock); + if ((options & OPTION_SSL) == 0) { + if (port != 0) + myport = port; + sock = hydra_connect_tcp(ip, myport); + port = myport; + } else { + if (port != 0) + mysslport = port; + sock = hydra_connect_ssl(ip, mysslport); + port = mysslport; + } + if (sock < 0) { + hydra_report(stderr, "[ERROR] Child with pid %d terminating, cannot connect\n", (int) getpid()); + if (freemischttpform) + free(miscptr); + freemischttpform = 0; + hydra_child_exit(1); + } + next_run = 2; + break; + } + case 2: /* run the cracking function */ + next_run = start_http_form(sock, ip, port, options, miscptr, fp, type, ptr_head); + break; + case 3: /* clean exit */ + if (sock >= 0) + sock = hydra_disconnect(sock); + if (freemischttpform) + free(miscptr); + freemischttpform = 0; + hydra_child_exit(0); + break; + case 4: /* silent error exit */ + if (sock >= 0) + sock = hydra_disconnect(sock); + if (freemischttpform) + free(miscptr); + freemischttpform = 0; + hydra_child_exit(1); + break; + default: + if (freemischttpform) + free(miscptr); + freemischttpform = 0; + hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); + hydra_child_exit(0); + } + run = next_run; + } + if (freemischttpform) + free(miscptr); +} + +void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { + ptr_header_node ptr_head = initialize(ip, options, miscptr); + service_http_form(ip, sp, options, miscptr, fp, port, "GET", ptr_head); +} + +void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { + ptr_header_node ptr_head = initialize(ip, options, miscptr); + service_http_form(ip, sp, options, miscptr, fp, port, "POST", ptr_head); +} + +int service_http_form_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { + // called before the childrens are forked off, so this is the function + // which should be filled if initial connections and service setup has to be + // performed once only. + // + // fill if needed. + // + // return codes: + // 0 all OK + // -1 error, hydra will exit, so print a good error message here + + return 0; +} + +ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { + ptr_header_node ptr_head = NULL; + char *ptr, *ptr2; + char *proxy_string; + + if (webtarget != NULL && (webtarget = strstr(miscptr, "://")) != NULL) { + webtarget += strlen("://"); + if ((ptr2 = index(webtarget, ':')) != NULL) { /* step over port if present */ + *ptr2 = 0; + ptr2++; + ptr = ptr2; + if (*ptr == '/' || (ptr = index(ptr2, '/')) != NULL) + miscptr = ptr; + else + miscptr = slash; /* to make things easier to user */ + } else if ((ptr2 = index(webtarget, '/')) != NULL) { + if (freemischttpform == 0) { + freemischttpform = 1; + miscptr = malloc(strlen(ptr2) + 1); + strcpy(miscptr, ptr2); + *ptr2 = 0; + } + } else + webtarget = NULL; + } + if (cmdlinetarget != NULL && webtarget == NULL) + webtarget = cmdlinetarget; + else if (webtarget == NULL && cmdlinetarget == NULL) + webtarget = hydra_address2string(ip); + if (port != 0) + webport = port; + else if ((options & OPTION_SSL) == 0) + webport = PORT_HTTP; + else + webport = PORT_HTTP_SSL; + + sprintf(bufferurl, "%.1000s", miscptr); + url = bufferurl; + ptr = url; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + variables = ptr; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + cond = ptr; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + optional1 = ptr; + if (strstr(url, "\\:") != NULL) { + if ((ptr = malloc(strlen(url))) != NULL) { + strcpy(ptr, hydra_strrep(url, "\\:", ":")); + url = ptr; + } + } + if (strstr(variables, "\\:") != NULL) { + if ((ptr = malloc(strlen(variables))) != NULL) { + strcpy(ptr, hydra_strrep(variables, "\\:", ":")); + variables = ptr; + } + } + if (strstr(cond, "\\:") != NULL) { + if ((ptr = malloc(strlen(cond))) != NULL) { + strcpy(ptr, hydra_strrep(cond, "\\:", ":")); + cond = ptr; + } + } + if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */ ) + hydra_child_exit(2); + + //printf("url: %s, var: %s, cond: %s, opt: %s\n", url, variables, cond, optional1); + + if (*cond == 0) { + fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); + return -1; + } + + sprintf(cookieurl, "%.1000s", url); + + //conditions now have to contain F or S to set the fail or success condition + if (*cond != 0 && (strpos(cond, "F=") == 0)) { + success_cond = 0; + cond += 2; + } else if (*cond != 0 && (strpos(cond, "S=") == 0)) { + success_cond = 1; + cond += 2; + } else { + //by default condition is a fail + success_cond = 0; + } + + char *header = NULL, *value = NULL; + while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) { + switch (optional1[0]) { + case 'c': // fall through + case 'C': + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + sprintf(cookieurl, "%.1000s", hydra_strrep(optional1 + 2, "\\:", ":")); + optional1 = ptr; + break; + case 'h': + // add a new header at the end + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ + if(add_header(&ptr_head, optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + return -1; + case 'H': + // add a new header, or replace an existing one's value + ptr = optional1 + 2; + while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\')) + ptr++; + if (*ptr != 0) + *ptr++ = 0; + ptr2 = ptr; + while (*ptr2 != 0 && (*ptr2 != ':' || *(ptr2 - 1) == '\\')) + ptr2++; + if (*ptr2 != 0) + *ptr2++ = 0; + /* + * At this point: + * - (optional1 + 2) contains the header's name + * - ptr contains the header's value + */ + if(add_header(&ptr_head, optional1 + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)){ + // Success: break the switch and go ahead + optional1 = ptr2; + break; + } + // Error: abort execution + hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); + return -1; + // no default + } + } + + /* again: no snprintf to be portable. dont worry, buffer cant overflow */ + if (use_proxy == 1 && proxy_authentication != NULL) { + // proxy with authentication + add_header(ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(ptr_head, "User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); + proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); + if(proxy_string) { + strcpy(proxy_string, "Basic "); + strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); + add_header(ptr_head, "Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); + }else{ + hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); + return -1; + } + if (getcookie) { + //doing a GET to save cookies + cookie_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", cookie_request); + } + normal_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Auth): %s", normal_request); + } else { + if (use_proxy == 1) { + // proxy without authentication + add_header(ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(ptr_head, "User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); + if (getcookie) { + //doing a GET to get cookies + cookie_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", cookie_request); + } + normal_request = stringify_headers(ptr_head); + hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", normal_request); + } else { + // direct web server, no proxy + add_header(&ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "User-Agent", "Mozilla/5.0 (Hydra)", HEADER_TYPE_DEFAULT); + + if (getcookie) { + //doing a GET to save cookies + cookie_request = stringify_headers(&ptr_head); +// hydra_report(stdout, "HTTP headers (Direct Cookies): %s", cookie_request); + } + + normal_request = stringify_headers(&ptr_head); +// hydra_report(stdout, "HTTP Headers (Direct): %s", normal_request); + } + } + return ptr_head; +} From f102bae8d8334a7616a653a1926a2d54e30fbd5a Mon Sep 17 00:00:00 2001 From: strunk Date: Wed, 3 Sep 2014 18:50:17 +0200 Subject: [PATCH 16/20] Fixed some gcc warnings. --- hydra-http-form.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 53e1a94..e558083 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -756,7 +756,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F break; } case 2: /* run the cracking function */ - next_run = start_http_form(sock, ip, port, options, miscptr, fp, type, ptr_head); + next_run = start_http_form(sock, ip, port, options, miscptr, fp, type, *ptr_head); break; case 3: /* clean exit */ if (sock >= 0) @@ -789,12 +789,12 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { ptr_header_node ptr_head = initialize(ip, options, miscptr); - service_http_form(ip, sp, options, miscptr, fp, port, "GET", ptr_head); + service_http_form(ip, sp, options, miscptr, fp, port, "GET", &ptr_head); } void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { ptr_header_node ptr_head = initialize(ip, options, miscptr); - service_http_form(ip, sp, options, miscptr, fp, port, "POST", ptr_head); + service_http_form(ip, sp, options, miscptr, fp, port, "POST", &ptr_head); } int service_http_form_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { @@ -977,35 +977,35 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { /* again: no snprintf to be portable. dont worry, buffer cant overflow */ if (use_proxy == 1 && proxy_authentication != NULL) { // proxy with authentication - add_header(ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); - add_header(ptr_head, "User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "User-Agent", "Mozilla 5.0 (Hydra Proxy Auth)", HEADER_TYPE_DEFAULT); proxy_string = (char *) malloc(strlen(proxy_authentication) + 6); if(proxy_string) { strcpy(proxy_string, "Basic "); strncat(proxy_string, proxy_authentication, strlen(proxy_authentication) - 6); - add_header(ptr_head, "Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); }else{ hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); return -1; } if (getcookie) { //doing a GET to save cookies - cookie_request = stringify_headers(ptr_head); + cookie_request = stringify_headers(&ptr_head); hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", cookie_request); } - normal_request = stringify_headers(ptr_head); + normal_request = stringify_headers(&ptr_head); hydra_report(stdout, "HTTP headers (Proxy Auth): %s", normal_request); } else { if (use_proxy == 1) { // proxy without authentication - add_header(ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); - add_header(ptr_head, "User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "User-Agent", "Mozilla/5.0 (Hydra Proxy)", HEADER_TYPE_DEFAULT); if (getcookie) { //doing a GET to get cookies - cookie_request = stringify_headers(ptr_head); + cookie_request = stringify_headers(&ptr_head); hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", cookie_request); } - normal_request = stringify_headers(ptr_head); + normal_request = stringify_headers(&ptr_head); hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", normal_request); } else { // direct web server, no proxy From fd1dd61e837eec45886568058aadcecd4149065b Mon Sep 17 00:00:00 2001 From: strunk Date: Thu, 4 Sep 2014 17:53:36 +0200 Subject: [PATCH 17/20] Fixed all gcc warnings --- hydra-http-form.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index e558083..6c3063a 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -789,12 +789,22 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F void service_http_get_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { ptr_header_node ptr_head = initialize(ip, options, miscptr); - service_http_form(ip, sp, options, miscptr, fp, port, "GET", &ptr_head); + if(ptr_head) + service_http_form(ip, sp, options, miscptr, fp, port, "GET", &ptr_head); + else{ + hydra_report(stderr, "[ERROR] Could not launch head.\n"); + hydra_child_exit(1); + } } void service_http_post_form(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { ptr_header_node ptr_head = initialize(ip, options, miscptr); - service_http_form(ip, sp, options, miscptr, fp, port, "POST", &ptr_head); + if(ptr_head) + service_http_form(ip, sp, options, miscptr, fp, port, "POST", &ptr_head); + else{ + hydra_report(stderr, "[ERROR] Could not launch head.\n"); + hydra_child_exit(1); + } } int service_http_form_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { @@ -890,7 +900,7 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { if (*cond == 0) { fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); - return -1; + return NULL; } sprintf(cookieurl, "%.1000s", url); @@ -944,7 +954,7 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { } // Error: abort execution hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - return -1; + return NULL; case 'H': // add a new header, or replace an existing one's value ptr = optional1 + 2; @@ -969,7 +979,7 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { } // Error: abort execution hydra_report(stderr, "[ERROR] Out of memory for HTTP headers."); - return -1; + return NULL; // no default } } @@ -986,7 +996,7 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { add_header(&ptr_head, "Proxy-Authorization", proxy_string, HEADER_TYPE_DEFAULT); }else{ hydra_report(stderr, "Out of memory for \"Proxy-Authorization\" header."); - return -1; + return NULL; } if (getcookie) { //doing a GET to save cookies From 4292920180e3faa5be29f6fdae0709ac2c11d435 Mon Sep 17 00:00:00 2001 From: strunk Date: Mon, 8 Sep 2014 22:53:11 +0200 Subject: [PATCH 18/20] Removed unnecessary debug messages. --- hydra-http-form.c | 78 +++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 6c3063a..8c6e143 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -111,7 +111,6 @@ ptr_header_node header_exists(ptr_header_node * ptr_head, char * header_name, ch ptr_header_node cur_ptr = *ptr_head, found_header = NULL; -// hydra_report(stdout, "header_exists(): ptr_head = %s; cur_ptr = %s\n", ptr_head, cur_ptr); for(cur_ptr = *ptr_head; cur_ptr && !found_header; cur_ptr = cur_ptr->next) if(cur_ptr->header && strcmp(cur_ptr->header, header_name) == 0 && cur_ptr->type == type) found_header = cur_ptr; @@ -136,8 +135,6 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type) // get to the last header for(cur_ptr = *ptr_head; cur_ptr && cur_ptr->next; cur_ptr = cur_ptr->next); -// hydra_report(stdout, "cur_ptr = %s; ptr_head = %s", cur_ptr, *ptr_head); - char * new_header = strdup(header); char * new_value = strdup(value); @@ -154,7 +151,6 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type) * * In either case we just add the header to the list. */ -// hydra_report(stdout, "1"); new_ptr = (ptr_header_node) malloc(sizeof(t_header_node)); if(!new_ptr) return 0; @@ -163,13 +159,11 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type) new_ptr->type = type; new_ptr->next = NULL; - if(cur_ptr){ + if(cur_ptr) cur_ptr->next = new_ptr; -// hydra_report(stdout, "cur_ptr appended\n"); - }else{ + else{ // head is NULL, so the list is empty *ptr_head = new_ptr; -// hydra_report(stdout, "ptr_head allocated\n"); } }else if(type == HEADER_TYPE_USERHEADER_REPL && (existing_hdr = header_exists(ptr_head, new_header, HEADER_TYPE_DEFAULT))){ // It's a user-supplied header that must replace a default one @@ -177,17 +171,12 @@ int add_header(ptr_header_node * ptr_head, char *header, char *value, char type) free(existing_hdr->value); existing_hdr->value = new_value; existing_hdr->type = type; - hydra_report(stdout, "[DEBUG] Replaced header (HEADER_TYPE_USERHEADER_REPL) %s: %s\n", existing_hdr->header, existing_hdr->value); } }else{ // we're out of memory, so forcefully end return 0; } -// if(ptr_head) -// hydra_report(stdout, "add_header(): ptr_head = %s:%s\n", (*ptr_head)->header, (*ptr_head)->value); -// if(cur_ptr) -// hydra_report(stdout, "add_header(): cur_ptr = %s:%s\n", cur_ptr->header, cur_ptr->value); return 1; } @@ -205,12 +194,15 @@ void hdrrep(ptr_header_node * ptr_head, char * oldvalue, char * newvalue){ strcpy(cur_ptr->value, newvalue); else{ hydra_report(stderr, "[ERROR] Out of memory."); - hydra_child_exit(1); + hydra_child_exit(0); } } } } +/* + * Replace the value of the default header named 'hdrname'. + */ void hdrrepv(ptr_header_node * ptr_head, char * hdrname, char * new_value){ ptr_header_node cur_ptr = NULL; @@ -221,7 +213,7 @@ void hdrrepv(ptr_header_node * ptr_head, char * hdrname, char * new_value){ strcpy(cur_ptr->value, new_value); else{ hydra_report(stderr, "[ERROR] Out of memory"); - hydra_child_exit(1); + hydra_child_exit(0); } } } @@ -249,17 +241,14 @@ char * stringify_headers(ptr_header_node * ptr_head){ ptr_header_node cur_ptr = *ptr_head; int ttl_size = 0; -// hydra_report(stdout, "cur_ptr = %s", cur_ptr); for(; cur_ptr; cur_ptr = cur_ptr->next) ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 3; -// hydra_report(stdout, "ttl_size = %d", ttl_size); headers_str = (char *) malloc(ttl_size + 1); if(headers_str){ memset(headers_str, 0, ttl_size + 1); for(cur_ptr = *ptr_head; cur_ptr; cur_ptr = cur_ptr->next){ -// hydra_report(stdout, "Header: \"%s: %s\"", cur_ptr->header, cur_ptr->value); strcat(headers_str, cur_ptr->header); strcat(headers_str, ":"); strcat(headers_str, cur_ptr->value); @@ -491,11 +480,37 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc /* again: no snprintf to be portable. dont worry, buffer cant overflow */ if (use_proxy == 1 && proxy_authentication != NULL) { if (getcookie) { - //buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", buffer); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); + http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); // ignore result + if (strlen(cookie) > 0) + add_header(&ptr_head, "Cookie", cookie, HEADER_TYPE_DEFAULT); + hydra_reconnect(s, ip, port, options); + } + // now prepare for the "real" request + if (strcmp(type, "POST") == 0) { + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int) strlen(upd3variables)); + if(header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if(!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + } else { + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; } - //buffer = prepare_http_request(type, url, NULL); - hydra_report(stdout, "HTTP headers (Proxy Auth): %s", buffer); } else { if (use_proxy == 1) { // proxy without authentication @@ -666,18 +681,21 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc //re-use the code above to check for proxy use if (use_proxy == 1 && proxy_authentication != NULL) { // proxy with authentication - sprintf(buffer, "GET http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", - webtarget, webport, str3, str2, proxy_authentication, header); + hdrrepv(&ptr_head, "Host", str2); + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + normal_request = stringify_headers(&ptr_head); + http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); } else { if (use_proxy == 1) { // proxy without authentication hdrrepv(&ptr_head, "Host", str2); memset(proxy_string, 0, sizeof(proxy_string)); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); + normal_request = stringify_headers(&ptr_head); http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); } else { //direct web server, no proxy - //sprintf(buffer, "GET %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/4.0 (Hydra)\r\n%s\r\n", str3, str2, header); hdrrepv(&ptr_head, "Host", str2); normal_request = stringify_headers(&ptr_head); http_request = prepare_http_request("GET", str3, NULL, normal_request); @@ -792,7 +810,7 @@ void service_http_get_form(char *ip, int sp, unsigned char options, char *miscpt if(ptr_head) service_http_form(ip, sp, options, miscptr, fp, port, "GET", &ptr_head); else{ - hydra_report(stderr, "[ERROR] Could not launch head.\n"); + hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n"); hydra_child_exit(1); } } @@ -802,7 +820,7 @@ void service_http_post_form(char *ip, int sp, unsigned char options, char *miscp if(ptr_head) service_http_form(ip, sp, options, miscptr, fp, port, "POST", &ptr_head); else{ - hydra_report(stderr, "[ERROR] Could not launch head.\n"); + hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n"); hydra_child_exit(1); } } @@ -1001,10 +1019,8 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { if (getcookie) { //doing a GET to save cookies cookie_request = stringify_headers(&ptr_head); - hydra_report(stdout, "HTTP headers (Proxy Auth Cookies): %s", cookie_request); } normal_request = stringify_headers(&ptr_head); - hydra_report(stdout, "HTTP headers (Proxy Auth): %s", normal_request); } else { if (use_proxy == 1) { // proxy without authentication @@ -1013,10 +1029,8 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { if (getcookie) { //doing a GET to get cookies cookie_request = stringify_headers(&ptr_head); - hydra_report(stdout, "HTTP headers (Proxy Noauth Cookies): %s", cookie_request); } normal_request = stringify_headers(&ptr_head); - hydra_report(stdout, "HTTP headers (Proxy Noauth): %s", normal_request); } else { // direct web server, no proxy add_header(&ptr_head, "Host", webtarget, HEADER_TYPE_DEFAULT); @@ -1025,11 +1039,9 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { if (getcookie) { //doing a GET to save cookies cookie_request = stringify_headers(&ptr_head); -// hydra_report(stdout, "HTTP headers (Direct Cookies): %s", cookie_request); } normal_request = stringify_headers(&ptr_head); -// hydra_report(stdout, "HTTP Headers (Direct): %s", normal_request); } } return ptr_head; From 29522f3ea282180c276232809a7f5ca3c7523a00 Mon Sep 17 00:00:00 2001 From: strunk Date: Tue, 9 Sep 2014 22:44:06 +0200 Subject: [PATCH 19/20] Updated hydra-http-form module description --- hydra.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hydra.c b/hydra.c index e27b760..dcb6f83 100644 --- a/hydra.c +++ b/hydra.c @@ -563,13 +563,21 @@ void module_usage() { " failed string looks like and put it in this parameter!\n" "The following parameters are optional:\n" " C=/page/uri to define a different page to gather initial cookies from\n" - " H=My-Hdr: foo to send a user defined HTTP header with each request\n" + " (h|H)=My-Hdr: foo to send a user defined HTTP header with each request\n" " ^USER^ and ^PASS^ can also be put into these headers!\n" + " Note that 'h' and 'H' are not the same. The former will add the user-defined header at the end" + " regardless it's already being sent by Hydra or not. The latter will replace the value of that header" + " if it exists, by the one supplied by the user, or add the header at the end if it does not exist." + " For example: 'h=User-Agent: Googlebot' would send two 'User-Agent' headers, the one supplied by default" + " ('Mozilla/5.0 (Hydra)'), and the one supplied by the user ('Googlebot'). 'H=User-Agent: Googlebot' would" + " only send a single 'User-Agent' header with the value supplied, effectively replacing the default user agent." + " This is useful to pass hidden CSRF token fields that are tied to a previously issued cookie and are unique" + " for each session. Various C/H/h parameters can be specified separated by colons and optionally intermixed." "Examples:\n" " \"/login.php:user=^USER^&pass=^PASS^:incorrect\"\n" " \"/login.php:user=^USER^&pass=^PASS^&colon=colon\\:escape:S=authlog=.*success\"\n" " \"/login.php:user=^USER^&pass=^PASS^&mid=123:authlog=.*failed\"\n" - " \"/:user=^USER&pass=^PASS^:failed:H=Authorization: Basic dT1w:H=X-User: ^USER^\"\n" + " \"/:user=^USER&pass=^PASS^:failed:H=Authorization: Basic dT1w:H=Cookie: sessid=aaaa:h=X-User: ^USER^\"\n" " \"/exchweb/bin/auth/owaauth.dll:destination=http%%3A%%2F%%2F%%2Fexchange&flags=0&username=%%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:reason=:C=/exchweb\"\n", hydra_options.service); find = 1; From 932e835ac7d2205f3de42cbf9994551fe567cd21 Mon Sep 17 00:00:00 2001 From: strunk Date: Tue, 9 Sep 2014 22:54:43 +0200 Subject: [PATCH 20/20] Cleaned comments. --- hydra-http-form.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/hydra-http-form.c b/hydra-http-form.c index 8c6e143..b818311 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -52,17 +52,6 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da #include "hydra-mod.h" -/* HTTP Request Options */ -#define OPT_PROXY_AUTH 1 -#define OPT_PROXY_NOAUTH 2 -#define OPT_NOPROXY 4 -#define OPT_GETCOOKIES 8 - -/* Default HTTP Headers */ -#define DEFAULT_HOST 1 -#define DEFAULT_USER_AGENT 2 -#define DEFAULT_CONTENT_TYPE 4 - /* HTTP Header Types */ #define HEADER_TYPE_USERHEADER 'h' #define HEADER_TYPE_USERHEADER_REPL 'H' @@ -100,8 +89,9 @@ int redirected_cpt = MAX_REDIRECT; char *cookie_request, *normal_request; // Buffers for HTTP headers -//ptr_header_node ptr_head = NULL; - +/* + * Function to perform some initial setup. + */ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr); /* @@ -226,7 +216,6 @@ void cleanup(ptr_header_node * ptr_head){ free(cur_ptr->header); free(cur_ptr->value); next_ptr = cur_ptr->next; - //free(cur_ptr); } *ptr_head = NULL; @@ -410,7 +399,7 @@ int analyze_server_response(int s) { } } ptr = index(str, '='); - // only copy the cookie if it has a value (otherwise the server wants to delete the cookie + // only copy the cookie if it has a value (otherwise the server wants to delete the cookie) if (ptr != NULL && *(ptr + 1) != ';' && *(ptr + 1) != 0 && *(ptr + 1) != '\n' && *(ptr + 1) != '\r') { if (strlen(cookie) > 0) strncat(cookie, "; ", sizeof(cookie) - strlen(cookie) - 1); @@ -732,7 +721,7 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F hydra_register_socket(sp); /* - * Iterate through the runs. Values are the following: + * Iterate through the runs. Possible values are the following: * - 1 -> Open connection to remote server. * - 2 -> Run password attempts. * - 3 -> Disconnect and end with success. @@ -914,8 +903,6 @@ ptr_header_node initialize(char * ip, unsigned char options, char * miscptr) { if (url == NULL || variables == NULL || cond == NULL /*|| optional1 == NULL */ ) hydra_child_exit(2); - //printf("url: %s, var: %s, cond: %s, opt: %s\n", url, variables, cond, optional1); - if (*cond == 0) { fprintf(stderr, "[ERROR] invalid number of parameters in module option\n"); return NULL;