diff --git a/CHANGES b/CHANGES index 685f48d..8fd6cf4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,19 +1,6 @@ Changelog for hydra ------------------- -Release 9.5 -* many modules did not support -W (all those that used a library for the - connection). All (or most?) should be fixed now. -* http-form: - - The help for http-form was wrong. the condition variable must always be - the *last* parameter, not the third - - Proxy support was not working correctly -* smb2: fix for updated libsmb2 which resulted in correct guessing attempts - not being detected -* smtp: break early if the server does not allow authentication -* rdp: detect more return codes that say a user is disabled etc. - - Release 9.4 * Switched from pcre/pcre3 to pcre2 as pcre/pcre3 will be dropped from Debian * Small fix for weird RTSP servers diff --git a/Dockerfile b/Dockerfile index 9f16b02..4496f50 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim +FROM debian:buster-slim ARG HYDRA_VERSION="github" @@ -35,23 +35,18 @@ RUN set -x \ gcc \ 1>/dev/null \ # The next line fixes the curl "SSL certificate problem: unable to get local issuer certificate" for linux/arm - && c_rehash - -# Get hydra sources and compile -RUN cd /src \ - && make clean \ - && ./configure \ - && make \ - && make install - -# Make clean -RUN apt-get purge -y make gcc \ + && c_rehash \ + # Get hydra sources and compile + && cd /src \ + && ./configure 1>/dev/null \ + && make 1>/dev/null \ + && make install \ + # Make clean + && apt-get purge -y make gcc libgpg-error-dev libgcrypt-dev \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* \ - && rm -rf /src - -# Verify hydra installation -RUN hydra -h || error_code=$? \ + # Verify hydra installation + && hydra -h || error_code=$? \ && if [ ! "${error_code}" -eq 255 ]; then echo "Wrong exit code for 'hydra help' command"; exit 1; fi \ # Unprivileged user creation && echo 'hydra:x:10001:10001::/tmp:/sbin/nologin' > /etc/passwd \ diff --git a/INSTALL b/INSTALL index 20f12fd..752aa63 100644 --- a/INSTALL +++ b/INSTALL @@ -24,5 +24,5 @@ https://wiki.termux.com/wiki/Graphical_Environment For the Oracle login module, install the basic and SDK packages: - https://www.oracle.com/database/technologies/instant-client/downloads.html + http://www.oracle.com/technetwork/database/features/instant-client/index.html diff --git a/Makefile.am b/Makefile.am index f6d4bb0..8cd56d1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,10 @@ # -# Makefile for Hydra - (c) 2001-2023 by van Hauser / THC +# Makefile for Hydra - (c) 2001-2022 by van Hauser / THC # WARN_CLANG=-Wformat-nonliteral -Wstrncat-size -Wformat-security -Wsign-conversion -Wconversion -Wfloat-conversion -Wshorten-64-to-32 -Wuninitialized -Wmissing-variable-declarations -Wmissing-declarations WARN_GCC=-Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-truncation=2 -Wnull-dereference -Wstrict-overflow=2 -Wstringop-overflow=4 -Walloca-larger-than=4096 -Wtype-limits -Wconversion -Wtrampolines -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -fno-common -Wcast-align CFLAGS ?= -g -OPTS=-I. -O3 $(CFLAGS) -fcommon -Wno-deprecated-declarations -CPPFLAGS += -D_GNU_SOURCE +OPTS=-I. -O3 $(CFLAGS) -fcommon # -Wall -g -pedantic LIBS=-lm DESTDIR ?= diff --git a/README b/README index ca95b03..e8c7b6a 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ H Y D R A - (c) 2001-2023 by van Hauser / THC + (c) 2001-2022 by van Hauser / THC https://github.com/vanhauser-thc/thc-hydra many modules were written by David (dot) Maciejak @ gmail (dot) com BFG code by Jan Dlabal @@ -96,7 +96,7 @@ for a few optional modules (note that some might not be available on your distri apt-get install libssl-dev libssh-dev libidn11-dev libpcre3-dev \ libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev \ firebird-dev libmemcached-dev libgpg-error-dev \ - libgcrypt11-dev libgcrypt20-dev freetds-dev + libgcrypt11-dev libgcrypt20-dev ``` This enables all optional modules and features with the exception of Oracle, @@ -267,7 +267,6 @@ Examples: -x 1:3:a generate passwords from length 1 to 3 with all lowercase letters -x 2:5:/ generate passwords from length 2 to 5 containing only slashes -x 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers --x '3:3:aA1&~#\\ "\'<{([-|_^@)]=}>$%*?./ยง,;:!`' -v generates length 3 passwords with all 95 characters, and verbose. ``` Example: diff --git a/configure b/configure index dc86adb..d9c8b02 100755 --- a/configure +++ b/configure @@ -185,32 +185,6 @@ else echo " ... zlib not found, gzip support disabled" fi -echo "Checking for sybdb (sybdb.h) ..." -for i in $INCDIRS; do - if [ -f "$i/sybdb.h" ]; then - HAVE_SYBDB="y" - fi -done - -if [ -n "$HAVE_SYBDB" ]; then - echo " ... found" -else - echo " ... sybdb not found, MSSQL module will lack TDSv7 support" -fi - -echo "Checking for sybfront (sybfront.h) ..." -for i in $INCDIRS; do - if [ -f "$i/sybfront.h" ]; then - HAVE_SYBFRONT="y" - fi -done - -if [ -n "$HAVE_SYBFRONT" ]; then - echo " ... found" -else - echo " ... sybfront not found, MSSQL module will lack TDSv7 support" -fi - echo "Checking for openssl (libssl/libcrypto/ssl.h/sha.h) ..." if [ "X" != "X$DEBUG" ]; then echo DEBUG: SSL_LIB=$LIBDIRS `ls -d /*ssl /usr/*ssl /opt/*ssl /usr/local/*ssl /opt/local/*ssl /*ssl/lib /usr/*ssl/lib /opt/*ssl/lib /usr/local/*ssl/lib /opt/local/*ssl/lib 2> /dev/null` @@ -992,7 +966,7 @@ if [ -n "$ORACLE_PATH" -a -n "$ORACLE_IPATH" ]; then fi if [ "X" = "X$ORACLE_PATH" -o "X" = "X$ORACLE_IPATH" ]; then echo " ... NOT found, module Oracle disabled" - echo "Get basic and sdk package from https://www.oracle.com/database/technologies/instant-client/downloads.html" + echo "Get basic and sdk package from http://www.oracle.com/technetwork/database/features/instant-client/index.html" ORACLE_PATH="" ORACLE_IPATH="" fi @@ -1382,7 +1356,7 @@ echo "Checking for Android specialities ..." TMPC=comptest$$ STRRCHR=" not" echo '#include ' > $TMPC.c -echo '#include ' >> $TMPC.c +echo '#include ' >> $TMPC.c echo "int main() { char *x = strrchr(\"test\", 'e'); if (x == NULL) return 0; else return 1; }" >> $TMPC.c $CC -o $TMPC $TMPC.c > /dev/null 2>&1 test -x $TMPC && STRRCHR="" @@ -1522,12 +1496,6 @@ fi if [ -n "$RSA" ]; then XDEFINES="$XDEFINES -DNO_RSA_LEGACY" fi -if [ -n "$HAVE_SYBDB" ]; then - XDEFINES="$XDEFINES -DHAVE_SYBDB" -fi -if [ -n "$HAVE_SYBFRONT" ]; then - XDEFINES="$XDEFINES -DHAVE_SYBFRONT" -fi if [ -n "$HAVE_ZLIB" ]; then XDEFINES="$XDEFINES -DHAVE_ZLIB" fi @@ -1659,9 +1627,6 @@ fi if [ -n "$HAVE_ZLIB" ]; then XLIBS="$XLIBS -lz" fi -if [ -n "$HAVE_SYBDB" ]; then - XLIBS="$XLIBS -lsybdb" -fi if [ -n "$CURSES_PATH" ]; then XLIBS="$XLIBS -lcurses" fi @@ -1839,4 +1804,4 @@ if [ "x$NOSTRIP" = "x" ]; then else cat Makefile.am | sed 's/^install:.*/install: all/' >> Makefile fi -echo "now type \"make\"" \ No newline at end of file +echo "now type \"make\"" diff --git a/hydra-firebird.c b/hydra-firebird.c index dea104f..4898c46 100644 --- a/hydra-firebird.c +++ b/hydra-firebird.c @@ -22,7 +22,6 @@ void dummy_firebird() { printf("\n"); } #define DEFAULT_DB "C:\\Program Files\\Firebird\\Firebird_1_5\\security.fdb" -extern hydra_option hydra_options; extern char *HYDRA_EXIT; int32_t start_firebird(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { @@ -125,8 +124,6 @@ void service_firebird(char *ip, int32_t sp, unsigned char options, char *miscptr */ next_run = start_firebird(sock, ip, port, options, miscptr, fp); - if ((next_run == 1 || next_run == 2) && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: diff --git a/hydra-ftp.c b/hydra-ftp.c index c6e256c..590d671 100644 --- a/hydra-ftp.c +++ b/hydra-ftp.c @@ -26,10 +26,8 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char if (verbose) printf("[INFO] user %s does not exist, skipping\n", login); hydra_completed_pair_skip(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { - free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 4; - } free(buf); return 1; } @@ -37,10 +35,8 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char if (buf[0] == '2') { hydra_report_found_host(port, ip, "ftp", fp); hydra_completed_pair_found(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { - free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 4; - } free(buf); return 1; } @@ -65,10 +61,8 @@ int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char if (buf[0] == '2') { hydra_report_found_host(port, ip, "ftp", fp); hydra_completed_pair_found(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { - free(buf); + if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 4; - } free(buf); return 1; } diff --git a/hydra-gtk/configure b/hydra-gtk/configure index 6cd3de7..653ba7d 100755 --- a/hydra-gtk/configure +++ b/hydra-gtk/configure @@ -2391,7 +2391,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - '#include ' \ + '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -3192,7 +3192,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - '#include ' \ + '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -3797,8 +3797,8 @@ main () for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) - return 2; - return 0; + exit(2); + exit (0); } _ACEOF rm -f conftest$ac_exeext diff --git a/hydra-http-form.c b/hydra-http-form.c old mode 100755 new mode 100644 index 7de90e3..a864088 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -20,23 +20,33 @@ Here's a couple of examples: - ./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 ":" separated values: -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 ZAP) with the varying usernames and passwords in the "^USER^" and -"^PASS^" placeholders. -The third + are optional parameters like C=, H= etc. (see below) -The final(!) parameter is the string that it checks for an *invalid* or *valid* -login +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 (F=), -so checking for an *invalid* login string. +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 debug flag (-d) it will show you the response from the +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. This should be done together with -t 1. +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 */ @@ -66,8 +76,6 @@ int32_t success_cond = 0; int32_t getcookie = 1; int32_t auth_flag = 0; int32_t code_302_is_success = 0; -int32_t code_401_is_failure = 0; -int32_t multipart_mode = 0; char cookie[4096] = "", cmiscptr[1024]; @@ -316,15 +324,10 @@ void hdrrep(ptr_header_node *ptr_head, char *oldvalue, char *newvalue) { 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)) { - size_t oldlen = strlen(oldvalue); - size_t newlen = strlen(newvalue); - if (oldlen != newlen) - cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(cur_ptr->value) - oldlen + newlen + 1); - if (cur_ptr->value) { - char *p = strstr(cur_ptr->value, oldvalue); - memmove(p + newlen, p + oldlen, strlen(p + oldlen) + 1); - memcpy(p, newvalue, newlen); - } else { + cur_ptr->value = (char *)realloc(cur_ptr->value, strlen(newvalue) + 1); + if (cur_ptr->value) + strcpy(cur_ptr->value, newvalue); + else { hydra_report(stderr, "[ERROR] Out of memory (hddrep).\n"); hydra_child_exit(0); } @@ -391,7 +394,7 @@ char *stringify_headers(ptr_header_node *ptr_head) { } int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { - char *ptr, *ptr2, *tmp; + char *ptr, *ptr2; if (miscptr == NULL) return 1; @@ -439,26 +442,9 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { sprintf(cookieurl, "%.1000s", hydra_strrep(miscptr + 2, "\\:", ":")); miscptr = ptr; break; - case '1': - code_401_is_failure = 1; - tmp = strchr(miscptr, ':'); - if (tmp) - miscptr = tmp + 1; - else - miscptr += strlen(miscptr); - break; case '2': code_302_is_success = 1; - tmp = strchr(miscptr, ':'); - if (tmp) - miscptr = tmp + 1; - else - miscptr += strlen(miscptr); - break; - case 'm': // fall through - case 'M': - multipart_mode = 1; - tmp = strchr(miscptr, ':'); + char *tmp = strchr(miscptr, ':'); if (tmp) miscptr = tmp + 1; else @@ -542,97 +528,6 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { return 1; } -char *build_multipart_body(char *multipart_boundary) { - if (!variables) - return NULL; - - char *body = NULL; - size_t body_size = 0; - - // Duplicate "variables" for tokenizing - char *vars_dup = strdup(variables); - if (!vars_dup) - return NULL; - - // Tokenize the string using '&' as a delimiter - char *pair = strtok(vars_dup, "&"); - while (pair != NULL) { - // Find the '=' separator in each pair - char *equal_sign = strchr(pair, '='); - if (!equal_sign) { - pair = strtok(NULL, "&"); - continue; - } - *equal_sign = '\0'; - char *key = pair; - char *value = equal_sign + 1; - - // Build the multipart section for the field - int section_len = snprintf(NULL, 0, - "--%s\r\n" - "Content-Disposition: form-data; name=\"%s\"\r\n" - "\r\n" - "%s\r\n", - multipart_boundary, key, value); - - char *section = malloc(section_len + 1); - if (!section) { - free(body); - free(vars_dup); - return NULL; - } - snprintf(section, section_len + 1, - "--%s\r\n" - "Content-Disposition: form-data; name=\"%s\"\r\n" - "\r\n" - "%s\r\n", - multipart_boundary, key, value); - - // Reallocate the body buffer to add this section - size_t new_body_size = body_size + section_len; - char *new_body = realloc(body, new_body_size + 1); // +1 for null terminator - if (!new_body) { - free(section); - free(body); - free(vars_dup); - return NULL; - } - body = new_body; - if (body_size == 0) - strcpy(body, section); - else - strcat(body, section); - body_size = new_body_size; - free(section); - - pair = strtok(NULL, "&"); - } - free(vars_dup); - - // Append the closing boundary: ----\r\n - int closing_len = snprintf(NULL, 0, "--%s--\r\n", multipart_boundary); - char *closing = malloc(closing_len + 1); - if (!closing) { - free(body); - return NULL; - } - snprintf(closing, closing_len + 1, "--%s--\r\n", multipart_boundary); - - size_t final_size = body_size + closing_len; - char *final_body = realloc(body, final_size + 1); - if (!final_body) { - free(closing); - free(body); - return NULL; - } - body = final_body; - strcat(body, closing); - free(closing); - - return body; -} - - char *prepare_http_request(char *type, char *path, char *params, char *headers) { uint32_t reqlen = 0; char *http_request = NULL; @@ -773,7 +668,7 @@ int32_t analyze_server_response(int32_t s) { 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 + // ones before if (ptr != cookie && *(ptr - 1) == ' ') { strncpy(tmpcookie, cookie, ptr - cookie - 2); tmpcookie[ptr - cookie - 2] = 0; @@ -841,7 +736,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options char *http_request = NULL; int32_t found = !success_cond, i, j; char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; - char content_type[256]; + memset(header, 0, sizeof(header)); cookie[0] = 0; // reset cookies from potential previous attempt @@ -861,23 +756,10 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options clogin[sizeof(clogin) - 1] = 0; strncpy(cpass, html_encode(pass), sizeof(cpass) - 1); cpass[sizeof(cpass) - 1] = 0; - - if (multipart_mode) { - snprintf(content_type, sizeof(content_type), "multipart/form-data; boundary=----THC-HydraBoundaryz2Z2z"); - char *multipart_body = build_multipart_body("----THC-HydraBoundaryz2Z2z"); - upd3variables = multipart_body; - -}else{ - snprintf(content_type, sizeof(content_type), "application/x-www-form-urlencoded"); - upd3variables = variables; -} - - upd3variables = hydra_strrep(upd3variables, "^USER^", clogin); - upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); - upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login); - upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass); - - + upd3variables = hydra_strrep(variables, "^USER^", clogin); + upd3variables = hydra_strrep(upd3variables, "^PASS^", cpass); + upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login); + upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass); // Replace the user/pass placeholders in the user-supplied headers hdrrep(&ptr_head, "^USER^", clogin); @@ -889,7 +771,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) { if (getcookie) { memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); @@ -903,14 +785,14 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char 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%.600s", webtarget, url); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)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", content_type, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); if (cookie_header != NULL) free(cookie_header); cookie_header = stringify_cookies(ptr_cookie); @@ -924,10 +806,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } else { if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -944,10 +824,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } } else { if (use_proxy == 1) { @@ -955,7 +833,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (getcookie) { // doing a GET to get cookies memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, cookieurl); if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); @@ -969,14 +847,14 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char 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%.600s", webtarget, url); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, url); snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)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", content_type, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); if (cookie_header != NULL) free(cookie_header); cookie_header = stringify_cookies(ptr_cookie); @@ -990,10 +868,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } else { if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -1010,10 +886,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } } else { // direct web server, no proxy @@ -1043,7 +917,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options 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", content_type, HEADER_TYPE_DEFAULT); + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); if (cookie_header != NULL) free(cookie_header); cookie_header = stringify_cookies(ptr_cookie); @@ -1057,10 +931,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("POST", url, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } else { if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) hdrrepv(&ptr_head, "Content-Length", "0"); @@ -1077,10 +949,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (http_request != NULL) free(http_request); http_request = prepare_http_request("GET", url, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } } } } @@ -1094,17 +964,12 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options found = success_cond; } - if (auth_flag) { // we received a 401 error - user may be using wrong module - if (code_401_is_failure) { // apparently they don't think so -- treat 401 as failure - hydra_completed_pair(); - return 1; - } else { - hydra_report(stderr, - "[ERROR] received HTTP error code 401. The target may be using HTTP auth, " - "not a web form. Use module \"http%s-get\" instead, or set \"1=\".\n", - (options & OPTION_SSL) > 0 ? "s" : ""); - return 2; - } + if (auth_flag) { // we received a 401 error - user is 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 2; } if (strlen(cookie) > 0) @@ -1217,7 +1082,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options // proxy with authentication hdrrepv(&ptr_head, "Host", str2); memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); if (normal_request != NULL) free(normal_request); normal_request = stringify_headers(&ptr_head); @@ -1229,7 +1094,7 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options // proxy without authentication hdrrepv(&ptr_head, "Host", str2); memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s:%d%.600s", webtarget, webport, str3); if (normal_request != NULL) free(normal_request); normal_request = stringify_headers(&ptr_head); @@ -1250,10 +1115,8 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options hydra_reconnect(s, ip, port, options, hostname); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - } found = analyze_server_response(s); if (strlen(cookie) > 0) @@ -1571,29 +1434,28 @@ void usage_http_form(const char *service) { "redirections in\n" "a row. It always gathers a new cookie from the same URL without " "variables\n" - "The parameters requires at a minimum three \":\" separated values,\n" - "plus optional values.\n" + "The parameters take three \":\" separated values, plus optional " + "values.\n" "(Note: if you need a colon in the option string as value, escape it " "with \"\\:\", but do not escape a \"\\\" with \"\\\\\".)\n" - "\nSyntax: :
[:[:]:\n" - "\nFirst is the page on the server to GET or POST to (URL), e.g. \"/login\".\n" - "Second is the POST/GET variables (taken from either the browser, proxy, etc.)\n" - " without the initial '?' character and the usernames and passwords being\n" - " replaced with \"^USER^\" (\"^USER64^\" for base64 encodings) and \"^PASS^\"\n" - " (\"^PASS64^\" for base64 encodings).\n" - "Third are optional parameters (see below)\n" - "Last is the string that it checks for an *invalid* login (by default).\n" - " Invalid condition login check can be preceded by \"F=\", successful condition\n" + "\nSyntax: ::[:[:]\n" + "First is the page on the server to GET or POST to (URL).\n" + "Second is the POST/GET variables (taken from either the browser, proxy, " + "etc.\n" + " with url-encoded (resp. base64-encoded) usernames and passwords being " + "replaced in the\n" + " \"^USER^\" (resp. \"^USER64^\") and \"^PASS^\" (resp. \"^PASS64^\") " + "placeholders (FORM PARAMETERS)\n" + "Third is the string that it checks for an *invalid* login (by default)\n" + " Invalid condition login check can be preceded by \"F=\", successful " + "condition\n" " login check must be preceded by \"S=\".\n" - " This is where most people get it wrong! You have to check the webapp what a\n" - " failed string looks like and put it in this parameter! Add the -d switch to see\n" - " the sent/received data!\n" - " Note that using invalid login condition checks can result in false positives!\n" - "\nThe following parameters are optional and are put between the form parameters\n" - "and the condition string; separate them too with colons:\n" - " 1= 401 error response is interpreted as user/pass wrong\n" + " This is where most people get it wrong. You have to check the webapp " + "what a\n" + " failed string looks like and put it in this parameter! Add the -d switch to see\nthe sent/received data!\n" + "\nThe following parameters are optional:\n" " 2= 302 page forward return codes identify a successful attempt\n" - " M= attack forms that use multipart format\n" " (c|C)=/page/uri to define a different page to gather initial " "cookies from\n" " (g|G)= skip pre-requests - only use this when no pre-cookies are required\n" @@ -1607,29 +1469,24 @@ void usage_http_form(const char *service) { "exists, by the\n" " one supplied by the user, or add the header at the " "end\n" - "\nNote that if you are going to put colons (:) in your headers you should escape\n" - "them with a backslash (\\). All colons that are not option separators should be\n" - "escaped (see the examples above and below).\n" - "You can specify a header without escaping the colons, but that way you will not\n" - "be able to put colons in the header value itself, as they will be interpreted by\n" - "hydra as option separators.\n" + "\nNote that if you are going to put colons (:) in your headers you should escape them with a backslash (\\).\n" + " All colons that are not option separators should be escaped (see the " + "examples above and below).\n" + " You can specify a header without escaping the colons, but that way you " + "will not be able to put colons\n" + " in the header value itself, as they will be interpreted by hydra as " + "option separators.\n" "\nExamples:\n" " \"/login.php:user=^USER^&pass=^PASS^:incorrect\"\n" " \"/" - "login.php:user=^USER64^&pass=^PASS64^&colon=colon\\:escape:S=result=" + "login.php:user=^USER64^&pass=^PASS64^&colon=colon\\:escape:S=authlog=.*" "success\"\n" " \"/login.php:user=^USER^&pass=^PASS^&mid=123:authlog=.*failed\"\n" - " \"/:user=^USER&pass=^PASS^:H=Authorization\\: Basic " + " \"/:user=^USER&pass=^PASS^:failed:H=Authorization\\: Basic " "dT1w:H=Cookie\\: sessid=aaaa:h=X-User\\: ^USER^:H=User-Agent\\: wget\"\n" - " \"/exchweb/bin/auth/:F=failed" + " \"/exchweb/bin/auth/" "owaauth.dll:destination=http%%3A%%2F%%2F%%2Fexchange&flags=0&" "username=%%5C^USER^&password=^PASS^&SubmitCreds=x&trusted=0:" - "C=/exchweb\":reason=\n" - "To attack multiple targets, you can use the -M option with a file " - "containing the targets and their parameters.\n" - "Example file content:\n" - " localhost:8443/login:type=login&login=^USER^&password=^PASS^:h=test\\: header:F=401\n" - " localhost:9443/login2:type=login&login=^USER^&password=^PASS^:h=test\\: header:F=302\n" - " ...\n\n", + "reason=:C=/exchweb\"\n", service); } diff --git a/hydra-http.c b/hydra-http.c old mode 100755 new mode 100644 index e78f865..c76b937 --- a/hydra-http.c +++ b/hydra-http.c @@ -451,7 +451,7 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis start--; memset(start, '\0', condition_len); if (debug) - hydra_report(stderr, "Modified options:%s\n", miscptr); + hydra_report(stderr, "Modificated options:%s\n", miscptr); } else { if (debug) hydra_report(stderr, "Condition not found\n"); @@ -474,12 +474,6 @@ void usage_http(const char *service) { " combination is invalid. Note: this must be the last option " "supplied.\n" "For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: " - "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n" - "To attack multiple targets, you can use the -M option with a file " - "containing the targets and their parameters.\n" - "Example file content:\n" - " localhost:5000/protected:A=BASIC\n" - " localhost:5002/protected_path:A=NTLM\n" - " ...\n\n", + "sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n", service); } diff --git a/hydra-memcached.c b/hydra-memcached.c index 5a7c112..ca21d26 100644 --- a/hydra-memcached.c +++ b/hydra-memcached.c @@ -13,7 +13,6 @@ void dummy_mcached() { printf("\n"); } extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); -extern hydra_option hydra_options; extern char *HYDRA_EXIT; int mcached_send_com_quit(int32_t sock) { @@ -118,8 +117,6 @@ void service_mcached(char *ip, int32_t sp, unsigned char options, char *miscptr, switch (run) { case 1: next_run = start_mcached(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 2: hydra_child_exit(0); diff --git a/hydra-mod.c b/hydra-mod.c index c988c1d..a24889b 100644 --- a/hydra-mod.c +++ b/hydra-mod.c @@ -662,10 +662,10 @@ char *hydra_get_next_pair() { pair[sizeof(pair) - 1] = 0; __fck = read(intern_socket, pair, sizeof(pair) - 1); // if (debug) hydra_dump_data(pair, __fck, "CHILD READ PAIR"); - if (pair[0] == 0 || __fck <= 0) - return HYDRA_EMPTY; - if (__fck >= sizeof(HYDRA_EXIT) && memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0) + if (memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0) return HYDRA_EXIT; + if (pair[0] == 0) + return HYDRA_EMPTY; } return pair; } diff --git a/hydra-mongodb.c b/hydra-mongodb.c index 66269be..201c3ff 100644 --- a/hydra-mongodb.c +++ b/hydra-mongodb.c @@ -14,7 +14,6 @@ void dummy_mongodb() { printf("\n"); } extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); -extern hydra_option hydra_options; extern char *HYDRA_EXIT; char *buf; @@ -73,17 +72,10 @@ int32_t start_mongodb(int32_t s, char *ip, int32_t port, unsigned char options, mongoc_log_set_handler(NULL, NULL); bson_init(&q); - if (login[0] == '\0' && pass[0] == '\0') { - snprintf(uri, sizeof(uri), "mongodb://%s:%d/?authSource=%s", hydra_address2string(ip), port, miscptr); - } else { - snprintf(uri, sizeof(uri), "mongodb://%s:%s@%s:%d/?authSource=%s", login, pass, hydra_address2string(ip), port, miscptr); - } - + snprintf(uri, sizeof(uri), "mongodb://%s:%s@%s:%d/?authSource=%s", login, pass, hydra_address2string(ip), port, miscptr); client = mongoc_client_new(uri); - if (!client) { - hydra_completed_pair_skip(); + if (!client) return 3; - } mongoc_client_set_appname(client, "hydra"); collection = mongoc_client_get_collection(client, miscptr, "test"); @@ -98,11 +90,11 @@ int32_t start_mongodb(int32_t s, char *ip, int32_t port, unsigned char options, mongoc_collection_destroy(collection); mongoc_client_destroy(client); mongoc_cleanup(); - hydra_completed_pair(); + hydra_completed_pair_skip(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { return 3; } - return 1; + return 2; } } @@ -137,8 +129,6 @@ void service_mongodb(char *ip, int32_t sp, unsigned char options, char *miscptr, switch (run) { case 1: next_run = start_mongodb(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 2: hydra_child_exit(0); diff --git a/hydra-mssql.c b/hydra-mssql.c index 1133641..ee273ca 100644 --- a/hydra-mssql.c +++ b/hydra-mssql.c @@ -1,14 +1,10 @@ #include "hydra-mod.h" -extern char *HYDRA_EXIT; -char *buf; - -#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB) -#include -#include -#endif #define MSLEN 30 +extern char *HYDRA_EXIT; +char *buf; + unsigned char p_hdr[] = "\x02\x00\x02\x00\x00\x00\x02\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" @@ -60,7 +56,6 @@ unsigned char p_lng[] = "\x02\x01\x00\x47\x00\x00\x02\x00\x00\x00\x00" int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { char *empty = ""; char *login, *pass, buffer[1024]; - char *ipaddr_str = hydra_address2string(ip); char ms_login[MSLEN + 1]; char ms_pass[MSLEN + 1]; unsigned char len_login, len_pass; @@ -70,42 +65,6 @@ int32_t start_mssql(int32_t s, char *ip, int32_t port, unsigned char options, ch login = empty; if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; -#if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB) - if ((strlen(login) > MSLEN) || (strlen(pass) > MSLEN)){ - - DBPROCESS *dbproc; - LOGINREC *attempt; - - attempt = dblogin(); - - DBSETLUSER(attempt, login); - DBSETLPWD(attempt, pass); - - // Connect without specifying a database - dbproc = dbopen(attempt, ipaddr_str); - - if (dbproc != NULL) { - dbclose(dbproc); - dbexit(); - hydra_report_found_host(port, ip, "mssql", fp); - hydra_completed_pair_found(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 2; - return 1; - } - - hydra_completed_pair(); - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) - return 2; - - return 1; - - } -#else - if ((strlen(login) > MSLEN) || (strlen(pass) > MSLEN)){ - fprintf(stderr,"[WARNING] To crack credentials longer than 30 characters, install freetds and recompile\n"); - } -#endif if (strlen(login) > MSLEN) login[MSLEN - 1] = 0; if (strlen(pass) > MSLEN) @@ -160,10 +119,6 @@ void service_mssql(char *ip, int32_t sp, unsigned char options, char *miscptr, F int32_t run = 1, next_run = 1, sock = -1; int32_t myport = PORT_MSSQL, mysslport = PORT_MSSQL_SSL; - #if defined(HAVE_SYBFRONT) && defined(HAVE_SYBDB) - dbinit(); - #endif - hydra_register_socket(sp); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return; diff --git a/hydra-mysql.c b/hydra-mysql.c index 01a258e..eae5fd9 100644 --- a/hydra-mysql.c +++ b/hydra-mysql.c @@ -35,7 +35,6 @@ char *hydra_scramble(char *to, const char *message, const char *password); extern int32_t internal__hydra_recv(int32_t socket, char *buf, int32_t length); extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); -extern hydra_option hydra_options; extern char *HYDRA_EXIT; char mysqlsalt[9]; @@ -333,8 +332,6 @@ void service_mysql(char *ip, int32_t sp, unsigned char options, char *miscptr, F break; case 2: /* run the cracking function */ next_run = start_mysql(sock, ip, port, options, miscptr, fp); - if ((next_run == 1 || next_run == 2) && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) { diff --git a/hydra-oracle-listener.c b/hydra-oracle-listener.c index 563670b..e6b77ec 100644 --- a/hydra-oracle-listener.c +++ b/hydra-oracle-listener.c @@ -19,7 +19,6 @@ void dummy_oracle_listener() { printf("\n"); } #include #define HASHSIZE 17 -extern hydra_option hydra_options; extern char *HYDRA_EXIT; char *buf; unsigned char *hash; @@ -305,8 +304,6 @@ void service_oracle_listener(char *ip, int32_t sp, unsigned char options, char * } /* run the cracking function */ next_run = start_oracle_listener(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) diff --git a/hydra-oracle-sid.c b/hydra-oracle-sid.c index 32ac557..c2db73a 100644 --- a/hydra-oracle-sid.c +++ b/hydra-oracle-sid.c @@ -16,7 +16,6 @@ void dummy_oracle_sid() { printf("\n"); } #include #define HASHSIZE 16 -extern hydra_option hydra_options; extern char *HYDRA_EXIT; char *buf; unsigned char *hash; @@ -114,8 +113,6 @@ void service_oracle_sid(char *ip, int32_t sp, unsigned char options, char *miscp } /* run the cracking function */ next_run = start_oracle_sid(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) diff --git a/hydra-oracle.c b/hydra-oracle.c index 2ae18de..46deb44 100644 --- a/hydra-oracle.c +++ b/hydra-oracle.c @@ -21,7 +21,6 @@ void dummy_oracle() { printf("\n"); } #include #include -extern hydra_option hydra_options; extern char *HYDRA_EXIT; OCIEnv *o_environment; @@ -166,8 +165,6 @@ void service_oracle(char *ip, int32_t sp, unsigned char options, char *miscptr, break; case 2: next_run = start_oracle(sock, ip, port, options, miscptr, fp); - if ((next_run == 1 || next_run == 2) && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: /* clean exit */ if (sock >= 0) diff --git a/hydra-pop3.c b/hydra-pop3.c index 3671a95..acd6c2e 100644 --- a/hydra-pop3.c +++ b/hydra-pop3.c @@ -109,7 +109,7 @@ char *pop3_read_server_capacity(int32_t sock) { buf[strlen(buf) - 1] = 0; if (buf[strlen(buf) - 1] == '\r') buf[strlen(buf) - 1] = 0; - if (buf[strlen(buf) - 1] == '.' || *(ptr) == '.' || *(ptr) == '-') + if (*(ptr) == '.' || *(ptr) == '-') resp = 1; } } diff --git a/hydra-postgres.c b/hydra-postgres.c index 3b2cac9..7f958f7 100644 --- a/hydra-postgres.c +++ b/hydra-postgres.c @@ -16,7 +16,6 @@ void dummy_postgres() { printf("\n"); } #define DEFAULT_DB "template1" -extern hydra_option hydra_options; extern char *HYDRA_EXIT; int32_t start_postgres(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { @@ -41,7 +40,7 @@ int32_t start_postgres(int32_t s, char *ip, int32_t port, unsigned char options, * Building the connection string */ - snprintf(connection_string, sizeof(connection_string), "host = '%s' port = '%d' dbname = '%s' user = '%s' password = '%s' ", hydra_address2string(ip), port, database, login, pass); + snprintf(connection_string, sizeof(connection_string), "host = '%s' dbname = '%s' user = '%s' password = '%s' ", hydra_address2string(ip), database, login, pass); if (verbose) hydra_report(stderr, "connection string: %s\n", connection_string); @@ -100,8 +99,6 @@ void service_postgres(char *ip, int32_t sp, unsigned char options, char *miscptr * Here we start the password cracking process */ next_run = start_postgres(sock, ip, port, options, miscptr, fp); - if ((next_run == 2 || next_run == 1) && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: if (sock >= 0) diff --git a/hydra-rdp.c b/hydra-rdp.c index 0b3c690..b33c87d 100644 --- a/hydra-rdp.c +++ b/hydra-rdp.c @@ -9,37 +9,27 @@ #include "hydra-mod.h" -extern hydra_option hydra_options; extern char *HYDRA_EXIT; #ifndef LIBFREERDP void dummy_rdp() { printf("\n"); } #else #include -#include freerdp *instance = 0; BOOL rdp_connect(char *server, int32_t port, char *domain, char *login, char *password) { int32_t err = 0; - rdpSettings* settings = instance->context->settings; - - settings->Username = login; - settings->Password = password; - settings->IgnoreCertificate = TRUE; + instance->settings->Username = login; + instance->settings->Password = password; + instance->settings->IgnoreCertificate = TRUE; if (password[0] == 0) - settings->AuthenticationOnly = FALSE; + instance->settings->AuthenticationOnly = FALSE; else - settings->AuthenticationOnly = TRUE; - settings->ServerHostname = server; - settings->ServerPort = port; - settings->Domain = domain; - -#if FREERDP_VERSION_MAJOR == 2 - settings->MaxTimeInCheckLoop = 100; -#endif - // freerdp timeout format is microseconds -> default:15000 - settings->TcpConnectTimeout = hydra_options.waittime * 1000; - settings->TlsSecLevel = 0; + instance->settings->AuthenticationOnly = TRUE; + instance->settings->ServerHostname = server; + instance->settings->ServerPort = port; + instance->settings->Domain = domain; + instance->settings->MaxTimeInCheckLoop = 100; freerdp_connect(instance); err = freerdp_get_last_error(instance->context); return err; @@ -82,10 +72,6 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr, // login failure hydra_completed_pair(); break; - case 0x0002000f: - // login failure - hydra_completed_pair_skip(); - break; case 0x0002000d: hydra_report(stderr, "[%d][rdp] account on %s might be valid but account not " @@ -114,7 +100,6 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr, void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { int32_t run = 1, next_run = 1; int32_t myport = PORT_RDP; - int32_t __first_rdp_connect = 1; if (port != 0) myport = port; @@ -126,13 +111,7 @@ void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL next_run = 0; switch (run) { case 1: /* run the cracking function */ - if (__first_rdp_connect != 0) - __first_rdp_connect = 0; - else - sleep(hydra_options.conwait); next_run = start_rdp(ip, myport, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 2: /* clean exit */ freerdp_disconnect(instance); diff --git a/hydra-redis.c b/hydra-redis.c index 5a81cec..179007c 100644 --- a/hydra-redis.c +++ b/hydra-redis.c @@ -24,11 +24,6 @@ int32_t start_redis(int32_t s, char *ip, int32_t port, unsigned char options, ch return 1; } buf = hydra_receive_line(s); - if (buf == NULL) { - hydra_report(stderr, "[ERROR] Failed to receive response from Redis server.\n"); - return 3; - } - if (buf[0] == '+') { hydra_report_found_host(port, ip, "redis", fp); hydra_completed_pair_found(); diff --git a/hydra-rtsp.c b/hydra-rtsp.c index 5526f9b..3b6e84b 100644 --- a/hydra-rtsp.c +++ b/hydra-rtsp.c @@ -6,13 +6,10 @@ // // -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - #include "hydra-mod.h" #include "sasl.h" #include +#define _GNU_SOURCE #include extern char *HYDRA_EXIT; diff --git a/hydra-sapr3.c b/hydra-sapr3.c index 76ce7b7..26024da 100644 --- a/hydra-sapr3.c +++ b/hydra-sapr3.c @@ -14,7 +14,6 @@ const int32_t *__ctype_b; extern void flood(); /* for -lm */ -extern hydra_option hydra_options; extern char *HYDRA_EXIT; RFC_ERROR_INFO_EX error_info; @@ -100,8 +99,6 @@ void service_sapr3(char *ip, int32_t sp, unsigned char options, char *miscptr, F switch (run) { case 1: /* connect and service init function */ next_run = start_sapr3(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 2: hydra_child_exit(0); diff --git a/hydra-smb.c b/hydra-smb.c index 0db54da..6fc5bbd 100644 --- a/hydra-smb.c +++ b/hydra-smb.c @@ -1280,8 +1280,8 @@ int32_t start_smb(int32_t s, char *ip, int32_t port, unsigned char options, char } else if (SMBerr == 0x000193) { /* Valid password, account expired */ hydra_report(stdout, "[%d][smb] Host: %s Account: %s Valid password, account expired\n", port, ipaddr_str, login); hydra_report_found_host(port, ip, "smb", fp); - hydra_completed_pair_skip(); - } else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, password expired */ + hydra_completed_pair_found(); + } else if ((SMBerr == 0x000224) || (SMBerr == 0xC20002)) { /* Valid password, account expired */ hydra_report(stdout, "[%d][smb] Host: %s Account: %s Valid password, password " "expired and must be changed on next logon\n", @@ -1304,13 +1304,14 @@ int32_t start_smb(int32_t s, char *ip, int32_t port, unsigned char options, char hydra_report(stderr, "[INFO] LM dialect may be disabled, try LMV2 instead\n"); hydra_completed_pair_skip(); } else if (SMBerr == 0x000024) { /* change password on next login [success] */ - hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login); + hydra_report(stdout, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login); hydra_completed_pair_found(); } else if (SMBerr == 0x00006D) { /* STATUS_LOGON_FAILURE */ hydra_completed_pair(); } else if (SMBerr == 0x000071) { /* password expired */ - hydra_report(stdout, "[%d][smb] Host: %s Account: %s Information: PASSWORD EXPIRED\n", port, ipaddr_str, login); - hydra_completed_pair_found(); + if (verbose) + fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: PASSWORD EXPIRED\n", port, ipaddr_str, login); + hydra_completed_pair_skip(); } else if ((SMBerr == 0x000072) || (SMBerr == 0xBF0002)) { /* account disabled */ /* BF0002 on w2k */ if (verbose) fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_DISABLED\n", port, ipaddr_str, login); diff --git a/hydra-smb2.c b/hydra-smb2.c index d1d220d..275bbae 100644 --- a/hydra-smb2.c +++ b/hydra-smb2.c @@ -27,7 +27,6 @@ #include #include -extern hydra_option hydra_options; extern char *HYDRA_EXIT; typedef struct creds { @@ -127,11 +126,6 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) { */ switch (errno) { - case 0: - // maybe false positive? unclear ... :( ... needs more testing - smbc_free_context(ctx, 1); - return true; - break; case ENOENT: // Noticed this when connecting to older samba servers on linux // where any credentials are accepted. @@ -174,15 +168,10 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) { } void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { - static int first_run = 0; hydra_register_socket(sp); - while (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT))) { char *login, *pass; - if (first_run && hydra_options.conwait) - sleep(hydra_options.conwait); - login = hydra_get_next_login(); pass = hydra_get_next_password(); @@ -197,8 +186,6 @@ void service_smb2(char *ip, int32_t sp, unsigned char options, char *miscptr, FI } else { hydra_completed_pair(); } - - first_run = 1; } EXIT_NORMAL; } diff --git a/hydra-smtp.c b/hydra-smtp.c index 97d5b72..dc6e54a 100644 --- a/hydra-smtp.c +++ b/hydra-smtp.c @@ -61,10 +61,6 @@ int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, cha return 1; if (strstr(buf, "334") == NULL) { hydra_report(stderr, "[ERROR] SMTP PLAIN AUTH : %s\n", buf); - if (strstr(buf, "503") != NULL) { - free(buf); - return 4; - } free(buf); return 3; } @@ -442,12 +438,6 @@ void service_smtp(char *ip, int32_t sp, unsigned char options, char *miscptr, FI } hydra_child_exit(0); return; - case 4: /* error exit */ - if (sock >= 0) { - sock = hydra_disconnect(sock); - } - hydra_child_exit(3); - return; default: hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); hydra_child_exit(0); diff --git a/hydra-ssh.c b/hydra-ssh.c index 6ccae4e..785ae1e 100644 --- a/hydra-ssh.c +++ b/hydra-ssh.c @@ -47,9 +47,6 @@ int32_t start_ssh(int32_t s, char *ip, int32_t port, unsigned char options, char ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &hydra_options.waittime); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none"); - // might be better to add the legacy (first two for KEX and HOST) to the default instead of specifying the full list - ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256"); - ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256"); if (ssh_connect(session) != 0) { // if the connection was drop, exit and let hydra main handle it if (verbose) @@ -122,8 +119,6 @@ void service_ssh(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL switch (run) { case 1: /* connect and service init function */ next_run = start_ssh(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 2: ssh_disconnect(session); @@ -195,9 +190,6 @@ int32_t service_ssh_init(char *ip, int32_t sp, unsigned char options, char *misc ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &hydra_options.waittime); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none"); - // might be better to add the legacy (first two for KEX and HOST) to the default instead of specifying the full list - ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256"); - ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256"); if (ssh_connect(session) != 0) { fprintf(stderr, "[ERROR] could not connect to ssh://%s:%d - %s\n", hydra_address2string_beautiful(ip), port, ssh_get_error(session)); return 2; diff --git a/hydra-sshkey.c b/hydra-sshkey.c index cac66e0..092d655 100644 --- a/hydra-sshkey.c +++ b/hydra-sshkey.c @@ -16,7 +16,6 @@ void dummy_sshkey() { printf("\n"); } #if LIBSSH_VERSION_MAJOR >= 0 && LIBSSH_VERSION_MINOR >= 4 extern ssh_session session; -extern hydra_option hydra_options; extern char *HYDRA_EXIT; extern int32_t new_session; @@ -118,8 +117,6 @@ void service_sshkey(char *ip, int32_t sp, unsigned char options, char *miscptr, switch (run) { case 1: /* connect and service init function */ next_run = start_sshkey(sock, ip, port, options, miscptr, fp); - if (next_run == 1 && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 2: ssh_disconnect(session); diff --git a/hydra-svn.c b/hydra-svn.c index 0664924..063f12c 100644 --- a/hydra-svn.c +++ b/hydra-svn.c @@ -4,9 +4,7 @@ #ifdef LIBSVN /* needed on openSUSE */ -#ifndef _GNU_SOURCE #define _GNU_SOURCE -#endif #if !defined PATH_MAX && defined HAVE_SYS_PARAM_H #include @@ -32,7 +30,6 @@ void dummy_svn() { printf("\n"); } extern int32_t hydra_data_ready_timed(int32_t socket, long sec, long usec); -extern hydra_option hydra_options; extern char *HYDRA_EXIT; #define DEFAULT_BRANCH "trunk" @@ -198,8 +195,6 @@ void service_svn(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL break; case 2: next_run = start_svn(sock, ip, port, options, miscptr, fp); - if ((next_run == 1 || next_run == 2) && hydra_options.conwait) - sleep(hydra_options.conwait); break; case 3: if (sock >= 0) diff --git a/hydra.1 b/hydra.1 index b9cb7a5..81b2feb 100644 --- a/hydra.1 +++ b/hydra.1 @@ -1,4 +1,4 @@ -.TH "HYDRA" "1" "01/01/2023" +.TH "HYDRA" "1" "01/01/2022" .SH NAME hydra \- a very fast network logon cracker which supports many different services .SH SYNOPSIS diff --git a/hydra.c b/hydra.c index 416cf25..12772bb 100644 --- a/hydra.c +++ b/hydra.c @@ -1,5 +1,5 @@ /* - * hydra (c) 2001-2023 by van Hauser / THC + * hydra (c) 2001-2022 by van Hauser / THC * https://github.com/vanhauser-thc/thc-hydra * * Parallized network login hacker. @@ -228,7 +228,7 @@ char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cobaltstrike cvs fire #define RESTOREFILE "./hydra.restore" #define PROGRAM "Hydra" -#define VERSION "v9.6dev" +#define VERSION "v9.4" #define AUTHOR "van Hauser/THC" #define EMAIL "" #define AUTHOR2 "David Maciejak" @@ -267,7 +267,6 @@ typedef struct { typedef struct { char *target; - char *miscptr; char ip[36]; char *login_ptr; char *pass_ptr; @@ -344,11 +343,6 @@ int32_t prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed int32_t child_head_no = -1, child_socket; int32_t total_redo_count = 0; -// requred for distributed attack capability -uint32_t num_segments = 0; -uint32_t my_segment = 0; -char junk_file[50]; - // moved for restore feature int32_t process_restore = 0, dont_unlink; char *login_ptr = NULL, *pass_ptr = "", *csv_ptr = NULL, *servers_ptr = NULL; @@ -394,7 +388,7 @@ static const struct { {"http-get-form", service_http_form_init, service_http_get_form, usage_http_form}, {"http-head", service_http_init, service_http_head, NULL}, {"http-form", service_http_form_init, NULL, usage_http_form}, - {"http-post", service_http_init, service_http_post, usage_http}, + {"http-post", NULL, service_http_post, usage_http}, {"http-post-form", service_http_form_init, service_http_post_form, usage_http_form}, SERVICE3("http-proxy", http_proxy), SERVICE3("http-proxy-urlenum", http_proxy_urlenum), @@ -525,8 +519,6 @@ void help(int32_t ext) { "instead of -L/-P options\n" " -M FILE list of servers to attack, one entry per " "line, ':' to specify port\n"); - PRINT_NORMAL(ext, " -D XofY Divide wordlist into Y segments and use the " - "Xth segment.\n"); PRINT_EXTEND(ext, " -o FILE write found login/password pairs to FILE instead of stdout\n" " -b FORMAT specify the format for the -o FILE: text(default), json, " "jsonv1\n" @@ -1182,12 +1174,13 @@ void hydra_service_init(int32_t target_no) { int32_t x = 99; int32_t i; hydra_target *t = hydra_targets[target_no]; + char *miscptr = hydra_options.miscptr; FILE *ofp = hydra_brains.ofp; for (i = 0; x == 99 && i < sizeof(services) / sizeof(services[0]); i++) { if (strcmp(hydra_options.service, services[i].name) == 0) { if (services[i].init) { - x = services[i].init(t->ip, -1, options, t->miscptr, ofp, t->port, t->target); + x = services[i].init(t->ip, -1, options, miscptr, ofp, t->port, t->target); break; } } @@ -1271,13 +1264,13 @@ int32_t hydra_spawn_head(int32_t head_no, int32_t target_no) { hydra_target *t = hydra_targets[target_no]; int32_t sp = hydra_heads[head_no]->sp[1]; - // char *miscptr = hydra_options.miscptr; + char *miscptr = hydra_options.miscptr; FILE *ofp = hydra_brains.ofp; hydra_target *head_target = hydra_targets[hydra_heads[head_no]->target_no]; for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) { if (strcmp(hydra_options.service, services[i].name) == 0) { if (services[i].exec) { - services[i].exec(t->ip, sp, options, t->miscptr, ofp, t->port, head_target->target); + services[i].exec(t->ip, sp, options, miscptr, ofp, t->port, head_target->target); // just in case a module returns (which it shouldnt) we let it exit // here exit(-1); @@ -1598,73 +1591,6 @@ char *hydra_reverse_login(int32_t head_no, char *login) { return hydra_heads[head_no]->reverse; } -void delete_junk_files(){ - remove(junk_file); -} - -FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ - - if(my_segment > num_segments){ - fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile); - return NULL; - } - - FILE *output_file; - char line[500]; - char output_file_name[50]; - - uint32_t line_number = 0; - - double total_lines = countlines(file,0); - - if(num_segments > total_lines){ - fprintf(stderr, "[ERROR] in option -D XofY, Y must not be greater than the total number of lines in the file to be divided: %s\n", hydra_options.passfile); - return NULL; - } - - double segment_size_double = total_lines / num_segments; - - // round up segment_size_float to integer - uint64_t segment_size = (uint64_t)segment_size_double; - if(segment_size < segment_size_double) - segment_size++; - - uint64_t segment_start = segment_size * (my_segment - 1) + 1; - uint64_t segment_end = segment_size * my_segment; - - - - srand(time(NULL)); - int filetag = rand(); - - sprintf(output_file_name, "segment_%d_%d.txt",filetag, my_segment); - output_file = fopen(output_file_name, "w"); - - if(!output_file){ - fprintf(stderr, "[ERROR] Segment file empty: %s\n", hydra_options.passfile); - return NULL; - } - - strcpy(junk_file, output_file_name); - - atexit(delete_junk_files); - - while(fgets(line, sizeof line, file) != NULL && line_number < segment_end){ - line_number++; - - if(line_number >= segment_start && line_number <= segment_end) - fprintf(output_file, "%s", line); - - } - - rewind(file); - fclose(output_file); - output_file = fopen(output_file_name, "r"); - - return output_file; - - } - int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { // variables moved to save stack snpdone = 0; @@ -2119,7 +2045,7 @@ void process_proxy_line(int32_t type, char *string) { string[strlen(string) - 1] = 0; if (string[strlen(string) - 1] == '\r') string[strlen(string) - 1] = 0; - if (proxy_count >= MAX_PROXY_COUNT) { + if (proxy_count > MAX_PROXY_COUNT) { fprintf(stderr, "[WARNING] maximum amount of proxies loaded, ignoring this entry: %s\n", string); return; } @@ -2245,13 +2171,13 @@ void process_proxy_line(int32_t type, char *string) { int main(int argc, char *argv[]) { char *proxy_string = NULL, *device = NULL, *memcheck; char *outfile_format_tmp; - FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp, *filecloser=NULL; + FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp; size_t countinfile = 1, sizeinfile = 0; uint64_t math2; int32_t i = 0, j = 0, k, error = 0, modusage = 0, ignore_restore = 0, do_switch; int32_t head_no = 0, target_no = 0, exit_condition = 0, readres; time_t starttime, elapsed_status, elapsed_restore, status_print = 59, tmp_time; - char *tmpptr, *tmpptr2, *tmpptr3; + char *tmpptr, *tmpptr2; char rc, buf[MAXBUF]; time_t last_attempt = 0; fd_set fdreadheads; @@ -2260,7 +2186,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in6 *ipv6 = NULL; struct sockaddr_in *ipv4 = NULL; - printf("%s %s (c) 2023 by %s & %s - Please do not use in military or secret " + printf("%s %s (c) 2022 by %s & %s - Please do not use in military or secret " "service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).\n\n", PROGRAM, VERSION, AUTHOR, AUTHOR2); #ifndef LIBAFP @@ -2381,7 +2307,6 @@ int main(int argc, char *argv[]) { hydra_options.loginfile = NULL; hydra_options.pass = NULL; hydra_options.passfile = NULL; - hydra_options.distributed = NULL; hydra_options.tasks = TASKS; hydra_options.max_use = MAXTASKS; hydra_options.outfile_format = FORMAT_PLAIN_TEXT; @@ -2395,18 +2320,8 @@ int main(int argc, char *argv[]) { help(1); if (argc < 2) help(0); - while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:D:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) { + while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) { switch (i) { - case 'D': - hydra_options.distributed = optarg; - if (sscanf(hydra_options.distributed, "%dof%d", &my_segment, &num_segments) != 2) { - fprintf(stderr, "Invalid format. Expected format -D XofY where X and Y are integers.\n"); - exit(EXIT_FAILURE); - } - else{ - fprintf(stdout, "Option \'D\': successfully set X to %d and Y to %d\n", my_segment, num_segments); - } - break; case 'h': help(1); break; @@ -3286,79 +3201,77 @@ int main(int argc, char *argv[]) { bail("Compiled without SSL support, module not available"); #endif } - if (hydra_options.infile_ptr == NULL) { - if (hydra_options.miscptr == NULL) { - fprintf(stderr, "[WARNING] You must supply the web page as an " - "additional option or via -m, default path set to /\n"); - hydra_options.miscptr = malloc(2); - hydra_options.miscptr = "/"; + if (hydra_options.miscptr == NULL) { + fprintf(stderr, "[WARNING] You must supply the web page as an " + "additional option or via -m, default path set to /\n"); + hydra_options.miscptr = malloc(2); + hydra_options.miscptr = "/"; + } + // if (*hydra_options.miscptr != '/' && strstr(hydra_options.miscptr, + // "://") == NULL) + // bail("The web page you supplied must start with a \"/\", \"http://\" + // or \"https://\", e.g. \"/protected/login\""); + if (hydra_options.miscptr[0] != '/') + bail("optional parameter must start with a '/' slash!\n"); + if (getenv("HYDRA_PROXY_HTTP") && getenv("HYDRA_PROXY")) + bail("Found HYDRA_PROXY_HTTP *and* HYDRA_PROXY environment variables - " + "you can use only ONE for the service http-head/http-get!"); + if (getenv("HYDRA_PROXY_HTTP")) { + printf("[INFO] Using HTTP Proxy: %s\n", getenv("HYDRA_PROXY_HTTP")); + use_proxy = 1; + } + if (strstr(hydra_options.miscptr, "\\:") != NULL) { + fprintf(stderr, "[INFORMATION] escape sequence \\: detected in module " + "option, no parameter verification is performed.\n"); + } else { + sprintf(bufferurl, "%.6000s", hydra_options.miscptr); + url = strtok(bufferurl, ":"); + variables = strtok(NULL, ":"); + cond = strtok(NULL, ":"); + optional1 = strtok(NULL, "\n"); + if ((variables == NULL) || (strstr(variables, "^USER^") == NULL && strstr(variables, "^PASS^") == NULL && strstr(variables, "^USER64^") == NULL && strstr(variables, "^PASS64^") == NULL)) { + fprintf(stderr, + "[ERROR] the variables argument needs at least the strings " + "^USER^, ^PASS^, ^USER64^ or ^PASS64^: %s\n", + STR_NULL(variables)); + exit(-1); } - // if (*hydra_options.miscptr != '/' && strstr(hydra_options.miscptr, - // "://") == NULL) - // bail("The web page you supplied must start with a \"/\", \"http://\" - // or \"https://\", e.g. \"/protected/login\""); - if (hydra_options.miscptr[0] != '/') - bail("optional parameter must start with a '/' slash!\n"); - if (getenv("HYDRA_PROXY_HTTP") && getenv("HYDRA_PROXY")) - bail("Found HYDRA_PROXY_HTTP *and* HYDRA_PROXY environment variables - " - "you can use only ONE for the service http-head/http-get!"); - if (getenv("HYDRA_PROXY_HTTP")) { - printf("[INFO] Using HTTP Proxy: %s\n", getenv("HYDRA_PROXY_HTTP")); - use_proxy = 1; + if ((url == NULL) || (cond == NULL)) { + fprintf(stderr, + "[ERROR] Wrong syntax, requires three arguments separated by " + "a colon which may not be null: %s\n", + bufferurl); + exit(-1); } - if (strstr(hydra_options.miscptr, "\\:") != NULL) { - fprintf(stderr, "[INFORMATION] escape sequence \\: detected in module " - "option, no parameter verification is performed.\n"); - } else { - sprintf(bufferurl, "%.6000s", hydra_options.miscptr); - url = strtok(bufferurl, ":"); - variables = strtok(NULL, ":"); - cond = strtok(NULL, ":"); - optional1 = strtok(NULL, "\n"); - if ((variables == NULL) || (strstr(variables, "^USER^") == NULL && strstr(variables, "^PASS^") == NULL && strstr(variables, "^USER64^") == NULL && strstr(variables, "^PASS64^") == NULL)) { - fprintf(stderr, - "[ERROR] the variables argument needs at least the strings " - "^USER^, ^PASS^, ^USER64^ or ^PASS64^: %s\n", - STR_NULL(variables)); + while ((optional1 = strtok(NULL, ":")) != NULL) { + if (optional1[1] != '=' && optional1[1] != ':' && optional1[1] != 0) { + fprintf(stderr, "[ERROR] Wrong syntax of optional argument: %s\n", optional1); exit(-1); } - if ((url == NULL) || (cond == NULL)) { - fprintf(stderr, - "[ERROR] Wrong syntax, requires three arguments separated by " - "a colon which may not be null: %s\n", - bufferurl); - exit(-1); - } - while ((optional1 = strtok(NULL, ":")) != NULL) { - if (optional1[1] != '=' && optional1[1] != ':' && optional1[1] != 0) { - fprintf(stderr, "[ERROR] Wrong syntax of optional argument: %s\n", optional1); + + switch (optional1[0]) { + case 'C': // fall through + case 'c': + if (optional1[1] != '=' || optional1[2] != '/') { + fprintf(stderr, + "[ERROR] Wrong syntax of parameter C, must look like " + "'C=/url/of/page', not http:// etc.: %s\n", + optional1); exit(-1); } - - switch (optional1[0]) { - case 'C': // fall through - case 'c': - if (optional1[1] != '=' || optional1[2] != '/') { - fprintf(stderr, - "[ERROR] Wrong syntax of parameter C, must look like " - "'C=/url/of/page', not http:// etc.: %s\n", - optional1); - exit(-1); - } - break; - case 'H': // fall through - case 'h': - if (optional1[1] != '=' || strtok(NULL, ":") == NULL) { - fprintf(stderr, - "[ERROR] Wrong syntax of parameter H, must look like " - "'H=X-My-Header: MyValue', no http:// : %s\n", - optional1); - exit(-1); - } - break; - default: - fprintf(stderr, "[ERROR] Unknown optional argument: %s\n", optional1); + break; + case 'H': // fall through + case 'h': + if (optional1[1] != '=' || strtok(NULL, ":") == NULL) { + fprintf(stderr, + "[ERROR] Wrong syntax of parameter H, must look like " + "'H=X-My-Header: MyValue', no http:// : %s\n", + optional1); + exit(-1); } + break; + default: + fprintf(stderr, "[ERROR] Unknown optional argument: %s\n", optional1); } } } @@ -3489,13 +3402,6 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile); exit(-1); } - else if (hydra_options.passfile == NULL){ - if(my_segment && num_segments){ - filecloser = lfp; - lfp = hydra_divide_file(lfp, my_segment, num_segments); - fclose(filecloser); - } - } hydra_brains.countlogin = countlines(lfp, 0); hydra_brains.sizelogin = size_of_data; if (hydra_brains.countlogin == 0) { @@ -3528,11 +3434,6 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile); exit(-1); } - else if(my_segment && num_segments){ - filecloser = pfp; - pfp = hydra_divide_file(pfp, my_segment, num_segments); - fclose(filecloser); - } hydra_brains.countpass = countlines(pfp, 0); hydra_brains.sizepass = size_of_data; if (hydra_brains.countpass == 0) { @@ -3587,11 +3488,6 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile); exit(-1); } - else if(my_segment && num_segments){ - filecloser = cfp; - cfp = hydra_divide_file(cfp, my_segment, num_segments); - fclose(filecloser); - } hydra_brains.countlogin = countlines(cfp, 1); hydra_brains.sizelogin = size_of_data; if (hydra_brains.countlogin == 0) { @@ -3647,7 +3543,7 @@ int main(int argc, char *argv[]) { fclose(rfp); } - if (hydra_options.infile_ptr != NULL) { + if (hydra_options.infile_ptr != NULL) { if ((ifp = fopen(hydra_options.infile_ptr, "r")) == NULL) { fprintf(stderr, "[ERROR] File for targets not found: %s\n", hydra_options.infile_ptr); exit(-1); @@ -3695,7 +3591,6 @@ int main(int argc, char *argv[]) { } } else hydra_targets[i]->target = tmpptr; - if ((tmpptr2 = strchr(tmpptr, ':')) != NULL) { *tmpptr2++ = 0; tmpptr = tmpptr2; @@ -3705,13 +3600,6 @@ int main(int argc, char *argv[]) { } if (hydra_targets[i]->port == 0) hydra_targets[i]->port = hydra_options.port; - - if ((tmpptr3 = strchr(tmpptr, '/')) != NULL) { - hydra_targets[i]->miscptr = tmpptr3; - } - else - hydra_targets[i]->miscptr = "/"; - while (*tmpptr != 0) tmpptr++; tmpptr++; @@ -3734,7 +3622,6 @@ int main(int argc, char *argv[]) { memset(hydra_targets[0], 0, sizeof(hydra_target)); hydra_targets[0]->target = servers_ptr = hydra_options.server; hydra_targets[0]->port = hydra_options.port; - hydra_targets[0]->miscptr = hydra_options.miscptr; sizeservers = strlen(hydra_options.server) + 1; } else { /* CIDR notation on command line, e.g. 192.168.0.0/24 */ @@ -3779,7 +3666,6 @@ int main(int argc, char *argv[]) { memcpy(&target.sin_addr.s_addr, (char *)&addr_cur2, 4); hydra_targets[i]->target = strdup(inet_ntoa((struct in_addr)target.sin_addr)); hydra_targets[i]->port = hydra_options.port; - hydra_targets[i]->miscptr = hydra_options.miscptr; addr_cur++; i++; } @@ -3795,7 +3681,6 @@ int main(int argc, char *argv[]) { memset(hydra_targets[0], 0, sizeof(hydra_target)); hydra_targets[0]->target = servers_ptr = hydra_options.server; hydra_targets[0]->port = hydra_options.port; - hydra_targets[0]->miscptr = hydra_options.miscptr; sizeservers = strlen(hydra_options.server) + 1; } for (i = 0; i < hydra_brains.targets; i++) { @@ -4228,7 +4113,7 @@ int main(int argc, char *argv[]) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); } else - printf("[%d][%s] host: %s misc: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_targets[hydra_heads[head_no]->target_no]->miscptr, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); + printf("[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); } if (hydra_options.outfile_format == FORMAT_JSONV1 && hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { fprintf(hydra_brains.ofp, @@ -4523,4 +4408,4 @@ int main(int argc, char *argv[]) { return -1; else return 0; -} \ No newline at end of file +} diff --git a/hydra.h b/hydra.h index 24b63e8..353b318 100644 --- a/hydra.h +++ b/hydra.h @@ -194,7 +194,6 @@ typedef struct { int32_t cidr; int32_t time_next_attempt; output_format_t outfile_format; - char *distributed; // Use distributed computing by splitting user files on the fly char *login; char *loginfile; char *pass; diff --git a/pw-inspector.1 b/pw-inspector.1 index c9f228c..90bff65 100644 --- a/pw-inspector.1 +++ b/pw-inspector.1 @@ -42,7 +42,7 @@ upcase characters (A,B,C,D, etc.) numbers (1,2,3,4, etc.) .TP .B \-p -printable characters (which are not \-l/\-n/\-n, e.g. $,!,/,(,*, etc.) +printable characters (which are not \-l/\-n/\-p, e.g. $,!,/,(,*, etc.) .TP .B \ -s special characters \- all others not withint the sets above diff --git a/pw-inspector.c b/pw-inspector.c index 8b87a5a..2f53e05 100644 --- a/pw-inspector.c +++ b/pw-inspector.c @@ -30,7 +30,7 @@ void help() { printf(" -l lowcase characters (a,b,c,d, etc.)\n"); printf(" -u upcase characters (A,B,C,D, etc.)\n"); printf(" -n numbers (1,2,3,4, etc.)\n"); - printf(" -p printable characters (which are not -l/-u/-n, e.g. " + printf(" -p printable characters (which are not -l/-n/-p, e.g. " "$,!,/,(,*, etc.)\n"); printf(" -s special characters - all others not within the sets " "above\n"); @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) { int32_t sets = 0, countsets = 0, minlen = 0, maxlen = MAXLENGTH, count = 0; int32_t set_low = 0, set_up = 0, set_no = 0, set_print = 0, set_other = 0; FILE *in = stdin, *out = stdout; - unsigned char buf[MAXLENGTH + 1]; + char buf[MAXLENGTH + 1]; prg = argv[0]; if (argc < 2) @@ -124,9 +124,9 @@ int main(int argc, char *argv[]) { if (countsets == 0) countsets = sets; - while (fgets((void *)buf, sizeof(buf), in) != NULL) { - int is_low = 0, is_up = 0, is_no = 0, is_print = 0, is_other = 0; - if (!buf[0]) + while (fgets(buf, sizeof(buf), in) != NULL) { + i = -1; + if (buf[0] == 0) continue; if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; @@ -134,31 +134,40 @@ int main(int argc, char *argv[]) { buf[strlen(buf) - 1] = 0; if (strlen(buf) >= minlen && strlen(buf) <= maxlen) { i = 0; - j = 1; - for (i = 0; i < strlen(buf) && j; i++) { - j = 0; - if (set_low && islower(buf[i])) { - j = 1; - is_low = 1; - } else if (set_up && isupper(buf[i])) { - j = 1; - is_up = 1; - } else if (set_no && isdigit(buf[i])) { - j = 1; - is_no = 1; - } else if (set_print && isprint(buf[i]) && !isalnum(buf[i])) { - j = 1; - is_print = 1; - } else if (set_other && !isprint(buf[i])) { - j = 1; - is_other = 1; + if (countsets > 0) { + if (set_low) + if (strpbrk(buf, "abcdefghijklmnopqrstuvwxyz") != NULL) + i++; + if (set_up) + if (strpbrk(buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") != NULL) + i++; + if (set_no) + if (strpbrk(buf, "0123456789") != NULL) + i++; + if (set_print) { + j = 0; + for (k = 0; k < strlen(buf); k++) + if (isprint((int32_t)buf[k]) != 0 && isalnum((int32_t)buf[k]) == 0) + j = 1; + if (j) + i++; + } + if (set_other) { + j = 0; + for (k = 0; k < strlen(buf); k++) + if (isprint((int32_t)buf[k]) == 0 && isalnum((int32_t)buf[k]) == 0) + j = 1; + if (j) + i++; } } - if (j && countsets <= is_low + is_up + is_no + is_print + is_other) { + if (i >= countsets) { fprintf(out, "%s\n", buf); count++; } } + /* fprintf(stderr, "[DEBUG] i: %d minlen: %d maxlen: %d len: %d\n", i, + * minlen, maxlen, strlen(buf)); */ } fclose(in); fclose(out);