mirror of
https://github.com/vanhauser-thc/thc-hydra.git
synced 2025-08-21 05:43:52 -07:00
Added -h and -H options support for direct HTTP GET/POST requests.
This commit is contained in:
parent
8ebbde3223
commit
70c598ee32
1 changed files with 207 additions and 269 deletions
|
@ -52,10 +52,24 @@ Added fail or success condition, getting cookies, and allow 5 redirections by da
|
||||||
|
|
||||||
#include "hydra-mod.h"
|
#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;
|
extern char *HYDRA_EXIT;
|
||||||
char *buf;
|
char *buf;
|
||||||
char *cond;
|
char *cond;
|
||||||
|
|
||||||
|
char http_request[MAX_REQ_LEN];
|
||||||
typedef struct header_node {
|
typedef struct header_node {
|
||||||
char *header;
|
char *header;
|
||||||
char *value;
|
char *value;
|
||||||
|
@ -76,10 +90,40 @@ char cookie[4096] = "", cmiscptr[1024];
|
||||||
extern char *webtarget;
|
extern char *webtarget;
|
||||||
extern char *slash;
|
extern char *slash;
|
||||||
int webport, freemischttpform = 0;
|
int webport, freemischttpform = 0;
|
||||||
|
int http_opts;
|
||||||
char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1;
|
char bufferurl[1024], cookieurl[1024] = "", userheader[1024] = "", *url, *variables, *optional1;
|
||||||
|
|
||||||
ptr_header_node ptr_head = NULL;
|
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).
|
* 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;
|
ptr_head = new_ptr;
|
||||||
|
|
||||||
// TODO Remove the debug messages
|
// TODO Remove the debug messages
|
||||||
hydra_report_debug(stdout, "[add_header] Added header %s: %s", header, value);
|
// hydra_report(stdout, "[add_header] Added header %s: %s\n", header, value);
|
||||||
hydra_report_debug(stdout, "[add_header] len(header) = %d", strlen(header));
|
// hydra_report(stdout, "[add_header] len(header) = %d", strlen(header));
|
||||||
hydra_report_debug(stdout, "[add_header] len(value) = %d", strlen(value));
|
// hydra_report(stdout, "[add_header] len(value) = %d", strlen(value));
|
||||||
|
|
||||||
return 1;
|
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){
|
for(cur_ptr = ptr_head; cur_ptr; cur_ptr = cur_ptr->next){
|
||||||
if(strcmp(cur_ptr->header, header) == 0){
|
if(strcmp(cur_ptr->header, header) == 0){
|
||||||
free(cur_ptr->value);
|
//free(cur_ptr->value);
|
||||||
cur_ptr->value = value;
|
cur_ptr->value = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -139,25 +183,84 @@ int add_or_replace_header(char *header, char *value){
|
||||||
return add_header(header, value);
|
return add_header(header, value);
|
||||||
|
|
||||||
// TODO Remove the debug messages
|
// TODO Remove the debug messages
|
||||||
hydra_report_debug(stdout, "[add_or_replace_header] Added header %s: %s", header, value);
|
// hydra_report(stdout, "[add_or_replace_header] Added header %s: %s\n", header, value);
|
||||||
hydra_report_debug(stdout, "[add_or_replace_header] len(header) = %d", strlen(header));
|
// hydra_report(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] len(value) = %d", strlen(value));
|
||||||
|
|
||||||
return 1;
|
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.
|
* 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 * headers_str = NULL;
|
char * headers_str = NULL;
|
||||||
ptr_header_node cur_ptr = ptr_head, tmp_ptr = NULL;
|
ptr_header_node cur_ptr = ptr_head, tmp_ptr = NULL;
|
||||||
int ttl_size = 0;
|
int ttl_size = strlen(http_request);
|
||||||
|
|
||||||
while(cur_ptr){
|
while(cur_ptr){
|
||||||
if(cur_ptr->header && cur_ptr->value){ // Check for NULLs
|
if(cur_ptr->header && cur_ptr->value){ // Check for NULLs
|
||||||
ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 1;
|
ttl_size += strlen(cur_ptr->header) + strlen(cur_ptr->value) + 1;
|
||||||
|
if(headers_str)
|
||||||
headers_str = (char *) realloc(headers_str, sizeof(char) * ttl_size);
|
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
|
if(headers_str){ // Check for errors
|
||||||
strcat(headers_str, cur_ptr->header);
|
strcat(headers_str, cur_ptr->header);
|
||||||
strcat(headers_str, ": ");
|
strcat(headers_str, ": ");
|
||||||
|
@ -172,9 +275,9 @@ char * stringify_headers_and_clean(){
|
||||||
// Clean it up and get to the next header
|
// Clean it up and get to the next header
|
||||||
tmp_ptr = cur_ptr;
|
tmp_ptr = cur_ptr;
|
||||||
cur_ptr = cur_ptr->next;
|
cur_ptr = cur_ptr->next;
|
||||||
free(tmp_ptr->header);
|
//free(tmp_ptr->header);
|
||||||
free(tmp_ptr->value);
|
//free(tmp_ptr->value);
|
||||||
free(tmp_ptr);
|
//free(tmp_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return headers_str;
|
return headers_str;
|
||||||
|
@ -328,13 +431,15 @@ 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) {
|
||||||
char *empty = "";
|
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];
|
char header[8096], *upd3variables, cuserheader[1024];
|
||||||
int found = !success_cond, i, j;
|
int found = !success_cond, i, j;
|
||||||
|
|
||||||
memset(header, 0, sizeof(header));
|
memset(header, 0, sizeof(header));
|
||||||
cookie[0] = 0; // reset cookies from potential previous attempt
|
cookie[0] = 0; // reset cookies from potential previous attempt
|
||||||
|
|
||||||
|
// Take the next login/pass pair
|
||||||
if (strlen(login = hydra_get_next_login()) == 0)
|
if (strlen(login = hydra_get_next_login()) == 0)
|
||||||
login = empty;
|
login = empty;
|
||||||
if (strlen(pass = hydra_get_next_password()) == 0)
|
if (strlen(pass = hydra_get_next_password()) == 0)
|
||||||
|
@ -343,235 +448,21 @@ int start_http_form(int s, char *ip, int port, unsigned char options, char *misc
|
||||||
clogin[sizeof(clogin) - 1] = 0;
|
clogin[sizeof(clogin) - 1] = 0;
|
||||||
strncpy(cpass, html_encode(pass), sizeof(cpass) - 1);
|
strncpy(cpass, html_encode(pass), sizeof(cpass) - 1);
|
||||||
cpass[sizeof(cpass) - 1] = 0;
|
cpass[sizeof(cpass) - 1] = 0;
|
||||||
|
|
||||||
|
// Replace the user/pass placeholders in the command line options
|
||||||
upd3variables = hydra_strrep(variables, "^USER^", clogin);
|
upd3variables = hydra_strrep(variables, "^USER^", clogin);
|
||||||
upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* again: no snprintf to be portable. dont worry, buffer cant overflow */
|
// Replace the user/pass placeholders in the user-supplied headers
|
||||||
if (use_proxy == 1 && proxy_authentication != NULL) {
|
hdrrep("^USER^", clogin);
|
||||||
// proxy with authentication
|
hdrrep("^PASS^", cpass);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, "POST") == 0) {
|
buffer = stringify_headers_and_clean();
|
||||||
sprintf(buffer,
|
hydra_report(stdout, "HTTP headers:\n%s\r\n%s", http_request, 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) {
|
hydra_child_exit(1);
|
||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,6 +564,34 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F
|
||||||
success_cond = 0;
|
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;
|
char *header = NULL, *value = NULL;
|
||||||
while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) {
|
while ( /*(optional1 = strtok(NULL, ":")) != NULL */ *optional1 != 0) {
|
||||||
switch (optional1[0]) {
|
switch (optional1[0]) {
|
||||||
|
@ -708,7 +627,9 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F
|
||||||
if(header && value){
|
if(header && value){
|
||||||
strcpy(header, optional1 + 2);
|
strcpy(header, optional1 + 2);
|
||||||
strcpy(value, hydra_strrep(ptr, "\\:", ":"));
|
strcpy(value, hydra_strrep(ptr, "\\:", ":"));
|
||||||
if(add_header(hydra_trim(header), hydra_trim(value))){
|
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
|
// Success: break the switch and go ahead
|
||||||
optional1 = ptr2;
|
optional1 = ptr2;
|
||||||
break;
|
break;
|
||||||
|
@ -720,12 +641,29 @@ void service_http_form(char *ip, int sp, unsigned char options, char *miscptr, F
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
// add a new header, or replace an existing one's value
|
// 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));
|
header = (char *) malloc(strlen(optional1 + 2));
|
||||||
value = (char *) malloc(strlen(ptr));
|
value = (char *) malloc(strlen(ptr));
|
||||||
if(header && value){
|
if(header && value){
|
||||||
strcpy(header, optional1 + 2);
|
strcpy(header, optional1 + 2);
|
||||||
strcpy(value, hydra_strrep(ptr, "\\:", ":"));
|
strcpy(value, hydra_strrep(ptr, "\\:", ":"));
|
||||||
if(add_or_replace_header(hydra_trim(header), hydra_trim(value))){
|
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
|
// Success: break the switch and go ahead
|
||||||
optional1 = ptr2;
|
optional1 = ptr2;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue