diff --git a/CHANGES b/CHANGES index 685f48d..a78dfea 100644 --- a/CHANGES +++ b/CHANGES @@ -2,8 +2,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 diff --git a/Dockerfile b/Dockerfile index 9f16b02..599e7e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim +FROM debian:buster-slim ARG HYDRA_VERSION="github" 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..0dd498e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ 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 +OPTS=-I. -O3 $(CFLAGS) -fcommon CPPFLAGS += -D_GNU_SOURCE # -Wall -g -pedantic LIBS=-lm diff --git a/README b/README index ca95b03..44cb585 100644 --- a/README +++ b/README @@ -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,7 @@ 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. +-x '3:3:aA1&~#\\ "\'<{([-|_^@)]=}>$%*?./§,;:!`' -v generates lenght 3 passwords with all 95 characters, and verbose. ``` Example: diff --git a/configure b/configure index dc86adb..425f80a 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 @@ -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-http-form.c b/hydra-http-form.c old mode 100755 new mode 100644 index 7de90e3..d41cbd9 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -66,8 +66,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 +314,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 +384,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 +432,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 +518,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 +658,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 +726,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 +746,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); @@ -910,7 +782,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); @@ -924,10 +796,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 +814,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) { @@ -976,7 +844,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); @@ -990,10 +858,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 +876,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 +907,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 +921,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 +939,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 +954,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) @@ -1250,10 +1105,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) @@ -1590,10 +1443,8 @@ void usage_http_form(const char *service) { " 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" + " and the condition string; seperate them too with colons:\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" @@ -1624,12 +1475,6 @@ void usage_http_form(const char *service) { " \"/exchweb/bin/auth/:F=failed" "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", + "C=/exchweb\":reason=\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..de86f66 100644 --- a/hydra-mod.c +++ b/hydra-mod.c @@ -664,7 +664,7 @@ char *hydra_get_next_pair() { // 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 (__fck >= sizeof(HYDRA_EXIT) && memcmp(&HYDRA_EXIT, &pair, sizeof(HYDRA_EXIT)) == 0) return HYDRA_EXIT; } return pair; diff --git a/hydra-mongodb.c b/hydra-mongodb.c index 66269be..d413192 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; @@ -137,8 +136,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..456a1c3 100644 --- a/hydra-rdp.c +++ b/hydra-rdp.c @@ -16,30 +16,24 @@ 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 + instance->settings->AuthenticationOnly = TRUE; + instance->settings->ServerHostname = server; + instance->settings->ServerPort = port; + instance->settings->Domain = domain; + instance->settings->MaxTimeInCheckLoop = 100; // freerdp timeout format is microseconds -> default:15000 - settings->TcpConnectTimeout = hydra_options.waittime * 1000; - settings->TlsSecLevel = 0; + instance->settings->TcpConnectTimeout = hydra_options.waittime * 1000; + instance->settings->TlsSecLevel = 0; freerdp_connect(instance); err = freerdp_get_last_error(instance->context); return err; @@ -131,8 +125,6 @@ void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL 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..3b4bdca 100644 --- a/hydra-rtsp.c +++ b/hydra-rtsp.c @@ -6,9 +6,7 @@ // // -#ifndef _GNU_SOURCE #define _GNU_SOURCE -#endif #include "hydra-mod.h" #include "sasl.h" 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..5e99451 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,7 +126,7 @@ bool smb2_run_test(creds_t *cr, const char *server, uint16_t port) { */ switch (errno) { - case 0: + case 0: // maybe false positive? unclear ... :( ... needs more testing smbc_free_context(ctx, 1); return true; @@ -174,15 +173,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 +191,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-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.c b/hydra.c index 416cf25..c250f4c 100644 --- a/hydra.c +++ b/hydra.c @@ -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.5" #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; @@ -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.c b/pw-inspector.c index 8b87a5a..cc91c02 100644 --- a/pw-inspector.c +++ b/pw-inspector.c @@ -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);