mirror of
https://github.com/vanhauser-thc/thc-hydra.git
synced 2025-08-21 05:43:52 -07:00
Merge pull request #342 from mathewmarcus/add_feature_321
Optionally add request headers to http-get
This commit is contained in:
commit
5d94930978
3 changed files with 157 additions and 96 deletions
|
@ -49,24 +49,18 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hydra-mod.h"
|
#include "hydra-http.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'
|
|
||||||
|
|
||||||
extern char *HYDRA_EXIT;
|
extern char *HYDRA_EXIT;
|
||||||
char *buf;
|
char *buf;
|
||||||
char *cond;
|
char *cond;
|
||||||
|
|
||||||
typedef struct header_node {
|
struct header_node {
|
||||||
char *header;
|
char *header;
|
||||||
char *value;
|
char *value;
|
||||||
char type;
|
char type;
|
||||||
struct header_node *next;
|
struct header_node *next;
|
||||||
} t_header_node, *ptr_header_node;
|
};
|
||||||
|
|
||||||
typedef struct cookie_node {
|
typedef struct cookie_node {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -81,8 +75,6 @@ int32_t auth_flag = 0;
|
||||||
|
|
||||||
char cookie[4096] = "", cmiscptr[1024];
|
char cookie[4096] = "", cmiscptr[1024];
|
||||||
|
|
||||||
extern char *webtarget;
|
|
||||||
extern char *slash;
|
|
||||||
int32_t webport, freemischttpform = 0;
|
int32_t webport, freemischttpform = 0;
|
||||||
char bufferurl[6096 + 24], cookieurl[6096 + 24] = "", userheader[6096 + 24] = "", *url, *variables, *optional1;
|
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;
|
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) {
|
char *prepare_http_request(char *type, char *path, char *params, char *headers) {
|
||||||
uint32_t reqlen = 0;
|
uint32_t reqlen = 0;
|
||||||
|
@ -1200,81 +1276,8 @@ ptr_header_node initialize(char *ip, unsigned char options, char *miscptr) {
|
||||||
* Parse the user-supplied options.
|
* Parse the user-supplied options.
|
||||||
* Beware of the backslashes (\)!
|
* Beware of the backslashes (\)!
|
||||||
*/
|
*/
|
||||||
while (*optional1 != 0) {
|
if (!parse_options(optional1, &ptr_head))
|
||||||
switch (optional1[0]) {
|
return NULL;
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* again: no snprintf to be portable. don't worry, buffer can't overflow */
|
/* again: no snprintf to be portable. don't worry, buffer can't overflow */
|
||||||
if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) {
|
if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) {
|
||||||
|
|
57
hydra-http.c
57
hydra-http.c
|
@ -1,4 +1,4 @@
|
||||||
#include "hydra-mod.h"
|
#include "hydra-http.h"
|
||||||
#include "sasl.h"
|
#include "sasl.h"
|
||||||
|
|
||||||
extern char *HYDRA_EXIT;
|
extern char *HYDRA_EXIT;
|
||||||
|
@ -8,10 +8,10 @@ char *http_buf = NULL;
|
||||||
int32_t webport, freemischttp = 0;
|
int32_t webport, freemischttp = 0;
|
||||||
int32_t http_auth_mechanism = AUTH_BASIC;
|
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 *empty = "";
|
||||||
char *login, *pass, buffer[500], buffer2[500];
|
char *login, *pass, *buffer, buffer2[500];
|
||||||
char header[64] = "Content-Length: 0\r\n";
|
char *header;
|
||||||
char *ptr, *fooptr;
|
char *ptr, *fooptr;
|
||||||
int32_t complete_line = 0;
|
int32_t complete_line = 0;
|
||||||
char tmpreplybuf[1024] = "", *tmpreplybufptr;
|
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)
|
if (strlen(pass = hydra_get_next_password()) == 0)
|
||||||
pass = empty;
|
pass = empty;
|
||||||
|
|
||||||
if (strcmp(type, "POST") != 0)
|
if (strcmp(type, "POST") == 0)
|
||||||
header[0] = 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
|
// we must reset this if buf is NULL and we do MD5 digest
|
||||||
if (http_buf == NULL && http_auth_mechanism == AUTH_DIGESTMD5)
|
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;
|
fooptr = buffer2;
|
||||||
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header);
|
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header);
|
||||||
if (fooptr == NULL) {
|
if (fooptr == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
free(header);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,8 +106,11 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
|
||||||
buf1, header);
|
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;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//receive challenge
|
//receive challenge
|
||||||
if (http_buf != NULL)
|
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);
|
http_buf = hydra_receive_line(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http_buf == NULL)
|
if (http_buf == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
free(header);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (pos != NULL) {
|
if (pos != NULL) {
|
||||||
char *str;
|
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) {
|
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
|
||||||
|
free(buffer);
|
||||||
|
free(header);
|
||||||
return 1;
|
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 (http_buf == NULL) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
hydra_report(stderr, "[ERROR] Server did not answer\n");
|
hydra_report(stderr, "[ERROR] Server did not answer\n");
|
||||||
|
free(buffer);
|
||||||
|
free(header);
|
||||||
return 3;
|
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) {
|
if (find_auth) {
|
||||||
// free(http_buf);
|
// free(http_buf);
|
||||||
// http_buf = NULL;
|
// http_buf = NULL;
|
||||||
|
free(buffer);
|
||||||
|
free(header);
|
||||||
return 1;
|
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);
|
// free(http_buf);
|
||||||
// http_buf = NULL;
|
// http_buf = NULL;
|
||||||
|
free(buffer);
|
||||||
|
free(header);
|
||||||
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
|
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
|
||||||
return 3;
|
return 3;
|
||||||
return 1;
|
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 run = 1, next_run = 1, sock = -1;
|
||||||
int32_t myport = PORT_HTTP, mysslport = PORT_HTTP_SSL;
|
int32_t myport = PORT_HTTP, mysslport = PORT_HTTP_SSL;
|
||||||
char *ptr, *ptr2;
|
char *ptr, *ptr2;
|
||||||
|
ptr_header_node ptr_head = NULL;
|
||||||
|
|
||||||
hydra_register_socket(sp);
|
hydra_register_socket(sp);
|
||||||
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
|
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
|
else
|
||||||
webport = mysslport;
|
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) {
|
while (1) {
|
||||||
next_run = 0;
|
next_run = 0;
|
||||||
switch (run) {
|
switch (run) {
|
||||||
|
@ -306,7 +341,7 @@ void service_http(char *ip, int32_t sp, unsigned char options, char *miscptr, FI
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: /* run the cracking function */
|
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;
|
break;
|
||||||
case 3: /* clean exit */
|
case 3: /* clean exit */
|
||||||
if (sock >= 0)
|
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) {
|
void usage_http(const char* service) {
|
||||||
printf("Module %s requires the page to authenticate.\n"
|
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
21
hydra-http.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue