diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..628d9fd --- /dev/null +++ b/Android.mk @@ -0,0 +1,104 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_CFLAGS:= -O3 -DLIBOPENSSL -DLIBFIREBIRD -DLIBIDN -DHAVE_PR29_H -DHAVE_PCRE \ + -DLIBMYSQLCLIENT -DLIBNCP -DLIBPOSTGRES -DLIBSVN -DLIBSSH -DNO_RINDEX \ + -DHAVE_MATH_H -DHAVE_MYSQL_H -DOPENSSL_NO_DEPRECATED -DNO_RSA_LEGACY \ + -fdata-sections -ffunction-sections + +LOCAL_LDFLAGS:=-Wl,--gc-sections + +LOCAL_C_INCLUDES:= \ + $(LOCAL_PATH)\ + external/openssl/include\ + external/libssh/include\ + external/libidn/lib\ + external/libmysqlclient/include\ + external/subversion/subversion/include\ + external/apr/include\ + external/firebird/include\ + external/libncp/include\ + external/libpcre + +LOCAL_SRC_FILES:= \ + bfg.c\ + crc32.c\ + d3des.c\ + hmacmd5.c\ + hydra-afp.c\ + hydra-asterisk.c\ + hydra.c\ + hydra-cisco.c\ + hydra-cisco-enable.c\ + hydra-cvs.c\ + hydra-firebird.c\ + hydra-ftp.c\ + hydra-http.c\ + hydra-http-form.c\ + hydra-http-proxy.c\ + hydra-http-proxy-urlenum.c\ + hydra-icq.c\ + hydra-imap.c\ + hydra-irc.c\ + hydra-ldap.c\ + hydra-mod.c\ + hydra-mssql.c\ + hydra-mysql.c\ + hydra-ncp.c\ + hydra-nntp.c\ + hydra-oracle.c\ + hydra-oracle-listener.c\ + hydra-oracle-sid.c\ + hydra-pcanywhere.c\ + hydra-pcnfs.c\ + hydra-pop3.c\ + hydra-postgres.c\ + hydra-rdp.c\ + hydra-redis.c\ + hydra-rexec.c\ + hydra-rlogin.c\ + hydra-rsh.c\ + hydra-s7-300.c\ + hydra-sapr3.c\ + hydra-sip.c\ + hydra-smb.c\ + hydra-smtp.c\ + hydra-smtp-enum.c\ + hydra-snmp.c\ + hydra-socks5.c\ + hydra-ssh.c\ + hydra-sshkey.c\ + hydra-svn.c\ + hydra-teamspeak.c\ + hydra-telnet.c\ + hydra-vmauthd.c\ + hydra-vnc.c\ + hydra-xmpp.c\ + ntlm.c\ + sasl.c + +LOCAL_STATIC_LIBRARIES := \ + libfbclient \ + libidn \ + libmysqlclient \ + libncp \ + libpcre \ + libpcrecpp \ + libpcreposix \ + libpq \ + libssh \ + libsvn_client-1 \ + libapr-1 \ + libaprutil-1 \ + libiconv\ + libneon + +LOCAL_SHARED_LIBRARIES := \ + libcrypto\ + libssl\ + libsqlite\ + libexpat + +LOCAL_MODULE:= hydra + +include $(BUILD_EXECUTABLE) diff --git a/CHANGES b/CHANGES index 0a903f3..45c2b43 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,16 @@ Changelog for hydra ------------------- +Release 8.1-pre +* Fixed for cisco-enable if an intial Login/Password is used (thanks to joswr1te for reporting) +* Added patch by tux-mind for better MySQL compilation and an Android patches and Makefile. Thanks! +* Added xhydra gtk patch by Petar Kaleychev to support -e r reverse login attempt, thanks! +* Fixed a crash in the cisco module (thanks to Anatoly Mamaev for reporting) +* Small fix for HTTP form module for redirect pages where a S= string match would not work (thanks to mkosmach for reporting) +* Updated configure to detect subversion packages on current Cygwin +* Fixed RDP module to support the port option (thanks to and.enshin(at)gmail.com) + + Release 8.0 ! Development moved to a public github repository: https://github.com/vanhauser-thc/thc-hydra * Added module for redis (submitted by Alejandro Ramos, thanks!) diff --git a/configure b/configure index 9ba9ebb..85eea5b 100755 --- a/configure +++ b/configure @@ -3,17 +3,7 @@ # uname -s = Linux | OpenBSD | FreeBSD # uname -m = i636 or x86_64 -if [ "$1" = "-h" ]; then - echo Options: - echo " --prefix=path path to install hydra and its datafiles to" - echo " --with-oracle=prefix prefix for oracle include dir" - echo " --with-oracle-lib=prefix prefix for oracle lib dir" - echo " --disable-xhydra disable compilation of hydra GUI" - echo " --nostrip do not per default strip binaries before install" - echo " --help this here" - exit 0 -fi -if [ "$1" = "--help" ]; then +if [ "$1" = "-h" -o "$1" = "--help" ]; then echo Options: echo " --prefix=path path to install hydra and its datafiles to" echo " --with-oracle=prefix prefix for oracle include dir" @@ -30,7 +20,7 @@ rm -f Makefile.in SYSS=`uname -s 2> /dev/null` SYSO=`uname -o 2> /dev/null` SIXFOUR="" -if [ "$SYSS" = "Linux" -o "$SYSS" = "OpenBSD" -o "$SYSS" = "FreeBSD" -o "$SYSS" = "NetBSD" ]; then +if [ "$SYSS" = "Linux" -o "$SYSS" = "OpenBSD" -o "$SYSS" = "FreeBSD" -o "$SYSS" = "NetBSD" -o "$SYSS" = "Darwin" ]; then SF=`uname -m | grep 64` if [ `uname -m` = "s390x" ]; then SF=64 @@ -323,6 +313,12 @@ for i in $LIBDIRS ; do APR_PATH="$i" fi fi + if [ "X" = "X$SVN_PATH" ]; then + if [ -f "$i/libsvn_client-1.dll.a" ]&&[ -f "$i/libapr-1.dll.a" ]&&[ -f "$i/libaprutil-1.dll.a" ]; then + SVN_PATH="$i" + APR_PATH="$i" + fi + fi if [ "X" = "X$SVN_PATH" ]; then if [ -f "$i/libsvn_client-1.dylib" ]&&[ -f "$i/libapr-1.dylib" ]&&[ -f "$i/libaprutil-1.dylib" ]; then SVN_PATH="$i" @@ -451,10 +447,15 @@ for i in $LIBDIRS ; do fi fi done +MYSQLINSUBDIR="" for i in $INCDIRS ; do if [ "X" != "X$MYSQL_PATH" ]; then if [ -f "$i/mysql/mysql.h" ]; then MYSQL_IPATH="$i/mysql" + MYSQLINSUBDIR="mysql/" + fi + if [ -f "$i/mysql.h" ]; then + MYSQL_IPATH="$i" fi fi done @@ -931,6 +932,11 @@ if [ -n "$SVN_IPATH" ]; then fi if [ -n "$MYSQL_IPATH" ]; then XIPATHS="$XIPATHS -I$MYSQL_IPATH" + if [ -n "$MYSQLINSUBDIR" ]; then + XDEFINES="$XDEFINES -DHAVE_MYSQL_MYSQL_H" + else + XDEFINES="$XDEFINES -DHAVE_MYSQL_H" + fi fi if [ -n "$AFP_IPATH" ]; then XIPATHS="$XIPATHS -I$AFP_IPATH" diff --git a/hydra-cisco.c b/hydra-cisco.c index 424f0ad..65fd31b 100644 --- a/hydra-cisco.c +++ b/hydra-cisco.c @@ -24,6 +24,7 @@ int start_cisco(int s, char *ip, int port, unsigned char options, char *miscptr, return 1; } sleep(1); + buf = NULL; do { if (buf != NULL) free(buf); @@ -51,8 +52,11 @@ int start_cisco(int s, char *ip, int port, unsigned char options, char *miscptr, if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; } + + buf = NULL; do { - free(buf); + if (buf != NULL) + free(buf); if ((buf = hydra_receive_line(s)) == NULL) return 3; if (buf[strlen(buf) - 1] == '\n') @@ -78,6 +82,7 @@ int start_cisco(int s, char *ip, int port, unsigned char options, char *miscptr, if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { return 1; } + buf = NULL; do { if (buf != NULL) free(buf); diff --git a/hydra-gtk/src/callbacks.c b/hydra-gtk/src/callbacks.c index bc19a5c..715194a 100755 --- a/hydra-gtk/src/callbacks.c +++ b/hydra-gtk/src/callbacks.c @@ -150,7 +150,7 @@ int hydra_get_options(char *options[]) { } } - /* empty passes / login as pass? */ + /* empty passes / login as pass / reversed login? */ memset(passLoginNull, 0, 4); widget = lookup_widget(GTK_WIDGET(wndMain), "chkPassNull"); if (gtk_toggle_button_get_active((GtkToggleButton *) widget)) { @@ -164,6 +164,17 @@ int hydra_get_options(char *options[]) { passLoginNull[1] = 's'; } } + /* The "Try reversed login" button was implemented by Petar Kaleychev */ + widget = lookup_widget(GTK_WIDGET(wndMain), "chkPassReverse"); + if (gtk_toggle_button_get_active((GtkToggleButton *) widget)) { + if (passLoginNull[0] == 0) { + passLoginNull[0] = 'r'; + } else if (passLoginNull[1] == 0) { + passLoginNull[1] = 'r'; + } else { + passLoginNull[2] = 'r'; + } + } if (passLoginNull[0] != 0) { options[i++] = "-e"; options[i++] = passLoginNull; diff --git a/hydra-gtk/src/interface.c b/hydra-gtk/src/interface.c index 6fdebc5..4ea8213 100755 --- a/hydra-gtk/src/interface.c +++ b/hydra-gtk/src/interface.c @@ -88,6 +88,7 @@ GtkWidget *create_wndMain(void) { GtkWidget *table6; GtkWidget *chkPassLogin; GtkWidget *chkPassNull; + GtkWidget *chkPassReverse; GtkWidget *label2; GtkWidget *table4; GtkWidget *frame9; @@ -528,7 +529,7 @@ GtkWidget *create_wndMain(void) { gtk_widget_show(label20); gtk_frame_set_label_widget(GTK_FRAME(frame8), label20); - table6 = gtk_table_new(1, 2, FALSE); + table6 = gtk_table_new(1, 3, FALSE); gtk_widget_set_name(table6, "table6"); gtk_widget_show(table6); gtk_box_pack_start(GTK_BOX(vbox2), table6, TRUE, TRUE, 0); @@ -545,6 +546,12 @@ GtkWidget *create_wndMain(void) { gtk_table_attach(GTK_TABLE(table6), chkPassNull, 1, 2, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK), (GtkAttachOptions) (GTK_EXPAND), 0, 0); gtk_tooltips_set_tip(tooltips, chkPassNull, "Enable this option to try an empty password, in addition to the password/file", NULL); + chkPassReverse = gtk_check_button_new_with_mnemonic ("Try reversed login"); + gtk_widget_set_name (chkPassReverse, "chkPassReverse"); + gtk_widget_show (chkPassReverse); + gtk_table_attach (GTK_TABLE (table6), chkPassReverse, 2, 3, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK), (GtkAttachOptions) (GTK_EXPAND), 0, 0); + gtk_tooltips_set_tip (tooltips, chkPassReverse, "Enable this option to try an reverse password, in addition to the password/file", NULL); + label2 = gtk_label_new("Passwords"); gtk_widget_set_name(label2, "label2"); gtk_widget_show(label2); @@ -1049,6 +1056,7 @@ GtkWidget *create_wndMain(void) { GLADE_HOOKUP_OBJECT(wndMain, table6, "table6"); GLADE_HOOKUP_OBJECT(wndMain, chkPassLogin, "chkPassLogin"); GLADE_HOOKUP_OBJECT(wndMain, chkPassNull, "chkPassNull"); + GLADE_HOOKUP_OBJECT(wndMain, chkPassReverse, "chkPassReverse"); GLADE_HOOKUP_OBJECT(wndMain, label2, "label2"); GLADE_HOOKUP_OBJECT(wndMain, table4, "table4"); GLADE_HOOKUP_OBJECT(wndMain, frame9, "frame9"); diff --git a/hydra-http-form.c b/hydra-http-form.c deleted file mode 100644 index d142f53..0000000 --- a/hydra-http-form.c +++ /dev/null @@ -1,1059 +0,0 @@ - -/* - -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(next_ptr->header); - free(next_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; // buffer for the 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); - 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; - } - } 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); - - 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; - 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)); - str3[strlen(str) - strlen(str2)] = 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 - 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 - 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 - hdrrepv(&ptr_head, "Host", str2); - http_request = prepare_http_request("GET", str3, NULL, cookie_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); - - free(http_request); - } - } - - //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; -} - -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); - cleanup(&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); - cleanup(&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; -} diff --git a/hydra-mod.c b/hydra-mod.c index a9cefab..526a25c 100644 --- a/hydra-mod.c +++ b/hydra-mod.c @@ -3,6 +3,8 @@ #ifdef LIBOPENSSL #include #include +#include +#include #endif #ifdef HAVE_PCRE #include diff --git a/hydra-mysql.c b/hydra-mysql.c index 4a839cc..77b3d61 100644 --- a/hydra-mysql.c +++ b/hydra-mysql.c @@ -22,8 +22,13 @@ void service_mysql(char *ip, int sp, unsigned char options, char *miscptr, FILE #ifndef LIBMYSQLCLIENT #else - +#if defined(HAVE_MYSQL_MYSQL_H) #include +#elif defined(HAVE_MYSQL_H) +#include +#else +#error libmysqlclient found, but no usable headers available +#endif MYSQL *mysql = NULL; #endif diff --git a/hydra-rdp.c b/hydra-rdp.c index f01ee96..9b747bd 100644 --- a/hydra-rdp.c +++ b/hydra-rdp.c @@ -2453,6 +2453,9 @@ void service_rdp(char *ip, int sp, unsigned char options, char *miscptr, FILE * int run = 1, next_run = 1; int myport = PORT_RDP; + if (port != 0) + myport = port; + hydra_register_socket(sp); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return; diff --git a/hydra.c b/hydra.c index 9fced14..e27b760 100644 --- a/hydra.c +++ b/hydra.c @@ -264,7 +264,9 @@ typedef struct { // external vars extern char HYDRA_EXIT[5]; +#if !defined(ANDROID) && !defined(__BIONIC__) extern int errno; +#endif extern int debug; extern int verbose; extern int waittime; @@ -501,7 +503,7 @@ void module_usage() { "Examples:\n" " hydra -P pass.txt target cisco-enable (direct console access)\n" " hydra -P pass.txt -m cisco target cisco-enable (Logon password cisco)\n" - " hydra -l foo -m bar -P pass.txt -m cisco target cisco-enable (AAA Login foo, password bar)\n"); + " hydra -l foo -m bar -P pass.txt target cisco-enable (AAA Login foo, password bar)\n"); find = 1; } if (!find && (strcmp(hydra_options.service, "cisco") == 0)) { @@ -2756,8 +2758,10 @@ int main(int argc, char *argv[]) { } if (strcmp(hydra_options.service, "cisco-enable") == 0) { i = 2; - if (hydra_options.login == NULL) - hydra_options.login = empty_login; + if (hydra_options.login == NULL) { + //hydra_options.login = empty_login; + i = 1; // login will be the initial Username: login, or line Password: + } if (hydra_options.miscptr == NULL) { fprintf(stderr, "[WARNING] You did not supply the initial support to the Cisco via -l, assuming direct console access\n"); } @@ -2920,7 +2924,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[WARNING] you specified port 443 for attacking a http service, however did not specify the -S ssl switch nor used https-..., therefore using plain HTTP\n"); if (hydra_options.loop_mode && hydra_options.colonfile != NULL) - bail("The loop mode option (-u) works with all modes - except colon files (-C)\n"); + bail("The loop mode option (-u) works with all modes - except colon files (-C)\n"); if (strncmp(hydra_options.service, "http-", strlen("http-")) != 0 && strcmp(hydra_options.service, "http-head") != 0 && getenv("HYDRA_PROXY_HTTP") != NULL) fprintf(stderr, "[WARNING] the HYDRA_PROXY_HTTP environment variable works only with the http-head/http-get module, ignored...\n"); if (i == 2) { @@ -2978,12 +2982,16 @@ int main(int argc, char *argv[]) { if (hydra_options.colonfile == NULL) { if (hydra_options.loginfile != NULL) { - if ((lfp = fopen(hydra_options.loginfile, "r")) == NULL) - bail("File for logins not found!"); + if ((lfp = fopen(hydra_options.loginfile, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for logins not found: %s", hydra_options.loginfile); + exit(-1); + } hydra_brains.countlogin = countlines(lfp, 0); hydra_brains.sizelogin = size_of_data; - if (hydra_brains.countlogin == 0) - bail("File for logins is empty!"); + if (hydra_brains.countlogin == 0) { + fprintf(stderr, "[ERROR] File for logins is empty: %s", hydra_options.loginfile); + exit(-1); + } if (hydra_brains.countlogin > MAX_LINES) { fprintf(stderr, "[ERROR] Maximum number of logins is %d, this file has %lu entries.\n", MAX_LINES, hydra_brains.countlogin); exit(-1); @@ -3003,12 +3011,16 @@ int main(int argc, char *argv[]) { hydra_brains.countlogin = 1; } if (hydra_options.passfile != NULL) { - if ((pfp = fopen(hydra_options.passfile, "r")) == NULL) - bail("File for passwords not found!"); + if ((pfp = fopen(hydra_options.passfile, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for passwords not found: %s", hydra_options.passfile); + exit(-1); + } hydra_brains.countpass = countlines(pfp, 0); hydra_brains.sizepass = size_of_data; - if (hydra_brains.countpass == 0) - bail("File for passwords is empty!"); + if (hydra_brains.countpass == 0) { + fprintf(stderr, "[ERROR] File for passwords is empty: %s", hydra_options.passfile); + exit(-1); + } if (hydra_brains.countpass > MAX_LINES) { fprintf(stderr, "[ERROR] Maximum number of passwords is %d, this file has %lu entries.\n", MAX_LINES, hydra_brains.countpass); exit(-1); @@ -3046,12 +3058,16 @@ int main(int argc, char *argv[]) { } } } else { - if ((cfp = fopen(hydra_options.colonfile, "r")) == NULL) - bail("File with login:password information not found!"); + if ((cfp = fopen(hydra_options.colonfile, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s", hydra_options.colonfile); + exit(-1); + } hydra_brains.countlogin = countlines(cfp, 1); hydra_brains.sizelogin = size_of_data; - if (hydra_brains.countlogin == 0) - bail("File for login:password information is empty!"); + if (hydra_brains.countlogin == 0) { + fprintf(stderr, "[ERROR] File for colon files (login:pass) is empty: %s", hydra_options.colonfile); + exit(-1); + } if (hydra_brains.countlogin > MAX_LINES / 2) { fprintf(stderr, "[ERROR] Maximum number of colon file entries is %d, this file has %lu entries.\n", MAX_LINES / 2, hydra_brains.countlogin); exit(-1); @@ -3087,11 +3103,15 @@ int main(int argc, char *argv[]) { } if (hydra_options.infile_ptr != NULL) { - if ((ifp = fopen(hydra_options.infile_ptr, "r")) == NULL) - bail("File for IP addresses not found!"); + if ((ifp = fopen(hydra_options.infile_ptr, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for targets not found: %s", hydra_options.infile_ptr); + exit(-1); + } hydra_brains.targets = countservers = countinfile = countlines(ifp, 0); - if (countinfile == 0) - bail("File for IP addresses is empty!"); + if (countinfile == 0) { + fprintf(stderr, "[ERROR] File for targets is empty: %s", hydra_options.infile_ptr); + exit(-1); + } hydra_targets = malloc(sizeof(hydra_targets) * (countservers + 2) + 8); if (hydra_targets == NULL) bail("Could not allocate enough memory for target data"); diff --git a/rdp.h b/rdp.h index c4188df..66af31a 100644 --- a/rdp.h +++ b/rdp.h @@ -551,6 +551,7 @@ enum RDP_UPDATE_PDU_TYPE #include #include #include +#include #if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f) #define D2I_X509_CONST const diff --git a/web/index.html b/web/index.html index dd32d7e..3057301 100755 --- a/web/index.html +++ b/web/index.html @@ -163,7 +163,7 @@ [0x06] Compilation Help - Hydry compiles fine on all platforms that have gcc - Linux, all BSD, Mac OS/X, Cygwin on Windows, Solaris, etc. + Hydra compiles fine on all platforms that have gcc - Linux, all BSD, Mac OS/X, Cygwin on Windows, Solaris, etc. It should even compile on historical SunOS, Ultrix etc. platforms :-) There are many optional modules for network protocols like SSH, SVN etc. that require libraries.