Merge pull request #342 from mathewmarcus/add_feature_321

Optionally add request headers to http-get
This commit is contained in:
van Hauser 2018-07-16 17:39:15 +02:00 committed by GitHub
commit 5d94930978
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 157 additions and 96 deletions

View file

@ -49,24 +49,18 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da
*/
#include "hydra-mod.h"
/* HTTP Header Types */
#define HEADER_TYPE_USERHEADER 'h'
#define HEADER_TYPE_USERHEADER_REPL 'H'
#define HEADER_TYPE_DEFAULT 'D'
#define HEADER_TYPE_DEFAULT_REPL 'd'
#include "hydra-http.h"
extern char *HYDRA_EXIT;
char *buf;
char *cond;
typedef struct header_node {
struct header_node {
char *header;
char *value;
char type;
struct header_node *next;
} t_header_node, *ptr_header_node;
};
typedef struct cookie_node {
char *name;
@ -81,8 +75,6 @@ int32_t auth_flag = 0;
char cookie[4096] = "", cmiscptr[1024];
extern char *webtarget;
extern char *slash;
int32_t webport, freemischttpform = 0;
char bufferurl[6096 + 24], cookieurl[6096 + 24] = "", userheader[6096 + 24] = "", *url, *variables, *optional1;
@ -396,6 +388,90 @@ char *stringify_headers(ptr_header_node *ptr_head) {
return headers_str;
}
int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) {
char *ptr, *ptr2;
/*
* Parse the user-supplied options.
* Beware of the backslashes (\)!
*/
while (*miscptr != 0) {
switch (miscptr[0]) {
case 'c': // fall through
case 'C':
ptr = miscptr + 2;
while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\'))
ptr++;
if (*ptr != 0)
*ptr++ = 0;
sprintf(cookieurl, "%.1000s", hydra_strrep(miscptr + 2, "\\:", ":"));
miscptr = ptr;
break;
case 'h':
// add a new header at the end
ptr = miscptr + 2;
while (*ptr != 0 && *ptr != ':')
ptr++;
if (*(ptr - 1) == '\\')
*(ptr - 1) = 0;
if (*ptr != 0) {
*ptr = 0;
ptr += 2;
}
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, miscptr + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER)) {
// Success: break the switch and go ahead
miscptr = ptr2;
break;
}
// Error: abort execution
hydra_report(stderr, "[ERROR] Out of memory for HTTP headers (h).");
return 0;
case 'H':
// add a new header, or replace an existing one's value
ptr = miscptr + 2;
while (*ptr != 0 && *ptr != ':')
ptr++;
if (*(ptr - 1) == '\\')
*(ptr - 1) = 0;
if (*ptr != 0) {
*ptr = 0;
ptr += 2;
}
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, miscptr + 2, hydra_strrep(ptr, "\\:", ":"), HEADER_TYPE_USERHEADER_REPL)) {
// Success: break the switch and go ahead
miscptr = ptr2;
break;
}
// Error: abort execution
hydra_report(stderr, "[ERROR] Out of memory for HTTP headers (H).");
return 0;
// no default
}
}
return 1;
}
char *prepare_http_request(char *type, char *path, char *params, char *headers) {
uint32_t reqlen = 0;
@ -1200,81 +1276,8 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
* Parse the user-supplied options.
* Beware of the backslashes (\)!
*/
while (*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++;
if (*(ptr - 1) == '\\')
*(ptr - 1) = 0;
if (*ptr != 0) {
*ptr = 0;
ptr += 2;
}
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 (h).");
return NULL;
case 'H':
// add a new header, or replace an existing one's value
ptr = optional1 + 2;
while (*ptr != 0 && *ptr != ':')
ptr++;
if (*(ptr - 1) == '\\')
*(ptr - 1) = 0;
if (*ptr != 0) {
*ptr = 0;
ptr += 2;
}
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 (H).");
return NULL;
// no default
}
}
if (!parse_options(optional1, &ptr_head))
return NULL;
/* again: no snprintf to be portable. don't worry, buffer can't overflow */
if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) {

View file

@ -1,4 +1,4 @@
#include "hydra-mod.h"
#include "hydra-http.h"
#include "sasl.h"
extern char *HYDRA_EXIT;
@ -8,10 +8,10 @@ char *http_buf = NULL;
int32_t webport, freemischttp = 0;
int32_t http_auth_mechanism = AUTH_BASIC;
int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE * fp, char *type) {
int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE * fp, char *type, ptr_header_node ptr_head) {
char *empty = "";
char *login, *pass, buffer[500], buffer2[500];
char header[64] = "Content-Length: 0\r\n";
char *login, *pass, *buffer, buffer2[500];
char *header;
char *ptr, *fooptr;
int32_t complete_line = 0;
char tmpreplybuf[1024] = "", *tmpreplybufptr;
@ -21,8 +21,15 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (strlen(pass = hydra_get_next_password()) == 0)
pass = empty;
if (strcmp(type, "POST") != 0)
header[0] = 0;
if (strcmp(type, "POST") == 0)
add_header(&ptr_head, "Content-Length", "0", HEADER_TYPE_DEFAULT);
header = stringify_headers(&ptr_head);
if(!(buffer = malloc(strlen(header) + 500))) {
free(header);
return 3;
}
// we must reset this if buf is NULL and we do MD5 digest
if (http_buf == NULL && http_auth_mechanism == AUTH_DIGESTMD5)
@ -62,6 +69,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header);
if (fooptr == NULL) {
free(buffer);
free(header);
return 3;
}
@ -97,8 +106,11 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
buf1, header);
}
if (hydra_send(s, buffer, strlen(buffer), 0) < 0)
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
free(buffer);
free(header);
return 1;
}
//receive challenge
if (http_buf != NULL)
@ -109,8 +121,11 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
http_buf = hydra_receive_line(s);
}
if (http_buf == NULL)
if (http_buf == NULL) {
free(buffer);
free(header);
return 1;
}
if (pos != NULL) {
char *str;
@ -153,6 +168,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
}
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
free(buffer);
free(header);
return 1;
}
@ -189,6 +206,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (http_buf == NULL) {
if (verbose)
hydra_report(stderr, "[ERROR] Server did not answer\n");
free(buffer);
free(header);
return 3;
}
@ -228,6 +247,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (find_auth) {
// free(http_buf);
// http_buf = NULL;
free(buffer);
free(header);
return 1;
}
}
@ -235,6 +256,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
}
// free(http_buf);
// http_buf = NULL;
free(buffer);
free(header);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3;
return 1;
@ -244,6 +267,7 @@ void service_http(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
int32_t run = 1, next_run = 1, sock = -1;
int32_t myport = PORT_HTTP, mysslport = PORT_HTTP_SSL;
char *ptr, *ptr2;
ptr_header_node ptr_head = NULL;
hydra_register_socket(sp);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
@ -278,6 +302,17 @@ void service_http(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
else
webport = mysslport;
/* Advance to options string */
ptr = miscptr;
while (*ptr != 0 && (*ptr != ':' || *(ptr - 1) == '\\'))
ptr++;
if (*ptr != 0)
*ptr++ = 0;
optional1 = ptr;
if (!parse_options(optional1, &ptr_head))
run = 4;
while (1) {
next_run = 0;
switch (run) {
@ -306,7 +341,7 @@ void service_http(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
break;
}
case 2: /* run the cracking function */
next_run = start_http(sock, ip, port, options, miscptr, fp, type);
next_run = start_http(sock, ip, port, options, miscptr, fp, type, ptr_head);
break;
case 3: /* clean exit */
if (sock >= 0)
@ -353,5 +388,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis
void usage_http(const char* service) {
printf("Module %s requires the page to authenticate.\n"
"For example: \"/secret\" or \"http://bla.com/foo/bar\" or \"https://test.com:8080/members\"\n\n", service);
"The following parameters are optional:\n"
" (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each request\n"
"For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: sessid=aaaa\" or \"https://test.com:8080/members\"\n\n", service);
}

21
hydra-http.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef _HYDRA_HTTP_H
#define _HYDRA_HTTP_H
#include "hydra-mod.h"
/* HTTP Header Types */
#define HEADER_TYPE_USERHEADER 'h'
#define HEADER_TYPE_USERHEADER_REPL 'H'
#define HEADER_TYPE_DEFAULT 'D'
#define HEADER_TYPE_DEFAULT_REPL 'd'
typedef struct header_node t_header_node, *ptr_header_node;
extern char *webtarget;
extern char *slash;
extern char *optional1;
extern int32_t parse_options(char *miscptr, ptr_header_node * ptr_head);
extern int32_t add_header(ptr_header_node * ptr_head, char *header, char *value, char type);
extern char *stringify_headers(ptr_header_node *ptr_head);
#endif