diff --git a/hydra.c b/hydra.c index 38003d2..20a4a0b 100755 --- a/hydra.c +++ b/hydra.c @@ -192,25 +192,25 @@ extern int32_t service_rpcap_init(char *ip, int32_t sp, unsigned char options, c char *SERVICES = "adam6500 asterisk afp cisco cisco-enable cvs firebird ftp ftps http[s]-{head|get|post} http[s]-{get|post}-form http-proxy http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3[-{cram|digest}md5][s] mssql mysql ncp nntp oracle oracle-listener oracle-sid pcanywhere pcnfs pop3[s] postgres radmin2 rdp redis rexec rlogin rpcap rsh rtsp s7-300 sapr3 sip smb smtp[s] smtp-enum snmp socks5 ssh sshkey svn teamspeak telnet[s] vmauthd vnc xmpp"; -#define MAXBUF 520 +#define MAXBUF 520 #define MAXLINESIZE ( ( MAXBUF / 2 ) - 4 ) -#define MAXTASKS 64 +#define MAXTASKS 64 #define MAXSERVERS 16 -#define MAXFAIL 3 +#define MAXFAIL 3 #define MAXENDWAIT 20 -#define WAITTIME 32 -#define TASKS 16 -#define SKIPLOGIN 256 +#define WAITTIME 32 +#define TASKS 16 +#define SKIPLOGIN 256 #define USLEEP_LOOP 10 -#define MAX_LINES 50000000 // 50 millions, do not put more than 65millions -#define MAX_BYTES 500000000 // 500 millions, do not put more than 650millions +#define MAX_LINES 50000000 // 50 millions, do not put more than 65millions +#define MAX_BYTES 500000000 // 500 millions, do not put more than 650millions #define RESTOREFILE "./hydra.restore" #define PROGRAM "Hydra" #define VERSION "v8.7-dev" -#define AUTHOR "van Hauser/THC" -#define EMAIL "" +#define AUTHOR "van Hauser/THC" +#define EMAIL "" #define RESOURCE "http://www.thc.org/thc-hydra" extern char *hydra_strcasestr(const char *haystack, const char *needle); @@ -277,7 +277,7 @@ typedef struct { } hydra_target; typedef struct { - int32_t active; // active tasks of hydra_options.max_use + int32_t active; // active tasks of hydra_options.max_use int32_t targets; int32_t finished; int32_t exit; @@ -447,8 +447,8 @@ static const struct { #define PRINT_NORMAL(ext, text, ...) printf(text, ##__VA_ARGS__) #define PRINT_EXTEND(ext, text, ...) do { \ - if (ext) \ - printf(text, ##__VA_ARGS__); \ + if (ext) \ + printf(text, ##__VA_ARGS__); \ } while(0) @@ -458,111 +458,111 @@ int32_t /*inline*/ check_flag(int32_t value, int32_t flag) { // inline does not void help(int32_t ext) { PRINT_NORMAL(ext, "Syntax: hydra [[[-l LOGIN|-L FILE] [-p PASS|-P FILE]] | [-C FILE]] [-e nsr]" - " [-o FILE] [-t TASKS] [-M FILE [-T TASKS]] [-w TIME] [-W TIME] [-f] [-s PORT]" + " [-o FILE] [-t TASKS] [-M FILE [-T TASKS]] [-w TIME] [-W TIME] [-f] [-s PORT]" #ifdef HAVE_MATH_H - " [-x MIN:MAX:CHARSET]" + " [-x MIN:MAX:CHARSET]" #endif - " [-c TIME] [-ISOuvVd46] " - //"[server service [OPT]]|" - "[service://server[:PORT][/OPT]]\n"); + " [-c TIME] [-ISOuvVd46] " + //"[server service [OPT]]|" + "[service://server[:PORT][/OPT]]\n"); PRINT_NORMAL(ext, "\nOptions:\n"); - PRINT_EXTEND(ext, " -R restore a previous aborted/crashed session\n" - " -I ignore an existing restore file (don't wait 10 seconds)\n" + PRINT_EXTEND(ext, " -R restore a previous aborted/crashed session\n" + " -I ignore an existing restore file (don't wait 10 seconds)\n" #ifdef LIBOPENSSL - " -S perform an SSL connect\n" + " -S perform an SSL connect\n" #endif - " -s PORT if the service is on a different default port, define it here\n"); + " -s PORT if the service is on a different default port, define it here\n"); PRINT_NORMAL(ext, " -l LOGIN or -L FILE login with LOGIN name, or load several logins from FILE\n" - " -p PASS or -P FILE try password PASS, or load several passwords from FILE\n"); + " -p PASS or -P FILE try password PASS, or load several passwords from FILE\n"); PRINT_EXTEND(ext, #ifdef HAVE_MATH_H - " -x MIN:MAX:CHARSET password bruteforce generation, type \"-x -h\" to get help\n" - " -y disable use of symbols in bruteforce, see above\n" + " -x MIN:MAX:CHARSET password bruteforce generation, type \"-x -h\" to get help\n" + " -y disable use of symbols in bruteforce, see above\n" #endif - " -e nsr try \"n\" null password, \"s\" login as pass and/or \"r\" reversed login\n" - " -u loop around users, not passwords (effective! implied with -x)\n"); + " -e nsr try \"n\" null password, \"s\" login as pass and/or \"r\" reversed login\n" + " -u loop around users, not passwords (effective! implied with -x)\n"); PRINT_NORMAL(ext, " -C FILE colon separated \"login:pass\" format, instead of -L/-P options\n" - " -M FILE list of servers to attack, one entry per line, ':' to specify port\n"); + " -M FILE list of servers to attack, one entry per line, ':' to specify port\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" - " -f / -F exit when a login/pass pair is found (-M: -f per host, -F global)\n"); + " -b FORMAT specify the format for the -o FILE: text(default), json, jsonv1\n" + " -f / -F exit when a login/pass pair is found (-M: -f per host, -F global)\n"); PRINT_NORMAL(ext, " -t TASKS run TASKS number of connects in parallel per target (default: %d)\n", TASKS); PRINT_EXTEND(ext, " -T TASKS run TASKS connects in parallel overall (for -M, default: %d)\n" - " -w / -W TIME wait time for a response (%d) / between connects per thread (%d)\n" + " -w / -W TIME wait time for a response (%d) / between connects per thread (%d)\n" #ifdef MSG_PEEK - " -c TIME wait time per login attempt over all threads (enforces -t 1)\n" + " -c TIME wait time per login attempt over all threads (enforces -t 1)\n" #endif - " -4 / -6 use IPv4 (default) / IPv6 addresses (put always in [] also in -M)\n" - " -v / -V / -d verbose mode / show login+pass for each attempt / debug mode \n" - " -O use old SSL v2 and v3\n" - " -q do not print messages about connection errors\n", - MAXTASKS, WAITTIME, conwait - ); - PRINT_NORMAL(ext, " -U service module usage details\n" - " -h more command line options (COMPLETE HELP)\n" - " server the target: DNS, IP or 192.168.0.0/24 (this OR the -M option)\n" - " service the service to crack (see below for supported protocols)\n" - " OPT some service modules support additional input (-U for module help)\n"); + " -4 / -6 use IPv4 (default) / IPv6 addresses (put always in [] also in -M)\n" + " -v / -V / -d verbose mode / show login+pass for each attempt / debug mode \n" + " -O use old SSL v2 and v3\n" + " -q do not print messages about connection errors\n", + MAXTASKS, WAITTIME, conwait + ); + PRINT_NORMAL(ext, " -U service module usage details\n" + " -h more command line options (COMPLETE HELP)\n" + " server the target: DNS, IP or 192.168.0.0/24 (this OR the -M option)\n" + " service the service to crack (see below for supported protocols)\n" + " OPT some service modules support additional input (-U for module help)\n"); PRINT_NORMAL(ext, "\nSupported services: %s\n" - "\n%s is a tool to guess/crack valid login/password pairs. Licensed under AGPL\n" - "v3.0. The newest version is always available at %s\n" - "Don't use in military or secret service organizations, or for illegal purposes.\n", - SERVICES, PROGRAM, RESOURCE - ); + "\n%s is a tool to guess/crack valid login/password pairs. Licensed under AGPL\n" + "v3.0. The newest version is always available at %s\n" + "Don't use in military or secret service organizations, or for illegal purposes.\n", + SERVICES, PROGRAM, RESOURCE + ); if (ext && strlen(unsupported) > 0) { - if (unsupported[strlen(unsupported) - 1] == ' ') - unsupported[strlen(unsupported) - 1] = 0; - printf("These services were not compiled in: %s.\n", unsupported); + if (unsupported[strlen(unsupported) - 1] == ' ') + unsupported[strlen(unsupported) - 1] = 0; + printf("These services were not compiled in: %s.\n", unsupported); } PRINT_EXTEND(ext, "\nUse HYDRA_PROXY_HTTP or HYDRA_PROXY environment variables for a proxy setup.\n" - "E.g. %% export HYDRA_PROXY=socks5://l:p@127.0.0.1:9150 (or: socks4:// connect://)\n" - " %% export HYDRA_PROXY=connect_and_socks_proxylist.txt (up to 64 entries)\n" - " %% export HYDRA_PROXY_HTTP=http://login:pass@proxy:8080\n" - " %% export HYDRA_PROXY_HTTP=proxylist.txt (up to 64 entries)\n"); + "E.g. %% export HYDRA_PROXY=socks5://l:p@127.0.0.1:9150 (or: socks4:// connect://)\n" + " %% export HYDRA_PROXY=connect_and_socks_proxylist.txt (up to 64 entries)\n" + " %% export HYDRA_PROXY_HTTP=http://login:pass@proxy:8080\n" + " %% export HYDRA_PROXY_HTTP=proxylist.txt (up to 64 entries)\n"); PRINT_NORMAL(ext, "\nExample%s:%s hydra -l user -P passlist.txt ftp://192.168.0.1\n", ext == 0 ? "" : "s", ext == 0 ? "" : "\n"); PRINT_EXTEND(ext, " hydra -L userlist.txt -p defaultpw imap://192.168.0.1/PLAIN\n" - " hydra -C defaults.txt -6 pop3s://[2001:db8::1]:143/TLS:DIGEST-MD5\n" - " hydra -l admin -p password ftp://[192.168.0.0/24]/\n" - " hydra -L logins.txt -P pws.txt -M targets.txt ssh\n"); + " hydra -C defaults.txt -6 pop3s://[2001:db8::1]:143/TLS:DIGEST-MD5\n" + " hydra -l admin -p password ftp://[192.168.0.0/24]/\n" + " hydra -L logins.txt -P pws.txt -M targets.txt ssh\n"); exit(-1); } void help_bfg() { printf("Hydra bruteforce password generation option usage:\n\n" - " -x MIN:MAX:CHARSET\n\n" - " MIN is the minimum number of characters in the password\n" - " MAX is the maximum number of characters in the password\n" - " CHARSET is a specification of the characters to use in the generation\n" - " valid CHARSET values are: 'a' for lowercase letters,\n" - " 'A' for uppercase letters, '1' for numbers, and for all others,\n" - " just add their real representation.\n" - " -y disable the use if the above letters as placeholders\n\n" - "Examples:\n" - " -x 3:5:a generate passwords from length 3 to 5 with all lowercase letters\n" - " -x 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers\n" - " -x 1:3:/ generate passwords from length 1 to 3 containing only slashes\n" - " -x 5:5:/%%,.- generate passwords with length 5 which consists only of /%%,.-\n" - " -x 3:5:aA1 -y generate passwords from length 3 to 5 with a, A and 1 only\n" - "\nThe bruteforce mode was made by Jan Dlabal, http://houbysoft.com/bfg/\n"); + " -x MIN:MAX:CHARSET\n\n" + " MIN is the minimum number of characters in the password\n" + " MAX is the maximum number of characters in the password\n" + " CHARSET is a specification of the characters to use in the generation\n" + " valid CHARSET values are: 'a' for lowercase letters,\n" + " 'A' for uppercase letters, '1' for numbers, and for all others,\n" + " just add their real representation.\n" + " -y disable the use if the above letters as placeholders\n\n" + "Examples:\n" + " -x 3:5:a generate passwords from length 3 to 5 with all lowercase letters\n" + " -x 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers\n" + " -x 1:3:/ generate passwords from length 1 to 3 containing only slashes\n" + " -x 5:5:/%%,.- generate passwords with length 5 which consists only of /%%,.-\n" + " -x 3:5:aA1 -y generate passwords from length 3 to 5 with a, A and 1 only\n" + "\nThe bruteforce mode was made by Jan Dlabal, http://houbysoft.com/bfg/\n"); exit(-1); } void module_usage() { int32_t i; if (!hydra_options.service) { - printf("The Module %s does not need or support optional parameters\n", hydra_options.service); - exit(0); + printf("The Module %s does not need or support optional parameters\n", hydra_options.service); + exit(0); } printf("\nHelp for module %s:\n============================================================================\n", hydra_options.service); for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) { - if (strcmp(hydra_options.service, services[i].name) == 0) { - if (services[i].usage) { - services[i].usage(hydra_options.service); - exit(0); - } - } + if (strcmp(hydra_options.service, services[i].name) == 0) { + if (services[i].usage) { + services[i].usage(hydra_options.service); + exit(0); + } + } } printf("The Module %s does not need or support optional parameters\n", hydra_options.service); @@ -575,54 +575,54 @@ void hydra_debug(int32_t force, char *string) { int32_t active = 0, inactive = 0, i; if (!debug && !force) - return; + return; printf("[DEBUG] Code: %s Time: %lu\n", string, (uint64_t) time(NULL)); printf("[DEBUG] Options: mode %d ssl %d restore %d showAttempt %d tasks %d max_use %d tnp %d tpsal %d tprl %d exit_found %d miscptr %s service %s\n", - hydra_options.mode, hydra_options.ssl, hydra_options.restore, - hydra_options.showAttempt, hydra_options.tasks, hydra_options.max_use, - hydra_options.try_null_password, hydra_options.try_password_same_as_login, - hydra_options.try_password_reverse_login, hydra_options.exit_found, - STR_NULL(hydra_options.miscptr), hydra_options.service); + hydra_options.mode, hydra_options.ssl, hydra_options.restore, + hydra_options.showAttempt, hydra_options.tasks, hydra_options.max_use, + hydra_options.try_null_password, hydra_options.try_password_same_as_login, + hydra_options.try_password_reverse_login, hydra_options.exit_found, + STR_NULL(hydra_options.miscptr), hydra_options.service); printf("[DEBUG] Brains: active %d targets %d finished %d todo_all %lu todo %lu sent %lu found %lu countlogin %lu sizelogin %lu countpass %lu sizepass %lu\n", - hydra_brains.active, hydra_brains.targets, hydra_brains.finished, - hydra_brains.todo_all + total_redo_count, hydra_brains.todo, - hydra_brains.sent, hydra_brains.found, - (uint64_t) hydra_brains.countlogin, - (uint64_t) hydra_brains.sizelogin, - (uint64_t) hydra_brains.countpass, - (uint64_t) hydra_brains.sizepass); + hydra_brains.active, hydra_brains.targets, hydra_brains.finished, + hydra_brains.todo_all + total_redo_count, hydra_brains.todo, + hydra_brains.sent, hydra_brains.found, + (uint64_t) hydra_brains.countlogin, + (uint64_t) hydra_brains.sizelogin, + (uint64_t) hydra_brains.countpass, + (uint64_t) hydra_brains.sizepass); for (i = 0; i < hydra_brains.targets; i++) { - hydra_target* target = hydra_targets[i]; - printf - ("[DEBUG] Target %d - target %s ip %s login_no %lu pass_no %lu sent %lu pass_state %d redo_state %d (%d redos) use_count %d failed %d done %d fail_count %d login_ptr %s pass_ptr %s\n", - i, STR_NULL(target->target), hydra_address2string_beautiful(target->ip), - target->login_no, target->pass_no, target->sent, - target->pass_state, target->redo_state, target->redo, - target->use_count, target->failed, target->done, - target->fail_count, - STR_NULL(target->login_ptr), - STR_NULL(target->pass_ptr)); + hydra_target* target = hydra_targets[i]; + printf + ("[DEBUG] Target %d - target %s ip %s login_no %lu pass_no %lu sent %lu pass_state %d redo_state %d (%d redos) use_count %d failed %d done %d fail_count %d login_ptr %s pass_ptr %s\n", + i, STR_NULL(target->target), hydra_address2string_beautiful(target->ip), + target->login_no, target->pass_no, target->sent, + target->pass_state, target->redo_state, target->redo, + target->use_count, target->failed, target->done, + target->fail_count, + STR_NULL(target->login_ptr), + STR_NULL(target->pass_ptr)); } if (hydra_heads == NULL) - return; + return; for (i = 0; i < hydra_options.max_use; i++) { - if (hydra_heads[i]->active >= HEAD_UNUSED) { - printf("[DEBUG] Task %d - pid %d active %d redo %d current_login_ptr %s current_pass_ptr %s\n", - i, (int32_t) hydra_heads[i]->pid, - hydra_heads[i]->active, - hydra_heads[i]->redo, - STR_NULL(hydra_heads[i]->current_login_ptr), - STR_NULL(hydra_heads[i]->current_pass_ptr)); - if (hydra_heads[i]->active == HEAD_UNUSED) - inactive++; - else - active++; - } + if (hydra_heads[i]->active >= HEAD_UNUSED) { + printf("[DEBUG] Task %d - pid %d active %d redo %d current_login_ptr %s current_pass_ptr %s\n", + i, (int32_t) hydra_heads[i]->pid, + hydra_heads[i]->active, + hydra_heads[i]->redo, + STR_NULL(hydra_heads[i]->current_login_ptr), + STR_NULL(hydra_heads[i]->current_pass_ptr)); + if (hydra_heads[i]->active == HEAD_UNUSED) + inactive++; + else + active++; + } } printf("[DEBUG] Tasks %d inactive %d active\n", inactive, active); } @@ -640,23 +640,23 @@ void hydra_restore_write(int32_t print_msg) { hydra_head hh; if (process_restore != 1) - return; + return; for (i = 0; i < hydra_brains.targets; i++) - if (hydra_targets[j]->done != TARGET_FINISHED && hydra_targets[j]->done != TARGET_UNRESOLVED) - j++; + if (hydra_targets[j]->done != TARGET_FINISHED && hydra_targets[j]->done != TARGET_UNRESOLVED) + j++; if (j == 0) { - process_restore = 0; - return; + process_restore = 0; + return; } if ((f = fopen(RESTOREFILE, "w")) == NULL) { - fprintf(stderr, "[ERROR] Can not create restore file (%s) - \n", RESTOREFILE); - perror(""); - process_restore = 0; - return; + fprintf(stderr, "[ERROR] Can not create restore file (%s) - \n", RESTOREFILE); + perror(""); + process_restore = 0; + return; } else if (debug) - printf("[DEBUG] Writing restore file... "); + printf("[DEBUG] Writing restore file... "); fprintf(f, "%s\n", PROGRAM); buf[0] = VERSION[1]; @@ -670,60 +670,60 @@ void hydra_restore_write(int32_t print_msg) { brain.finished = brain.active = 0; fck = fwrite(&bf_options, sizeof(bf_options), 1, f); if (bf_options.crs != NULL) - fck = fwrite(bf_options.crs, BF_CHARSMAX, 1, f); + fck = fwrite(bf_options.crs, BF_CHARSMAX, 1, f); else - fck = fwrite(mynull, sizeof(mynull), 1, f); + fck = fwrite(mynull, sizeof(mynull), 1, f); fck = fwrite(&brain, sizeof(hydra_brain), 1, f); fck = fwrite(&hydra_options, sizeof(hydra_option), 1, f); fprintf(f, "%s\n", hydra_options.server == NULL ? "" : hydra_options.server); if (hydra_options.outfile_ptr == NULL) - fprintf(f, "\n"); + fprintf(f, "\n"); else - fprintf(f, "%s\n", hydra_options.outfile_ptr); + fprintf(f, "%s\n", hydra_options.outfile_ptr); fprintf(f, "%s\n%s\n", hydra_options.miscptr == NULL ? "" : hydra_options.miscptr, hydra_options.service); fck = fwrite(login_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, 1, f); if (hydra_options.colonfile == NULL || hydra_options.colonfile == empty_login) - fck = fwrite(pass_ptr, hydra_brains.sizepass + hydra_brains.countpass + 8, 1, f); + fck = fwrite(pass_ptr, hydra_brains.sizepass + hydra_brains.countpass + 8, 1, f); for (j = 0; j < hydra_brains.targets; j++) - if (hydra_targets[j]->done != TARGET_FINISHED) { - fck = fwrite(hydra_targets[j], sizeof(hydra_target), 1, f); - fprintf(f, "%s\n%d\n%d\n", hydra_targets[j]->target == NULL ? "" : hydra_targets[j]->target, (int32_t) (hydra_targets[j]->login_ptr - login_ptr), - (int32_t) (hydra_targets[j]->pass_ptr - pass_ptr)); - fprintf(f, "%s\n%s\n", hydra_targets[j]->login_ptr, hydra_targets[j]->pass_ptr); - if (hydra_targets[j]->redo) - for (i = 0; i < hydra_targets[j]->redo; i++) - fprintf(f, "%s\n%s\n", hydra_targets[j]->redo_login[i], hydra_targets[j]->redo_pass[i]); - if (hydra_targets[j]->skipcnt) - for (i = 0; i < hydra_targets[j]->skipcnt; i++) - fprintf(f, "%s\n", hydra_targets[j]->skiplogin[i]); - } + if (hydra_targets[j]->done != TARGET_FINISHED) { + fck = fwrite(hydra_targets[j], sizeof(hydra_target), 1, f); + fprintf(f, "%s\n%d\n%d\n", hydra_targets[j]->target == NULL ? "" : hydra_targets[j]->target, (int32_t) (hydra_targets[j]->login_ptr - login_ptr), + (int32_t) (hydra_targets[j]->pass_ptr - pass_ptr)); + fprintf(f, "%s\n%s\n", hydra_targets[j]->login_ptr, hydra_targets[j]->pass_ptr); + if (hydra_targets[j]->redo) + for (i = 0; i < hydra_targets[j]->redo; i++) + fprintf(f, "%s\n%s\n", hydra_targets[j]->redo_login[i], hydra_targets[j]->redo_pass[i]); + if (hydra_targets[j]->skipcnt) + for (i = 0; i < hydra_targets[j]->skipcnt; i++) + fprintf(f, "%s\n", hydra_targets[j]->skiplogin[i]); + } for (j = 0; j < hydra_options.max_use; j++) { - memcpy((char *) &hh, hydra_heads[j], sizeof(hydra_head)); - if (j == 0 && debug) { - printf("[DEBUG] sizeof hydra_head: %lu\n", sizeof(hydra_head)); - printf("[DEBUG] memcmp: %d\n", memcmp(hydra_heads[j], &hh, sizeof(hydra_head))); - } - hh.active = 0; // re-enable disabled heads - if ((hh.current_login_ptr != NULL && hh.current_login_ptr != empty_login) - || (hh.current_pass_ptr != NULL && hh.current_pass_ptr != empty_login)) { - hh.redo = 1; - if (print_msg && debug) - printf("[DEBUG] we will redo the following combination: target %s child %d login \"%s\" pass \"%s\"\n", hydra_targets[hh.target_no]->target, - j, hh.current_login_ptr, hh.current_pass_ptr); - } - fck = fwrite((char *) &hh, sizeof(hydra_head), 1, f); - if (hh.redo /* && (hydra_options.bfg == 0 || (hh.current_pass_ptr == hydra_targets[hh.target_no]->bfg_ptr[j] && isprint((char) hh.current_pass_ptr[0]))) */ ) - fprintf(f, "%s\n%s\n", hh.current_login_ptr == NULL ? "" : hh.current_login_ptr, hh.current_pass_ptr == NULL ? "" : hh.current_pass_ptr); - else - fprintf(f, "\n\n"); + memcpy((char *) &hh, hydra_heads[j], sizeof(hydra_head)); + if (j == 0 && debug) { + printf("[DEBUG] sizeof hydra_head: %lu\n", sizeof(hydra_head)); + printf("[DEBUG] memcmp: %d\n", memcmp(hydra_heads[j], &hh, sizeof(hydra_head))); + } + hh.active = 0; // re-enable disabled heads + if ((hh.current_login_ptr != NULL && hh.current_login_ptr != empty_login) + || (hh.current_pass_ptr != NULL && hh.current_pass_ptr != empty_login)) { + hh.redo = 1; + if (print_msg && debug) + printf("[DEBUG] we will redo the following combination: target %s child %d login \"%s\" pass \"%s\"\n", hydra_targets[hh.target_no]->target, + j, hh.current_login_ptr, hh.current_pass_ptr); + } + fck = fwrite((char *) &hh, sizeof(hydra_head), 1, f); + if (hh.redo /* && (hydra_options.bfg == 0 || (hh.current_pass_ptr == hydra_targets[hh.target_no]->bfg_ptr[j] && isprint((char) hh.current_pass_ptr[0]))) */ ) + fprintf(f, "%s\n%s\n", hh.current_login_ptr == NULL ? "" : hh.current_login_ptr, hh.current_pass_ptr == NULL ? "" : hh.current_pass_ptr); + else + fprintf(f, "\n\n"); } fprintf(f, "%s\n", PROGRAM); fclose(f); if (debug) - printf("[DEBUG] done writing session file\n"); + printf("[DEBUG] done writing session file\n"); if (print_msg) - printf("The session file ./hydra.restore was written. Type \"hydra -R\" to resume session.\n"); + printf("The session file ./hydra.restore was written. Type \"hydra -R\" to resume session.\n"); hydra_debug(0, "hydra_restore_write()"); } @@ -735,47 +735,47 @@ void hydra_restore_read() { printf("[INFORMATION] reading restore file %s\n", RESTOREFILE); if ((f = fopen(RESTOREFILE, "r")) == NULL) { - fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE); - perror(""); - exit(-1); + fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE); + perror(""); + exit(-1); } sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; + out[strlen(out) - 1] = 0; if (strcmp(out, PROGRAM) != 0) { - fprintf(stderr, "[ERROR] invalid restore file (begin)\n"); - exit(-1); + fprintf(stderr, "[ERROR] invalid restore file (begin)\n"); + exit(-1); } if ((fck = (int32_t) fread(buf, 1, 4, f)) != 4) { - fprintf(stderr, "[ERROR] invalid restore file (platform)\n"); - exit(-1); + fprintf(stderr, "[ERROR] invalid restore file (platform)\n"); + exit(-1); } if (buf[0] == 0 || buf[1] == 0) { - fprintf(stderr, "[ERROR] restore file is prior hydra version v8.5!\n"); - exit(-1); + fprintf(stderr, "[ERROR] restore file is prior hydra version v8.5!\n"); + exit(-1); } if (buf[0] != VERSION[1] || buf[1] != VERSION[3]) - fprintf(stderr, "[WARNING] restore file was created by version %c.%c, this is version %s\n", buf[0], buf[2], VERSION); + fprintf(stderr, "[WARNING] restore file was created by version %c.%c, this is version %s\n", buf[0], buf[2], VERSION); if (buf[2] != sizeof(int32_t) % 256 || buf[3] != sizeof(hydra_head*) % 256) { - fprintf(stderr, "[ERROR] restore file was created on a different, incompatible processor platform!\n"); - exit(-1); + fprintf(stderr, "[ERROR] restore file was created on a different, incompatible processor platform!\n"); + exit(-1); } fck = (int32_t) fread(&bf_options, sizeof(bf_options), 1, f); fck = (int32_t) fread(mynull, sizeof(mynull), 1, f); if (debug) - printf("[DEBUG] reading restore file: Step 1 complete\n"); + printf("[DEBUG] reading restore file: Step 1 complete\n"); if (mynull[0] + mynull[1] + mynull[2] + mynull[3] == 0) { - bf_options.crs = NULL; + bf_options.crs = NULL; } else { - bf_options.crs = malloc(BF_CHARSMAX); - memcpy(bf_options.crs, mynull, sizeof(mynull)); - fck = fread(bf_options.crs + sizeof(mynull), BF_CHARSMAX - sizeof(mynull), 1, f); + bf_options.crs = malloc(BF_CHARSMAX); + memcpy(bf_options.crs, mynull, sizeof(mynull)); + fck = fread(bf_options.crs + sizeof(mynull), BF_CHARSMAX - sizeof(mynull), 1, f); } if (debug) - printf("[DEBUG] reading restore file: Step 2 complete\n"); + printf("[DEBUG] reading restore file: Step 2 complete\n"); fck = (int32_t) fread(&hydra_brains, sizeof(hydra_brain), 1, f); hydra_brains.ofp = stdout; @@ -784,161 +784,161 @@ void hydra_restore_read() { verbose = hydra_options.verbose; debug = hydra_options.debug; if (debug || orig_debug) - printf("[DEBUG] run_debug %d, orig_debug %d\n", debug, orig_debug); + printf("[DEBUG] run_debug %d, orig_debug %d\n", debug, orig_debug); if (orig_debug) { - debug = 1; - hydra_options.debug = 1; + debug = 1; + hydra_options.debug = 1; } waittime = hydra_options.waittime; conwait = hydra_options.conwait; port = hydra_options.port; sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; + out[strlen(out) - 1] = 0; hydra_options.server = strdup(out); sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; + out[strlen(out) - 1] = 0; if (debug) - printf("[DEBUG] reading restore file: Step 3 complete\n"); + printf("[DEBUG] reading restore file: Step 3 complete\n"); if (strlen(out) > 0) { - hydra_options.outfile_ptr = malloc(strlen(out) + 1); - strcpy(hydra_options.outfile_ptr, out); + hydra_options.outfile_ptr = malloc(strlen(out) + 1); + strcpy(hydra_options.outfile_ptr, out); } else - hydra_options.outfile_ptr = NULL; + hydra_options.outfile_ptr = NULL; if (debug) - printf("[DEBUG] reading restore file: Step 4 complete\n"); + printf("[DEBUG] reading restore file: Step 4 complete\n"); sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; + out[strlen(out) - 1] = 0; if (debug) - printf("[DEBUG] reading restore file: Step 5 complete\n"); + printf("[DEBUG] reading restore file: Step 5 complete\n"); if (strlen(out) == 0) - hydra_options.miscptr = NULL; + hydra_options.miscptr = NULL; else { - hydra_options.miscptr = malloc(strlen(out) + 1); - strcpy(hydra_options.miscptr, out); + hydra_options.miscptr = malloc(strlen(out) + 1); + strcpy(hydra_options.miscptr, out); } if (debug) - printf("[DEBUG] reading restore file: Step 6 complete\n"); + printf("[DEBUG] reading restore file: Step 6 complete\n"); sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; + out[strlen(out) - 1] = 0; if (debug) - printf("[DEBUG] reading restore file: Step 7 complete\n"); + printf("[DEBUG] reading restore file: Step 7 complete\n"); hydra_options.service = malloc(strlen(out) + 1); strcpy(hydra_options.service, out); if (debug) - printf("[DEBUG] reading restore file: Step 8 complete\n"); + printf("[DEBUG] reading restore file: Step 8 complete\n"); login_ptr = malloc(hydra_brains.sizelogin + hydra_brains.countlogin + 8); fck = (int32_t) fread(login_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, 1, f); if (debug) - printf("[DEBUG] reading restore file: Step 9 complete\n"); - if (!check_flag(hydra_options.mode, MODE_COLON_FILE)) { // NOT colonfile mode - pass_ptr = malloc(hydra_brains.sizepass + hydra_brains.countpass + 8); - fck = (int32_t) fread(pass_ptr, hydra_brains.sizepass + hydra_brains.countpass + 8, 1, f); - } else { // colonfile mode - hydra_options.colonfile = empty_login; // dummy - pass_ptr = csv_ptr = login_ptr; + printf("[DEBUG] reading restore file: Step 9 complete\n"); + if (!check_flag(hydra_options.mode, MODE_COLON_FILE)) { // NOT colonfile mode + pass_ptr = malloc(hydra_brains.sizepass + hydra_brains.countpass + 8); + fck = (int32_t) fread(pass_ptr, hydra_brains.sizepass + hydra_brains.countpass + 8, 1, f); + } else { // colonfile mode + hydra_options.colonfile = empty_login; // dummy + pass_ptr = csv_ptr = login_ptr; } if (debug) - printf("[DEBUG] reading restore file: Step 10 complete\n"); + printf("[DEBUG] reading restore file: Step 10 complete\n"); hydra_targets = (hydra_target **) malloc((hydra_brains.targets + 3) * sizeof(hydra_target*)); for (j = 0; j < hydra_brains.targets; j++) { - hydra_targets[j] = malloc(sizeof(hydra_target)); - fck = (int32_t) fread(hydra_targets[j], sizeof(hydra_target), 1, f); - sck = fgets(out, sizeof(out), f); - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - hydra_targets[j]->target = malloc(strlen(out) + 1); - strcpy(hydra_targets[j]->target, out); - sck = fgets(out, sizeof(out), f); - hydra_targets[j]->login_ptr = login_ptr + atoi(out); - sck = fgets(out, sizeof(out), f); - hydra_targets[j]->pass_ptr = pass_ptr + atoi(out); - sck = fgets(out, sizeof(out), f); // target login_ptr, ignord - sck = fgets(out, sizeof(out), f); - if (hydra_options.bfg) { - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - hydra_targets[j]->pass_ptr = malloc(strlen(out) + 1); - strcpy(hydra_targets[j]->pass_ptr, out); - } - if (hydra_targets[j]->redo > 0) { - if (debug) printf("[DEBUG] target %d redo %d\n", j, hydra_targets[j]->redo); - for (i = 0; i < hydra_targets[j]->redo; i++) { - sck = fgets(out, sizeof(out), f); - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - hydra_targets[j]->redo_login[i] = malloc(strlen(out) + 1); - strcpy(hydra_targets[j]->redo_login[i], out); - sck = fgets(out, sizeof(out), f); - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - hydra_targets[j]->redo_pass[i] = malloc(strlen(out) + 1); - strcpy(hydra_targets[j]->redo_pass[i], out); - } - } - if (hydra_targets[j]->skipcnt >= hydra_brains.countlogin) - hydra_targets[j]->skipcnt = 0; - if (hydra_targets[j]->skipcnt > 0) - for (i = 0; i < hydra_targets[j]->skipcnt; i++) { - sck = fgets(out, sizeof(out), f); - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - hydra_targets[j]->skiplogin[i] = malloc(strlen(out) + 1); - strcpy(hydra_targets[j]->skiplogin[i], out); - } - hydra_targets[j]->fail_count = 0; - hydra_targets[j]->use_count = 0; - hydra_targets[j]->failed = 0; + hydra_targets[j] = malloc(sizeof(hydra_target)); + fck = (int32_t) fread(hydra_targets[j], sizeof(hydra_target), 1, f); + sck = fgets(out, sizeof(out), f); + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + hydra_targets[j]->target = malloc(strlen(out) + 1); + strcpy(hydra_targets[j]->target, out); + sck = fgets(out, sizeof(out), f); + hydra_targets[j]->login_ptr = login_ptr + atoi(out); + sck = fgets(out, sizeof(out), f); + hydra_targets[j]->pass_ptr = pass_ptr + atoi(out); + sck = fgets(out, sizeof(out), f); // target login_ptr, ignord + sck = fgets(out, sizeof(out), f); + if (hydra_options.bfg) { + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + hydra_targets[j]->pass_ptr = malloc(strlen(out) + 1); + strcpy(hydra_targets[j]->pass_ptr, out); + } + if (hydra_targets[j]->redo > 0) { + if (debug) printf("[DEBUG] target %d redo %d\n", j, hydra_targets[j]->redo); + for (i = 0; i < hydra_targets[j]->redo; i++) { + sck = fgets(out, sizeof(out), f); + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + hydra_targets[j]->redo_login[i] = malloc(strlen(out) + 1); + strcpy(hydra_targets[j]->redo_login[i], out); + sck = fgets(out, sizeof(out), f); + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + hydra_targets[j]->redo_pass[i] = malloc(strlen(out) + 1); + strcpy(hydra_targets[j]->redo_pass[i], out); + } + } + if (hydra_targets[j]->skipcnt >= hydra_brains.countlogin) + hydra_targets[j]->skipcnt = 0; + if (hydra_targets[j]->skipcnt > 0) + for (i = 0; i < hydra_targets[j]->skipcnt; i++) { + sck = fgets(out, sizeof(out), f); + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + hydra_targets[j]->skiplogin[i] = malloc(strlen(out) + 1); + strcpy(hydra_targets[j]->skiplogin[i], out); + } + hydra_targets[j]->fail_count = 0; + hydra_targets[j]->use_count = 0; + hydra_targets[j]->failed = 0; } if (debug) - printf("[DEBUG] reading restore file: Step 11 complete\n"); + printf("[DEBUG] reading restore file: Step 11 complete\n"); hydra_heads = malloc(sizeof(hydra_head*) * hydra_options.max_use); for (j = 0; j < hydra_options.max_use; j++) { - hydra_heads[j] = malloc(sizeof(hydra_head)); - fck = (int32_t) fread(hydra_heads[j], sizeof(hydra_head), 1, f); - hydra_heads[j]->sp[0] = -1; - hydra_heads[j]->sp[1] = -1; - sck = fgets(out, sizeof(out), f); - if (hydra_heads[j]->redo) { - if (debug) printf("[DEBUG] head %d redo\n", j); - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - hydra_heads[j]->current_login_ptr = malloc(strlen(out) + 1); - strcpy(hydra_heads[j]->current_login_ptr, out); - } - sck = fgets(out, sizeof(out), f); - if (hydra_heads[j]->redo) { - if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; - if (debug) - printf("[DEBUG] TEMP head %d: pass == %s, login == %s\n", j, out, hydra_heads[j]->current_login_ptr); - if (out[0] != 0 || hydra_heads[j]->current_login_ptr[0] != 0) { - hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1); - strcpy(hydra_heads[j]->current_pass_ptr, out); - if (debug) - printf("[DEBUG] redo: %d %s/%s\n", j, hydra_heads[j]->current_login_ptr, hydra_heads[j]->current_pass_ptr); - } else { - hydra_heads[j]->redo = 0; - free(hydra_heads[j]->current_login_ptr); - hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login; - } - } else { - hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login; - } + hydra_heads[j] = malloc(sizeof(hydra_head)); + fck = (int32_t) fread(hydra_heads[j], sizeof(hydra_head), 1, f); + hydra_heads[j]->sp[0] = -1; + hydra_heads[j]->sp[1] = -1; + sck = fgets(out, sizeof(out), f); + if (hydra_heads[j]->redo) { + if (debug) printf("[DEBUG] head %d redo\n", j); + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + hydra_heads[j]->current_login_ptr = malloc(strlen(out) + 1); + strcpy(hydra_heads[j]->current_login_ptr, out); + } + sck = fgets(out, sizeof(out), f); + if (hydra_heads[j]->redo) { + if (out[0] != 0 && out[strlen(out) - 1] == '\n') + out[strlen(out) - 1] = 0; + if (debug) + printf("[DEBUG] TEMP head %d: pass == %s, login == %s\n", j, out, hydra_heads[j]->current_login_ptr); + if (out[0] != 0 || hydra_heads[j]->current_login_ptr[0] != 0) { + hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1); + strcpy(hydra_heads[j]->current_pass_ptr, out); + if (debug) + printf("[DEBUG] redo: %d %s/%s\n", j, hydra_heads[j]->current_login_ptr, hydra_heads[j]->current_pass_ptr); + } else { + hydra_heads[j]->redo = 0; + free(hydra_heads[j]->current_login_ptr); + hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login; + } + } else { + hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login; + } } if (debug) - printf("[DEBUG] reading restore file: Step 12 complete\n"); + printf("[DEBUG] reading restore file: Step 12 complete\n"); sck = fgets(out, sizeof(out), f); if (out[0] != 0 && out[strlen(out) - 1] == '\n') - out[strlen(out) - 1] = 0; + out[strlen(out) - 1] = 0; if (strcmp(out, PROGRAM) != 0) { - fprintf(stderr, "[ERROR] invalid restore file (end)\n"); - exit(-1); + fprintf(stderr, "[ERROR] invalid restore file (end)\n"); + exit(-1); } fclose(f); hydra_debug(0, "hydra_restore_read"); @@ -950,17 +950,17 @@ void killed_childs(int32_t signo) { killed++; pid = wait3(NULL, WNOHANG, NULL); for (i = 0; i < hydra_options.max_use; i++) { - if (pid == hydra_heads[i]->pid) { - hydra_heads[i]->pid = -1; - hydra_kill_head(i, 1, 0); - return; - } + if (pid == hydra_heads[i]->pid) { + hydra_heads[i]->pid = -1; + hydra_kill_head(i, 1, 0); + return; + } } } void killed_childs_report(int32_t signo) { if (debug) - printf("[DEBUG] children crashed! (%d)\n", child_head_no); + printf("[DEBUG] children crashed! (%d)\n", child_head_no); fck = write(child_socket, "E", 1); _exit(-1); } @@ -969,16 +969,16 @@ void kill_children(int32_t signo) { int32_t i; if (verbose) - fprintf(stderr, "[ERROR] Received signal %d, going down ...\n", signo); + fprintf(stderr, "[ERROR] Received signal %d, going down ...\n", signo); if (process_restore == 1) - hydra_restore_write(1); + hydra_restore_write(1); if (hydra_heads != NULL) { - for (i = 0; i < hydra_options.max_use; i++) - if (hydra_heads[i] != NULL && hydra_heads[i]->pid > 0) - kill(hydra_heads[i]->pid, SIGTERM); - for (i = 0; i < hydra_options.max_use; i++) - if (hydra_heads[i] != NULL && hydra_heads[i]->pid > 0) - kill(hydra_heads[i]->pid, SIGKILL); + for (i = 0; i < hydra_options.max_use; i++) + if (hydra_heads[i] != NULL && hydra_heads[i]->pid > 0) + kill(hydra_heads[i]->pid, SIGTERM); + for (i = 0; i < hydra_options.max_use; i++) + if (hydra_heads[i] != NULL && hydra_heads[i]->pid > 0) + kill(hydra_heads[i]->pid, SIGKILL); } exit(0); } @@ -998,23 +998,23 @@ uint64_t countlines(FILE * fd, int32_t colonmode) { #ifdef HAVE_ZLIB while (!gzeof(fp)) { - if (gzgets(fp, buf, MAXLINESIZE) != NULL) { + if (gzgets(fp, buf, MAXLINESIZE) != NULL) { #else while (!feof(fp)) { - if (fgets(buf, MAXLINESIZE, fp) != NULL) { + if (fgets(buf, MAXLINESIZE, fp) != NULL) { #endif - size_of_data += strlen(buf); - if (buf[0] != 0) { - if (buf[0] == '\r' || buf[0] == '\n') { - if (only_one_empty_line == 0) { - only_one_empty_line = 1; - clines++; - } - } else { - clines++; - } - } - } + size_of_data += strlen(buf); + if (buf[0] != 0) { + if (buf[0] == '\r' || buf[0] == '\n') { + if (only_one_empty_line == 0) { + only_one_empty_line = 1; + clines++; + } + } else { + clines++; + } + } + } } #ifdef HAVE_ZLIB gzrewind(fp); @@ -1033,47 +1033,47 @@ void fill_mem(char *ptr, FILE * fd, int32_t colonmode) { gzFile fp = gzdopen(fileno(fd), "r"); while (!gzeof(fp)) { - if (gzgets(fp, tmp, MAXLINESIZE) != NULL) { + if (gzgets(fp, tmp, MAXLINESIZE) != NULL) { #else FILE *fp = fd; while (!feof(fp)) { - if (fgets(tmp, MAXLINESIZE, fp) != NULL) { + if (fgets(tmp, MAXLINESIZE, fp) != NULL) { #endif - if (tmp[0] != 0) { - if (tmp[strlen(tmp) - 1] == '\n') - tmp[strlen(tmp) - 1] = '\0'; - if (tmp[0] != 0 && tmp[strlen(tmp) - 1] == '\r') - tmp[strlen(tmp) - 1] = '\0'; - if ((len = strlen(tmp)) > 0 || (only_one_empty_line == 0 && colonmode == 0)) { - if (len == 0 && colonmode == 0) { - only_one_empty_line = 1; - len = 1; - tmp[len] = 0; - } - if (colonmode) { - if ((ptr2 = index(tmp, ':')) == NULL) { - fprintf(stderr, "[ERROR] invalid line in colon file (-C), missing colon in line: %s\n", tmp); - exit(-1); - } else { - // if (tmp[0] == ':') { - // *ptr = 0; - // ptr++; - // } - // if (tmp[len - 1] == ':' && len > 1) { - // len++; - // tmp[len - 1] = 0; - // } - *ptr2 = 0; - } - } - memcpy(ptr, tmp, len); - ptr += len; - *ptr = '\0'; - ptr++; - } - } - } + if (tmp[0] != 0) { + if (tmp[strlen(tmp) - 1] == '\n') + tmp[strlen(tmp) - 1] = '\0'; + if (tmp[0] != 0 && tmp[strlen(tmp) - 1] == '\r') + tmp[strlen(tmp) - 1] = '\0'; + if ((len = strlen(tmp)) > 0 || (only_one_empty_line == 0 && colonmode == 0)) { + if (len == 0 && colonmode == 0) { + only_one_empty_line = 1; + len = 1; + tmp[len] = 0; + } + if (colonmode) { + if ((ptr2 = index(tmp, ':')) == NULL) { + fprintf(stderr, "[ERROR] invalid line in colon file (-C), missing colon in line: %s\n", tmp); + exit(-1); + } else { + // if (tmp[0] == ':') { + // *ptr = 0; + // ptr++; + // } + // if (tmp[len - 1] == ':' && len > 1) { + // len++; + // tmp[len - 1] = 0; + // } + *ptr2 = 0; + } + } + memcpy(ptr, tmp, len); + ptr += len; + *ptr = '\0'; + ptr++; + } + } + } } #ifdef HAVE_ZLIB gzclose(fp); @@ -1101,28 +1101,28 @@ void hydra_service_init(int32_t target_no) { 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, miscptr, ofp, t->port, t->target); - break; - } - } + if (strcmp(hydra_options.service, services[i].name) == 0) { + if (services[i].init) { + x = services[i].init(t->ip, -1, options, miscptr, ofp, t->port, t->target); + break; + } + } } // dirty workaround here: #ifdef LIBSSH if (strcmp(hydra_options.service, "ssh") == 0) - x = service_ssh_init(t->ip, -1, options, login_ptr, ofp, t->port, t->target); + x = service_ssh_init(t->ip, -1, options, login_ptr, ofp, t->port, t->target); #endif if (x != 0 && x != 99) { - if (x > 0 && x < 4) - hydra_targets[target_no]->done = x; - else - hydra_targets[target_no]->done = TARGET_ERROR; - hydra_brains.finished++; - if (hydra_brains.targets == 1) - exit(-1); + if (x > 0 && x < 4) + hydra_targets[target_no]->done = x; + else + hydra_targets[target_no]->done = TARGET_ERROR; + hydra_brains.finished++; + if (hydra_brains.targets == 1) + exit(-1); } } @@ -1130,96 +1130,96 @@ int32_t hydra_spawn_head(int32_t head_no, int32_t target_no) { int32_t i; if (head_no < 0 || head_no >= hydra_options.max_use || target_no < 0 || target_no >= hydra_brains.targets) { - if (verbose > 1 || debug) - printf("[DEBUG-ERROR] spawn_head: head_no %d, target_no %d\n", head_no, target_no); - return -1; + if (verbose > 1 || debug) + printf("[DEBUG-ERROR] spawn_head: head_no %d, target_no %d\n", head_no, target_no); + return -1; } if (hydra_heads[head_no]->active == HEAD_DISABLED) { - printf("[DEBUG-ERROR] child %d should not be respawned!\n", head_no); - return -1; + printf("[DEBUG-ERROR] child %d should not be respawned!\n", head_no); + return -1; } if (socketpair(PF_UNIX, SOCK_STREAM, 0, hydra_heads[head_no]->sp) == 0) { - child_head_no = head_no; - if ((hydra_heads[head_no]->pid = fork()) == 0) { // THIS IS THE CHILD - // set new signals for child - process_restore = 0; - child_socket = hydra_heads[head_no]->sp[1]; - signal(SIGCHLD, killed_childs); - signal(SIGTERM, exit); + child_head_no = head_no; + if ((hydra_heads[head_no]->pid = fork()) == 0) { // THIS IS THE CHILD + // set new signals for child + process_restore = 0; + child_socket = hydra_heads[head_no]->sp[1]; + signal(SIGCHLD, killed_childs); + signal(SIGTERM, exit); #ifdef SIGBUS - signal(SIGBUS, exit); + signal(SIGBUS, exit); #endif - signal(SIGSEGV, killed_childs_report); - signal(SIGHUP, exit); - signal(SIGINT, exit); - signal(SIGPIPE, exit); - // free structures to make memory available - cmdlinetarget = hydra_targets[target_no]->target; - for (i = 0; i < hydra_options.max_use; i++) - if (i != head_no) - free(hydra_heads[i]); - for (i = 0; i < hydra_brains.targets; i++) - if (i != target_no) - free(hydra_targets[i]); - if (hydra_options.loginfile != NULL) - free(login_ptr); - if (hydra_options.passfile != NULL) - free(pass_ptr); - if (hydra_options.colonfile != NULL && hydra_options.colonfile != empty_login) - free(csv_ptr); - // we must keep servers_ptr for cmdlinetarget to work - if (debug) - printf("[DEBUG] head_no %d has pid %d\n", head_no, getpid()); + signal(SIGSEGV, killed_childs_report); + signal(SIGHUP, exit); + signal(SIGINT, exit); + signal(SIGPIPE, exit); + // free structures to make memory available + cmdlinetarget = hydra_targets[target_no]->target; + for (i = 0; i < hydra_options.max_use; i++) + if (i != head_no) + free(hydra_heads[i]); + for (i = 0; i < hydra_brains.targets; i++) + if (i != target_no) + free(hydra_targets[i]); + if (hydra_options.loginfile != NULL) + free(login_ptr); + if (hydra_options.passfile != NULL) + free(pass_ptr); + if (hydra_options.colonfile != NULL && hydra_options.colonfile != empty_login) + free(csv_ptr); + // we must keep servers_ptr for cmdlinetarget to work + if (debug) + printf("[DEBUG] head_no %d has pid %d\n", head_no, getpid()); - hydra_target* t = hydra_targets[target_no]; - int32_t sp = hydra_heads[head_no]->sp[1]; - 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, miscptr, ofp, t->port, head_target->target); - // just in case a module returns (which it shouldnt) we let it exit here - exit(-1); - } - } - } + hydra_target* t = hydra_targets[target_no]; + int32_t sp = hydra_heads[head_no]->sp[1]; + 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, miscptr, ofp, t->port, head_target->target); + // just in case a module returns (which it shouldnt) we let it exit here + exit(-1); + } + } + } - // FIXME: dirty workaround here - if (strcmp(hydra_options.service, "xmpp") == 0) { - service_xmpp(hydra_targets[target_no]->target, hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port, hydra_targets[hydra_heads[head_no]->target_no]->target); - } + // FIXME: dirty workaround here + if (strcmp(hydra_options.service, "xmpp") == 0) { + service_xmpp(hydra_targets[target_no]->target, hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port, hydra_targets[hydra_heads[head_no]->target_no]->target); + } - // just in case a module returns (which it shouldnt) we let it exit here - exit(-1); - } else { - child_head_no = -1; - if (hydra_heads[head_no]->pid > 0) { - fck = write(hydra_heads[head_no]->sp[1], "n", 1); // yes, a small "n" - this way we can distinguish later if the client successfully tested a pair and is requesting a new one or the mother did that - (void) fcntl(hydra_heads[head_no]->sp[0], F_SETFL, O_NONBLOCK); - if (hydra_heads[head_no]->redo != 1) - hydra_heads[head_no]->target_no = target_no; - hydra_heads[head_no]->active = HEAD_ACTIVE; - hydra_targets[hydra_heads[head_no]->target_no]->use_count++; - hydra_brains.active++; - hydra_heads[head_no]->last_seen = time(NULL); - if (debug) - printf("[DEBUG] child %d spawned for target %d with pid %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->pid); - } else { - perror("[ERROR] Fork for children failed"); - hydra_heads[head_no]->sp[0] = -1; - hydra_heads[head_no]->active = HEAD_UNUSED; - return -1; - } - } + // just in case a module returns (which it shouldnt) we let it exit here + exit(-1); + } else { + child_head_no = -1; + if (hydra_heads[head_no]->pid > 0) { + fck = write(hydra_heads[head_no]->sp[1], "n", 1); // yes, a small "n" - this way we can distinguish later if the client successfully tested a pair and is requesting a new one or the mother did that + (void) fcntl(hydra_heads[head_no]->sp[0], F_SETFL, O_NONBLOCK); + if (hydra_heads[head_no]->redo != 1) + hydra_heads[head_no]->target_no = target_no; + hydra_heads[head_no]->active = HEAD_ACTIVE; + hydra_targets[hydra_heads[head_no]->target_no]->use_count++; + hydra_brains.active++; + hydra_heads[head_no]->last_seen = time(NULL); + if (debug) + printf("[DEBUG] child %d spawned for target %d with pid %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->pid); + } else { + perror("[ERROR] Fork for children failed"); + hydra_heads[head_no]->sp[0] = -1; + hydra_heads[head_no]->active = HEAD_UNUSED; + return -1; + } + } } else { - perror("[ERROR] socketpair creation failed"); - hydra_heads[head_no]->sp[0] = -1; - hydra_heads[head_no]->active = HEAD_UNUSED; - return -1; + perror("[ERROR] socketpair creation failed"); + hydra_heads[head_no]->sp[0] = -1; + hydra_heads[head_no]->active = HEAD_UNUSED; + return -1; } return 0; } @@ -1228,129 +1228,129 @@ int32_t hydra_lookup_port(char *service) { int32_t i = 0, port = -2; hydra_portlist hydra_portlists[] = { - {"ftp", PORT_FTP, PORT_FTP_SSL}, - {"ftps", PORT_FTP, PORT_FTP_SSL}, - {"http-head", PORT_HTTP, PORT_HTTP_SSL}, - {"http-post", PORT_HTTP, PORT_HTTP_SSL}, - {"http-get", PORT_HTTP, PORT_HTTP_SSL}, - {"http-get-form", PORT_HTTP, PORT_HTTP_SSL}, - {"http-post-form", PORT_HTTP, PORT_HTTP_SSL}, - {"https-get-form", PORT_HTTP, PORT_HTTP_SSL}, - {"https-post-form", PORT_HTTP, PORT_HTTP_SSL}, - {"https-head", PORT_HTTP, PORT_HTTP_SSL}, - {"https-get", PORT_HTTP, PORT_HTTP_SSL}, - {"http-proxy", PORT_HTTP_PROXY, PORT_HTTP_PROXY_SSL}, - {"http-proxy-urlenum", PORT_HTTP_PROXY, PORT_HTTP_PROXY_SSL}, - {"icq", PORT_ICQ, PORT_ICQ_SSL}, - {"imap", PORT_IMAP, PORT_IMAP_SSL}, - {"ldap2", PORT_LDAP, PORT_LDAP_SSL}, - {"ldap3", PORT_LDAP, PORT_LDAP_SSL}, - {"ldap3-crammd5", PORT_LDAP, PORT_LDAP_SSL}, - {"ldap3-digestmd5", PORT_LDAP, PORT_LDAP_SSL}, - {"oracle-listener", PORT_ORACLE, PORT_ORACLE_SSL}, - {"oracle-sid", PORT_ORACLE, PORT_ORACLE_SSL}, - {"oracle", PORT_ORACLE, PORT_ORACLE_SSL}, - {"mssql", PORT_MSSQL, PORT_MSSQL_SSL}, - {"mysql", PORT_MYSQL, PORT_MYSQL_SSL}, - {"postgres", PORT_POSTGRES, PORT_POSTGRES_SSL}, - {"pcanywhere", PORT_PCANYWHERE, PORT_PCANYWHERE_SSL}, - {"nntp", PORT_NNTP, PORT_NNTP_SSL}, - {"pcnfs", PORT_PCNFS, PORT_PCNFS_SSL}, - {"pop3", PORT_POP3, PORT_POP3_SSL}, - {"redis", PORT_REDIS, PORT_REDIS_SSL}, - {"rexec", PORT_REXEC, PORT_REXEC_SSL}, - {"rlogin", PORT_RLOGIN, PORT_RLOGIN_SSL}, - {"rsh", PORT_RSH, PORT_RSH_SSL}, - {"sapr3", PORT_SAPR3, PORT_SAPR3_SSL}, - {"smb", PORT_SMBNT, PORT_SMBNT_SSL}, - {"smbnt", PORT_SMBNT, PORT_SMBNT_SSL}, - {"socks5", PORT_SOCKS5, PORT_SOCKS5_SSL}, - {"ssh", PORT_SSH, PORT_SSH_SSL}, - {"sshkey", PORT_SSH, PORT_SSH_SSL}, - {"telnet", PORT_TELNET, PORT_TELNET_SSL}, - {"adam6500", PORT_ADAM6500, PORT_ADAM6500_SSL}, - {"cisco", PORT_TELNET, PORT_TELNET_SSL}, - {"cisco-enable", PORT_TELNET, PORT_TELNET_SSL}, - {"vnc", PORT_VNC, PORT_VNC_SSL}, - {"snmp", PORT_SNMP, PORT_SNMP_SSL}, - {"cvs", PORT_CVS, PORT_CVS_SSL}, - {"svn", PORT_SVN, PORT_SVN_SSL}, - {"firebird", PORT_FIREBIRD, PORT_FIREBIRD_SSL}, - {"afp", PORT_AFP, PORT_AFP_SSL}, - {"ncp", PORT_NCP, PORT_NCP_SSL}, - {"smtp", PORT_SMTP, PORT_SMTP_SSL}, - {"smtp-enum", PORT_SMTP, PORT_SMTP_SSL}, - {"teamspeak", PORT_TEAMSPEAK, PORT_TEAMSPEAK_SSL}, - {"sip", PORT_SIP, PORT_SIP_SSL}, - {"vmauthd", PORT_VMAUTHD, PORT_VMAUTHD_SSL}, - {"xmpp", PORT_XMPP, PORT_XMPP_SSL}, - {"irc", PORT_IRC, PORT_IRC_SSL}, - {"rdp", PORT_RDP, PORT_RDP_SSL}, - {"asterisk", PORT_ASTERISK, PORT_ASTERISK_SSL}, - {"s7-300", PORT_S7_300, PORT_S7_300_SSL}, - {"rtsp", PORT_RTSP, PORT_RTSP_SSL}, - {"rpcap", PORT_RPCAP, PORT_RPCAP_SSL}, - {"radmin2", PORT_RADMIN2, PORT_RADMIN2}, - // ADD NEW SERVICES HERE - add new port numbers to hydra.h - {"", PORT_NOPORT, PORT_NOPORT} + {"ftp", PORT_FTP, PORT_FTP_SSL}, + {"ftps", PORT_FTP, PORT_FTP_SSL}, + {"http-head", PORT_HTTP, PORT_HTTP_SSL}, + {"http-post", PORT_HTTP, PORT_HTTP_SSL}, + {"http-get", PORT_HTTP, PORT_HTTP_SSL}, + {"http-get-form", PORT_HTTP, PORT_HTTP_SSL}, + {"http-post-form", PORT_HTTP, PORT_HTTP_SSL}, + {"https-get-form", PORT_HTTP, PORT_HTTP_SSL}, + {"https-post-form", PORT_HTTP, PORT_HTTP_SSL}, + {"https-head", PORT_HTTP, PORT_HTTP_SSL}, + {"https-get", PORT_HTTP, PORT_HTTP_SSL}, + {"http-proxy", PORT_HTTP_PROXY, PORT_HTTP_PROXY_SSL}, + {"http-proxy-urlenum", PORT_HTTP_PROXY, PORT_HTTP_PROXY_SSL}, + {"icq", PORT_ICQ, PORT_ICQ_SSL}, + {"imap", PORT_IMAP, PORT_IMAP_SSL}, + {"ldap2", PORT_LDAP, PORT_LDAP_SSL}, + {"ldap3", PORT_LDAP, PORT_LDAP_SSL}, + {"ldap3-crammd5", PORT_LDAP, PORT_LDAP_SSL}, + {"ldap3-digestmd5", PORT_LDAP, PORT_LDAP_SSL}, + {"oracle-listener", PORT_ORACLE, PORT_ORACLE_SSL}, + {"oracle-sid", PORT_ORACLE, PORT_ORACLE_SSL}, + {"oracle", PORT_ORACLE, PORT_ORACLE_SSL}, + {"mssql", PORT_MSSQL, PORT_MSSQL_SSL}, + {"mysql", PORT_MYSQL, PORT_MYSQL_SSL}, + {"postgres", PORT_POSTGRES, PORT_POSTGRES_SSL}, + {"pcanywhere", PORT_PCANYWHERE, PORT_PCANYWHERE_SSL}, + {"nntp", PORT_NNTP, PORT_NNTP_SSL}, + {"pcnfs", PORT_PCNFS, PORT_PCNFS_SSL}, + {"pop3", PORT_POP3, PORT_POP3_SSL}, + {"redis", PORT_REDIS, PORT_REDIS_SSL}, + {"rexec", PORT_REXEC, PORT_REXEC_SSL}, + {"rlogin", PORT_RLOGIN, PORT_RLOGIN_SSL}, + {"rsh", PORT_RSH, PORT_RSH_SSL}, + {"sapr3", PORT_SAPR3, PORT_SAPR3_SSL}, + {"smb", PORT_SMBNT, PORT_SMBNT_SSL}, + {"smbnt", PORT_SMBNT, PORT_SMBNT_SSL}, + {"socks5", PORT_SOCKS5, PORT_SOCKS5_SSL}, + {"ssh", PORT_SSH, PORT_SSH_SSL}, + {"sshkey", PORT_SSH, PORT_SSH_SSL}, + {"telnet", PORT_TELNET, PORT_TELNET_SSL}, + {"adam6500", PORT_ADAM6500, PORT_ADAM6500_SSL}, + {"cisco", PORT_TELNET, PORT_TELNET_SSL}, + {"cisco-enable", PORT_TELNET, PORT_TELNET_SSL}, + {"vnc", PORT_VNC, PORT_VNC_SSL}, + {"snmp", PORT_SNMP, PORT_SNMP_SSL}, + {"cvs", PORT_CVS, PORT_CVS_SSL}, + {"svn", PORT_SVN, PORT_SVN_SSL}, + {"firebird", PORT_FIREBIRD, PORT_FIREBIRD_SSL}, + {"afp", PORT_AFP, PORT_AFP_SSL}, + {"ncp", PORT_NCP, PORT_NCP_SSL}, + {"smtp", PORT_SMTP, PORT_SMTP_SSL}, + {"smtp-enum", PORT_SMTP, PORT_SMTP_SSL}, + {"teamspeak", PORT_TEAMSPEAK, PORT_TEAMSPEAK_SSL}, + {"sip", PORT_SIP, PORT_SIP_SSL}, + {"vmauthd", PORT_VMAUTHD, PORT_VMAUTHD_SSL}, + {"xmpp", PORT_XMPP, PORT_XMPP_SSL}, + {"irc", PORT_IRC, PORT_IRC_SSL}, + {"rdp", PORT_RDP, PORT_RDP_SSL}, + {"asterisk", PORT_ASTERISK, PORT_ASTERISK_SSL}, + {"s7-300", PORT_S7_300, PORT_S7_300_SSL}, + {"rtsp", PORT_RTSP, PORT_RTSP_SSL}, + {"rpcap", PORT_RPCAP, PORT_RPCAP_SSL}, + {"radmin2", PORT_RADMIN2, PORT_RADMIN2}, + // ADD NEW SERVICES HERE - add new port numbers to hydra.h + {"", PORT_NOPORT, PORT_NOPORT} }; while (strlen(hydra_portlists[i].name) > 0 && port == -2) { - if (strcmp(service, hydra_portlists[i].name) == 0) { - if (hydra_options.ssl) - port = hydra_portlists[i].port_ssl; - else - port = hydra_portlists[i].port; - } - i++; + if (strcmp(service, hydra_portlists[i].name) == 0) { + if (hydra_options.ssl) + port = hydra_portlists[i].port_ssl; + else + port = hydra_portlists[i].port; + } + i++; } if (port < 1) - return -1; + return -1; else - return port; + return port; } // killit = 1 : kill(pid); fail = 1 : redo, fail = 2/3 : disable void hydra_kill_head(int32_t head_no, int32_t killit, int32_t fail) { if (debug) - printf("[DEBUG] head_no %d, kill %d, fail %d\n", head_no, killit, fail); + printf("[DEBUG] head_no %d, kill %d, fail %d\n", head_no, killit, fail); if (head_no < 0) - return; + return; if (hydra_heads[head_no]->active == HEAD_ACTIVE || (hydra_heads[head_no]->sp[0] > 2 && hydra_heads[head_no]->sp[1] > 2)) { - close(hydra_heads[head_no]->sp[0]); - close(hydra_heads[head_no]->sp[1]); + close(hydra_heads[head_no]->sp[0]); + close(hydra_heads[head_no]->sp[1]); } if (killit) { - if (hydra_heads[head_no]->pid > 0) - kill(hydra_heads[head_no]->pid, SIGTERM); - hydra_brains.active--; + if (hydra_heads[head_no]->pid > 0) + kill(hydra_heads[head_no]->pid, SIGTERM); + hydra_brains.active--; } if (hydra_heads[head_no]->active == HEAD_ACTIVE) { - hydra_heads[head_no]->active = HEAD_UNUSED; - hydra_targets[hydra_heads[head_no]->target_no]->use_count--; + hydra_heads[head_no]->active = HEAD_UNUSED; + hydra_targets[hydra_heads[head_no]->target_no]->use_count--; } if (fail == 1) { - if (hydra_options.cidr != 1) - hydra_heads[head_no]->redo = 1; + if (hydra_options.cidr != 1) + hydra_heads[head_no]->redo = 1; } else if (fail == 2) { - if (hydra_options.cidr != 1) - hydra_heads[head_no]->active = HEAD_DISABLED; - if (hydra_heads[head_no]->target_no >= 0) - hydra_targets[hydra_heads[head_no]->target_no]->failed++; + if (hydra_options.cidr != 1) + hydra_heads[head_no]->active = HEAD_DISABLED; + if (hydra_heads[head_no]->target_no >= 0) + hydra_targets[hydra_heads[head_no]->target_no]->failed++; } else if (fail == 3) { - hydra_heads[head_no]->active = HEAD_DISABLED; - if (hydra_heads[head_no]->target_no >= 0) - hydra_targets[hydra_heads[head_no]->target_no]->failed++; + hydra_heads[head_no]->active = HEAD_DISABLED; + if (hydra_heads[head_no]->target_no >= 0) + hydra_targets[hydra_heads[head_no]->target_no]->failed++; } if (hydra_heads[head_no]->pid > 0 && killit) - kill(hydra_heads[head_no]->pid, SIGKILL); + kill(hydra_heads[head_no]->pid, SIGKILL); hydra_heads[head_no]->pid = -1; if (fail < 1 && hydra_heads[head_no]->target_no >= 0 && hydra_options.bfg && hydra_targets[hydra_heads[head_no]->target_no]->pass_state == 3 - && strlen(hydra_heads[head_no]->current_pass_ptr) > 0 && hydra_heads[head_no]->current_pass_ptr != hydra_heads[head_no]->current_login_ptr) { - free(hydra_heads[head_no]->current_pass_ptr); - hydra_heads[head_no]->current_pass_ptr = empty_login; - // hydra_bfg_remove(head_no); - // hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = NULL; + && strlen(hydra_heads[head_no]->current_pass_ptr) > 0 && hydra_heads[head_no]->current_pass_ptr != hydra_heads[head_no]->current_login_ptr) { + free(hydra_heads[head_no]->current_pass_ptr); + hydra_heads[head_no]->current_pass_ptr = empty_login; + // hydra_bfg_remove(head_no); + // hydra_targets[hydra_heads[head_no]->target_no]->bfg_ptr[head_no] = NULL; } (void) wait3(NULL, WNOHANG, NULL); } @@ -1359,89 +1359,89 @@ void hydra_increase_fail_count(int32_t target_no, int32_t head_no) { int32_t i, k, maxfail = 0; if (target_no < 0) - return; + return; if (hydra_targets[target_no]->ok) { - const int32_t tasks = hydra_options.tasks; - const int32_t success = tasks - hydra_targets[target_no]->failed; - const int32_t t = tasks < 5 ? 6 - tasks : 1; - const int32_t s = success < 5 ? 6 - success : 1; - maxfail = MAXFAIL + t + s + 2; + const int32_t tasks = hydra_options.tasks; + const int32_t success = tasks - hydra_targets[target_no]->failed; + const int32_t t = tasks < 5 ? 6 - tasks : 1; + const int32_t s = success < 5 ? 6 - success : 1; + maxfail = MAXFAIL + t + s + 2; } hydra_targets[target_no]->fail_count++; if (debug) - printf("[DEBUG] hydra_increase_fail_count: %d >= %d => disable\n", hydra_targets[target_no]->fail_count, maxfail); + printf("[DEBUG] hydra_increase_fail_count: %d >= %d => disable\n", hydra_targets[target_no]->fail_count, maxfail); if (hydra_targets[target_no]->fail_count >= maxfail) { - k = 0; - for (i = 0; i < hydra_options.max_use; i++) - if (hydra_heads[i]->active >= HEAD_UNUSED && hydra_heads[i]->target_no == target_no) - k++; - if (k <= 1) { - // we need to put this in a list, otherwise we fail one login+pw test - if (hydra_targets[target_no]->done == TARGET_ACTIVE - && hydra_targets[target_no]->redo <= hydra_options.max_use * 2 - && ((hydra_heads[head_no]->current_login_ptr != empty_login && hydra_heads[head_no]->current_pass_ptr != empty_login) - || (hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL))) { - hydra_targets[target_no]->redo_login[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_login_ptr; - hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_pass_ptr; - hydra_targets[target_no]->redo++; - total_redo_count++; - if (debug) - printf("[DEBUG] - will be retried at the end: ip %s - login %s - pass %s - child %d\n", hydra_targets[target_no]->target, - hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no); - hydra_heads[head_no]->current_login_ptr = empty_login; - hydra_heads[head_no]->current_pass_ptr = empty_login; - } - if (hydra_targets[target_no]->fail_count >= MAXFAIL + hydra_options.tasks * hydra_targets[target_no]->ok) { - if (hydra_targets[target_no]->done == TARGET_ACTIVE && hydra_options.max_use == hydra_targets[target_no]->failed) { - if (hydra_targets[target_no]->ok == 1) - hydra_targets[target_no]->done = TARGET_ERROR; // mark target as done by errors - else - hydra_targets[target_no]->done = TARGET_UNRESOLVED; // mark target as done by unable to connect - hydra_brains.finished++; - fprintf(stderr, "[ERROR] Too many connect errors to target, disabling %s://%s%s%s:%d\n", hydra_options.service, hydra_targets[target_no]->ip[0] == 16 - && index(hydra_targets[target_no]->target, ':') != NULL ? "[" : "", hydra_targets[target_no]->target, hydra_targets[target_no]->ip[0] == 16 - && index(hydra_targets[target_no]->target, ':') != NULL ? "]" : "", hydra_targets[target_no]->port); - } - if (hydra_brains.targets > hydra_brains.finished) - hydra_kill_head(head_no, 1, 0); - else - hydra_kill_head(head_no, 1, 2); - } // we keep the last one alive as long as it make sense - } else { - // we need to put this in a list, otherwise we fail one login+pw test - if (hydra_targets[target_no]->done == TARGET_ACTIVE - && hydra_targets[target_no]->redo <= hydra_options.max_use * 2 - && ((hydra_heads[head_no]->current_login_ptr != empty_login && hydra_heads[head_no]->current_pass_ptr != empty_login) - || (hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL))) { - hydra_targets[target_no]->redo_login[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_login_ptr; - hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_pass_ptr; - hydra_targets[target_no]->redo++; - total_redo_count++; - if (debug) - printf("[DEBUG] - will be retried at the end: ip %s - login %s - pass %s - child %d\n", hydra_targets[target_no]->target, - hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no); - hydra_heads[head_no]->current_login_ptr = empty_login; - hydra_heads[head_no]->current_pass_ptr = empty_login; - } - hydra_targets[target_no]->fail_count--; - if (k < 5 && hydra_targets[target_no]->ok) - hydra_targets[target_no]->fail_count--; - if (k == 2 && hydra_targets[target_no]->ok) - hydra_targets[target_no]->fail_count--; - if (hydra_brains.targets > hydra_brains.finished) - hydra_kill_head(head_no, 1, 0); - else { - hydra_kill_head(head_no, 1, 2); - if (verbose) - printf("[VERBOSE] Disabled child %d because of too many errors\n", head_no); - } - } + k = 0; + for (i = 0; i < hydra_options.max_use; i++) + if (hydra_heads[i]->active >= HEAD_UNUSED && hydra_heads[i]->target_no == target_no) + k++; + if (k <= 1) { + // we need to put this in a list, otherwise we fail one login+pw test + if (hydra_targets[target_no]->done == TARGET_ACTIVE + && hydra_targets[target_no]->redo <= hydra_options.max_use * 2 + && ((hydra_heads[head_no]->current_login_ptr != empty_login && hydra_heads[head_no]->current_pass_ptr != empty_login) + || (hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL))) { + hydra_targets[target_no]->redo_login[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_login_ptr; + hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_pass_ptr; + hydra_targets[target_no]->redo++; + total_redo_count++; + if (debug) + printf("[DEBUG] - will be retried at the end: ip %s - login %s - pass %s - child %d\n", hydra_targets[target_no]->target, + hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no); + hydra_heads[head_no]->current_login_ptr = empty_login; + hydra_heads[head_no]->current_pass_ptr = empty_login; + } + if (hydra_targets[target_no]->fail_count >= MAXFAIL + hydra_options.tasks * hydra_targets[target_no]->ok) { + if (hydra_targets[target_no]->done == TARGET_ACTIVE && hydra_options.max_use == hydra_targets[target_no]->failed) { + if (hydra_targets[target_no]->ok == 1) + hydra_targets[target_no]->done = TARGET_ERROR; // mark target as done by errors + else + hydra_targets[target_no]->done = TARGET_UNRESOLVED; // mark target as done by unable to connect + hydra_brains.finished++; + fprintf(stderr, "[ERROR] Too many connect errors to target, disabling %s://%s%s%s:%d\n", hydra_options.service, hydra_targets[target_no]->ip[0] == 16 + && index(hydra_targets[target_no]->target, ':') != NULL ? "[" : "", hydra_targets[target_no]->target, hydra_targets[target_no]->ip[0] == 16 + && index(hydra_targets[target_no]->target, ':') != NULL ? "]" : "", hydra_targets[target_no]->port); + } + if (hydra_brains.targets > hydra_brains.finished) + hydra_kill_head(head_no, 1, 0); + else + hydra_kill_head(head_no, 1, 2); + } // we keep the last one alive as long as it make sense + } else { + // we need to put this in a list, otherwise we fail one login+pw test + if (hydra_targets[target_no]->done == TARGET_ACTIVE + && hydra_targets[target_no]->redo <= hydra_options.max_use * 2 + && ((hydra_heads[head_no]->current_login_ptr != empty_login && hydra_heads[head_no]->current_pass_ptr != empty_login) + || (hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL))) { + hydra_targets[target_no]->redo_login[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_login_ptr; + hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo] = hydra_heads[head_no]->current_pass_ptr; + hydra_targets[target_no]->redo++; + total_redo_count++; + if (debug) + printf("[DEBUG] - will be retried at the end: ip %s - login %s - pass %s - child %d\n", hydra_targets[target_no]->target, + hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no); + hydra_heads[head_no]->current_login_ptr = empty_login; + hydra_heads[head_no]->current_pass_ptr = empty_login; + } + hydra_targets[target_no]->fail_count--; + if (k < 5 && hydra_targets[target_no]->ok) + hydra_targets[target_no]->fail_count--; + if (k == 2 && hydra_targets[target_no]->ok) + hydra_targets[target_no]->fail_count--; + if (hydra_brains.targets > hydra_brains.finished) + hydra_kill_head(head_no, 1, 0); + else { + hydra_kill_head(head_no, 1, 2); + if (verbose) + printf("[VERBOSE] Disabled child %d because of too many errors\n", head_no); + } + } } else { - hydra_kill_head(head_no, 1, 1); - if (verbose) - printf("[VERBOSE] Retrying connection for child %d\n", head_no); + hydra_kill_head(head_no, 1, 1); + if (verbose) + printf("[VERBOSE] Retrying connection for child %d\n", head_no); } } @@ -1451,13 +1451,13 @@ char *hydra_reverse_login(int32_t head_no, char *login) { unsigned char keep; if (login == NULL || (j = strlen(login)) < 1) - return empty_login; + return empty_login; if (j > 248) - j = 248; + j = 248; for (i = 0; i < j; i++) - hydra_heads[head_no]->reverse[i] = login[j - (i + 1)]; + hydra_heads[head_no]->reverse[i] = login[j - (i + 1)]; hydra_heads[head_no]->reverse[j] = 0; // UTF stuff now @@ -1465,30 +1465,30 @@ char *hydra_reverse_login(int32_t head_no, char *login) { pos = start + j; while(start < --pos) { - switch( (*pos & 0xF0) >> 4 ) { - case 0xF: /* U+010000-U+10FFFF: four bytes. */ - keep = *pos; - *pos = *(pos-3); - *(pos-3) = keep; - keep = *(pos-1); - *(pos-1) = *(pos-2); - *(pos-2) = keep; - pos -= 3; - break; - case 0xE: /* U+000800-U+00FFFF: three bytes. */ - keep = *pos; - *pos = *(pos-2); - *(pos-2) = keep; - pos -= 2; - break; - case 0xC: /* fall-through */ - case 0xD: /* U+000080-U+0007FF: two bytes. */ - keep = *pos; - *pos = *(pos-1); - *(pos-1) = keep; - pos--; - break; - } + switch( (*pos & 0xF0) >> 4 ) { + case 0xF: /* U+010000-U+10FFFF: four bytes. */ + keep = *pos; + *pos = *(pos-3); + *(pos-3) = keep; + keep = *(pos-1); + *(pos-1) = *(pos-2); + *(pos-2) = keep; + pos -= 3; + break; + case 0xE: /* U+000800-U+00FFFF: three bytes. */ + keep = *pos; + *pos = *(pos-2); + *(pos-2) = keep; + pos -= 2; + break; + case 0xC: /* fall-through */ + case 0xD: /* U+000080-U+0007FF: two bytes. */ + keep = *pos; + *pos = *(pos-1); + *(pos-1) = keep; + pos--; + break; + } } return hydra_heads[head_no]->reverse; @@ -1501,356 +1501,356 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { snpdont = 0; loop_cnt++; if (hydra_heads[head_no]->redo && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { - hydra_heads[head_no]->redo = 0; - snp_is_redo = 1; - snpdone = 1; + hydra_heads[head_no]->redo = 0; + snp_is_redo = 1; + snpdone = 1; } else { - if (hydra_targets[target_no]->sent >= hydra_brains.todo + hydra_targets[target_no]->redo) { - if (hydra_targets[target_no]->done == TARGET_ACTIVE) { - hydra_targets[target_no]->done = TARGET_FINISHED; - hydra_brains.finished++; - if (verbose) - printf("[STATUS] attack finished for %s (waiting for children to complete tests)\n", hydra_targets[target_no]->target); - } - return -1; - } + if (hydra_targets[target_no]->sent >= hydra_brains.todo + hydra_targets[target_no]->redo) { + if (hydra_targets[target_no]->done == TARGET_ACTIVE) { + hydra_targets[target_no]->done = TARGET_FINISHED; + hydra_brains.finished++; + if (verbose) + printf("[STATUS] attack finished for %s (waiting for children to complete tests)\n", hydra_targets[target_no]->target); + } + return -1; + } } if (debug) - printf - ("[DEBUG] send_next_pair_init target %d, head %d, redo %d, redo_state %d, pass_state %d. loop_mode %d, curlogin %s, curpass %s, tlogin %s, tpass %s, logincnt %lu/%lu, passcnt %lu/%lu, loop_cnt %d\n", - target_no, head_no, hydra_targets[target_no]->redo, hydra_targets[target_no]->redo_state, hydra_targets[target_no]->pass_state, hydra_options.loop_mode, - hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->login_ptr, hydra_targets[target_no]->pass_ptr, - hydra_targets[target_no]->login_no, hydra_brains.countlogin, hydra_targets[target_no]->pass_no, hydra_brains.countpass, loop_cnt); + printf + ("[DEBUG] send_next_pair_init target %d, head %d, redo %d, redo_state %d, pass_state %d. loop_mode %d, curlogin %s, curpass %s, tlogin %s, tpass %s, logincnt %lu/%lu, passcnt %lu/%lu, loop_cnt %d\n", + target_no, head_no, hydra_targets[target_no]->redo, hydra_targets[target_no]->redo_state, hydra_targets[target_no]->pass_state, hydra_options.loop_mode, + hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->login_ptr, hydra_targets[target_no]->pass_ptr, + hydra_targets[target_no]->login_no, hydra_brains.countlogin, hydra_targets[target_no]->pass_no, hydra_brains.countpass, loop_cnt); if (loop_cnt > (hydra_brains.countlogin * 2) + 1 && loop_cnt > (hydra_brains.countpass * 2) + 1) { - if (debug) - printf("[DEBUG] too many loops in send_next_pair, returning -1 (loop_cnt %d, sent %lu, todo %lu)\n", loop_cnt, hydra_targets[target_no]->sent, hydra_brains.todo); - return -1; + if (debug) + printf("[DEBUG] too many loops in send_next_pair, returning -1 (loop_cnt %d, sent %lu, todo %lu)\n", loop_cnt, hydra_targets[target_no]->sent, hydra_brains.todo); + return -1; } if (hydra_heads[head_no]->redo && hydra_heads[head_no]->current_login_ptr != NULL && hydra_heads[head_no]->current_pass_ptr != NULL) { - hydra_heads[head_no]->redo = 0; - snp_is_redo = 1; - snpdone = 1; + hydra_heads[head_no]->redo = 0; + snp_is_redo = 1; + snpdone = 1; } else { - if (debug && (hydra_heads[head_no]->current_login_ptr != NULL || hydra_heads[head_no]->current_pass_ptr != NULL)) - printf("[COMPLETED] target %s - login \"%s\" - pass \"%s\" - child %d - %lu of %lu\n", - hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no, - hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo); - hydra_heads[head_no]->redo = 0; - if (hydra_targets[target_no]->redo_state > 0) { - if (hydra_targets[target_no]->redo_state <= hydra_targets[target_no]->redo) { - hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo_state - 1]; - hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->redo_login[hydra_targets[target_no]->redo_state - 1]; - hydra_targets[target_no]->redo_state++; - snpdone = 1; - } else { - // if a pair does not complete after this point it is lost - if (hydra_targets[target_no]->done == TARGET_ACTIVE) { - hydra_targets[target_no]->done = TARGET_FINISHED; - hydra_brains.finished++; - if (verbose) - printf("[STATUS] attack finished for %s (waiting for children to complete tests)\n", hydra_targets[target_no]->target); - } - loop_cnt = 0; - return -1; - } - } else { // normale state, no redo - if (hydra_targets[target_no]->done != TARGET_ACTIVE) { - loop_cnt = 0; - return -1; // head will be disabled by main while() - } - if (hydra_options.loop_mode == 0) { // one user after another - if (hydra_targets[target_no]->login_no < hydra_brains.countlogin) { - // as we loop password in mode == 0 we set the current login first - hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->login_ptr; - // then we do the extra options -e ns handling - if (hydra_targets[target_no]->pass_state == 0 && snpdone == 0) { - if (hydra_options.try_password_same_as_login) { - hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->login_ptr; - snpdone = 1; - hydra_targets[target_no]->pass_no++; - } - hydra_targets[target_no]->pass_state++; - } - if (hydra_targets[target_no]->pass_state == 1 && snpdone == 0) { - // small check that there is a login name (could also be emtpy) and if we already tried empty password it would be a double - if (hydra_options.try_null_password) { - if (hydra_options.try_password_same_as_login == 0 || (hydra_targets[target_no]->login_ptr != NULL && strlen(hydra_targets[target_no]->login_ptr) > 0)) { - hydra_heads[head_no]->current_pass_ptr = empty_login; - snpdone = 1; - } else { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - } - hydra_targets[target_no]->pass_no++; - } - hydra_targets[target_no]->pass_state++; - } - if (hydra_targets[target_no]->pass_state == 2 && snpdone == 0) { - // small check that there is a login name (could also be emtpy) and if we already tried empty password it would be a double - if (hydra_options.try_password_reverse_login) { - if ((hydra_options.try_password_same_as_login == 0 - || strcmp(hydra_targets[target_no]->login_ptr, hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)) != 0) - && (hydra_options.try_null_password == 0 || (hydra_targets[target_no]->login_ptr != NULL && strlen(hydra_targets[target_no]->login_ptr) > 0))) { - hydra_heads[head_no]->current_pass_ptr = hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr); - snpdone = 1; - } else { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - } - hydra_targets[target_no]->pass_no++; - } - hydra_targets[target_no]->pass_state++; - } - // now we handle the -C -l/-L -p/-P data - if (hydra_targets[target_no]->pass_state == 3 && snpdone == 0) { - if (check_flag(hydra_options.mode, MODE_COLON_FILE)) { // colon mode - hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->login_ptr; - hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->pass_ptr; - hydra_targets[target_no]->login_no++; - snpdone = 1; - hydra_targets[target_no]->login_ptr = hydra_targets[target_no]->pass_ptr; - //hydra_targets[target_no]->login_ptr++; - while (*hydra_targets[target_no]->login_ptr != 0) - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->pass_ptr = hydra_targets[target_no]->login_ptr; - //hydra_targets[target_no]->pass_ptr++; - while (*hydra_targets[target_no]->pass_ptr != 0) - hydra_targets[target_no]->pass_ptr++; - hydra_targets[target_no]->pass_ptr++; - if (strcmp(hydra_targets[target_no]->login_ptr, hydra_heads[head_no]->current_login_ptr) != 0) - hydra_targets[target_no]->pass_state = 0; - if ((hydra_options.try_password_same_as_login && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_heads[head_no]->current_login_ptr) == 0) - || (hydra_options.try_null_password && strlen(hydra_heads[head_no]->current_pass_ptr) == 0) - || - (hydra_options.try_password_reverse_login - && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)) == 0)) { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - if (debug) - printf("[DEBUG] double detected (-C)\n"); - return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small - } - } else { // standard -l -L -p -P mode - hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->pass_ptr; - hydra_targets[target_no]->pass_no++; - // double check - if (hydra_targets[target_no]->pass_no >= hydra_brains.countpass) { - // all passwords done, next user for next password - hydra_targets[target_no]->login_ptr++; - while (*hydra_targets[target_no]->login_ptr != 0) - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->pass_ptr = pass_ptr; - hydra_targets[target_no]->login_no++; - hydra_targets[target_no]->pass_no = 0; - hydra_targets[target_no]->pass_state = 0; - if (hydra_brains.countpass == hydra_options.try_password_reverse_login + hydra_options.try_null_password + hydra_options.try_password_same_as_login) - return hydra_send_next_pair(target_no, head_no); - } else { - hydra_targets[target_no]->pass_ptr++; - while (*hydra_targets[target_no]->pass_ptr != 0) - hydra_targets[target_no]->pass_ptr++; - hydra_targets[target_no]->pass_ptr++; - } - if ((hydra_options.try_password_same_as_login && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_heads[head_no]->current_login_ptr) == 0) - || (hydra_options.try_null_password && strlen(hydra_heads[head_no]->current_pass_ptr) == 0) - || - (hydra_options.try_password_reverse_login - && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)) == 0)) { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - if (debug) - printf("[DEBUG] double detected (-Pp)\n"); - return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small - } - snpdone = 1; - } - } - } - } else { // loop_mode == 1 - if (hydra_targets[target_no]->pass_no < hydra_brains.countpass) { - hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->login_ptr; - if (hydra_targets[target_no]->pass_state == 0) { - if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) - hydra_heads[head_no]->current_pass_ptr = strdup(hydra_heads[head_no]->current_login_ptr); - else - hydra_heads[head_no]->current_pass_ptr = hydra_heads[head_no]->current_login_ptr; - } else if (hydra_targets[target_no]->pass_state == 1) { - if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) - hydra_heads[head_no]->current_pass_ptr = strdup(empty_login); - else - hydra_heads[head_no]->current_pass_ptr = empty_login; - } else if (hydra_targets[target_no]->pass_state == 2) { - if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) - hydra_heads[head_no]->current_pass_ptr = strdup(hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)); - else - hydra_heads[head_no]->current_pass_ptr = hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr); - } else { - if (hydra_options.bfg && hydra_targets[target_no]->pass_state == 3 - && hydra_heads[head_no]->current_pass_ptr != NULL && - strlen(hydra_heads[head_no]->current_pass_ptr) > 0 && hydra_heads[head_no]->current_pass_ptr != hydra_heads[head_no]->current_login_ptr) - free(hydra_heads[head_no]->current_pass_ptr); - hydra_heads[head_no]->current_pass_ptr = strdup(hydra_targets[target_no]->pass_ptr); - } - hydra_targets[target_no]->login_no++; - snpdone = 1; + if (debug && (hydra_heads[head_no]->current_login_ptr != NULL || hydra_heads[head_no]->current_pass_ptr != NULL)) + printf("[COMPLETED] target %s - login \"%s\" - pass \"%s\" - child %d - %lu of %lu\n", + hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no, + hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo); + hydra_heads[head_no]->redo = 0; + if (hydra_targets[target_no]->redo_state > 0) { + if (hydra_targets[target_no]->redo_state <= hydra_targets[target_no]->redo) { + hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->redo_pass[hydra_targets[target_no]->redo_state - 1]; + hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->redo_login[hydra_targets[target_no]->redo_state - 1]; + hydra_targets[target_no]->redo_state++; + snpdone = 1; + } else { + // if a pair does not complete after this point it is lost + if (hydra_targets[target_no]->done == TARGET_ACTIVE) { + hydra_targets[target_no]->done = TARGET_FINISHED; + hydra_brains.finished++; + if (verbose) + printf("[STATUS] attack finished for %s (waiting for children to complete tests)\n", hydra_targets[target_no]->target); + } + loop_cnt = 0; + return -1; + } + } else { // normale state, no redo + if (hydra_targets[target_no]->done != TARGET_ACTIVE) { + loop_cnt = 0; + return -1; // head will be disabled by main while() + } + if (hydra_options.loop_mode == 0) { // one user after another + if (hydra_targets[target_no]->login_no < hydra_brains.countlogin) { + // as we loop password in mode == 0 we set the current login first + hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->login_ptr; + // then we do the extra options -e ns handling + if (hydra_targets[target_no]->pass_state == 0 && snpdone == 0) { + if (hydra_options.try_password_same_as_login) { + hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->login_ptr; + snpdone = 1; + hydra_targets[target_no]->pass_no++; + } + hydra_targets[target_no]->pass_state++; + } + if (hydra_targets[target_no]->pass_state == 1 && snpdone == 0) { + // small check that there is a login name (could also be emtpy) and if we already tried empty password it would be a double + if (hydra_options.try_null_password) { + if (hydra_options.try_password_same_as_login == 0 || (hydra_targets[target_no]->login_ptr != NULL && strlen(hydra_targets[target_no]->login_ptr) > 0)) { + hydra_heads[head_no]->current_pass_ptr = empty_login; + snpdone = 1; + } else { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + } + hydra_targets[target_no]->pass_no++; + } + hydra_targets[target_no]->pass_state++; + } + if (hydra_targets[target_no]->pass_state == 2 && snpdone == 0) { + // small check that there is a login name (could also be emtpy) and if we already tried empty password it would be a double + if (hydra_options.try_password_reverse_login) { + if ((hydra_options.try_password_same_as_login == 0 + || strcmp(hydra_targets[target_no]->login_ptr, hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)) != 0) + && (hydra_options.try_null_password == 0 || (hydra_targets[target_no]->login_ptr != NULL && strlen(hydra_targets[target_no]->login_ptr) > 0))) { + hydra_heads[head_no]->current_pass_ptr = hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr); + snpdone = 1; + } else { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + } + hydra_targets[target_no]->pass_no++; + } + hydra_targets[target_no]->pass_state++; + } + // now we handle the -C -l/-L -p/-P data + if (hydra_targets[target_no]->pass_state == 3 && snpdone == 0) { + if (check_flag(hydra_options.mode, MODE_COLON_FILE)) { // colon mode + hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->login_ptr; + hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->pass_ptr; + hydra_targets[target_no]->login_no++; + snpdone = 1; + hydra_targets[target_no]->login_ptr = hydra_targets[target_no]->pass_ptr; + //hydra_targets[target_no]->login_ptr++; + while (*hydra_targets[target_no]->login_ptr != 0) + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->pass_ptr = hydra_targets[target_no]->login_ptr; + //hydra_targets[target_no]->pass_ptr++; + while (*hydra_targets[target_no]->pass_ptr != 0) + hydra_targets[target_no]->pass_ptr++; + hydra_targets[target_no]->pass_ptr++; + if (strcmp(hydra_targets[target_no]->login_ptr, hydra_heads[head_no]->current_login_ptr) != 0) + hydra_targets[target_no]->pass_state = 0; + if ((hydra_options.try_password_same_as_login && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_heads[head_no]->current_login_ptr) == 0) + || (hydra_options.try_null_password && strlen(hydra_heads[head_no]->current_pass_ptr) == 0) + || + (hydra_options.try_password_reverse_login + && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)) == 0)) { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + if (debug) + printf("[DEBUG] double detected (-C)\n"); + return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small + } + } else { // standard -l -L -p -P mode + hydra_heads[head_no]->current_pass_ptr = hydra_targets[target_no]->pass_ptr; + hydra_targets[target_no]->pass_no++; + // double check + if (hydra_targets[target_no]->pass_no >= hydra_brains.countpass) { + // all passwords done, next user for next password + hydra_targets[target_no]->login_ptr++; + while (*hydra_targets[target_no]->login_ptr != 0) + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->pass_ptr = pass_ptr; + hydra_targets[target_no]->login_no++; + hydra_targets[target_no]->pass_no = 0; + hydra_targets[target_no]->pass_state = 0; + if (hydra_brains.countpass == hydra_options.try_password_reverse_login + hydra_options.try_null_password + hydra_options.try_password_same_as_login) + return hydra_send_next_pair(target_no, head_no); + } else { + hydra_targets[target_no]->pass_ptr++; + while (*hydra_targets[target_no]->pass_ptr != 0) + hydra_targets[target_no]->pass_ptr++; + hydra_targets[target_no]->pass_ptr++; + } + if ((hydra_options.try_password_same_as_login && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_heads[head_no]->current_login_ptr) == 0) + || (hydra_options.try_null_password && strlen(hydra_heads[head_no]->current_pass_ptr) == 0) + || + (hydra_options.try_password_reverse_login + && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)) == 0)) { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + if (debug) + printf("[DEBUG] double detected (-Pp)\n"); + return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small + } + snpdone = 1; + } + } + } + } else { // loop_mode == 1 + if (hydra_targets[target_no]->pass_no < hydra_brains.countpass) { + hydra_heads[head_no]->current_login_ptr = hydra_targets[target_no]->login_ptr; + if (hydra_targets[target_no]->pass_state == 0) { + if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) + hydra_heads[head_no]->current_pass_ptr = strdup(hydra_heads[head_no]->current_login_ptr); + else + hydra_heads[head_no]->current_pass_ptr = hydra_heads[head_no]->current_login_ptr; + } else if (hydra_targets[target_no]->pass_state == 1) { + if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) + hydra_heads[head_no]->current_pass_ptr = strdup(empty_login); + else + hydra_heads[head_no]->current_pass_ptr = empty_login; + } else if (hydra_targets[target_no]->pass_state == 2) { + if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) + hydra_heads[head_no]->current_pass_ptr = strdup(hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr)); + else + hydra_heads[head_no]->current_pass_ptr = hydra_reverse_login(head_no, hydra_heads[head_no]->current_login_ptr); + } else { + if (hydra_options.bfg && hydra_targets[target_no]->pass_state == 3 + && hydra_heads[head_no]->current_pass_ptr != NULL && + strlen(hydra_heads[head_no]->current_pass_ptr) > 0 && hydra_heads[head_no]->current_pass_ptr != hydra_heads[head_no]->current_login_ptr) + free(hydra_heads[head_no]->current_pass_ptr); + hydra_heads[head_no]->current_pass_ptr = strdup(hydra_targets[target_no]->pass_ptr); + } + hydra_targets[target_no]->login_no++; + snpdone = 1; - if (hydra_targets[target_no]->login_no >= hydra_brains.countlogin) { - if (hydra_targets[target_no]->pass_state < 3) { - hydra_targets[target_no]->pass_state++; - if (hydra_targets[target_no]->pass_state == 1 && hydra_options.try_null_password == 0) - hydra_targets[target_no]->pass_state++; - if (hydra_targets[target_no]->pass_state == 2 && hydra_options.try_password_reverse_login == 0) - hydra_targets[target_no]->pass_state++; - if (hydra_targets[target_no]->pass_state == 3) - snpdont = 1; - hydra_targets[target_no]->pass_no++; - } + if (hydra_targets[target_no]->login_no >= hydra_brains.countlogin) { + if (hydra_targets[target_no]->pass_state < 3) { + hydra_targets[target_no]->pass_state++; + if (hydra_targets[target_no]->pass_state == 1 && hydra_options.try_null_password == 0) + hydra_targets[target_no]->pass_state++; + if (hydra_targets[target_no]->pass_state == 2 && hydra_options.try_password_reverse_login == 0) + hydra_targets[target_no]->pass_state++; + if (hydra_targets[target_no]->pass_state == 3) + snpdont = 1; + hydra_targets[target_no]->pass_no++; + } - if (hydra_targets[target_no]->pass_state == 3) { - if (snpdont) { - hydra_targets[target_no]->pass_ptr = pass_ptr; - } else { - if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) { + if (hydra_targets[target_no]->pass_state == 3) { + if (snpdont) { + hydra_targets[target_no]->pass_ptr = pass_ptr; + } else { + if (check_flag(hydra_options.mode, MODE_PASSWORD_BRUTE)) { #ifndef HAVE_MATH_H - sleep(1); + sleep(1); #else - hydra_targets[target_no]->pass_ptr = bf_next(); - if (debug) - printf("[DEBUG] bfg new password for next child: %s\n", hydra_targets[target_no]->pass_ptr); + hydra_targets[target_no]->pass_ptr = bf_next(); + if (debug) + printf("[DEBUG] bfg new password for next child: %s\n", hydra_targets[target_no]->pass_ptr); #endif - } else { // -p -P mode - hydra_targets[target_no]->pass_ptr++; - while (*hydra_targets[target_no]->pass_ptr != 0) - hydra_targets[target_no]->pass_ptr++; - hydra_targets[target_no]->pass_ptr++; - } - hydra_targets[target_no]->pass_no++; - } - } + } else { // -p -P mode + hydra_targets[target_no]->pass_ptr++; + while (*hydra_targets[target_no]->pass_ptr != 0) + hydra_targets[target_no]->pass_ptr++; + hydra_targets[target_no]->pass_ptr++; + } + hydra_targets[target_no]->pass_no++; + } + } - hydra_targets[target_no]->login_no = 0; - hydra_targets[target_no]->login_ptr = login_ptr; - } else { - hydra_targets[target_no]->login_ptr++; - while (*hydra_targets[target_no]->login_ptr != 0) - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->login_ptr++; - } - if (hydra_targets[target_no]->pass_state == 3 && snpdont == 0) { - if ((hydra_options.try_null_password && strlen(hydra_heads[head_no]->current_pass_ptr) < 1) - || (hydra_options.try_password_same_as_login && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_heads[head_no]->current_login_ptr) == 0) - || (hydra_options.try_password_reverse_login && strcmp(hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr) == 0)) { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - if (debug) - printf("[DEBUG] double detected (1)\n"); - return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small - } - } - } - } - } + hydra_targets[target_no]->login_no = 0; + hydra_targets[target_no]->login_ptr = login_ptr; + } else { + hydra_targets[target_no]->login_ptr++; + while (*hydra_targets[target_no]->login_ptr != 0) + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->login_ptr++; + } + if (hydra_targets[target_no]->pass_state == 3 && snpdont == 0) { + if ((hydra_options.try_null_password && strlen(hydra_heads[head_no]->current_pass_ptr) < 1) + || (hydra_options.try_password_same_as_login && strcmp(hydra_heads[head_no]->current_pass_ptr, hydra_heads[head_no]->current_login_ptr) == 0) + || (hydra_options.try_password_reverse_login && strcmp(hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr) == 0)) { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + if (debug) + printf("[DEBUG] double detected (1)\n"); + return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small + } + } + } + } + } - if (debug) - printf("[DEBUG] send_next_pair_mid done %d, pass_state %d, clogin %s, cpass %s, tlogin %s, tpass %s, redo %d\n", - snpdone, hydra_targets[target_no]->pass_state, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->login_ptr, - hydra_targets[target_no]->pass_ptr, hydra_targets[target_no]->redo); + if (debug) + printf("[DEBUG] send_next_pair_mid done %d, pass_state %d, clogin %s, cpass %s, tlogin %s, tpass %s, redo %d\n", + snpdone, hydra_targets[target_no]->pass_state, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->login_ptr, + hydra_targets[target_no]->pass_ptr, hydra_targets[target_no]->redo); - // no pair? then we go for redo state - if (!snpdone && hydra_targets[target_no]->redo_state == 0 && hydra_targets[target_no]->redo > 0) { - if (debug) - printf("[DEBUG] Entering redo_state\n"); - hydra_targets[target_no]->redo_state++; - return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small - } + // no pair? then we go for redo state + if (!snpdone && hydra_targets[target_no]->redo_state == 0 && hydra_targets[target_no]->redo > 0) { + if (debug) + printf("[DEBUG] Entering redo_state\n"); + hydra_targets[target_no]->redo_state++; + return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small + } } if (!snpdone || hydra_targets[target_no]->skipcnt >= hydra_brains.countlogin) { - fck = write(hydra_heads[head_no]->sp[0], HYDRA_EXIT, sizeof(HYDRA_EXIT)); - if (hydra_targets[target_no]->use_count <= 1) { - if (hydra_targets[target_no]->done == TARGET_ACTIVE) { - hydra_targets[target_no]->done = TARGET_FINISHED; - hydra_brains.finished++; - if (verbose) - printf("[STATUS] attack finished for %s (waiting for children to complete tests)\n", hydra_targets[target_no]->target); - } - } - if (hydra_brains.targets > hydra_brains.finished) - hydra_kill_head(head_no, 1, 0); // otherwise done in main while loop + fck = write(hydra_heads[head_no]->sp[0], HYDRA_EXIT, sizeof(HYDRA_EXIT)); + if (hydra_targets[target_no]->use_count <= 1) { + if (hydra_targets[target_no]->done == TARGET_ACTIVE) { + hydra_targets[target_no]->done = TARGET_FINISHED; + hydra_brains.finished++; + if (verbose) + printf("[STATUS] attack finished for %s (waiting for children to complete tests)\n", hydra_targets[target_no]->target); + } + } + if (hydra_brains.targets > hydra_brains.finished) + hydra_kill_head(head_no, 1, 0); // otherwise done in main while loop } else { - if (hydra_targets[target_no]->skipcnt > 0) { - snpj = 0; - for (snpi = 0; snpi < hydra_targets[target_no]->skipcnt && snpj == 0; snpi++) - if (strcmp(hydra_heads[head_no]->current_login_ptr, hydra_targets[target_no]->skiplogin[snpi]) == 0) - snpj = 1; - if (snpj) { - if (snp_is_redo == 0) { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - } - if (debug) - printf("[DEBUG] double found for %s == %s, skipping\n", hydra_heads[head_no]->current_login_ptr, hydra_targets[target_no]->skiplogin[snpi - 1]); - // only if -l/L -p/P with -u and if loginptr was not justed increased - if (!check_flag(hydra_options.mode, MODE_COLON_FILE) && hydra_options.loop_mode == 0 && hydra_targets[target_no]->pass_no > 0) { // -l -P (not! -u) - // increase login_ptr to next - hydra_targets[target_no]->login_no++; - if (hydra_targets[target_no]->login_no < hydra_brains.countlogin) { - hydra_targets[target_no]->login_ptr++; - while (*hydra_targets[target_no]->login_ptr != 0) - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->login_ptr++; - } - // add count - hydra_brains.sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; - hydra_targets[target_no]->sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; - // reset password list - hydra_targets[target_no]->pass_ptr = pass_ptr; - hydra_targets[target_no]->pass_no = 0; - hydra_targets[target_no]->pass_state = 0; - } - return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small - } - } + if (hydra_targets[target_no]->skipcnt > 0) { + snpj = 0; + for (snpi = 0; snpi < hydra_targets[target_no]->skipcnt && snpj == 0; snpi++) + if (strcmp(hydra_heads[head_no]->current_login_ptr, hydra_targets[target_no]->skiplogin[snpi]) == 0) + snpj = 1; + if (snpj) { + if (snp_is_redo == 0) { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + } + if (debug) + printf("[DEBUG] double found for %s == %s, skipping\n", hydra_heads[head_no]->current_login_ptr, hydra_targets[target_no]->skiplogin[snpi - 1]); + // only if -l/L -p/P with -u and if loginptr was not justed increased + if (!check_flag(hydra_options.mode, MODE_COLON_FILE) && hydra_options.loop_mode == 0 && hydra_targets[target_no]->pass_no > 0) { // -l -P (not! -u) + // increase login_ptr to next + hydra_targets[target_no]->login_no++; + if (hydra_targets[target_no]->login_no < hydra_brains.countlogin) { + hydra_targets[target_no]->login_ptr++; + while (*hydra_targets[target_no]->login_ptr != 0) + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->login_ptr++; + } + // add count + hydra_brains.sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; + hydra_targets[target_no]->sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; + // reset password list + hydra_targets[target_no]->pass_ptr = pass_ptr; + hydra_targets[target_no]->pass_no = 0; + hydra_targets[target_no]->pass_state = 0; + } + return hydra_send_next_pair(target_no, head_no); // little trick to keep the code small + } + } - memset(&snpbuf, 0, sizeof(snpbuf)); - strncpy(snpbuf, hydra_heads[head_no]->current_login_ptr, MAXLINESIZE - 3); - if (strlen(hydra_heads[head_no]->current_login_ptr) > MAXLINESIZE - 3) - snpbuflen = MAXLINESIZE - 2; - else - snpbuflen = strlen(hydra_heads[head_no]->current_login_ptr) + 1; - strncpy(snpbuf + snpbuflen, hydra_heads[head_no]->current_pass_ptr, MAXLINESIZE - snpbuflen - 1); - if (strlen(hydra_heads[head_no]->current_pass_ptr) > MAXLINESIZE - snpbuflen - 1) - snpbuflen += MAXLINESIZE - snpbuflen - 1; - else - snpbuflen += strlen(hydra_heads[head_no]->current_pass_ptr) + 1; - if (snp_is_redo == 0) { - hydra_brains.sent++; - hydra_targets[target_no]->sent++; - } else if (debug) - printf("[DEBUG] send_next_pair_redo done %d, pass_state %d, clogin %s, cpass %s, tlogin %s, tpass %s, is_redo %d\n", - snpdone, hydra_targets[target_no]->pass_state, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->login_ptr, - hydra_targets[target_no]->pass_ptr, snp_is_redo); - //hydra_dump_data(snpbuf, snpbuflen, "SENT"); - fck = write(hydra_heads[head_no]->sp[0], snpbuf, snpbuflen); - if (fck < snpbuflen) { - if (verbose) - fprintf(stderr, "[ERROR] can not write to child %d, restarting it ...\n", head_no); - hydra_increase_fail_count(target_no, head_no); - loop_cnt = 0; - return 0; // not prevent disabling it, if its needed its already done in the above line - } - if (debug || hydra_options.showAttempt) { - printf("[%sATTEMPT] target %s - login \"%s\" - pass \"%s\" - %lu of %lu [child %d] (%d/%d)\n", - hydra_targets[target_no]->redo_state ? "REDO-" : snp_is_redo ? "RE-" : "", hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, - hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo, head_no, hydra_targets[target_no]->redo_state ? hydra_targets[target_no]->redo_state - 1 : 0, hydra_targets[target_no]->redo); - } - loop_cnt = 0; - return 0; + memset(&snpbuf, 0, sizeof(snpbuf)); + strncpy(snpbuf, hydra_heads[head_no]->current_login_ptr, MAXLINESIZE - 3); + if (strlen(hydra_heads[head_no]->current_login_ptr) > MAXLINESIZE - 3) + snpbuflen = MAXLINESIZE - 2; + else + snpbuflen = strlen(hydra_heads[head_no]->current_login_ptr) + 1; + strncpy(snpbuf + snpbuflen, hydra_heads[head_no]->current_pass_ptr, MAXLINESIZE - snpbuflen - 1); + if (strlen(hydra_heads[head_no]->current_pass_ptr) > MAXLINESIZE - snpbuflen - 1) + snpbuflen += MAXLINESIZE - snpbuflen - 1; + else + snpbuflen += strlen(hydra_heads[head_no]->current_pass_ptr) + 1; + if (snp_is_redo == 0) { + hydra_brains.sent++; + hydra_targets[target_no]->sent++; + } else if (debug) + printf("[DEBUG] send_next_pair_redo done %d, pass_state %d, clogin %s, cpass %s, tlogin %s, tpass %s, is_redo %d\n", + snpdone, hydra_targets[target_no]->pass_state, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->login_ptr, + hydra_targets[target_no]->pass_ptr, snp_is_redo); + //hydra_dump_data(snpbuf, snpbuflen, "SENT"); + fck = write(hydra_heads[head_no]->sp[0], snpbuf, snpbuflen); + if (fck < snpbuflen) { + if (verbose) + fprintf(stderr, "[ERROR] can not write to child %d, restarting it ...\n", head_no); + hydra_increase_fail_count(target_no, head_no); + loop_cnt = 0; + return 0; // not prevent disabling it, if its needed its already done in the above line + } + if (debug || hydra_options.showAttempt) { + printf("[%sATTEMPT] target %s - login \"%s\" - pass \"%s\" - %lu of %lu [child %d] (%d/%d)\n", + hydra_targets[target_no]->redo_state ? "REDO-" : snp_is_redo ? "RE-" : "", hydra_targets[target_no]->target, hydra_heads[head_no]->current_login_ptr, + hydra_heads[head_no]->current_pass_ptr, hydra_targets[target_no]->sent, hydra_brains.todo + hydra_targets[target_no]->redo, head_no, hydra_targets[target_no]->redo_state ? hydra_targets[target_no]->redo_state - 1 : 0, hydra_targets[target_no]->redo); + } + loop_cnt = 0; + return 0; } loop_cnt = 0; return -1; @@ -1860,37 +1860,37 @@ void hydra_skip_user(int32_t target_no, char *username) { int32_t i; if (username == NULL || *username == 0) - return; + return; // double check for (i = 0; i < hydra_targets[target_no]->skipcnt; i++) - if (strcmp(username, hydra_targets[target_no]->skiplogin[i]) == 0) - return; + if (strcmp(username, hydra_targets[target_no]->skiplogin[i]) == 0) + return; if (hydra_targets[target_no]->skipcnt < SKIPLOGIN && (hydra_targets[target_no]->skiplogin[hydra_targets[target_no]->skipcnt] = malloc(strlen(username) + 1)) != NULL) { - strcpy(hydra_targets[target_no]->skiplogin[hydra_targets[target_no]->skipcnt], username); - hydra_targets[target_no]->skipcnt++; + strcpy(hydra_targets[target_no]->skiplogin[hydra_targets[target_no]->skipcnt], username); + hydra_targets[target_no]->skipcnt++; } if (hydra_options.loop_mode == 0 && !check_flag(hydra_options.mode, MODE_COLON_FILE)) { - if (memcmp(username, hydra_targets[target_no]->login_ptr, strlen(username)) == 0) { - if (debug) - printf("[DEBUG] skipping username %s\n", username); - // increase count - hydra_brains.sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; - hydra_targets[target_no]->sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; - // step to next login - hydra_targets[target_no]->login_no++; - if (hydra_targets[target_no]->login_no < hydra_brains.countlogin) { - hydra_targets[target_no]->login_ptr++; - while (*hydra_targets[target_no]->login_ptr != 0) - hydra_targets[target_no]->login_ptr++; - hydra_targets[target_no]->login_ptr++; - } - // reset password state - hydra_targets[target_no]->pass_ptr = pass_ptr; - hydra_targets[target_no]->pass_no = 0; - hydra_targets[target_no]->pass_state = 0; - } + if (memcmp(username, hydra_targets[target_no]->login_ptr, strlen(username)) == 0) { + if (debug) + printf("[DEBUG] skipping username %s\n", username); + // increase count + hydra_brains.sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; + hydra_targets[target_no]->sent += hydra_brains.countpass - hydra_targets[target_no]->pass_no; + // step to next login + hydra_targets[target_no]->login_no++; + if (hydra_targets[target_no]->login_no < hydra_brains.countlogin) { + hydra_targets[target_no]->login_ptr++; + while (*hydra_targets[target_no]->login_ptr != 0) + hydra_targets[target_no]->login_ptr++; + hydra_targets[target_no]->login_ptr++; + } + // reset password state + hydra_targets[target_no]->pass_ptr = pass_ptr; + hydra_targets[target_no]->pass_no = 0; + hydra_targets[target_no]->pass_state = 0; + } } } @@ -1898,24 +1898,24 @@ int32_t hydra_check_for_exit_condition() { int32_t i, k = 0; if (hydra_brains.exit) { - if (debug) - printf("[DEBUG] exit was forced\n"); - return -1; + if (debug) + printf("[DEBUG] exit was forced\n"); + return -1; } if (hydra_brains.targets <= hydra_brains.finished && hydra_brains.active < 1) { - if (debug) - printf("[DEBUG] all targets done and all heads finished\n"); - return 1; + if (debug) + printf("[DEBUG] all targets done and all heads finished\n"); + return 1; } if (hydra_brains.active < 1) { - // no head active?! check if they are all disabled, if so, we are done - for (i = 0; i < hydra_options.max_use && k == 0; i++) - if (hydra_heads[i]->active >= HEAD_UNUSED) - k = 1; - if (k == 0) { - fprintf(stderr, "[ERROR] all children were disabled due too many connection errors\n"); - return -1; - } + // no head active?! check if they are all disabled, if so, we are done + for (i = 0; i < hydra_options.max_use && k == 0; i++) + if (hydra_heads[i]->active >= HEAD_UNUSED) + k = 1; + if (k == 0) { + fprintf(stderr, "[ERROR] all children were disabled due too many connection errors\n"); + return -1; + } } return 0; } @@ -1924,11 +1924,11 @@ int32_t hydra_select_target() { int32_t target_no = -1, i, j = -1000; for (i = 0; i < hydra_brains.targets; i++) - if (hydra_targets[i]->use_count < hydra_options.tasks && hydra_targets[i]->done == TARGET_ACTIVE) - if (j < hydra_options.tasks - hydra_targets[i]->failed - hydra_targets[i]->use_count) { - target_no = i; - j = hydra_options.tasks - hydra_targets[i]->failed - hydra_targets[i]->use_count; - } + if (hydra_targets[i]->use_count < hydra_options.tasks && hydra_targets[i]->done == TARGET_ACTIVE) + if (j < hydra_options.tasks - hydra_targets[i]->failed - hydra_targets[i]->use_count) { + target_no = i; + j = hydra_options.tasks - hydra_targets[i]->failed - hydra_targets[i]->use_count; + } return target_no; } @@ -1940,119 +1940,119 @@ void process_proxy_line(int32_t type, char *string) { struct sockaddr_in *ipv4 = NULL; if (string == NULL || string[0] == 0 || string[0] == '#') - return; + return; while (*string == ' ' || *string == '\t') - string++; + string++; if (*string == '#' || *string == ';' || strlen(string) < 5) - return; + return; if (string[strlen(string) - 1] == '\n') - string[strlen(string) - 1] = 0; + string[strlen(string) - 1] = 0; if (string[strlen(string) - 1] == '\r') - string[strlen(string) - 1] = 0; + string[strlen(string) - 1] = 0; if (proxy_count > MAX_PROXY_COUNT) { - fprintf(stderr, "[WARNING] maximum amount of proxies loaded, ignoring this entry: %s\n", string); - return; + fprintf(stderr, "[WARNING] maximum amount of proxies loaded, ignoring this entry: %s\n", string); + return; } if (debug) - printf("[DEBUG] proxy line: %s\n", string); + printf("[DEBUG] proxy line: %s\n", string); if ((sep = strstr(string, "://")) == NULL) { - fprintf(stderr, "[WARNING] invalid proxy definition: %s (ignored)\n", string); - return; + fprintf(stderr, "[WARNING] invalid proxy definition: %s (ignored)\n", string); + return; } *sep = 0; target_string = sep + 3; if ((sep = index(target_string, '@')) != NULL) { - auth_string = target_string; - *sep = 0; - target_string = sep + 1; - if (index(auth_string, ':') == NULL) { - fprintf(stderr, "[WARNING] %s has an invalid authentication definition %s, must be in the format login:pass, entry ignored\n", target_string, auth_string); - return; - } + auth_string = target_string; + *sep = 0; + target_string = sep + 1; + if (index(auth_string, ':') == NULL) { + fprintf(stderr, "[WARNING] %s has an invalid authentication definition %s, must be in the format login:pass, entry ignored\n", target_string, auth_string); + return; + } } if ((sep = index(target_string, ':')) != NULL) { - *sep = 0; - port_string = sep + 1; - if ((sep = index(port_string, '%')) != NULL) { - *sep = 0; - device_string = sep + 1; - } - if ((sep = index(port_string, '/')) != NULL) - *sep = 0; - port = atoi(port_string); - if (port < 1 || port > 65535) { - fprintf(stderr, "[WARNING] %s has an invalid port definition %d, entry ignored\n", target_string, port); - return; - } + *sep = 0; + port_string = sep + 1; + if ((sep = index(port_string, '%')) != NULL) { + *sep = 0; + device_string = sep + 1; + } + if ((sep = index(port_string, '/')) != NULL) + *sep = 0; + port = atoi(port_string); + if (port < 1 || port > 65535) { + fprintf(stderr, "[WARNING] %s has an invalid port definition %d, entry ignored\n", target_string, port); + return; + } } else { - fprintf(stderr, "[WARNING] %s has not port definition which is required, entry ignored\n", target_string); - return; + fprintf(stderr, "[WARNING] %s has not port definition which is required, entry ignored\n", target_string); + return; } if (use_proxy == 1 && strcmp(type_string, "http") != 0) { - fprintf(stderr, "[WARNING] %s:// is an invalid type, must be http:// if you use HYDRA_PROXY_HTTP, entry ignored\n", type_string); - return; + fprintf(stderr, "[WARNING] %s:// is an invalid type, must be http:// if you use HYDRA_PROXY_HTTP, entry ignored\n", type_string); + return; } if (use_proxy == 2 && strcmp(type_string, "connect") != 0 && strcmp(type_string, "socks4") != 0 && strcmp(type_string, "socks5") != 0) { - fprintf(stderr, "[WARNING] %s:// is an invalid type, must be connect://, socks4:// or socks5:// if you use HYDRA_PROXY, entry ignored\n", type_string); - return; + fprintf(stderr, "[WARNING] %s:// is an invalid type, must be connect://, socks4:// or socks5:// if you use HYDRA_PROXY, entry ignored\n", type_string); + return; } memset(&hints, 0, sizeof hints); if (getaddrinfo(target_string, NULL, &hints, &res) != 0) { - fprintf(stderr, "[ERROR] could not resolve proxy target %s, entry ignored\n", target_string); - return; + fprintf(stderr, "[ERROR] could not resolve proxy target %s, entry ignored\n", target_string); + return; } for (p = res; p != NULL; p = p->ai_next) { #ifdef AF_INET6 - if (p->ai_family == AF_INET6) { - if (ipv6 == NULL || memcmp((char *) &ipv6->sin6_addr, fe80, 2) == 0) - ipv6 = (struct sockaddr_in6 *) p->ai_addr; - } else + if (p->ai_family == AF_INET6) { + if (ipv6 == NULL || memcmp((char *) &ipv6->sin6_addr, fe80, 2) == 0) + ipv6 = (struct sockaddr_in6 *) p->ai_addr; + } else #endif - if (p->ai_family == AF_INET) { - if (ipv4 == NULL) - ipv4 = (struct sockaddr_in *) p->ai_addr; - } + if (p->ai_family == AF_INET) { + if (ipv4 == NULL) + ipv4 = (struct sockaddr_in *) p->ai_addr; + } } freeaddrinfo(res); // now fill the stuff #ifdef AF_INET6 if (ipv6 != NULL && (ipv4 == NULL || prefer_ipv6)) { - if (memcmp(proxy_string_ip[proxy_count] + 1, fe80, 2) == 0 && device_string == NULL) { - fprintf(stderr, "[WARNING] The proxy address %s is a link local address, link local addresses require the interface being defined like this: fe80::1%%eth0, entry ignored\n", target_string); - return; - } - proxy_string_ip[proxy_count][0] = 16; - memcpy(proxy_string_ip[proxy_count] + 1, (char *) &ipv6->sin6_addr, 16); - if (device_string != NULL && strlen(device_string) <= 16) - strcpy(proxy_string_ip[proxy_count] + 17, device_string); + if (memcmp(proxy_string_ip[proxy_count] + 1, fe80, 2) == 0 && device_string == NULL) { + fprintf(stderr, "[WARNING] The proxy address %s is a link local address, link local addresses require the interface being defined like this: fe80::1%%eth0, entry ignored\n", target_string); + return; + } + proxy_string_ip[proxy_count][0] = 16; + memcpy(proxy_string_ip[proxy_count] + 1, (char *) &ipv6->sin6_addr, 16); + if (device_string != NULL && strlen(device_string) <= 16) + strcpy(proxy_string_ip[proxy_count] + 17, device_string); } else #endif if (ipv4 != NULL) { - proxy_string_ip[proxy_count][0] = 4; - memcpy(proxy_string_ip[proxy_count] + 1, (char *) &ipv4->sin_addr, 4); + proxy_string_ip[proxy_count][0] = 4; + memcpy(proxy_string_ip[proxy_count] + 1, (char *) &ipv4->sin_addr, 4); } else { - fprintf(stderr, "[WARNING] Could not resolve proxy address: %s, entry ignored\n", target_string); - return; + fprintf(stderr, "[WARNING] Could not resolve proxy address: %s, entry ignored\n", target_string); + return; } if (auth_string != NULL) { - if ((proxy_authentication[proxy_count] = malloc(strlen(auth_string) * 2 + 8)) == NULL) { - perror("malloc"); - return; - } - strcpy(proxy_authentication[proxy_count], auth_string); - if (strncmp(type_string, "socks", 5) != 0) // so it is web - hydra_tobase64((unsigned char *) proxy_authentication[proxy_count], strlen(proxy_authentication[proxy_count]), strlen(auth_string) * 2 + 8); + if ((proxy_authentication[proxy_count] = malloc(strlen(auth_string) * 2 + 8)) == NULL) { + perror("malloc"); + return; + } + strcpy(proxy_authentication[proxy_count], auth_string); + if (strncmp(type_string, "socks", 5) != 0) // so it is web + hydra_tobase64((unsigned char *) proxy_authentication[proxy_count], strlen(proxy_authentication[proxy_count]), strlen(auth_string) * 2 + 8); } else - proxy_authentication[proxy_count] = NULL; + proxy_authentication[proxy_count] = NULL; strcpy(proxy_string_type[proxy_count], type_string); proxy_string_port[proxy_count] = port; if (debug) - printf("[DEBUG] count %d type %s target %s port %d auth %s\n", proxy_count, proxy_string_type[proxy_count], target_string, proxy_string_port[proxy_count], proxy_authentication[proxy_count]); + printf("[DEBUG] count %d type %s target %s port %d auth %s\n", proxy_count, proxy_string_type[proxy_count], target_string, proxy_string_port[proxy_count], proxy_authentication[proxy_count]); proxy_count++; } @@ -2060,6 +2060,7 @@ int main(int argc, char *argv[]) { char *proxy_string = NULL, *device = NULL, *memcheck, *cmdtarget = NULL; char *outfile_format_tmp; char *output; + char *redis_output_tmp; FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp; size_t countinfile = 1, sizeinfile = 0; uint64_t math2; @@ -2149,16 +2150,18 @@ int main(int argc, char *argv[]) { #endif #ifndef HAVE_MATH_H if (strlen(unsupported) > 0) - strcat(unsupported, "and "); + strcat(unsupported, "and "); strcat(unsupported, "password bruteforce generation "); #endif #ifndef HAVE_PCRE if (strlen(unsupported) > 0) - strcat(unsupported, "and "); + strcat(unsupported, "and "); strcat(unsupported, "regex support "); #endif output = malloc(sizeof(char) * 4096); memset(output, 0, sizeof(char) * 4096); + redis_output_tmp = malloc(sizeof(char) * 4096); + memset(redis_output_tmp, 0, sizeof(char) * 4096); (void) setvbuf(stdout, NULL, _IONBF, 0); (void) setvbuf(stderr, NULL, _IONBF, 0); // set defaults @@ -2189,196 +2192,208 @@ int main(int argc, char *argv[]) { // command line processing if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) - help(1); + help(1); if (argc < 2) - help(0); - while ((i = getopt(argc, argv, "hIq64Rde:vVl:fFg:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:")) >= 0) { - switch (i) { - case 'h': - help(1); - break; - case 'q': - quiet = 1; - break; - case 'O': - old_ssl = 1; - break; - case 'u': - hydra_options.loop_mode = 1; - break; - case '6': - prefer_ipv6 = 1; - break; - case '4': - prefer_ipv6 = 0; - break; - case 'R': - hydra_options.restore = 1; - hydra_restore_read(); - break; - case 'I': - ignore_restore = 1; // this is not to be saved in hydra_options! - break; - case 'd': - hydra_options.debug = ++debug; - ++verbose; - break; - case 'e': - i = 0; - while (i < strlen(optarg)) { - switch (optarg[i]) { - case 'r': - hydra_options.try_password_reverse_login = 1; - hydra_options.mode = hydra_options.mode | MODE_PASSWORD_REVERSE; - break; - case 'n': - hydra_options.try_null_password = 1; - hydra_options.mode = hydra_options.mode | MODE_PASSWORD_NULL; - break; - case 's': - hydra_options.try_password_same_as_login = 1; - hydra_options.mode = hydra_options.mode | MODE_PASSWORD_SAME; - break; - default: - fprintf(stderr, "[ERROR] unknown mode %c for option -e, only supporting \"n\", \"s\" and \"r\"\n", optarg[i]); - exit(-1); - } - i++; - } - break; - case 'v': - hydra_options.verbose = verbose = 1; - break; - case 'V': - hydra_options.showAttempt = 1; - break; - case 'l': - hydra_options.login = optarg; - break; - case 'L': - hydra_options.loginfile = optarg; - hydra_options.mode = hydra_options.mode | MODE_LOGIN_LIST; - break; - case 'p': - hydra_options.pass = optarg; - break; - case 'P': - hydra_options.passfile = optarg; - hydra_options.mode = hydra_options.mode | MODE_PASSWORD_LIST; - break; - case 'f': - hydra_options.exit_found = 1; - break; - case 'F': - hydra_options.exit_found = 2; - break; - case 'o': - hydra_options.outfile_ptr = optarg; - // colored_output = 0; - break; - case 'b': - outfile_format_tmp = optarg; - if (0==strcasecmp(outfile_format_tmp,"text")) - hydra_options.outfile_format = FORMAT_PLAIN_TEXT; - else if (0==strcasecmp(outfile_format_tmp,"json")) // latest json formatting. - hydra_options.outfile_format = FORMAT_JSONV1; - else if (0==strcasecmp(outfile_format_tmp,"jsonv1")) - hydra_options.outfile_format = FORMAT_JSONV1; - else { - fprintf(stderr, "[ERROR] Output file format must be (text, json, jsonv1)\n"); - exit(-1); - } - // colored_output = 0; - break; - case 'M': - hydra_options.infile_ptr = optarg; - break; - case 'C': - hydra_options.colonfile = optarg; - hydra_options.mode = MODE_COLON_FILE; - break; - case 'm': - hydra_options.miscptr = optarg; - break; - case 'w': - hydra_options.waittime = waittime = atoi(optarg); - if (waittime < 1) { - fprintf(stderr, "[ERROR] waittime must be larger than 0\n"); - exit(-1); - } else if (waittime < 5) - fprintf(stderr, "[WARNING] the waittime you set is low, this can result in errornous results\n"); - break; - case 'W': - hydra_options.conwait = conwait = atoi(optarg); - break; - case 's': - hydra_options.port = port = atoi(optarg); - break; - case 'c': + help(0); + while ((i = getopt(argc, argv, "hIq64Rde:vVl:fFg:L:p:OP:o:b:k:M:C:t:T:m:w:W:s:SUux:yc:")) >= 0) { + switch (i) { + case 'h': + help(1); + break; + case 'q': + quiet = 1; + break; + case 'O': + old_ssl = 1; + break; + case 'u': + hydra_options.loop_mode = 1; + break; + case '6': + prefer_ipv6 = 1; + break; + case '4': + prefer_ipv6 = 0; + break; + case 'R': + hydra_options.restore = 1; + hydra_restore_read(); + break; + case 'I': + ignore_restore = 1; // this is not to be saved in hydra_options! + break; + case 'd': + hydra_options.debug = ++debug; + ++verbose; + break; + case 'e': + i = 0; + while (i < strlen(optarg)) { + switch (optarg[i]) { + case 'r': + hydra_options.try_password_reverse_login = 1; + hydra_options.mode = hydra_options.mode | MODE_PASSWORD_REVERSE; + break; + case 'n': + hydra_options.try_null_password = 1; + hydra_options.mode = hydra_options.mode | MODE_PASSWORD_NULL; + break; + case 's': + hydra_options.try_password_same_as_login = 1; + hydra_options.mode = hydra_options.mode | MODE_PASSWORD_SAME; + break; + default: + fprintf(stderr, "[ERROR] unknown mode %c for option -e, only supporting \"n\", \"s\" and \"r\"\n", optarg[i]); + exit(-1); + } + i++; + } + break; + case 'v': + hydra_options.verbose = verbose = 1; + break; + case 'V': + hydra_options.showAttempt = 1; + break; + case 'l': + hydra_options.login = optarg; + break; + case 'L': + hydra_options.loginfile = optarg; + hydra_options.mode = hydra_options.mode | MODE_LOGIN_LIST; + break; + case 'p': + hydra_options.pass = optarg; + break; + case 'P': + hydra_options.passfile = optarg; + hydra_options.mode = hydra_options.mode | MODE_PASSWORD_LIST; + break; + case 'f': + hydra_options.exit_found = 1; + break; + case 'F': + hydra_options.exit_found = 2; + break; + case 'o': + hydra_options.outfile_ptr = optarg; + // colored_output = 0; + break; + case 'b': + outfile_format_tmp = optarg; + if (0==strcasecmp(outfile_format_tmp,"text")) + hydra_options.outfile_format = FORMAT_PLAIN_TEXT; + else if (0==strcasecmp(outfile_format_tmp,"json")) // latest json formatting. + hydra_options.outfile_format = FORMAT_JSONV1; + else if (0==strcasecmp(outfile_format_tmp,"jsonv1")) + hydra_options.outfile_format = FORMAT_JSONV1; + else if (0==strcasecmp(outfile_format_tmp,"redis")){ + hydra_options.outfile_format = FORMAT_REDIS; + }else { + fprintf(stderr, "[ERROR] Output file format must be (text, json, jsonv1)\n"); + exit(-1); + } + // colored_output = 0; + break; + case 'k': + hydra_options.key = optarg; + hydra_options.map_key = malloc(sizeof(char) * 36); + memset(hydra_options.map_key, 0, sizeof(char) * 36); + if(strlen(optarg) >= 36){ + fprintf(stderr, "[ERROR] Redis key length <= 36\n"); + exit(-1); + } + key(hydra_options.map_key, optarg); + break; + case 'M': + hydra_options.infile_ptr = optarg; + break; + case 'C': + hydra_options.colonfile = optarg; + hydra_options.mode = MODE_COLON_FILE; + break; + case 'm': + hydra_options.miscptr = optarg; + break; + case 'w': + hydra_options.waittime = waittime = atoi(optarg); + if (waittime < 1) { + fprintf(stderr, "[ERROR] waittime must be larger than 0\n"); + exit(-1); + } else if (waittime < 5) + fprintf(stderr, "[WARNING] the waittime you set is low, this can result in errornous results\n"); + break; + case 'W': + hydra_options.conwait = conwait = atoi(optarg); + break; + case 's': + hydra_options.port = port = atoi(optarg); + break; + case 'c': #ifdef MSG_PEEK - hydra_options.time_next_attempt = atoi(optarg); - if (hydra_options.time_next_attempt < 0) { - fprintf(stderr, "[ERROR] -c option value can not be negative\n"); - exit(-1); - } + hydra_options.time_next_attempt = atoi(optarg); + if (hydra_options.time_next_attempt < 0) { + fprintf(stderr, "[ERROR] -c option value can not be negative\n"); + exit(-1); + } #else - fprintf(stderr, "[WARNING] -c option can not be used as your operating system is missing the MSG_PEEK feature\n"); + fprintf(stderr, "[WARNING] -c option can not be used as your operating system is missing the MSG_PEEK feature\n"); #endif - break; - case 'S': + break; + case 'S': #ifndef LIBOPENSSL - fprintf(stderr, "[WARNING] hydra was compiled without SSL support. Install openssl and recompile! Option ignored...\n"); - hydra_options.ssl = 0; - break; + fprintf(stderr, "[WARNING] hydra was compiled without SSL support. Install openssl and recompile! Option ignored...\n"); + hydra_options.ssl = 0; + break; #else - hydra_options.ssl = 1; - break; + hydra_options.ssl = 1; + break; #endif - case 't': - hydra_options.tasks = atoi(optarg); - break; - case 'T': - hydra_options.max_use = atoi(optarg); - break; - case 'U': - modusage = 1; - break; - case 'x': + case 't': + hydra_options.tasks = atoi(optarg); + break; + case 'T': + hydra_options.max_use = atoi(optarg); + break; + case 'U': + modusage = 1; + break; + case 'x': #ifndef HAVE_MATH_H - fprintf(stderr, "[ERROR] -x option is not available as math.h was not found at compile time\n"); - exit(-1); + fprintf(stderr, "[ERROR] -x option is not available as math.h was not found at compile time\n"); + exit(-1); #else - if (strcmp(optarg, "-h") == 0) - help_bfg(); - bf_options.arg = optarg; - hydra_options.bfg = 1; - hydra_options.mode = hydra_options.mode | MODE_PASSWORD_BRUTE; - hydra_options.loop_mode = 1; - break; + if (strcmp(optarg, "-h") == 0) + help_bfg(); + bf_options.arg = optarg; + hydra_options.bfg = 1; + hydra_options.mode = hydra_options.mode | MODE_PASSWORD_BRUTE; + hydra_options.loop_mode = 1; + break; #endif - case 'y': - bf_options.disable_symbols = 1; - break; - default: - exit(-1); - } + case 'y': + bf_options.disable_symbols = 1; + break; + default: + exit(-1); + } } if (hydra_options.time_next_attempt > 0 && hydra_options.tasks != 1) { - printf("[INFO] setting max tasks per host to 1 due to -c option usage\n"); - hydra_options.tasks = 1; + printf("[INFO] setting max tasks per host to 1 due to -c option usage\n"); + hydra_options.tasks = 1; } //check if output is redirected from the shell or in a file if (colored_output && !isatty(fileno(stdout))) - colored_output = 0; + colored_output = 0; #ifdef LIBNCURSES //then check if the term is color enabled using ncurses lib if (colored_output) { - if (!setupterm(NULL, 1, NULL) && (tigetnum("colors") <= 0)) { - colored_output = 0; - } + if (!setupterm(NULL, 1, NULL) && (tigetnum("colors") <= 0)) { + colored_output = 0; + } } #else //don't want border line effect so disabling color output @@ -2387,1274 +2402,1287 @@ int main(int argc, char *argv[]) { #endif if (debug) - printf("[DEBUG] Output color flag is %d\n", colored_output); + printf("[DEBUG] Output color flag is %d\n", colored_output); if (hydra_options.restore && argc > 2 + debug + verbose) - fprintf(stderr, "[WARNING] options after -R are now honored (since v8.6)\n"); -// bail("no option may be supplied together with -R"); + fprintf(stderr, "[WARNING] options after -R are now honored (since v8.6)\n"); +// bail("no option may be supplied together with -R"); printf("%s (%s) starting at %s\n", PROGRAM, RESOURCE, hydra_build_time()); if (debug) { - printf("[DEBUG] cmdline: "); - for (i = 0; i < argc; i++) - printf("%s ", argv[i]); - printf("\n"); + printf("[DEBUG] cmdline: "); + for (i = 0; i < argc; i++) + printf("%s ", argv[i]); + printf("\n"); } if (hydra_options.tasks > 1 && hydra_options.time_next_attempt) - fprintf(stderr, "[WARNING] when using the -c option, you should also set the task per target to one (-t 1)\n"); + fprintf(stderr, "[WARNING] when using the -c option, you should also set the task per target to one (-t 1)\n"); if (hydra_options.login != NULL && hydra_options.loginfile != NULL) - bail("You can only use -L OR -l, not both\n"); + bail("You can only use -L OR -l, not both\n"); if (hydra_options.pass != NULL && hydra_options.passfile != NULL) - bail("You can only use -P OR -p, not both\n"); - if (hydra_options.outfile_format != FORMAT_PLAIN_TEXT && hydra_options.outfile_ptr == NULL) - fprintf(stderr, "[WARNING] output file format specified (-b) - but no output file (-o)\n"); - + bail("You can only use -P OR -p, not both\n"); + if (hydra_options.outfile_format == FORMAT_JSONV1 && hydra_options.outfile_format != FORMAT_PLAIN_TEXT && hydra_options.outfile_ptr == NULL) + fprintf(stderr, "[WARNING] output file format specified (-b json) - but no output file (-o)\n"); + if (hydra_options.outfile_format == FORMAT_REDIS && hydra_options.key == NULL){ + fprintf(stderr, "[ERROR] redis output format specified (-b redis) - but no key (-k)\n"); + exit(1); + } if (hydra_options.restore) { -// hydra_restore_read(); - // stuff we have to copy from the non-restore part - if (strncmp(hydra_options.service, "http-", 5) == 0) { - 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/http-post!"); - if (getenv("HYDRA_PROXY_HTTP")) { - printf("[INFO] Using HTTP Proxy: %s\n", getenv("HYDRA_PROXY_HTTP")); - use_proxy = 1; - } - } - } else { // normal mode, aka non-restore mode - if (hydra_options.colonfile) - hydra_options.loop_mode = 0; // just to be sure - if (hydra_options.infile_ptr != NULL) { - if (optind + 2 < argc) - bail("The -M FILE option can not be used together with a host on the commandline"); - if (optind + 1 > argc) - bail("You need to define a service to attack"); - if (optind + 2 == argc) - fprintf(stderr, "[WARNING] With the -M FILE option you can not specify a server on the commandline. Lets hope you did everything right!\n"); - hydra_options.server = NULL; - hydra_options.service = argv[optind]; - if (optind + 2 == argc) - hydra_options.miscptr = argv[optind + 1]; - } else if (optind + 2 != argc && optind + 3 != argc && optind < argc) { - // check if targetdef follow syntax ://[:][/] or it's a syntax error - char *targetdef = strdup(argv[optind]); - char *service_pos, *target_pos, *port_pos = NULL, *param_pos = NULL; - cmdtarget = argv[optind]; +// hydra_restore_read(); + // stuff we have to copy from the non-restore part + if (strncmp(hydra_options.service, "http-", 5) == 0) { + 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/http-post!"); + if (getenv("HYDRA_PROXY_HTTP")) { + printf("[INFO] Using HTTP Proxy: %s\n", getenv("HYDRA_PROXY_HTTP")); + use_proxy = 1; + } + } + } else { // normal mode, aka non-restore mode + if (hydra_options.colonfile) + hydra_options.loop_mode = 0; // just to be sure + if (hydra_options.infile_ptr != NULL) { + if (optind + 2 < argc) + bail("The -M FILE option can not be used together with a host on the commandline"); + if (optind + 1 > argc) + bail("You need to define a service to attack"); + if (optind + 2 == argc) + fprintf(stderr, "[WARNING] With the -M FILE option you can not specify a server on the commandline. Lets hope you did everything right!\n"); + hydra_options.server = NULL; + hydra_options.service = argv[optind]; + if (optind + 2 == argc) + hydra_options.miscptr = argv[optind + 1]; + } else if (optind + 2 != argc && optind + 3 != argc && optind < argc) { + // check if targetdef follow syntax ://[:][/] or it's a syntax error + char *targetdef = strdup(argv[optind]); + char *service_pos, *target_pos, *port_pos = NULL, *param_pos = NULL; + cmdtarget = argv[optind]; - if ((targetdef != NULL) && (strstr(targetdef, "://") != NULL)) { - service_pos = strstr(targetdef, "://"); - if ((service_pos - targetdef) == 0) - bail("could not identify service"); - if ((hydra_options.service = malloc(1 + service_pos - targetdef)) == NULL) - bail("could not alloc memory"); - strncpy(hydra_options.service, targetdef, service_pos - targetdef); - hydra_options.service[service_pos - targetdef] = 0; - target_pos = targetdef + (service_pos - targetdef + 3); + if ((targetdef != NULL) && (strstr(targetdef, "://") != NULL)) { + service_pos = strstr(targetdef, "://"); + if ((service_pos - targetdef) == 0) + bail("could not identify service"); + if ((hydra_options.service = malloc(1 + service_pos - targetdef)) == NULL) + bail("could not alloc memory"); + strncpy(hydra_options.service, targetdef, service_pos - targetdef); + hydra_options.service[service_pos - targetdef] = 0; + target_pos = targetdef + (service_pos - targetdef + 3); - if (*target_pos == '[') { - target_pos++; - if ((param_pos = index(target_pos, ']')) == NULL) - bail("no closing ']' found in target definition"); - *param_pos++ = 0; - if (*param_pos == ':') - port_pos = ++param_pos; - if ((param_pos = index(param_pos, '/')) != NULL) - *param_pos++ = 0; - } else { - port_pos = index(target_pos, ':'); - param_pos = index(target_pos, '/'); - if (port_pos != NULL && param_pos != NULL && port_pos > param_pos) - port_pos = NULL; - if (port_pos != NULL) - *port_pos++ = 0; - if (param_pos != NULL) - *param_pos++ = 0; - if (port_pos != NULL && index(port_pos, ':') != NULL) { - if (prefer_ipv6) - bail("Illegal IPv6 target definition must be written within '[' ']'"); - else - bail("Illegal port definition"); - } - } - if (*target_pos == 0) - hydra_options.server = NULL; - else - hydra_options.server = target_pos; - if (port_pos != NULL) - hydra_options.port = port = atoi(port_pos); - if (param_pos != NULL) { - if (strstr(hydra_options.service, "http") != NULL && strstr(hydra_options.service, "http-proxy") == NULL && param_pos[1] != '/') - *--param_pos = '/'; - hydra_options.miscptr = strdup(param_pos); - } - //printf("target: %s service: %s port: %s opt: %s\n", target_pos, hydra_options.service, port_pos, param_pos); - if (debug) - printf("[DEBUG] opt:%d argc:%d mod:%s tgt:%s port:%u misc:%s\n", optind, argc, hydra_options.service, hydra_options.server, hydra_options.port, hydra_options.miscptr); - } else { - hydra_options.server = NULL; - hydra_options.service = NULL; + if (*target_pos == '[') { + target_pos++; + if ((param_pos = index(target_pos, ']')) == NULL) + bail("no closing ']' found in target definition"); + *param_pos++ = 0; + if (*param_pos == ':') + port_pos = ++param_pos; + if ((param_pos = index(param_pos, '/')) != NULL) + *param_pos++ = 0; + } else { + port_pos = index(target_pos, ':'); + param_pos = index(target_pos, '/'); + if (port_pos != NULL && param_pos != NULL && port_pos > param_pos) + port_pos = NULL; + if (port_pos != NULL) + *port_pos++ = 0; + if (param_pos != NULL) + *param_pos++ = 0; + if (port_pos != NULL && index(port_pos, ':') != NULL) { + if (prefer_ipv6) + bail("Illegal IPv6 target definition must be written within '[' ']'"); + else + bail("Illegal port definition"); + } + } + if (*target_pos == 0) + hydra_options.server = NULL; + else + hydra_options.server = target_pos; + if (port_pos != NULL) + hydra_options.port = port = atoi(port_pos); + if (param_pos != NULL) { + if (strstr(hydra_options.service, "http") != NULL && strstr(hydra_options.service, "http-proxy") == NULL && param_pos[1] != '/') + *--param_pos = '/'; + hydra_options.miscptr = strdup(param_pos); + } + //printf("target: %s service: %s port: %s opt: %s\n", target_pos, hydra_options.service, port_pos, param_pos); + if (debug) + printf("[DEBUG] opt:%d argc:%d mod:%s tgt:%s port:%u misc:%s\n", optind, argc, hydra_options.service, hydra_options.server, hydra_options.port, hydra_options.miscptr); + } else { + hydra_options.server = NULL; + hydra_options.service = NULL; - if (modusage) { - hydra_options.service = targetdef; - } else - help(0); - } - } else { - if (modusage && argv[optind] == NULL) { - printf("[ERROR] you must supply a service name after the -U help switch\n"); - exit(-1); - } - if (argv[optind] == NULL || strstr(argv[optind], "://") != NULL) { - printf("[ERROR] Invalid target definition!\n"); - printf("[ERROR] Either you use \"www.example.com module [optional-module-parameters]\" *or* you use the \"module://www.example.com/optional-module-parameters\" syntax!\n"); - exit(-1); - } - hydra_options.server = argv[optind]; - cmdlinetarget = argv[optind]; - hydra_options.service = argv[optind + 1]; - if (optind + 3 == argc) - hydra_options.miscptr = argv[optind + 2]; - } + if (modusage) { + hydra_options.service = targetdef; + } else + help(0); + } + } else { + if (modusage && argv[optind] == NULL) { + printf("[ERROR] you must supply a service name after the -U help switch\n"); + exit(-1); + } + if (argv[optind] == NULL || strstr(argv[optind], "://") != NULL) { + printf("[ERROR] Invalid target definition!\n"); + printf("[ERROR] Either you use \"www.example.com module [optional-module-parameters]\" *or* you use the \"module://www.example.com/optional-module-parameters\" syntax!\n"); + exit(-1); + } + hydra_options.server = argv[optind]; + cmdlinetarget = argv[optind]; + hydra_options.service = argv[optind + 1]; + if (optind + 3 == argc) + hydra_options.miscptr = argv[optind + 2]; + } - if (getenv("HYDRA_PROXY_CONNECT")) - fprintf(stderr, "[WARNING] The environment variable HYDRA_PROXY_CONNECT is not used! Use HYDRA_PROXY instead!\n"); + if (getenv("HYDRA_PROXY_CONNECT")) + fprintf(stderr, "[WARNING] The environment variable HYDRA_PROXY_CONNECT is not used! Use HYDRA_PROXY instead!\n"); - // wrong option use patch - if (hydra_options.ssl && ( ((strcmp(hydra_options.service, "smtp") == 0 || strcmp(hydra_options.service, "smtp-enum") == 0) && hydra_options.port != 465) || \ - (strcmp(hydra_options.service, "pop3") == 0 && hydra_options.port != 995) || \ - (strcmp(hydra_options.service, "imap") == 0 && hydra_options.port != 993) - )) - fprintf(stderr, "[WARNING] you want to access SMTP/POP3/IMAP with SSL. Are you sure you want to use direct SSL (-S) instead of STARTTLS (-m TLS)?\n"); + // wrong option use patch + if (hydra_options.ssl && ( ((strcmp(hydra_options.service, "smtp") == 0 || strcmp(hydra_options.service, "smtp-enum") == 0) && hydra_options.port != 465) || \ + (strcmp(hydra_options.service, "pop3") == 0 && hydra_options.port != 995) || \ + (strcmp(hydra_options.service, "imap") == 0 && hydra_options.port != 993) + )) + fprintf(stderr, "[WARNING] you want to access SMTP/POP3/IMAP with SSL. Are you sure you want to use direct SSL (-S) instead of STARTTLS (-m TLS)?\n"); - if (strcmp(hydra_options.service, "http") == 0 || strcmp(hydra_options.service, "https") == 0) { - fprintf(stderr, "[ERROR] There is no service \"%s\", most likely you mean one of the many web modules, e.g. http-get or http-form-post. Read it up!\n", hydra_options.service); - exit(-1); - } + if (strcmp(hydra_options.service, "http") == 0 || strcmp(hydra_options.service, "https") == 0) { + fprintf(stderr, "[ERROR] There is no service \"%s\", most likely you mean one of the many web modules, e.g. http-get or http-form-post. Read it up!\n", hydra_options.service); + exit(-1); + } - if (strcmp(hydra_options.service, "pop3s") == 0 || strcmp(hydra_options.service, "smtps") == 0 || strcmp(hydra_options.service, "imaps") == 0 - || strcmp(hydra_options.service, "telnets") == 0 || (strncmp(hydra_options.service, "ldap", 4) == 0 && hydra_options.service[strlen(hydra_options.service) - 1] == 's')) { - hydra_options.ssl = 1; - hydra_options.service[strlen(hydra_options.service) - 1] = 0; - } + if (strcmp(hydra_options.service, "pop3s") == 0 || strcmp(hydra_options.service, "smtps") == 0 || strcmp(hydra_options.service, "imaps") == 0 + || strcmp(hydra_options.service, "telnets") == 0 || (strncmp(hydra_options.service, "ldap", 4) == 0 && hydra_options.service[strlen(hydra_options.service) - 1] == 's')) { + hydra_options.ssl = 1; + hydra_options.service[strlen(hydra_options.service) - 1] = 0; + } - if (getenv("HYDRA_PROXY_HTTP") || getenv("HYDRA_PROXY")) { - if (strcmp(hydra_options.service, "afp") == 0 || strcmp(hydra_options.service, "firebird") == 0 || strncmp(hydra_options.service, "mysql", 5) == 0 || - strcmp(hydra_options.service, "ncp") == 0 || strcmp(hydra_options.service, "oracle") == 0 || strcmp(hydra_options.service, "postgres") == 0 || - strncmp(hydra_options.service, "ssh", 3) == 0 || strcmp(hydra_options.service, "sshkey") == 0 || strcmp(hydra_options.service, "svn") == 0 || - strcmp(hydra_options.service, "sapr3") == 0) { - fprintf(stderr, "[WARNING] module %s does not support HYDRA_PROXY* !\n", hydra_options.service); - proxy_string = NULL; - } - } + if (getenv("HYDRA_PROXY_HTTP") || getenv("HYDRA_PROXY")) { + if (strcmp(hydra_options.service, "afp") == 0 || strcmp(hydra_options.service, "firebird") == 0 || strncmp(hydra_options.service, "mysql", 5) == 0 || + strcmp(hydra_options.service, "ncp") == 0 || strcmp(hydra_options.service, "oracle") == 0 || strcmp(hydra_options.service, "postgres") == 0 || + strncmp(hydra_options.service, "ssh", 3) == 0 || strcmp(hydra_options.service, "sshkey") == 0 || strcmp(hydra_options.service, "svn") == 0 || + strcmp(hydra_options.service, "sapr3") == 0) { + fprintf(stderr, "[WARNING] module %s does not support HYDRA_PROXY* !\n", hydra_options.service); + proxy_string = NULL; + } + } - /* here start the services */ + /* here start the services */ - if (strcmp(hydra_options.service, "ssl") == 0 || strcmp(hydra_options.service, "www") == 0 || strcmp(hydra_options.service, "http") == 0 - || strcmp(hydra_options.service, "https") == 0) { - fprintf(stderr, "[WARNING] The service http has been replaced with http-head and http-get, using by default GET method. Same for https.\n"); - if (strcmp(hydra_options.service, "http") == 0) { - hydra_options.service = malloc(strlen("http-get") + 1); - strcpy(hydra_options.service, "http-get"); - } - if (strcmp(hydra_options.service, "https") == 0) { - hydra_options.service = malloc(strlen("https-get") + 1); - strcpy(hydra_options.service, "https-get"); - } - } + if (strcmp(hydra_options.service, "ssl") == 0 || strcmp(hydra_options.service, "www") == 0 || strcmp(hydra_options.service, "http") == 0 + || strcmp(hydra_options.service, "https") == 0) { + fprintf(stderr, "[WARNING] The service http has been replaced with http-head and http-get, using by default GET method. Same for https.\n"); + if (strcmp(hydra_options.service, "http") == 0) { + hydra_options.service = malloc(strlen("http-get") + 1); + strcpy(hydra_options.service, "http-get"); + } + if (strcmp(hydra_options.service, "https") == 0) { + hydra_options.service = malloc(strlen("https-get") + 1); + strcpy(hydra_options.service, "https-get"); + } + } - if (strcmp(hydra_options.service, "http-form-get") == 0) - strcpy(hydra_options.service, "http-get-form"); - if (strcmp(hydra_options.service, "https-form-get") == 0) - strcpy(hydra_options.service, "https-get-form"); - if (strcmp(hydra_options.service, "http-form-post") == 0) - strcpy(hydra_options.service, "http-post-form"); - if (strcmp(hydra_options.service, "https-form-post") == 0) - strcpy(hydra_options.service, "https-post-form"); + if (strcmp(hydra_options.service, "http-form-get") == 0) + strcpy(hydra_options.service, "http-get-form"); + if (strcmp(hydra_options.service, "https-form-get") == 0) + strcpy(hydra_options.service, "https-get-form"); + if (strcmp(hydra_options.service, "http-form-post") == 0) + strcpy(hydra_options.service, "http-post-form"); + if (strcmp(hydra_options.service, "https-form-post") == 0) + strcpy(hydra_options.service, "https-post-form"); - if (modusage == 1) { - if (hydra_options.service == NULL) { - printf("[ERROR] you must supply a service name after the -U help switch\n"); - exit(-1); - } - module_usage(); - } + if (modusage == 1) { + if (hydra_options.service == NULL) { + printf("[ERROR] you must supply a service name after the -U help switch\n"); + exit(-1); + } + module_usage(); + } - i = 0; - if (strcmp(hydra_options.service, "telnet") == 0) { - fprintf(stderr, "[WARNING] telnet is by its nature unreliable to analyze, if possible better choose FTP, SSH, etc. if available\n"); - i = 1; - } - if (strcmp(hydra_options.service, "ftp") == 0) - i = 1; - if (strcmp(hydra_options.service, "ftps") == 0) { - fprintf(stderr, "[WARNING] you enabled ftp-SSL (auth tls) mode. If you want to use direct SSL ftp, use -S and the ftp module instead.\n"); - i = 1; - } - if (strcmp(hydra_options.service, "pop3") == 0) { - fprintf(stderr, "[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!\n"); - i = 1; - } - if (strcmp(hydra_options.service, "imap") == 0) { - fprintf(stderr, "[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!\n"); - i = 1; - } - if (strcmp(hydra_options.service, "redis") == 0) - i = 2; - if (strcmp(hydra_options.service, "asterisk") == 0) - i = 1; - if (strcmp(hydra_options.service, "vmauthd") == 0) - i = 1; - if (strcmp(hydra_options.service, "rexec") == 0) - i = 1; - if (strcmp(hydra_options.service, "rlogin") == 0) - i = 1; - if (strcmp(hydra_options.service, "rsh") == 0) - i = 3; - if (strcmp(hydra_options.service, "nntp") == 0) - i = 1; - if (strcmp(hydra_options.service, "socks5") == 0) - i = 1; - if (strcmp(hydra_options.service, "icq") == 0) { - fprintf(stderr, "[WARNING] The icq module is not working with the modern protocol version! (somebody else will need to fix this as I don't care for icq)\n"); - i = 1; - } - if (strcmp(hydra_options.service, "mysql") == 0) { - i = 1; - if (hydra_options.tasks > 4) { - fprintf(stderr, "[INFO] Reduced number of tasks to 4 (mysql does not like many parallel connections)\n"); - hydra_options.tasks = 4; - } - } - if (strcmp(hydra_options.service, "mssql") == 0) - i = 1; - if ((strcmp(hydra_options.service, "oracle-listener") == 0) || (strcmp(hydra_options.service, "tns") == 0)) { - i = 2; - hydra_options.service = malloc(strlen("oracle-listener") + 1); - strcpy(hydra_options.service, "oracle-listener"); - } - if ((strcmp(hydra_options.service, "oracle-sid") == 0) || (strcmp(hydra_options.service, "sid") == 0)) { - i = 3; - hydra_options.service = malloc(strlen("oracle-sid") + 1); - strcpy(hydra_options.service, "oracle-sid"); - } + i = 0; + if (strcmp(hydra_options.service, "telnet") == 0) { + fprintf(stderr, "[WARNING] telnet is by its nature unreliable to analyze, if possible better choose FTP, SSH, etc. if available\n"); + i = 1; + } + if (strcmp(hydra_options.service, "ftp") == 0) + i = 1; + if (strcmp(hydra_options.service, "ftps") == 0) { + fprintf(stderr, "[WARNING] you enabled ftp-SSL (auth tls) mode. If you want to use direct SSL ftp, use -S and the ftp module instead.\n"); + i = 1; + } + if (strcmp(hydra_options.service, "pop3") == 0) { + fprintf(stderr, "[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!\n"); + i = 1; + } + if (strcmp(hydra_options.service, "imap") == 0) { + fprintf(stderr, "[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!\n"); + i = 1; + } + if (strcmp(hydra_options.service, "redis") == 0) + i = 2; + if (strcmp(hydra_options.service, "asterisk") == 0) + i = 1; + if (strcmp(hydra_options.service, "vmauthd") == 0) + i = 1; + if (strcmp(hydra_options.service, "rexec") == 0) + i = 1; + if (strcmp(hydra_options.service, "rlogin") == 0) + i = 1; + if (strcmp(hydra_options.service, "rsh") == 0) + i = 3; + if (strcmp(hydra_options.service, "nntp") == 0) + i = 1; + if (strcmp(hydra_options.service, "socks5") == 0) + i = 1; + if (strcmp(hydra_options.service, "icq") == 0) { + fprintf(stderr, "[WARNING] The icq module is not working with the modern protocol version! (somebody else will need to fix this as I don't care for icq)\n"); + i = 1; + } + if (strcmp(hydra_options.service, "mysql") == 0) { + i = 1; + if (hydra_options.tasks > 4) { + fprintf(stderr, "[INFO] Reduced number of tasks to 4 (mysql does not like many parallel connections)\n"); + hydra_options.tasks = 4; + } + } + if (strcmp(hydra_options.service, "mssql") == 0) + i = 1; + if ((strcmp(hydra_options.service, "oracle-listener") == 0) || (strcmp(hydra_options.service, "tns") == 0)) { + i = 2; + hydra_options.service = malloc(strlen("oracle-listener") + 1); + strcpy(hydra_options.service, "oracle-listener"); + } + if ((strcmp(hydra_options.service, "oracle-sid") == 0) || (strcmp(hydra_options.service, "sid") == 0)) { + i = 3; + hydra_options.service = malloc(strlen("oracle-sid") + 1); + strcpy(hydra_options.service, "oracle-sid"); + } #ifdef LIBORACLE - if ((strcmp(hydra_options.service, "oracle") == 0) || (strcmp(hydra_options.service, "ora") == 0)) { - i = 1; - hydra_options.service = malloc(strlen("oracle") + 1); - strcpy(hydra_options.service, "oracle"); - } + if ((strcmp(hydra_options.service, "oracle") == 0) || (strcmp(hydra_options.service, "ora") == 0)) { + i = 1; + hydra_options.service = malloc(strlen("oracle") + 1); + strcpy(hydra_options.service, "oracle"); + } #endif - if (strcmp(hydra_options.service, "postgres") == 0) + if (strcmp(hydra_options.service, "postgres") == 0) #ifdef LIBPOSTGRES - i = 1; + i = 1; #else - bail("Compiled without LIBPOSTGRES support, module not available!"); + bail("Compiled without LIBPOSTGRES support, module not available!"); #endif - if (strcmp(hydra_options.service, "firebird") == 0) + if (strcmp(hydra_options.service, "firebird") == 0) #ifdef LIBFIREBIRD - i = 1; + i = 1; #else - bail("Compiled without LIBFIREBIRD support, module not available!"); + bail("Compiled without LIBFIREBIRD support, module not available!"); #endif - if (strcmp(hydra_options.service, "afp") == 0) + if (strcmp(hydra_options.service, "afp") == 0) #ifdef LIBAFP - i = 1; + i = 1; #else - bail("Compiled without LIBAFP support, module not available!"); + bail("Compiled without LIBAFP support, module not available!"); #endif - if (strcmp(hydra_options.service, "svn") == 0) + if (strcmp(hydra_options.service, "svn") == 0) #ifdef LIBSVN - i = 1; + i = 1; #else - bail("Compiled without LIBSVN support, module not available!"); + bail("Compiled without LIBSVN support, module not available!"); #endif - if (strcmp(hydra_options.service, "ncp") == 0) + if (strcmp(hydra_options.service, "ncp") == 0) #ifdef LIBNCP - i = 1; + i = 1; #else - bail("Compiled without LIBNCP support, module not available!"); + bail("Compiled without LIBNCP support, module not available!"); #endif - if (strcmp(hydra_options.service, "pcanywhere") == 0) - i = 1; - if (strcmp(hydra_options.service, "http-proxy") == 0) { - i = 1; - if (hydra_options.miscptr != NULL && strncmp(hydra_options.miscptr, "http://", 7) != 0) - bail("module option must start with http://"); - } - if (strcmp(hydra_options.service, "cvs") == 0) { - i = 1; - if (hydra_options.miscptr == NULL || (strlen(hydra_options.miscptr) == 0)) { - fprintf(stderr, "[INFO] The CVS repository path wasn't passed so using /root by default\n"); - } - } - if (strcmp(hydra_options.service, "svn") == 0) { - i = 1; - if (hydra_options.miscptr == NULL || (strlen(hydra_options.miscptr) == 0)) { - fprintf(stderr, "[INFO] The SVN repository path wasn't passed so using /trunk by default\n"); - } - } - if (strcmp(hydra_options.service, "ssh") == 0 || strcmp(hydra_options.service, "sshkey") == 0) { - if (hydra_options.tasks > 8) - fprintf(stderr, "[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4\n"); + if (strcmp(hydra_options.service, "pcanywhere") == 0) + i = 1; + if (strcmp(hydra_options.service, "http-proxy") == 0) { + i = 1; + if (hydra_options.miscptr != NULL && strncmp(hydra_options.miscptr, "http://", 7) != 0) + bail("module option must start with http://"); + } + if (strcmp(hydra_options.service, "cvs") == 0) { + i = 1; + if (hydra_options.miscptr == NULL || (strlen(hydra_options.miscptr) == 0)) { + fprintf(stderr, "[INFO] The CVS repository path wasn't passed so using /root by default\n"); + } + } + if (strcmp(hydra_options.service, "svn") == 0) { + i = 1; + if (hydra_options.miscptr == NULL || (strlen(hydra_options.miscptr) == 0)) { + fprintf(stderr, "[INFO] The SVN repository path wasn't passed so using /trunk by default\n"); + } + } + if (strcmp(hydra_options.service, "ssh") == 0 || strcmp(hydra_options.service, "sshkey") == 0) { + if (hydra_options.tasks > 8) + fprintf(stderr, "[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4\n"); #ifdef LIBSSH - i = 1; + i = 1; #else - bail("Compiled without LIBSSH v0.4.x support, module is not available!"); + bail("Compiled without LIBSSH v0.4.x support, module is not available!"); #endif - } - if (strcmp(hydra_options.service, "smtp") == 0) { - fprintf(stderr, "[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!\n"); - i = 1; - } - if (strcmp(hydra_options.service, "smtp-enum") == 0) - i = 1; - if (strcmp(hydra_options.service, "teamspeak") == 0) - i = 1; - if ((strcmp(hydra_options.service, "smb") == 0) || (strcmp(hydra_options.service, "smbnt") == 0)) { - if (hydra_options.tasks > 1) { - fprintf(stderr, "[INFO] Reduced number of tasks to 1 (smb does not like parallel connections)\n"); - hydra_options.tasks = 1; - } - if (hydra_options.login != NULL && (index(hydra_options.login, '\\') != NULL || index(hydra_options.login, '/') != NULL)) - fprintf(stderr, "[WARNING] potential windows domain specification found in login. You must use the -m option to pass a domain.\n"); - i = 1; - } - if ((strcmp(hydra_options.service, "smb") == 0) || (strcmp(hydra_options.service, "smbnt") == 0)) { + } + if (strcmp(hydra_options.service, "smtp") == 0) { + fprintf(stderr, "[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!\n"); + i = 1; + } + if (strcmp(hydra_options.service, "smtp-enum") == 0) + i = 1; + if (strcmp(hydra_options.service, "teamspeak") == 0) + i = 1; + if ((strcmp(hydra_options.service, "smb") == 0) || (strcmp(hydra_options.service, "smbnt") == 0)) { + if (hydra_options.tasks > 1) { + fprintf(stderr, "[INFO] Reduced number of tasks to 1 (smb does not like parallel connections)\n"); + hydra_options.tasks = 1; + } + if (hydra_options.login != NULL && (index(hydra_options.login, '\\') != NULL || index(hydra_options.login, '/') != NULL)) + fprintf(stderr, "[WARNING] potential windows domain specification found in login. You must use the -m option to pass a domain.\n"); + i = 1; + } + if ((strcmp(hydra_options.service, "smb") == 0) || (strcmp(hydra_options.service, "smbnt") == 0)) { #ifdef LIBOPENSSL - if (hydra_options.tasks > 1) { - fprintf(stderr, "[INFO] Reduced number of tasks to 1 (smb does not like parallel connections)\n"); - hydra_options.tasks = 1; - } - i = 1; + if (hydra_options.tasks > 1) { + fprintf(stderr, "[INFO] Reduced number of tasks to 1 (smb does not like parallel connections)\n"); + hydra_options.tasks = 1; + } + i = 1; #endif - } - if ((strcmp(hydra_options.service, "smb") == 0) || (strcmp(hydra_options.service, "smbnt") == 0) || - (strcmp(hydra_options.service, "sip") == 0) || (strcmp(hydra_options.service, "rdp") == 0) || - (strcmp(hydra_options.service, "oracle-listener") == 0) || (strcmp(hydra_options.service, "oracle-sid") == 0)) { + } + if ((strcmp(hydra_options.service, "smb") == 0) || (strcmp(hydra_options.service, "smbnt") == 0) || + (strcmp(hydra_options.service, "sip") == 0) || (strcmp(hydra_options.service, "rdp") == 0) || + (strcmp(hydra_options.service, "oracle-listener") == 0) || (strcmp(hydra_options.service, "oracle-sid") == 0)) { #ifndef LIBOPENSSL - bail("Compiled without OPENSSL support, module not available!"); + bail("Compiled without OPENSSL support, module not available!"); #endif - } - if (strcmp(hydra_options.service, "pcnfs") == 0) { - i = 1; - if (port == 0) - bail("You must set the port for pcnfs with -s (run \"rpcinfo -p %s\" and look for the pcnfs v2 UDP port)"); - } - if (strcmp(hydra_options.service, "sapr3") == 0) { + } + if (strcmp(hydra_options.service, "pcnfs") == 0) { + i = 1; + if (port == 0) + bail("You must set the port for pcnfs with -s (run \"rpcinfo -p %s\" and look for the pcnfs v2 UDP port)"); + } + if (strcmp(hydra_options.service, "sapr3") == 0) { #ifdef LIBSAPR3 - i = 1; - if (port == PORT_SAPR3) - bail("You must set the port for sapr3 with -s , it should lie between 3200 and 3699."); - if (port < 3200 || port > 3699) - fprintf(stderr, "[WARNING] The port is not in the range 3200 to 3399 - please ensure it is ok!\n"); - if (hydra_options.miscptr == NULL || atoi(hydra_options.miscptr) < 0 || atoi(hydra_options.miscptr) > 999 || !isdigit(hydra_options.miscptr[0])) - bail("You must set the client ID (0-999) as an additional option or via -m"); + i = 1; + if (port == PORT_SAPR3) + bail("You must set the port for sapr3 with -s , it should lie between 3200 and 3699."); + if (port < 3200 || port > 3699) + fprintf(stderr, "[WARNING] The port is not in the range 3200 to 3399 - please ensure it is ok!\n"); + if (hydra_options.miscptr == NULL || atoi(hydra_options.miscptr) < 0 || atoi(hydra_options.miscptr) > 999 || !isdigit(hydra_options.miscptr[0])) + bail("You must set the client ID (0-999) as an additional option or via -m"); #else - bail("Compiled without LIBSAPR3 support, module not available!"); + bail("Compiled without LIBSAPR3 support, module not available!"); #endif - } - if (strcmp(hydra_options.service, "cisco") == 0) { - i = 2; - if (hydra_options.tasks > 4) - fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco services.\n"); - } - if (strcmp(hydra_options.service, "adam6500") == 0) { - i = 2; - fprintf(stderr, "[WARNING] the module adam6500 is work in progress! please submit a pcap of a successful login as well as false positives to vh@thc.org\n"); - if (hydra_options.tasks > 1) - fprintf(stderr, "[WARNING] reset the number of parallel task to 1 for adam6500 modbus authentication\n"); - hydra_options.tasks = 1; - } - if (strncmp(hydra_options.service, "snmpv", 5) == 0) { - hydra_options.service[4] = hydra_options.service[5]; - hydra_options.service[5] = 0; - } - if (strcmp(hydra_options.service, "snmp") == 0 || strcmp(hydra_options.service, "snmp1") == 0) { - hydra_options.service[4] = 0; - i = 2; - } - if (strcmp(hydra_options.service, "snmp2") == 0 || strcmp(hydra_options.service, "snmp3") == 0) { - if (hydra_options.miscptr == NULL) - hydra_options.miscptr = strdup(hydra_options.service + 4); - else { - tmpptr = malloc(strlen(hydra_options.miscptr) + 4); - strcpy(tmpptr, hydra_options.miscptr); - strcat(tmpptr, ":"); - strcat(tmpptr, hydra_options.service + 4); - hydra_options.miscptr = tmpptr; - } - hydra_options.service[4] = 0; - i = 2; - } - if (strcmp(hydra_options.service, "snmp") == 0 && hydra_options.miscptr != NULL) { - char *lptr; + } + if (strcmp(hydra_options.service, "cisco") == 0) { + i = 2; + if (hydra_options.tasks > 4) + fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco services.\n"); + } + if (strcmp(hydra_options.service, "adam6500") == 0) { + i = 2; + fprintf(stderr, "[WARNING] the module adam6500 is work in progress! please submit a pcap of a successful login as well as false positives to vh@thc.org\n"); + if (hydra_options.tasks > 1) + fprintf(stderr, "[WARNING] reset the number of parallel task to 1 for adam6500 modbus authentication\n"); + hydra_options.tasks = 1; + } + if (strncmp(hydra_options.service, "snmpv", 5) == 0) { + hydra_options.service[4] = hydra_options.service[5]; + hydra_options.service[5] = 0; + } + if (strcmp(hydra_options.service, "snmp") == 0 || strcmp(hydra_options.service, "snmp1") == 0) { + hydra_options.service[4] = 0; + i = 2; + } + if (strcmp(hydra_options.service, "snmp2") == 0 || strcmp(hydra_options.service, "snmp3") == 0) { + if (hydra_options.miscptr == NULL) + hydra_options.miscptr = strdup(hydra_options.service + 4); + else { + tmpptr = malloc(strlen(hydra_options.miscptr) + 4); + strcpy(tmpptr, hydra_options.miscptr); + strcat(tmpptr, ":"); + strcat(tmpptr, hydra_options.service + 4); + hydra_options.miscptr = tmpptr; + } + hydra_options.service[4] = 0; + i = 2; + } + if (strcmp(hydra_options.service, "snmp") == 0 && hydra_options.miscptr != NULL) { + char *lptr; - j = 1; - tmpptr = strdup(hydra_options.miscptr); - lptr = strtok(tmpptr, ":"); - while (lptr != NULL) { - i = 0; - if (strcasecmp(lptr, "1") == 0 || strcasecmp(lptr, "2") == 0 || strcasecmp(lptr, "3") == 0) { - i = 1; - j = lptr[0] - '0' + (j & 252); - } else if (strcasecmp(lptr, "READ") == 0 || strcasecmp(lptr, "WRITE") == 0 || strcasecmp(lptr, "PLAIN") == 0) - i = 1; - else if (strcasecmp(lptr, "MD5") == 0) { - i = 1; - j = 4 + (j & 51); - } else if (strcasecmp(lptr, "SHA") == 0 || strcasecmp(lptr, "SHA1") == 0) { - i = 1; - j = 8 + (j & 51); - } else if (strcasecmp(lptr, "DES") == 0) { - i = 1; - j = 16 + (j & 15); - } else if (strcasecmp(lptr, "AES") == 0) { - i = 1; - j = 32 + (j & 15); - } - if (i == 0) { - fprintf(stderr, "[ERROR] unknown parameter in module option: %s\n", lptr); - exit(-1); - } - lptr = strtok(NULL, ":"); - } - i = 2; - if ((j & 3) < 3 && j > 2) - fprintf(stderr, "[WARNING] SNMPv1 and SNMPv2 do not support hash and encryption, ignored\n"); - if ((j & 3) == 3) { - fprintf(stderr, "[WARNING] SNMPv3 is still in beta state, use at own risk and report problems\n"); - if (j >= 16) - bail("The SNMPv3 module so far only support authentication (md5/sha), not yet encryption\n"); - if (hydra_options.colonfile == NULL - && ((hydra_options.login == NULL && hydra_options.loginfile == NULL) || (hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.bfg == 0))) { - if (j > 3) { - fprintf(stderr, "[ERROR] you specified SNMPv3, defined hashing/encryption but only gave one of login or password list. Either supply both logins and passwords (this is what is usually used in SNMPv3), or remove the hashing/encryption option (unusual)\n"); - exit(-1); - } - fprintf(stderr, "[WARNING] you specified SNMPv3 but gave no logins, NoAuthNoPriv is assumed. This is an unusual case, you should know what you are doing\n"); - tmpptr = malloc(strlen(hydra_options.miscptr) + 8); - strcpy(tmpptr, hydra_options.miscptr); - strcat(tmpptr, ":"); - strcat(tmpptr, "PLAIN"); - hydra_options.miscptr = tmpptr; - } else { - i = 1; // snmpv3 with login+pass mode + j = 1; + tmpptr = strdup(hydra_options.miscptr); + lptr = strtok(tmpptr, ":"); + while (lptr != NULL) { + i = 0; + if (strcasecmp(lptr, "1") == 0 || strcasecmp(lptr, "2") == 0 || strcasecmp(lptr, "3") == 0) { + i = 1; + j = lptr[0] - '0' + (j & 252); + } else if (strcasecmp(lptr, "READ") == 0 || strcasecmp(lptr, "WRITE") == 0 || strcasecmp(lptr, "PLAIN") == 0) + i = 1; + else if (strcasecmp(lptr, "MD5") == 0) { + i = 1; + j = 4 + (j & 51); + } else if (strcasecmp(lptr, "SHA") == 0 || strcasecmp(lptr, "SHA1") == 0) { + i = 1; + j = 8 + (j & 51); + } else if (strcasecmp(lptr, "DES") == 0) { + i = 1; + j = 16 + (j & 15); + } else if (strcasecmp(lptr, "AES") == 0) { + i = 1; + j = 32 + (j & 15); + } + if (i == 0) { + fprintf(stderr, "[ERROR] unknown parameter in module option: %s\n", lptr); + exit(-1); + } + lptr = strtok(NULL, ":"); + } + i = 2; + if ((j & 3) < 3 && j > 2) + fprintf(stderr, "[WARNING] SNMPv1 and SNMPv2 do not support hash and encryption, ignored\n"); + if ((j & 3) == 3) { + fprintf(stderr, "[WARNING] SNMPv3 is still in beta state, use at own risk and report problems\n"); + if (j >= 16) + bail("The SNMPv3 module so far only support authentication (md5/sha), not yet encryption\n"); + if (hydra_options.colonfile == NULL + && ((hydra_options.login == NULL && hydra_options.loginfile == NULL) || (hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.bfg == 0))) { + if (j > 3) { + fprintf(stderr, "[ERROR] you specified SNMPv3, defined hashing/encryption but only gave one of login or password list. Either supply both logins and passwords (this is what is usually used in SNMPv3), or remove the hashing/encryption option (unusual)\n"); + exit(-1); + } + fprintf(stderr, "[WARNING] you specified SNMPv3 but gave no logins, NoAuthNoPriv is assumed. This is an unusual case, you should know what you are doing\n"); + tmpptr = malloc(strlen(hydra_options.miscptr) + 8); + strcpy(tmpptr, hydra_options.miscptr); + strcat(tmpptr, ":"); + strcat(tmpptr, "PLAIN"); + hydra_options.miscptr = tmpptr; + } else { + i = 1; // snmpv3 with login+pass mode #ifndef LIBOPENSSL - bail("hydra was not compiled with OPENSSL support, snmpv3 can only be used on NoAuthNoPriv mode (only logins, no passwords)!"); + bail("hydra was not compiled with OPENSSL support, snmpv3 can only be used on NoAuthNoPriv mode (only logins, no passwords)!"); #endif - printf("[INFO] Using %s SNMPv3 with %s authentication and %s privacy\n", j > 16 ? "AuthPriv" : "AuthNoPriv", (j & 8) == 8 ? "SHA" : "MD5", - (j & 16) == 16 ? "DES" : (j > 16) ? "AES" : "no"); - } - } - } - if (strcmp(hydra_options.service, "sip") == 0) { - if (hydra_options.miscptr == NULL) { - if (hydra_options.server != NULL) { - hydra_options.miscptr = hydra_options.server; - i = 1; - } else { - bail("The sip module does not work with multiple servers (-M)\n"); - } - } else { - i = 1; - } - } - if (strcmp(hydra_options.service, "ldap") == 0) { - bail("Please select ldap2 or ldap3 for simple authentication or ldap3-crammd5 or ldap3-digestmd5\n"); - } - if (strcmp(hydra_options.service, "ldap2") == 0 || strcmp(hydra_options.service, "ldap3") == 0) { - i = 1; - if ((hydra_options.miscptr != NULL && hydra_options.login != NULL) - || (hydra_options.miscptr != NULL && hydra_options.loginfile != NULL) || (hydra_options.login != NULL && hydra_options.loginfile != NULL)) - bail("you may only use one of -l, -L or -m\n"); - if (hydra_options.login == NULL && hydra_options.loginfile == NULL && hydra_options.miscptr == NULL) - fprintf(stderr, "[WARNING] no DN to authenticate is defined, using DN of null (use -m, -l or -L to define DNs)\n"); - if (hydra_options.login == NULL && hydra_options.loginfile == NULL) { - i = 2; - } - } - if (strcmp(hydra_options.service, "ldap3-crammd5") == 0 || strcmp(hydra_options.service, "ldap3-digestmd5") == 0) { - i = 1; - if (hydra_options.login == NULL && hydra_options.loginfile == NULL) - bail("-l or -L option is required to specify the login\n"); - if (hydra_options.miscptr == NULL) - bail("-m option is required to specify the DN\n"); - } - if (strcmp(hydra_options.service, "rtsp") == 0) - i = 1; - if (strcmp(hydra_options.service, "rpcap") == 0) - i = 1; - if (strcmp(hydra_options.service, "s7-300") == 0) { - if (hydra_options.tasks > 8) { - fprintf(stderr, "[INFO] Reduced number of tasks to 8 (the PLC does not like more connections)\n"); - hydra_options.tasks = 8; - } - i = 2; - } - if (strcmp(hydra_options.service, "cisco-enable") == 0) { - if (hydra_options.login != NULL || hydra_options.loginfile != NULL) - i = 1; // login will be the initial Username: login, or line Password: - else - i = 2; - if (hydra_options.miscptr == NULL) - fprintf(stderr, "[WARNING] You did not supply the initial support to the Cisco via -l, assuming direct console access\n"); - if (hydra_options.tasks > 4) - fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco enable services.\n"); - } - if (strcmp(hydra_options.service, "http-proxy-urlenum") == 0) { - i = 4; - hydra_options.pass = empty_login; - if (hydra_options.miscptr == NULL) { - fprintf(stderr, "[WARNING] You did not supply proxy credentials via the optional parameter\n"); - } - if (hydra_options.bfg || hydra_options.passfile != NULL) - bail("the http-proxy-urlenum does not need the -p/-P or -x option"); - } - if (strcmp(hydra_options.service, "vnc") == 0) { - i = 2; - if (hydra_options.tasks > 4) - fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for vnc services.\n"); - } - if (strcmp(hydra_options.service, "https-head") == 0 || strcmp(hydra_options.service, "https-get") == 0 || strcmp(hydra_options.service, "https-post") == 0) { + printf("[INFO] Using %s SNMPv3 with %s authentication and %s privacy\n", j > 16 ? "AuthPriv" : "AuthNoPriv", (j & 8) == 8 ? "SHA" : "MD5", + (j & 16) == 16 ? "DES" : (j > 16) ? "AES" : "no"); + } + } + } + if (strcmp(hydra_options.service, "sip") == 0) { + if (hydra_options.miscptr == NULL) { + if (hydra_options.server != NULL) { + hydra_options.miscptr = hydra_options.server; + i = 1; + } else { + bail("The sip module does not work with multiple servers (-M)\n"); + } + } else { + i = 1; + } + } + if (strcmp(hydra_options.service, "ldap") == 0) { + bail("Please select ldap2 or ldap3 for simple authentication or ldap3-crammd5 or ldap3-digestmd5\n"); + } + if (strcmp(hydra_options.service, "ldap2") == 0 || strcmp(hydra_options.service, "ldap3") == 0) { + i = 1; + if ((hydra_options.miscptr != NULL && hydra_options.login != NULL) + || (hydra_options.miscptr != NULL && hydra_options.loginfile != NULL) || (hydra_options.login != NULL && hydra_options.loginfile != NULL)) + bail("you may only use one of -l, -L or -m\n"); + if (hydra_options.login == NULL && hydra_options.loginfile == NULL && hydra_options.miscptr == NULL) + fprintf(stderr, "[WARNING] no DN to authenticate is defined, using DN of null (use -m, -l or -L to define DNs)\n"); + if (hydra_options.login == NULL && hydra_options.loginfile == NULL) { + i = 2; + } + } + if (strcmp(hydra_options.service, "ldap3-crammd5") == 0 || strcmp(hydra_options.service, "ldap3-digestmd5") == 0) { + i = 1; + if (hydra_options.login == NULL && hydra_options.loginfile == NULL) + bail("-l or -L option is required to specify the login\n"); + if (hydra_options.miscptr == NULL) + bail("-m option is required to specify the DN\n"); + } + if (strcmp(hydra_options.service, "rtsp") == 0) + i = 1; + if (strcmp(hydra_options.service, "rpcap") == 0) + i = 1; + if (strcmp(hydra_options.service, "s7-300") == 0) { + if (hydra_options.tasks > 8) { + fprintf(stderr, "[INFO] Reduced number of tasks to 8 (the PLC does not like more connections)\n"); + hydra_options.tasks = 8; + } + i = 2; + } + if (strcmp(hydra_options.service, "cisco-enable") == 0) { + if (hydra_options.login != NULL || hydra_options.loginfile != NULL) + i = 1; // login will be the initial Username: login, or line Password: + else + i = 2; + if (hydra_options.miscptr == NULL) + fprintf(stderr, "[WARNING] You did not supply the initial support to the Cisco via -l, assuming direct console access\n"); + if (hydra_options.tasks > 4) + fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for cisco enable services.\n"); + } + if (strcmp(hydra_options.service, "http-proxy-urlenum") == 0) { + i = 4; + hydra_options.pass = empty_login; + if (hydra_options.miscptr == NULL) { + fprintf(stderr, "[WARNING] You did not supply proxy credentials via the optional parameter\n"); + } + if (hydra_options.bfg || hydra_options.passfile != NULL) + bail("the http-proxy-urlenum does not need the -p/-P or -x option"); + } + if (strcmp(hydra_options.service, "vnc") == 0) { + i = 2; + if (hydra_options.tasks > 4) + fprintf(stderr, "[WARNING] you should set the number of parallel task to 4 for vnc services.\n"); + } + if (strcmp(hydra_options.service, "https-head") == 0 || strcmp(hydra_options.service, "https-get") == 0 || strcmp(hydra_options.service, "https-post") == 0) { #ifdef LIBOPENSSL - i = 1; - hydra_options.ssl = 1; - if (strcmp(hydra_options.service, "https-head") == 0) - strcpy(hydra_options.service, "http-head"); - else - if (strcmp(hydra_options.service, "https-post") == 0) - strcpy(hydra_options.service, "http-post"); - else - strcpy(hydra_options.service, "http-get"); + i = 1; + hydra_options.ssl = 1; + if (strcmp(hydra_options.service, "https-head") == 0) + strcpy(hydra_options.service, "http-head"); + else + if (strcmp(hydra_options.service, "https-post") == 0) + strcpy(hydra_options.service, "http-post"); + else + strcpy(hydra_options.service, "http-get"); #else - bail("Compiled without SSL support, module not available"); + bail("Compiled without SSL support, module not available"); #endif - } - if (strcmp(hydra_options.service, "http-get") == 0 || strcmp(hydra_options.service, "http-head") == 0 || strcmp(hydra_options.service, "http-post") == 0) { - i = 1; - 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 (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 (strcmp(hydra_options.service, "http-head") == 0) - fprintf(stderr, "[WARNING] http-head auth does not work with every server, better use http-get\n"); - } + } + if (strcmp(hydra_options.service, "http-get") == 0 || strcmp(hydra_options.service, "http-head") == 0 || strcmp(hydra_options.service, "http-post") == 0) { + i = 1; + 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 (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 (strcmp(hydra_options.service, "http-head") == 0) + fprintf(stderr, "[WARNING] http-head auth does not work with every server, better use http-get\n"); + } - if (strcmp(hydra_options.service, "http-get-form") == 0 || strcmp(hydra_options.service, "http-post-form") == 0 || strcmp(hydra_options.service, "https-get-form") == 0 - || strcmp(hydra_options.service, "https-post-form") == 0) { - char bufferurl[6096+24], *url, *variables, *cond, *optional1; //6096 comes from issue 192 on github. Extra 24 bytes for null padding. + if (strcmp(hydra_options.service, "http-get-form") == 0 || strcmp(hydra_options.service, "http-post-form") == 0 || strcmp(hydra_options.service, "https-get-form") == 0 + || strcmp(hydra_options.service, "https-post-form") == 0) { + char bufferurl[6096+24], *url, *variables, *cond, *optional1; //6096 comes from issue 192 on github. Extra 24 bytes for null padding. - if (strncmp(hydra_options.service, "http-", 5) == 0) { - i = 1; - } else { // https + if (strncmp(hydra_options.service, "http-", 5) == 0) { + i = 1; + } else { // https #ifdef LIBOPENSSL - i = 1; - hydra_options.ssl = 1; - if (strcmp(hydra_options.service, "https-post-form") == 0) - strcpy(hydra_options.service, "http-post-form"); - else - strcpy(hydra_options.service, "http-get-form"); + i = 1; + hydra_options.ssl = 1; + if (strcmp(hydra_options.service, "https-post-form") == 0) + strcpy(hydra_options.service, "http-post-form"); + else + strcpy(hydra_options.service, "http-get-form"); #else - bail("Compiled without SSL support, module not available"); + bail("Compiled without SSL support, module not available"); #endif - } - 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 (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 ((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); - 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); - } - } - } - } + 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 ((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); + 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); + } + } + } + } - if (strcmp(hydra_options.service, "xmpp") == 0) - i = 1; - if (strcmp(hydra_options.service, "irc") == 0) - i = 1; - if (strcmp(hydra_options.service, "rdp") == 0) { - if (hydra_options.tasks > 4) - fprintf(stderr, - "[WARNING] rdp servers often don't like many connections, use -t 1 or -t 4 to reduce the number of parallel connections and -W 1 or -W 3 to wait between connection to allow the server to recover\n"); - //if (hydra_options.tasks > 4) { - // fprintf(stderr, "[INFO] Reduced number of tasks to 4 (rdp does not like many parallel connections)\n"); - // hydra_options.tasks = 4; - //} - //if (conwait == 0) - // hydra_options.conwait = conwait = 1; - printf("[WARNING] the rdp module is currently reported to be unreliable, most likely against new Windows version. Please test, report - and if possible, fix.\n"); - i = 1; - } - if (strcmp(hydra_options.service, "radmin2") == 0) { + if (strcmp(hydra_options.service, "xmpp") == 0) + i = 1; + if (strcmp(hydra_options.service, "irc") == 0) + i = 1; + if (strcmp(hydra_options.service, "rdp") == 0) { + if (hydra_options.tasks > 4) + fprintf(stderr, + "[WARNING] rdp servers often don't like many connections, use -t 1 or -t 4 to reduce the number of parallel connections and -W 1 or -W 3 to wait between connection to allow the server to recover\n"); + //if (hydra_options.tasks > 4) { + // fprintf(stderr, "[INFO] Reduced number of tasks to 4 (rdp does not like many parallel connections)\n"); + // hydra_options.tasks = 4; + //} + //if (conwait == 0) + // hydra_options.conwait = conwait = 1; + printf("[WARNING] the rdp module is currently reported to be unreliable, most likely against new Windows version. Please test, report - and if possible, fix.\n"); + i = 1; + } + if (strcmp(hydra_options.service, "radmin2") == 0) { #ifdef HAVE_GCRYPT - i = 1; + i = 1; #else - bail("hydra was not compiled with gcrypt support, radmin2 module not available"); + bail("hydra was not compiled with gcrypt support, radmin2 module not available"); #endif - } + } - // ADD NEW SERVICES HERE + // ADD NEW SERVICES HERE - if (i == 0) { - fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service); - exit(-1); - } - if (port < 1 || port > 65535) { - if ((port = hydra_lookup_port(hydra_options.service)) < 1) { - fprintf(stderr, "[ERROR] No valid port set or no default port available. Use the -s Option.\n"); - exit(-1); - } - hydra_options.port = port; - } + if (i == 0) { + fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service); + exit(-1); + } + if (port < 1 || port > 65535) { + if ((port = hydra_lookup_port(hydra_options.service)) < 1) { + fprintf(stderr, "[ERROR] No valid port set or no default port available. Use the -s Option.\n"); + exit(-1); + } + hydra_options.port = port; + } - if (hydra_options.ssl == 0 && hydra_options.port == 443) - fprintf(stderr, "[WARNING] you specified port 443 for attacking a http service, however did not specify the -S ssl switch nor used https-..., therefore using plain HTTP\n"); + if (hydra_options.ssl == 0 && hydra_options.port == 443) + fprintf(stderr, "[WARNING] you specified port 443 for attacking a http service, however did not specify the -S ssl switch nor used https-..., therefore using plain HTTP\n"); - if (hydra_options.loop_mode && hydra_options.colonfile != NULL) - bail("The loop mode option (-u) works with all modes - except colon files (-C)\n"); - if (strncmp(hydra_options.service, "http-", strlen("http-")) != 0 && strcmp(hydra_options.service, "http-head") != 0 && getenv("HYDRA_PROXY_HTTP") != NULL) - fprintf(stderr, "[WARNING] the HYDRA_PROXY_HTTP environment variable works only with the http-head/http-get module, ignored...\n"); - if (i == 2) { - if (hydra_options.colonfile != NULL - || ((hydra_options.login != NULL || hydra_options.loginfile != NULL) && (hydra_options.pass != NULL || hydra_options.passfile != NULL || hydra_options.bfg > 0))) - bail - ("The redis, adam6500, cisco, oracle-listener, s7-300, snmp and vnc modules are only using the -p or -P option, not login (-l, -L) or colon file (-C).\nUse the telnet module for cisco using \"Username:\" authentication.\n"); - if ((hydra_options.login != NULL || hydra_options.loginfile != NULL) && (hydra_options.pass == NULL || hydra_options.passfile == NULL)) { - hydra_options.pass = hydra_options.login; - hydra_options.passfile = hydra_options.loginfile; - } - hydra_options.login = empty_login; - hydra_options.loginfile = NULL; - } - if (i == 3) { - if (hydra_options.colonfile != NULL || hydra_options.bfg > 0 - || ((hydra_options.login != NULL || hydra_options.loginfile != NULL) && (hydra_options.pass != NULL || hydra_options.passfile != NULL))) - bail("The rsh, oracle-sid login is neither using the -p, -P or -x options nor colon file (-C)\n"); - if ((hydra_options.login == NULL || hydra_options.loginfile == NULL) && (hydra_options.pass != NULL || hydra_options.passfile != NULL)) { - hydra_options.login = hydra_options.pass; - hydra_options.loginfile = hydra_options.passfile; - } - hydra_options.pass = empty_login; - hydra_options.passfile = NULL; - } - if (i == 3 && hydra_options.login == NULL && hydra_options.loginfile == NULL) - bail("I need at least either the -l or -L option to know the login"); - if (i == 2 && hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.bfg == 0) - bail("I need at least either the -p, -P or -x option to have a password to try"); - if (i == 1 && hydra_options.login == NULL && hydra_options.loginfile == NULL && hydra_options.colonfile == NULL) - bail("I need at least either the -l, -L or -C option to know the login"); - if (hydra_options.colonfile != NULL && ((hydra_options.bfg != 0 || hydra_options.login != NULL || hydra_options.loginfile != NULL) - || (hydra_options.pass != NULL && hydra_options.passfile != NULL))) - bail("The -C option is standalone, don't use it with -l/L, -p/P or -x!"); - if ((hydra_options.bfg) - && ((hydra_options.pass != NULL) || (hydra_options.passfile != NULL) - || (hydra_options.colonfile != NULL))) - bail("The -x (password bruteforce generation option) doesn't work with -p/P, -C or -e!\n"); - if (hydra_options.try_password_reverse_login == 0 && hydra_options.try_password_same_as_login == 0 && hydra_options.try_null_password == 0 - && (i != 3 && (hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.colonfile == NULL)) && hydra_options.bfg == 0) { - // test if the service is smtp-enum as it could be used either with a login+pass or only a login - if (strstr(hydra_options.service, "smtp-enum") != NULL) - hydra_options.pass = empty_login; - else - bail("I need at least the -e, -p, -P or -x option to have some passwords!"); - } - if (hydra_options.tasks < 1 || hydra_options.tasks > MAXTASKS) { - fprintf(stderr, "[ERROR] Option -t needs to be a number between 1 and %d\n", MAXTASKS); - exit(-1); - } - if (hydra_options.max_use > MAXTASKS) { - fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", MAXTASKS); - hydra_options.max_use = MAXTASKS; - } - // script kiddie patch - if (hydra_options.server != NULL && (hydra_strcasestr(hydra_options.server, "gmail.") != NULL || hydra_strcasestr(hydra_options.server, "googlemail.") != NULL)) - fprintf(stderr, "[WARNING] Google Mail has bruteforce detection and sends false positives. You are not doing anything illegal right?!\n"); + if (hydra_options.loop_mode && hydra_options.colonfile != NULL) + bail("The loop mode option (-u) works with all modes - except colon files (-C)\n"); + if (strncmp(hydra_options.service, "http-", strlen("http-")) != 0 && strcmp(hydra_options.service, "http-head") != 0 && getenv("HYDRA_PROXY_HTTP") != NULL) + fprintf(stderr, "[WARNING] the HYDRA_PROXY_HTTP environment variable works only with the http-head/http-get module, ignored...\n"); + if (i == 2) { + if (hydra_options.colonfile != NULL + || ((hydra_options.login != NULL || hydra_options.loginfile != NULL) && (hydra_options.pass != NULL || hydra_options.passfile != NULL || hydra_options.bfg > 0))) + bail + ("The redis, adam6500, cisco, oracle-listener, s7-300, snmp and vnc modules are only using the -p or -P option, not login (-l, -L) or colon file (-C).\nUse the telnet module for cisco using \"Username:\" authentication.\n"); + if ((hydra_options.login != NULL || hydra_options.loginfile != NULL) && (hydra_options.pass == NULL || hydra_options.passfile == NULL)) { + hydra_options.pass = hydra_options.login; + hydra_options.passfile = hydra_options.loginfile; + } + hydra_options.login = empty_login; + hydra_options.loginfile = NULL; + } + if (i == 3) { + if (hydra_options.colonfile != NULL || hydra_options.bfg > 0 + || ((hydra_options.login != NULL || hydra_options.loginfile != NULL) && (hydra_options.pass != NULL || hydra_options.passfile != NULL))) + bail("The rsh, oracle-sid login is neither using the -p, -P or -x options nor colon file (-C)\n"); + if ((hydra_options.login == NULL || hydra_options.loginfile == NULL) && (hydra_options.pass != NULL || hydra_options.passfile != NULL)) { + hydra_options.login = hydra_options.pass; + hydra_options.loginfile = hydra_options.passfile; + } + hydra_options.pass = empty_login; + hydra_options.passfile = NULL; + } + if (i == 3 && hydra_options.login == NULL && hydra_options.loginfile == NULL) + bail("I need at least either the -l or -L option to know the login"); + if (i == 2 && hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.bfg == 0) + bail("I need at least either the -p, -P or -x option to have a password to try"); + if (i == 1 && hydra_options.login == NULL && hydra_options.loginfile == NULL && hydra_options.colonfile == NULL) + bail("I need at least either the -l, -L or -C option to know the login"); + if (hydra_options.colonfile != NULL && ((hydra_options.bfg != 0 || hydra_options.login != NULL || hydra_options.loginfile != NULL) + || (hydra_options.pass != NULL && hydra_options.passfile != NULL))) + bail("The -C option is standalone, don't use it with -l/L, -p/P or -x!"); + if ((hydra_options.bfg) + && ((hydra_options.pass != NULL) || (hydra_options.passfile != NULL) + || (hydra_options.colonfile != NULL))) + bail("The -x (password bruteforce generation option) doesn't work with -p/P, -C or -e!\n"); + if (hydra_options.try_password_reverse_login == 0 && hydra_options.try_password_same_as_login == 0 && hydra_options.try_null_password == 0 + && (i != 3 && (hydra_options.pass == NULL && hydra_options.passfile == NULL && hydra_options.colonfile == NULL)) && hydra_options.bfg == 0) { + // test if the service is smtp-enum as it could be used either with a login+pass or only a login + if (strstr(hydra_options.service, "smtp-enum") != NULL) + hydra_options.pass = empty_login; + else + bail("I need at least the -e, -p, -P or -x option to have some passwords!"); + } + if (hydra_options.tasks < 1 || hydra_options.tasks > MAXTASKS) { + fprintf(stderr, "[ERROR] Option -t needs to be a number between 1 and %d\n", MAXTASKS); + exit(-1); + } + if (hydra_options.max_use > MAXTASKS) { + fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", MAXTASKS); + hydra_options.max_use = MAXTASKS; + } + // script kiddie patch + if (hydra_options.server != NULL && (hydra_strcasestr(hydra_options.server, "gmail.") != NULL || hydra_strcasestr(hydra_options.server, "googlemail.") != NULL)) + fprintf(stderr, "[WARNING] Google Mail has bruteforce detection and sends false positives. You are not doing anything illegal right?!\n"); - if (hydra_options.colonfile == NULL) { - if (hydra_options.loginfile != NULL) { - if ((lfp = fopen(hydra_options.loginfile, "r")) == NULL) { - fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile); - exit(-1); - } - hydra_brains.countlogin = countlines(lfp, 0); - hydra_brains.sizelogin = size_of_data; - if (hydra_brains.countlogin == 0) { - fprintf(stderr, "[ERROR] File for logins is empty: %s\n", hydra_options.loginfile); - exit(-1); - } - if (hydra_brains.countlogin > MAX_LINES) { - fprintf(stderr, "[ERROR] Maximum number of logins is %d, this file has %lu entries.\n", MAX_LINES, hydra_brains.countlogin); - exit(-1); - } - if (hydra_brains.sizelogin > MAX_BYTES) { - fprintf(stderr, "[ERROR] Maximum size of the login file is %d, this file has %lu bytes.\n", MAX_BYTES, (uint64_t) hydra_brains.sizelogin); - exit(-1); - } - login_ptr = malloc(hydra_brains.sizelogin + hydra_brains.countlogin + 8); - if (login_ptr == NULL) - bail("Could not allocate enough memory for login file data"); - memset(login_ptr, 0, hydra_brains.sizelogin + hydra_brains.countlogin + 8); - fill_mem(login_ptr, lfp, 0); - } else { - login_ptr = hydra_options.login; - hydra_brains.sizelogin = strlen(hydra_options.login) + 1; - hydra_brains.countlogin = 1; - } - if (hydra_options.passfile != NULL) { - if ((pfp = fopen(hydra_options.passfile, "r")) == NULL) { - fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile); - exit(-1); - } - hydra_brains.countpass = countlines(pfp, 0); - hydra_brains.sizepass = size_of_data; - if (hydra_brains.countpass == 0) { - fprintf(stderr, "[ERROR] File for passwords is empty: %s\n", hydra_options.passfile); - exit(-1); - } - if (hydra_brains.countpass > MAX_LINES) { - fprintf(stderr, "[ERROR] Maximum number of passwords is %d, this file has %lu entries.\n", MAX_LINES, hydra_brains.countpass); - exit(-1); - } - if (hydra_brains.sizepass > MAX_BYTES) { - fprintf(stderr, "[ERROR] Maximum size of the password file is %d, this file has %lu bytes.\n", MAX_BYTES, (uint64_t) hydra_brains.sizepass); - exit(-1); - } - pass_ptr = malloc(hydra_brains.sizepass + hydra_brains.countpass + 8); - if (pass_ptr == NULL) - bail("Could not allocate enough memory for password file data"); - memset(pass_ptr, 0, hydra_brains.sizepass + hydra_brains.countpass + 8); - fill_mem(pass_ptr, pfp, 0); - } else { - if (hydra_options.pass != NULL) { - pass_ptr = hydra_options.pass; - hydra_brains.countpass = 1; - hydra_brains.sizepass = strlen(hydra_options.pass) + 1; - } else { - if (hydra_options.bfg) { + if (hydra_options.colonfile == NULL) { + if (hydra_options.loginfile != NULL) { + if ((lfp = fopen(hydra_options.loginfile, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile); + exit(-1); + } + hydra_brains.countlogin = countlines(lfp, 0); + hydra_brains.sizelogin = size_of_data; + if (hydra_brains.countlogin == 0) { + fprintf(stderr, "[ERROR] File for logins is empty: %s\n", hydra_options.loginfile); + exit(-1); + } + if (hydra_brains.countlogin > MAX_LINES) { + fprintf(stderr, "[ERROR] Maximum number of logins is %d, this file has %lu entries.\n", MAX_LINES, hydra_brains.countlogin); + exit(-1); + } + if (hydra_brains.sizelogin > MAX_BYTES) { + fprintf(stderr, "[ERROR] Maximum size of the login file is %d, this file has %lu bytes.\n", MAX_BYTES, (uint64_t) hydra_brains.sizelogin); + exit(-1); + } + login_ptr = malloc(hydra_brains.sizelogin + hydra_brains.countlogin + 8); + if (login_ptr == NULL) + bail("Could not allocate enough memory for login file data"); + memset(login_ptr, 0, hydra_brains.sizelogin + hydra_brains.countlogin + 8); + fill_mem(login_ptr, lfp, 0); + } else { + login_ptr = hydra_options.login; + hydra_brains.sizelogin = strlen(hydra_options.login) + 1; + hydra_brains.countlogin = 1; + } + if (hydra_options.passfile != NULL) { + if ((pfp = fopen(hydra_options.passfile, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile); + exit(-1); + } + hydra_brains.countpass = countlines(pfp, 0); + hydra_brains.sizepass = size_of_data; + if (hydra_brains.countpass == 0) { + fprintf(stderr, "[ERROR] File for passwords is empty: %s\n", hydra_options.passfile); + exit(-1); + } + if (hydra_brains.countpass > MAX_LINES) { + fprintf(stderr, "[ERROR] Maximum number of passwords is %d, this file has %lu entries.\n", MAX_LINES, hydra_brains.countpass); + exit(-1); + } + if (hydra_brains.sizepass > MAX_BYTES) { + fprintf(stderr, "[ERROR] Maximum size of the password file is %d, this file has %lu bytes.\n", MAX_BYTES, (uint64_t) hydra_brains.sizepass); + exit(-1); + } + pass_ptr = malloc(hydra_brains.sizepass + hydra_brains.countpass + 8); + if (pass_ptr == NULL) + bail("Could not allocate enough memory for password file data"); + memset(pass_ptr, 0, hydra_brains.sizepass + hydra_brains.countpass + 8); + fill_mem(pass_ptr, pfp, 0); + } else { + if (hydra_options.pass != NULL) { + pass_ptr = hydra_options.pass; + hydra_brains.countpass = 1; + hydra_brains.sizepass = strlen(hydra_options.pass) + 1; + } else { + if (hydra_options.bfg) { #ifdef HAVE_MATH_H - if (bf_init(bf_options.arg)) - exit(-1); // error description is handled by bf_init - pass_ptr = bf_next(); - hydra_brains.countpass += bf_get_pcount(); - hydra_brains.sizepass += BF_BUFLEN; + if (bf_init(bf_options.arg)) + exit(-1); // error description is handled by bf_init + pass_ptr = bf_next(); + hydra_brains.countpass += bf_get_pcount(); + hydra_brains.sizepass += BF_BUFLEN; #else - sleep(1); + sleep(1); #endif - } else { - pass_ptr = hydra_options.pass = empty_login; - hydra_brains.countpass = 0; - hydra_brains.sizepass = 1; - } - } - } - } else { - if ((cfp = fopen(hydra_options.colonfile, "r")) == NULL) { - fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile); - exit(-1); - } - hydra_brains.countlogin = countlines(cfp, 1); - hydra_brains.sizelogin = size_of_data; - if (hydra_brains.countlogin == 0) { - fprintf(stderr, "[ERROR] File for colon files (login:pass) is empty: %s\n", hydra_options.colonfile); - exit(-1); - } - if (hydra_brains.countlogin > MAX_LINES / 2) { - fprintf(stderr, "[ERROR] Maximum number of colon file entries is %d, this file has %lu entries.\n", MAX_LINES / 2, hydra_brains.countlogin); - exit(-1); - } - if (hydra_brains.sizelogin > MAX_BYTES / 2) { - fprintf(stderr, "[ERROR] Maximum size of the colon file is %d, this file has %lu bytes.\n", MAX_BYTES / 2, (uint64_t) hydra_brains.sizelogin); - exit(-1); - } - csv_ptr = malloc(hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8); - if (csv_ptr == NULL) - bail("Could not allocate enough memory for colon file data"); - memset(csv_ptr, 0, hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8); - fill_mem(csv_ptr, cfp, 1); - //printf("count: %d, size: %d\n", hydra_brains.countlogin, hydra_brains.sizelogin); - //hydra_dump_data(csv_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, "colon data"); - hydra_brains.countpass = 1; - pass_ptr = login_ptr = csv_ptr; - while (*pass_ptr != 0) - pass_ptr++; - pass_ptr++; - } + } else { + pass_ptr = hydra_options.pass = empty_login; + hydra_brains.countpass = 0; + hydra_brains.sizepass = 1; + } + } + } + } else { + if ((cfp = fopen(hydra_options.colonfile, "r")) == NULL) { + fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile); + exit(-1); + } + hydra_brains.countlogin = countlines(cfp, 1); + hydra_brains.sizelogin = size_of_data; + if (hydra_brains.countlogin == 0) { + fprintf(stderr, "[ERROR] File for colon files (login:pass) is empty: %s\n", hydra_options.colonfile); + exit(-1); + } + if (hydra_brains.countlogin > MAX_LINES / 2) { + fprintf(stderr, "[ERROR] Maximum number of colon file entries is %d, this file has %lu entries.\n", MAX_LINES / 2, hydra_brains.countlogin); + exit(-1); + } + if (hydra_brains.sizelogin > MAX_BYTES / 2) { + fprintf(stderr, "[ERROR] Maximum size of the colon file is %d, this file has %lu bytes.\n", MAX_BYTES / 2, (uint64_t) hydra_brains.sizelogin); + exit(-1); + } + csv_ptr = malloc(hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8); + if (csv_ptr == NULL) + bail("Could not allocate enough memory for colon file data"); + memset(csv_ptr, 0, hydra_brains.sizelogin + 2 * hydra_brains.countlogin + 8); + fill_mem(csv_ptr, cfp, 1); + //printf("count: %d, size: %d\n", hydra_brains.countlogin, hydra_brains.sizelogin); + //hydra_dump_data(csv_ptr, hydra_brains.sizelogin + hydra_brains.countlogin + 8, "colon data"); + hydra_brains.countpass = 1; + pass_ptr = login_ptr = csv_ptr; + while (*pass_ptr != 0) + pass_ptr++; + pass_ptr++; + } - hydra_brains.countpass += hydra_options.try_password_reverse_login + hydra_options.try_password_same_as_login + hydra_options.try_null_password; - if ((memcheck = malloc(102400)) == NULL) { - fprintf(stderr, "[ERROR] your wordlist is too large, not enough memory!\n"); - exit(-1); - } - free(memcheck); - if ((rfp = fopen(RESTOREFILE, "r")) != NULL) { - fprintf(stderr, "[WARNING] Restorefile (%s) from a previous session found, to prevent overwriting, %s\n", ignore_restore == 1 ? "ignored ..." : "you have 10 seconds to abort... (use option -I to skip waiting)", RESTOREFILE); - if (ignore_restore != 1) - sleep(10); - fclose(rfp); - } + hydra_brains.countpass += hydra_options.try_password_reverse_login + hydra_options.try_password_same_as_login + hydra_options.try_null_password; + if ((memcheck = malloc(102400)) == NULL) { + fprintf(stderr, "[ERROR] your wordlist is too large, not enough memory!\n"); + exit(-1); + } + free(memcheck); + if ((rfp = fopen(RESTOREFILE, "r")) != NULL) { + fprintf(stderr, "[WARNING] Restorefile (%s) from a previous session found, to prevent overwriting, %s\n", ignore_restore == 1 ? "ignored ..." : "you have 10 seconds to abort... (use option -I to skip waiting)", RESTOREFILE); + if (ignore_restore != 1) + sleep(10); + fclose(rfp); + } - 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); - } - hydra_brains.targets = countservers = countinfile = countlines(ifp, 0); - if (countinfile == 0) { - fprintf(stderr, "[ERROR] File for targets is empty: %s\n", hydra_options.infile_ptr); - exit(-1); - } - // if (countinfile > 60) fprintf(stderr, "[WARNING] the -M option is not working correctly at the moment for target lists > 60!\n"); - hydra_targets = malloc(sizeof(hydra_target*) * (countservers + 2) + 8); - if (hydra_targets == NULL) - bail("Could not allocate enough memory for target data"); - sizeinfile = size_of_data; - if (countinfile > MAX_LINES / 1000) { - fprintf(stderr, "[ERROR] Maximum number of target file entries is %d, this file has %d entries.\n", MAX_LINES / 1000, (int32_t) countinfile); - exit(-1); - } - if (sizeinfile > MAX_BYTES / 1000) { - fprintf(stderr, "[ERROR] Maximum size of the server file is %d, this file has %d bytes.\n", MAX_BYTES / 1000, (int32_t) sizeinfile); - exit(-1); - } - if ((servers_ptr = malloc(sizeinfile + countservers + 8)) == NULL) - bail("Could not allocate enough memory for target file data"); - memset(servers_ptr, 0, sizeinfile + countservers + 8); - fill_mem(servers_ptr, ifp, 0); - sizeservers = sizeinfile; - tmpptr = servers_ptr; - for (i = 0; i < countinfile; i++) { - hydra_targets[i] = malloc(sizeof(hydra_target)); - memset(hydra_targets[i], 0, sizeof(hydra_target)); - if (*tmpptr == '[') { - tmpptr++; - hydra_targets[i]->target = tmpptr; - if ((tmpptr2 = index(tmpptr, ']')) != NULL) { - *tmpptr2++ = 0; - tmpptr = tmpptr2; - } - } else - hydra_targets[i]->target = tmpptr; - if ((tmpptr2 = index(hydra_targets[i]->target, ':')) != NULL) { - *tmpptr2++ = 0; - tmpptr = tmpptr2; - hydra_targets[i]->port = atoi(tmpptr2); - if (hydra_targets[i]->port < 1 || hydra_targets[i]->port > 65535) - hydra_targets[i]->port = 0; - } - if (hydra_targets[i]->port == 0) - hydra_targets[i]->port = hydra_options.port; - while (*tmpptr != 0) - tmpptr++; - tmpptr++; - } - } else if (index(hydra_options.server, '/') != NULL) { - if (cmdtarget == NULL) - bail("You seem to mix up \"service://target:port/options\" syntax with \"target service options\" syntax. Read the README on how to use hydra correctly!"); - if (strstr(cmdtarget, "://") != NULL) { - tmpptr = index(hydra_options.server, '/'); - if (tmpptr != NULL) - *tmpptr = 0; - countservers = hydra_brains.targets = 1; - hydra_targets = malloc(sizeof(hydra_target*) * 4); - hydra_targets[0] = malloc(sizeof(hydra_target)); - memset(hydra_targets[0], 0, sizeof(hydra_target)); - hydra_targets[0]->target = servers_ptr = hydra_options.server; - hydra_targets[0]->port = hydra_options.port; - sizeservers = strlen(hydra_options.server) + 1; - } else { - /* CIDR notation on command line, e.g. 192.168.0.0/24 */ - uint32_t four_from, four_to, addr_cur, addr_cur2, k, l; - in_addr_t addr4; - struct sockaddr_in target; + 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); + } + hydra_brains.targets = countservers = countinfile = countlines(ifp, 0); + if (countinfile == 0) { + fprintf(stderr, "[ERROR] File for targets is empty: %s\n", hydra_options.infile_ptr); + exit(-1); + } + // if (countinfile > 60) fprintf(stderr, "[WARNING] the -M option is not working correctly at the moment for target lists > 60!\n"); + hydra_targets = malloc(sizeof(hydra_target*) * (countservers + 2) + 8); + if (hydra_targets == NULL) + bail("Could not allocate enough memory for target data"); + sizeinfile = size_of_data; + if (countinfile > MAX_LINES / 1000) { + fprintf(stderr, "[ERROR] Maximum number of target file entries is %d, this file has %d entries.\n", MAX_LINES / 1000, (int32_t) countinfile); + exit(-1); + } + if (sizeinfile > MAX_BYTES / 1000) { + fprintf(stderr, "[ERROR] Maximum size of the server file is %d, this file has %d bytes.\n", MAX_BYTES / 1000, (int32_t) sizeinfile); + exit(-1); + } + if ((servers_ptr = malloc(sizeinfile + countservers + 8)) == NULL) + bail("Could not allocate enough memory for target file data"); + memset(servers_ptr, 0, sizeinfile + countservers + 8); + fill_mem(servers_ptr, ifp, 0); + sizeservers = sizeinfile; + tmpptr = servers_ptr; + for (i = 0; i < countinfile; i++) { + hydra_targets[i] = malloc(sizeof(hydra_target)); + memset(hydra_targets[i], 0, sizeof(hydra_target)); + if (*tmpptr == '[') { + tmpptr++; + hydra_targets[i]->target = tmpptr; + if ((tmpptr2 = index(tmpptr, ']')) != NULL) { + *tmpptr2++ = 0; + tmpptr = tmpptr2; + } + } else + hydra_targets[i]->target = tmpptr; + if ((tmpptr2 = index(hydra_targets[i]->target, ':')) != NULL) { + *tmpptr2++ = 0; + tmpptr = tmpptr2; + hydra_targets[i]->port = atoi(tmpptr2); + if (hydra_targets[i]->port < 1 || hydra_targets[i]->port > 65535) + hydra_targets[i]->port = 0; + } + if (hydra_targets[i]->port == 0) + hydra_targets[i]->port = hydra_options.port; + while (*tmpptr != 0) + tmpptr++; + tmpptr++; + } + } else if (index(hydra_options.server, '/') != NULL) { + if (cmdtarget == NULL) + bail("You seem to mix up \"service://target:port/options\" syntax with \"target service options\" syntax. Read the README on how to use hydra correctly!"); + if (strstr(cmdtarget, "://") != NULL) { + tmpptr = index(hydra_options.server, '/'); + if (tmpptr != NULL) + *tmpptr = 0; + countservers = hydra_brains.targets = 1; + hydra_targets = malloc(sizeof(hydra_target*) * 4); + hydra_targets[0] = malloc(sizeof(hydra_target)); + memset(hydra_targets[0], 0, sizeof(hydra_target)); + hydra_targets[0]->target = servers_ptr = hydra_options.server; + hydra_targets[0]->port = hydra_options.port; + sizeservers = strlen(hydra_options.server) + 1; + } else { + /* CIDR notation on command line, e.g. 192.168.0.0/24 */ + uint32_t four_from, four_to, addr_cur, addr_cur2, k, l; + in_addr_t addr4; + struct sockaddr_in target; - hydra_options.cidr = 1; - do_retry = 0; - if ((tmpptr = malloc(strlen(hydra_options.server) + 1)) == NULL) { - fprintf(stderr, "Error: can not allocate memory\n"); - exit(-1); - } - strcpy(tmpptr, hydra_options.server); - tmpptr2 = index(tmpptr, '/'); - *tmpptr2++ = 0; - if ((k = atoi(tmpptr2)) < 16 || k > 31) { - fprintf(stderr, "Error: network size may only be between /16 and /31: %s\n", hydra_options.server); - exit(-1); - } - if ((addr4 = htonl(inet_addr(tmpptr))) == 0xffffffff) { - fprintf(stderr, "Error: option is not a valid IPv4 address: %s\n", tmpptr); - exit(-1); - } - free(tmpptr); - l = 1 << (32 - k); - l--; - four_to = (addr4 | l); - l = 0xffffffff - l; - four_from = (addr4 & l); - l = 1 << (32 - k); - hydra_brains.targets = countservers = l; - hydra_targets = (hydra_target**)malloc(sizeof(hydra_target*) * (l + 2) + 8); - if (hydra_targets == NULL) - bail("Could not allocate enough memory for target data"); - i = 0; - addr_cur = four_from; - while (addr_cur <= four_to && i < l) { - hydra_targets[i] = malloc(sizeof(hydra_target)); - memset(hydra_targets[i], 0, sizeof(hydra_target)); - addr_cur2 = htonl(addr_cur); - 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; - addr_cur++; - i++; - } - if (verbose) - printf("[VERBOSE] CIDR attack from %s to %s\n", hydra_targets[0]->target, hydra_targets[l - 1]->target); - printf("[WARNING] The CIDR attack mode is still beta. Please report issues.\n"); - } - } else { // standard: single target on command line - countservers = hydra_brains.targets = 1; - hydra_targets = malloc(sizeof(hydra_target*) * 4); - hydra_targets[0] = malloc(sizeof(hydra_target)); - memset(hydra_targets[0], 0, sizeof(hydra_target)); - hydra_targets[0]->target = servers_ptr = hydra_options.server; - hydra_targets[0]->port = hydra_options.port; - sizeservers = strlen(hydra_options.server) + 1; - } - for (i = 0; i < hydra_brains.targets; i++) { - hydra_targets[i]->login_ptr = login_ptr; - hydra_targets[i]->pass_ptr = pass_ptr; - if (hydra_options.loop_mode) { - if (hydra_options.try_password_same_as_login) - hydra_targets[i]->pass_state = 0; - else if (hydra_options.try_null_password) { - hydra_targets[i]->pass_ptr = empty_login; - hydra_targets[i]->pass_state = 1; - } else if (hydra_options.try_password_reverse_login) - hydra_targets[i]->pass_state = 2; - else - hydra_targets[i]->pass_state = 3; - } - } - } // END OF restore == 0 + hydra_options.cidr = 1; + do_retry = 0; + if ((tmpptr = malloc(strlen(hydra_options.server) + 1)) == NULL) { + fprintf(stderr, "Error: can not allocate memory\n"); + exit(-1); + } + strcpy(tmpptr, hydra_options.server); + tmpptr2 = index(tmpptr, '/'); + *tmpptr2++ = 0; + if ((k = atoi(tmpptr2)) < 16 || k > 31) { + fprintf(stderr, "Error: network size may only be between /16 and /31: %s\n", hydra_options.server); + exit(-1); + } + if ((addr4 = htonl(inet_addr(tmpptr))) == 0xffffffff) { + fprintf(stderr, "Error: option is not a valid IPv4 address: %s\n", tmpptr); + exit(-1); + } + free(tmpptr); + l = 1 << (32 - k); + l--; + four_to = (addr4 | l); + l = 0xffffffff - l; + four_from = (addr4 & l); + l = 1 << (32 - k); + hydra_brains.targets = countservers = l; + hydra_targets = (hydra_target**)malloc(sizeof(hydra_target*) * (l + 2) + 8); + if (hydra_targets == NULL) + bail("Could not allocate enough memory for target data"); + i = 0; + addr_cur = four_from; + while (addr_cur <= four_to && i < l) { + hydra_targets[i] = malloc(sizeof(hydra_target)); + memset(hydra_targets[i], 0, sizeof(hydra_target)); + addr_cur2 = htonl(addr_cur); + 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; + addr_cur++; + i++; + } + if (verbose) + printf("[VERBOSE] CIDR attack from %s to %s\n", hydra_targets[0]->target, hydra_targets[l - 1]->target); + printf("[WARNING] The CIDR attack mode is still beta. Please report issues.\n"); + } + } else { // standard: single target on command line + countservers = hydra_brains.targets = 1; + hydra_targets = malloc(sizeof(hydra_target*) * 4); + hydra_targets[0] = malloc(sizeof(hydra_target)); + memset(hydra_targets[0], 0, sizeof(hydra_target)); + hydra_targets[0]->target = servers_ptr = hydra_options.server; + hydra_targets[0]->port = hydra_options.port; + sizeservers = strlen(hydra_options.server) + 1; + } + for (i = 0; i < hydra_brains.targets; i++) { + hydra_targets[i]->login_ptr = login_ptr; + hydra_targets[i]->pass_ptr = pass_ptr; + if (hydra_options.loop_mode) { + if (hydra_options.try_password_same_as_login) + hydra_targets[i]->pass_state = 0; + else if (hydra_options.try_null_password) { + hydra_targets[i]->pass_ptr = empty_login; + hydra_targets[i]->pass_state = 1; + } else if (hydra_options.try_password_reverse_login) + hydra_targets[i]->pass_state = 2; + else + hydra_targets[i]->pass_state = 3; + } + } + } // END OF restore == 0 // PROXY PROCESSING if (getenv("HYDRA_PROXY") && use_proxy == 0) { - printf("[INFO] Using Connect Proxy: %s\n", getenv("HYDRA_PROXY")); - use_proxy = 2; + printf("[INFO] Using Connect Proxy: %s\n", getenv("HYDRA_PROXY")); + use_proxy = 2; } if (use_proxy == 1) - proxy_string = getenv("HYDRA_PROXY_HTTP"); + proxy_string = getenv("HYDRA_PROXY_HTTP"); if (use_proxy == 2) - proxy_string = getenv("HYDRA_PROXY"); + proxy_string = getenv("HYDRA_PROXY"); if (use_proxy && getenv("HYDRA_PROXY_AUTH") != NULL) - fprintf(stderr, "[WARNING] environment variable HYDRA_PROXY_AUTH is deprecated, use authentication in the HYDRA_PROXY definitions, e.g. type://auth@target:port\n"); + fprintf(stderr, "[WARNING] environment variable HYDRA_PROXY_AUTH is deprecated, use authentication in the HYDRA_PROXY definitions, e.g. type://auth@target:port\n"); if (use_proxy && proxy_string != NULL) { - if (strstr(proxy_string, "://") != NULL) { - process_proxy_line(use_proxy, proxy_string); - } else { - if ((proxyfp = fopen(proxy_string, "r")) == NULL) { - fprintf(stderr, "[ERROR] proxy definition %s is neither of the kind type://auth@target:port nor a file containing proxy entries!\n", proxy_string); - exit(-1); - } - while (fgets(buf, sizeof(buf), proxyfp) != NULL) - process_proxy_line(use_proxy, buf); - fclose(proxyfp); - } - if (proxy_count == 0) - bail("proxy defined but not valid, exiting"); + if (strstr(proxy_string, "://") != NULL) { + process_proxy_line(use_proxy, proxy_string); + } else { + if ((proxyfp = fopen(proxy_string, "r")) == NULL) { + fprintf(stderr, "[ERROR] proxy definition %s is neither of the kind type://auth@target:port nor a file containing proxy entries!\n", proxy_string); + exit(-1); + } + while (fgets(buf, sizeof(buf), proxyfp) != NULL) + process_proxy_line(use_proxy, buf); + fclose(proxyfp); + } + if (proxy_count == 0) + bail("proxy defined but not valid, exiting"); } if (hydra_options.restore == 0) { - if ((strcmp(hydra_options.service, "rsh") == 0) || (strcmp(hydra_options.service, "oracle-sid") == 0)) - math2 = hydra_brains.countlogin; - else - math2 = hydra_brains.countlogin * hydra_brains.countpass; + if ((strcmp(hydra_options.service, "rsh") == 0) || (strcmp(hydra_options.service, "oracle-sid") == 0)) + math2 = hydra_brains.countlogin; + else + math2 = hydra_brains.countlogin * hydra_brains.countpass; #ifdef HAVE_MATH_H - if (hydra_options.bfg) { - math2 = hydra_brains.countlogin * bf_get_pcount(); - } + if (hydra_options.bfg) { + math2 = hydra_brains.countlogin * bf_get_pcount(); + } #endif - hydra_brains.todo = math2; - math2 = math2 * hydra_brains.targets; - hydra_brains.todo_all = math2; - if (hydra_brains.todo_all == 0) - bail("No login/password combination given!"); - if (hydra_brains.todo < hydra_options.tasks) { - if (verbose && hydra_options.tasks != TASKS) - printf("[VERBOSE] More tasks defined than login/pass pairs exist. Tasks reduced to %lu\n", hydra_brains.todo); - hydra_options.tasks = hydra_brains.todo; - } + hydra_brains.todo = math2; + math2 = math2 * hydra_brains.targets; + hydra_brains.todo_all = math2; + if (hydra_brains.todo_all == 0) + bail("No login/password combination given!"); + if (hydra_brains.todo < hydra_options.tasks) { + if (verbose && hydra_options.tasks != TASKS) + printf("[VERBOSE] More tasks defined than login/pass pairs exist. Tasks reduced to %lu\n", hydra_brains.todo); + hydra_options.tasks = hydra_brains.todo; + } } - if (hydra_options.max_use == MAXTASKS) { // only if it was not set via -T - if (hydra_options.max_use < hydra_brains.targets * hydra_options.tasks) - hydra_options.max_use = hydra_brains.targets * hydra_options.tasks; - if (hydra_options.max_use > MAXTASKS) - hydra_options.max_use = MAXTASKS; + if (hydra_options.max_use == MAXTASKS) { // only if it was not set via -T + if (hydra_options.max_use < hydra_brains.targets * hydra_options.tasks) + hydra_options.max_use = hydra_brains.targets * hydra_options.tasks; + if (hydra_options.max_use > MAXTASKS) + hydra_options.max_use = MAXTASKS; } if ((hydra_options.tasks == TASKS || hydra_options.tasks <= 8) && hydra_options.max_use < hydra_brains.targets * hydra_options.tasks) { - if ((hydra_options.tasks = hydra_options.max_use / hydra_brains.targets) == 0) - hydra_options.tasks = 1; - //fprintf(stderr, "[WARNING] More tasks defined per server than allowed for maximal connections. Tasks per server reduced to %d.\n", hydra_options.tasks); + if ((hydra_options.tasks = hydra_options.max_use / hydra_brains.targets) == 0) + hydra_options.tasks = 1; + //fprintf(stderr, "[WARNING] More tasks defined per server than allowed for maximal connections. Tasks per server reduced to %d.\n", hydra_options.tasks); } else { - if (hydra_options.tasks > MAXTASKS) { - //fprintf(stderr, "[WARNING] reducing tasks to MAXTASKS (%d)\n", MAXTASKS); - hydra_options.tasks = MAXTASKS; - } + if (hydra_options.tasks > MAXTASKS) { + //fprintf(stderr, "[WARNING] reducing tasks to MAXTASKS (%d)\n", MAXTASKS); + hydra_options.tasks = MAXTASKS; + } } // hydra_options.max_use = hydra_brains.targets * hydra_options.tasks; // if (hydra_options.max_use > MAXTASKS) - // hydra_options.max_use = MAXTASKS; + // hydra_options.max_use = MAXTASKS; if (hydra_options.max_use > hydra_options.tasks * hydra_brains.targets) - hydra_options.max_use = hydra_options.tasks * hydra_brains.targets; + hydra_options.max_use = hydra_options.tasks * hydra_brains.targets; math2 = (hydra_brains.todo * hydra_brains.targets) / hydra_options.max_use; if ((hydra_brains.todo * hydra_brains.targets) % hydra_options.max_use) - math2++; + math2++; // set options (bits!) options = 0; if (hydra_options.ssl) - options = options | OPTION_SSL; + options = options | OPTION_SSL; printf("[DATA] max %d task%s per %d server%s, overall %d task%s, %lu login tr", - hydra_options.tasks, hydra_options.tasks == 1 ? "" : "s", - hydra_brains.targets, hydra_brains.targets == 1 ? "" : "s", - hydra_options.max_use, hydra_options.max_use == 1 ? "" : "s", - hydra_brains.todo); + hydra_options.tasks, hydra_options.tasks == 1 ? "" : "s", + hydra_brains.targets, hydra_brains.targets == 1 ? "" : "s", + hydra_options.max_use, hydra_options.max_use == 1 ? "" : "s", + hydra_brains.todo); printf("%s", hydra_brains.todo == 1 ? "y" : "ies"); if (hydra_options.colonfile == NULL) { - printf(" (l:%lu/p:%lu), ~%lu tr", - (uint64_t) hydra_brains.countlogin, (uint64_t) hydra_brains.countpass, - math2); + printf(" (l:%lu/p:%lu), ~%lu tr", + (uint64_t) hydra_brains.countlogin, (uint64_t) hydra_brains.countpass, + math2); } else { - printf(", ~%lu tr", math2); + printf(", ~%lu tr", math2); } printf("%s", math2 == 1 ? "y" : "ies"); printf(" per task\n"); if (hydra_brains.targets == 1) { - if (index(hydra_targets[0]->target, ':') == NULL) { - printf("[DATA] attacking %s%s://%s:", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_targets[0]->target); - printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); - } else { - printf("[DATA] attacking %s%s://[%s]:", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_targets[0]->target); - printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); - } + if (index(hydra_targets[0]->target, ':') == NULL) { + printf("[DATA] attacking %s%s://%s:", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_targets[0]->target); + printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); + } else { + printf("[DATA] attacking %s%s://[%s]:", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_targets[0]->target); + printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); + } } else { - printf("[DATA] attacking %s%s://(%d targets):", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_brains.targets); - printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); + printf("[DATA] attacking %s%s://(%d targets):", hydra_options.service, hydra_options.ssl == 1 ? "s" : "", hydra_brains.targets); + printf("%d%s%s\n", port, hydra_options.miscptr == NULL || hydra_options.miscptr[0] != '/' ? "/" : "", hydra_options.miscptr != NULL ? hydra_options.miscptr : ""); } //service %s on port %d%s\n", hydra_options.service, port, hydra_options.ssl == 1 ? " with SSL" : ""); // if (hydra_options.miscptr != NULL && hydra_options.miscptr[0] != 0) -// printf("[DATA] with additional data %s\n", hydra_options.miscptr); - +// printf("[DATA] with additional data %s\n", hydra_options.miscptr); if (hydra_options.outfile_ptr != NULL) { - if ((hydra_brains.ofp = fopen(hydra_options.outfile_ptr, "a+")) == NULL) { - perror("[ERROR] Error creating outputfile"); - exit(-1); - } - if (hydra_options.outfile_format == FORMAT_JSONV1) { - //sprintf(output, "{\"test\":\"test\"}"); - fprintf(hydra_brains.ofp, "{ \"generator\": {\n" - "\t\"software\": \"%s\", \"version\": \"%s\", \"built\": \"%s\",\n" - "\t\"server\": \"%s\", \"service\": \"%s\", \"jsonoutputversion\": \"1.00\",\n" - "\t\"commandline\": \"%s", - PROGRAM, VERSION, hydra_build_time(), - hydra_options.server == NULL ? hydra_options.infile_ptr : hydra_options.server, hydra_options.service, prg); - set("a", "2"); - - for (i = 1; i < argc; i++) { - char *t = hydra_string_replace(argv[i],"\"","\\\""); - fprintf(hydra_brains.ofp, " %s", t); - free(t); - } - fprintf(hydra_brains.ofp, "\"\n\t},\n\"results\": ["); - } else { // else default is plain text aka == 0 - fprintf(hydra_brains.ofp, "# %s %s run at %s on %s %s (%s", PROGRAM, VERSION, hydra_build_time(), - hydra_options.server == NULL ? hydra_options.infile_ptr : hydra_options.server, hydra_options.service, prg); - for (i = 1; i < argc; i++) - fprintf(hydra_brains.ofp, " %s", argv[i]); - fprintf(hydra_brains.ofp, ")\n"); - } - } + if ((hydra_brains.ofp = fopen(hydra_options.outfile_ptr, "a+")) == NULL) { + perror("[ERROR] Error creating outputfile"); + exit(-1); + } + if (hydra_options.outfile_format == FORMAT_JSONV1) { + fprintf(hydra_brains.ofp, "{ \"generator\": {\n" + "\t\"software\": \"%s\", \"version\": \"%s\", \"built\": \"%s\",\n" + "\t\"server\": \"%s\", \"service\": \"%s\", \"jsonoutputversion\": \"1.00\",\n" + "\t\"commandline\": \"%s", + PROGRAM, VERSION, hydra_build_time(), + hydra_options.server == NULL ? hydra_options.infile_ptr : hydra_options.server, hydra_options.service, prg); + for (i = 1; i < argc; i++) { + char *t = hydra_string_replace(argv[i],"\"","\\\""); + fprintf(hydra_brains.ofp, " %s", t); + free(t); + } + fprintf(hydra_brains.ofp, "\"\n\t},\n\"results\": ["); + } else { // else default is plain text aka == 0 + fprintf(hydra_brains.ofp, "# %s %s run at %s on %s %s (%s", PROGRAM, VERSION, hydra_build_time(), + hydra_options.server == NULL ? hydra_options.infile_ptr : hydra_options.server, hydra_options.service, prg); + for (i = 1; i < argc; i++) + fprintf(hydra_brains.ofp, " %s", argv[i]); + fprintf(hydra_brains.ofp, ")\n"); + } + }else if (hydra_options.outfile_format == FORMAT_REDIS) { + sprintf(redis_output_tmp, "{ \"generator\": {" + "\"software\": \"%s\", \"version\": \"%s\", \"built\": \"%s\"," + "\"server\": \"%s\", \"service\": \"%s\", \"jsonoutputversion\": \"1.00\"," + "\"commandline\": \"%s", + PROGRAM, VERSION, hydra_build_time(), + hydra_options.server == NULL ? hydra_options.infile_ptr : hydra_options.server, hydra_options.service, prg); + for (i = 1; i < argc; i++) { + char *t = hydra_string_replace(argv[i],"\"","\\\""); + sprintf(redis_output_tmp + strlen(redis_output_tmp), " %s", t); + free(t); + } + sprintf(redis_output_tmp + strlen(redis_output_tmp), "\"},\"results\": \"%s\", \"status\":\"running\"}", hydra_options.map_key); + set(hydra_options.key, redis_output_tmp); + } // we have to flush all writeable buffered file pointers before forking // set appropriate signals for mother signal(SIGCHLD, killed_childs); if (debug == 0) - signal(SIGTERM, kill_children); + signal(SIGTERM, kill_children); if (debug == 0) { #ifdef SIGBUS - signal(SIGBUS, kill_children); + signal(SIGBUS, kill_children); #endif - signal(SIGSEGV, kill_children); + signal(SIGSEGV, kill_children); } signal(SIGHUP, kill_children); signal(SIGINT, kill_children); signal(SIGPIPE, SIG_IGN); if (verbose) - printf("[VERBOSE] Resolving addresses ... "); + printf("[VERBOSE] Resolving addresses ... "); if (debug) - printf("\n"); + printf("\n"); for (i = 0; i < hydra_brains.targets; i++) { - if (debug) - printf("[DEBUG] resolving %s\n", hydra_targets[i]->target); - memset(&hints, 0, sizeof(hints)); - ipv4 = NULL; + if (debug) + printf("[DEBUG] resolving %s\n", hydra_targets[i]->target); + memset(&hints, 0, sizeof(hints)); + ipv4 = NULL; #ifdef AF_INET6 - ipv6 = NULL; + ipv6 = NULL; #endif - if ((device = index(hydra_targets[i]->target, '%')) != NULL) - *device++ = 0; - if (getaddrinfo(hydra_targets[i]->target, NULL, &hints, &res) != 0) { - if (use_proxy == 0) { - if (verbose) - printf("[failed for %s] ", hydra_targets[i]->target); - else - fprintf(stderr, "[ERROR] could not resolve address: %s\n", hydra_targets[i]->target); - hydra_targets[i]->done = TARGET_UNRESOLVED; - hydra_brains.finished++; - } - } else { - for (p = res; p != NULL; p = p->ai_next) { + if ((device = index(hydra_targets[i]->target, '%')) != NULL) + *device++ = 0; + if (getaddrinfo(hydra_targets[i]->target, NULL, &hints, &res) != 0) { + if (use_proxy == 0) { + if (verbose) + printf("[failed for %s] ", hydra_targets[i]->target); + else + fprintf(stderr, "[ERROR] could not resolve address: %s\n", hydra_targets[i]->target); + hydra_targets[i]->done = TARGET_UNRESOLVED; + hydra_brains.finished++; + } + } else { + for (p = res; p != NULL; p = p->ai_next) { #ifdef AF_INET6 - if (p->ai_family == AF_INET6) { - if (ipv6 == NULL) - ipv6 = (struct sockaddr_in6 *) p->ai_addr; - } else + if (p->ai_family == AF_INET6) { + if (ipv6 == NULL) + ipv6 = (struct sockaddr_in6 *) p->ai_addr; + } else #endif - if (p->ai_family == AF_INET) { - if (ipv4 == NULL) - ipv4 = (struct sockaddr_in *) p->ai_addr; - } - } + if (p->ai_family == AF_INET) { + if (ipv4 == NULL) + ipv4 = (struct sockaddr_in *) p->ai_addr; + } + } #ifdef AF_INET6 - if (ipv6 != NULL && (ipv4 == NULL || prefer_ipv6)) { - // IPV6 FIXME - if ((strcmp(hydra_options.service, "socks5") == 0) || (strcmp(hydra_options.service, "sip") == 0)) { - fprintf(stderr, "[ERROR] Target %s resolves to an IPv6 address, however module %s does not support this. Maybe try \"-4\" option. Sending in patches helps.\n", - hydra_targets[i]->target, hydra_options.service); - hydra_targets[i]->done = TARGET_UNRESOLVED; - hydra_brains.finished++; - } else { - hydra_targets[i]->ip[0] = 16; - memcpy(&hydra_targets[i]->ip[1], (char *) &ipv6->sin6_addr, 16); - if (device != NULL && strlen(device) <= 16) - strcpy(&hydra_targets[i]->ip[17], device); - if (memcmp(&hydra_targets[i]->ip[17], fe80, 2) == 0) { - if (device == NULL) { - fprintf(stderr, "[ERROR] The target %s address is a link local address, link local addresses require the interface being defined like this: fe80::1%%eth0\n", - hydra_targets[i]->target); - exit(-1); - } - } - } - } else + if (ipv6 != NULL && (ipv4 == NULL || prefer_ipv6)) { + // IPV6 FIXME + if ((strcmp(hydra_options.service, "socks5") == 0) || (strcmp(hydra_options.service, "sip") == 0)) { + fprintf(stderr, "[ERROR] Target %s resolves to an IPv6 address, however module %s does not support this. Maybe try \"-4\" option. Sending in patches helps.\n", + hydra_targets[i]->target, hydra_options.service); + hydra_targets[i]->done = TARGET_UNRESOLVED; + hydra_brains.finished++; + } else { + hydra_targets[i]->ip[0] = 16; + memcpy(&hydra_targets[i]->ip[1], (char *) &ipv6->sin6_addr, 16); + if (device != NULL && strlen(device) <= 16) + strcpy(&hydra_targets[i]->ip[17], device); + if (memcmp(&hydra_targets[i]->ip[17], fe80, 2) == 0) { + if (device == NULL) { + fprintf(stderr, "[ERROR] The target %s address is a link local address, link local addresses require the interface being defined like this: fe80::1%%eth0\n", + hydra_targets[i]->target); + exit(-1); + } + } + } + } else #endif - if (ipv4 != NULL) { - hydra_targets[i]->ip[0] = 4; - memcpy(&hydra_targets[i]->ip[1], (char *) &ipv4->sin_addr, 4); - } else { - if (verbose) - printf("[failed for %s] ", hydra_targets[i]->target); - else - fprintf(stderr, "[ERROR] Could not resolve proxy address: %s\n", hydra_targets[i]->target); - hydra_targets[i]->done = TARGET_UNRESOLVED; - hydra_brains.finished++; - } - freeaddrinfo(res); - } - // restore device information if present - if (device != NULL) { - *(device - 1) = '%'; - fprintf(stderr, "[WARNING] not all modules support BINDTODEVICE for IPv6 link local addresses, e.g. SSH does not\n"); - } + if (ipv4 != NULL) { + hydra_targets[i]->ip[0] = 4; + memcpy(&hydra_targets[i]->ip[1], (char *) &ipv4->sin_addr, 4); + } else { + if (verbose) + printf("[failed for %s] ", hydra_targets[i]->target); + else + fprintf(stderr, "[ERROR] Could not resolve proxy address: %s\n", hydra_targets[i]->target); + hydra_targets[i]->done = TARGET_UNRESOLVED; + hydra_brains.finished++; + } + freeaddrinfo(res); + } + // restore device information if present + if (device != NULL) { + *(device - 1) = '%'; + fprintf(stderr, "[WARNING] not all modules support BINDTODEVICE for IPv6 link local addresses, e.g. SSH does not\n"); + } } if (verbose) - printf("[VERBOSE] resolving done\n"); + printf("[VERBOSE] resolving done\n"); if (hydra_brains.targets == 0) - bail("No server to scan!"); + bail("No server to scan!"); #ifndef SO_BINDTODEVICE if (device != NULL) { - fprintf(stderr, "[ERROR] your operating system does not support SO_BINDTODEVICE or IP_FORCE_OUT_IFP, dunno how to bind the IPv6 address to the interface %s!\n", device); + fprintf(stderr, "[ERROR] your operating system does not support SO_BINDTODEVICE or IP_FORCE_OUT_IFP, dunno how to bind the IPv6 address to the interface %s!\n", device); } #endif if (hydra_options.restore == 0) { - hydra_heads = malloc(sizeof(hydra_head*) * hydra_options.max_use); - target_no = 0; - for (i = 0; i < hydra_options.max_use; i++) { - hydra_heads[i] = malloc(sizeof(hydra_head)); - memset(hydra_heads[i], 0, sizeof(hydra_head)); - } + hydra_heads = malloc(sizeof(hydra_head*) * hydra_options.max_use); + target_no = 0; + for (i = 0; i < hydra_options.max_use; i++) { + hydra_heads[i] = malloc(sizeof(hydra_head)); + memset(hydra_heads[i], 0, sizeof(hydra_head)); + } } // here we call the init function of the relevant service module // should we do the init centrally or should each child do that? // that depends largely on the number of targets and maximum tasks // if (hydra_brains.targets == 1 || (hydra_brains.targets < 4 && hydra_options.tasks / hydra_brains.targets > 4 && hydra_brains.todo > 15)) for (i = 0; i < hydra_brains.targets; i++) - hydra_service_init(i); + hydra_service_init(i); starttime = elapsed_status = elapsed_restore = time(NULL); fflush(stdout); @@ -3664,9 +3692,9 @@ int main(int argc, char *argv[]) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (hydra_options.ssl) { - fprintf(stderr, "[WARNING] *****************************************************\n"); - fprintf(stderr, "[WARNING] OPENSSL v1.1 development changes are active - modules SMB, SNMP, RDP, ORACLE LISTENER and SSL in general might not work properly! Please test and report to vh@thc.org.\n"); - fprintf(stderr, "[WARNING] *****************************************************\n"); + fprintf(stderr, "[WARNING] *****************************************************\n"); + fprintf(stderr, "[WARNING] OPENSSL v1.1 development changes are active - modules SMB, SNMP, RDP, ORACLE LISTENER and SSL in general might not work properly! Please test and report to vh@thc.org.\n"); + fprintf(stderr, "[WARNING] *****************************************************\n"); } #endif @@ -3675,342 +3703,352 @@ int main(int argc, char *argv[]) { // this is the big function which starts the attacking children, feeds login/password pairs, etc.! while (exit_condition == 0) { - memset(&fdreadheads, 0, sizeof(fdreadheads)); - max_fd = 0; - FD_ZERO(&fdreadheads); - for (head_no = 0, max_fd = 1; head_no < hydra_options.max_use; head_no++) { - if (hydra_heads[head_no]->active == HEAD_ACTIVE) { - FD_SET(hydra_heads[head_no]->sp[0], &fdreadheads); - if (max_fd < hydra_heads[head_no]->sp[0]) - max_fd = hydra_heads[head_no]->sp[0]; - } - } - my_select(max_fd + 1, &fdreadheads, NULL, NULL, 0, 200000); - tmp_time = time(NULL); + memset(&fdreadheads, 0, sizeof(fdreadheads)); + max_fd = 0; + FD_ZERO(&fdreadheads); + for (head_no = 0, max_fd = 1; head_no < hydra_options.max_use; head_no++) { + if (hydra_heads[head_no]->active == HEAD_ACTIVE) { + FD_SET(hydra_heads[head_no]->sp[0], &fdreadheads); + if (max_fd < hydra_heads[head_no]->sp[0]) + max_fd = hydra_heads[head_no]->sp[0]; + } + } + my_select(max_fd + 1, &fdreadheads, NULL, NULL, 0, 200000); + tmp_time = time(NULL); - for (head_no = 0; head_no < hydra_options.max_use; head_no++) { - if (debug > 1 && hydra_heads[head_no]->active != HEAD_DISABLED) - printf("[DEBUG] head_no[%d] to target_no %d active %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->active); - - switch (hydra_heads[head_no]->active) { - case HEAD_DISABLED: - break; - case HEAD_UNUSED: - if (hydra_heads[head_no]->redo) { - hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); - } else { - if (hydra_brains.targets > hydra_brains.finished) - hydra_heads[head_no]->target_no = hydra_select_target(); - else - hydra_heads[head_no]->target_no = -1; - if (debug) - printf("[DEBUG] child %d got target %d selected\n", head_no, hydra_heads[head_no]->target_no); - if (hydra_heads[head_no]->target_no < 0) { - if (debug) - printf("[DEBUG] hydra_select_target() reports no more targets left\n"); - hydra_kill_head(head_no, 0, 3); - } else - hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); // target_no is ignored if head->redo == 1 - } - break; - case HEAD_ACTIVE: - if (FD_ISSET(hydra_heads[head_no]->sp[0], &fdreadheads)) { - do_switch = 1; - if (hydra_options.time_next_attempt > 0) { - if (last_attempt + hydra_options.time_next_attempt >= time(NULL)) { - if (recv(hydra_heads[head_no]->sp[0], &rc, 1, MSG_PEEK) == 1 && (rc == 'N' || rc == 'n')) - do_switch = 0; - } else - last_attempt = time(NULL); - } - if (do_switch) { - readres = read_safe(hydra_heads[head_no]->sp[0], &rc, 1); - if (readres > 0) { - FD_CLR(hydra_heads[head_no]->sp[0], &fdreadheads); - hydra_heads[head_no]->last_seen = tmp_time; - if (debug) - printf("[DEBUG] head_no[%d] read %c\n", head_no, rc); - switch (rc) { - // Valid Results: - // n - mother says to itself that child requests next login/password pair - // N - child requests next login/password pair - // Q - child reports that it is quitting - // C - child reports connect error (and is quitting) - // E - child reports protocol error (and is quitting) - // f - child reports that the username does not exist - // F - child reports that it found a valid login/password pair - // and requests next pair. Sends login/pw pair with next msg! - case 'N': // head wants next pair - hydra_targets[hydra_heads[head_no]->target_no]->ok = 1; - if (hydra_targets[hydra_heads[head_no]->target_no]->fail_count > 0) - hydra_targets[hydra_heads[head_no]->target_no]->fail_count--; - // no break here - case 'n': // mother sends this to itself initially - loop_cnt = 0; - if (hydra_send_next_pair(hydra_heads[head_no]->target_no, head_no) == -1) - hydra_kill_head(head_no, 1, 0); - break; + for (head_no = 0; head_no < hydra_options.max_use; head_no++) { + if (debug > 1 && hydra_heads[head_no]->active != HEAD_DISABLED) + printf("[DEBUG] head_no[%d] to target_no %d active %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->active); + + switch (hydra_heads[head_no]->active) { + case HEAD_DISABLED: + break; + case HEAD_UNUSED: + if (hydra_heads[head_no]->redo) { + hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); + } else { + if (hydra_brains.targets > hydra_brains.finished) + hydra_heads[head_no]->target_no = hydra_select_target(); + else + hydra_heads[head_no]->target_no = -1; + if (debug) + printf("[DEBUG] child %d got target %d selected\n", head_no, hydra_heads[head_no]->target_no); + if (hydra_heads[head_no]->target_no < 0) { + if (debug) + printf("[DEBUG] hydra_select_target() reports no more targets left\n"); + hydra_kill_head(head_no, 0, 3); + } else + hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); // target_no is ignored if head->redo == 1 + } + break; + case HEAD_ACTIVE: + if (FD_ISSET(hydra_heads[head_no]->sp[0], &fdreadheads)) { + do_switch = 1; + if (hydra_options.time_next_attempt > 0) { + if (last_attempt + hydra_options.time_next_attempt >= time(NULL)) { + if (recv(hydra_heads[head_no]->sp[0], &rc, 1, MSG_PEEK) == 1 && (rc == 'N' || rc == 'n')) + do_switch = 0; + } else + last_attempt = time(NULL); + } + if (do_switch) { + readres = read_safe(hydra_heads[head_no]->sp[0], &rc, 1); + if (readres > 0) { + FD_CLR(hydra_heads[head_no]->sp[0], &fdreadheads); + hydra_heads[head_no]->last_seen = tmp_time; + if (debug) + printf("[DEBUG] head_no[%d] read %c\n", head_no, rc); + switch (rc) { + // Valid Results: + // n - mother says to itself that child requests next login/password pair + // N - child requests next login/password pair + // Q - child reports that it is quitting + // C - child reports connect error (and is quitting) + // E - child reports protocol error (and is quitting) + // f - child reports that the username does not exist + // F - child reports that it found a valid login/password pair + // and requests next pair. Sends login/pw pair with next msg! + case 'N': // head wants next pair + hydra_targets[hydra_heads[head_no]->target_no]->ok = 1; + if (hydra_targets[hydra_heads[head_no]->target_no]->fail_count > 0) + hydra_targets[hydra_heads[head_no]->target_no]->fail_count--; + // no break here + case 'n': // mother sends this to itself initially + loop_cnt = 0; + if (hydra_send_next_pair(hydra_heads[head_no]->target_no, head_no) == -1) + hydra_kill_head(head_no, 1, 0); + break; - case 'F': // valid password found - hydra_brains.found++; - if (colored_output) { - if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { - if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) - printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, - hydra_targets[hydra_heads[head_no]->target_no]->target); - else - printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\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_pass_ptr); - } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { - printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m\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("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\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); - } else { - if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { - if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) - printf("[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, - hydra_targets[hydra_heads[head_no]->target_no]->target); - else - printf("[%d][%s] host: %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_pass_ptr); - } 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 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, "%s\n\t{\"port\": %d, \"service\": \"%s\", \"host\": \"%s\", \"login\": \"%s\", \"password\": \"%s\"}", - hydra_brains.found == 1 ? "" : ",", // prefix a comma if not first finding - hydra_targets[hydra_heads[head_no]->target_no]->port, - hydra_options.service, - hydra_targets[hydra_heads[head_no]->target_no]->target !=NULL ? hydra_targets[hydra_heads[head_no]->target_no]->target : "", - hydra_heads[head_no]->current_login_ptr !=NULL ? hydra_string_replace(hydra_heads[head_no]->current_login_ptr,"\"","\\\"") : "", - hydra_heads[head_no]->current_pass_ptr != NULL ? hydra_string_replace(hydra_heads[head_no]->current_pass_ptr,"\"","\\\"") : "" - ); - fflush(hydra_brains.ofp); - set("a", "3"); - } else if (hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { // else output format == 0 aka text - if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { - if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) - fprintf(hydra_brains.ofp, "[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, - hydra_targets[hydra_heads[head_no]->target_no]->target); - else - fprintf(hydra_brains.ofp, "[%d][%s] host: %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_pass_ptr); - } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { - fprintf(hydra_brains.ofp, "[%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 - fprintf(hydra_brains.ofp, "[%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); - fflush(hydra_brains.ofp); - } - if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found - if (hydra_targets[hydra_heads[head_no]->target_no]->done == TARGET_ACTIVE) { - hydra_targets[hydra_heads[head_no]->target_no]->done = TARGET_FINISHED; // mark target as done - hydra_brains.finished++; - printf("[STATUS] attack finished for %s (valid pair found)\n", hydra_targets[hydra_heads[head_no]->target_no]->target); - } - if (hydra_options.exit_found == 2) { - for (j = 0; j < hydra_brains.targets; j++) - if (hydra_targets[j]->done == TARGET_ACTIVE) { - hydra_targets[j]->done = TARGET_FINISHED; - hydra_brains.finished++; - } - } - for (j = 0; j < hydra_options.max_use; j++) - if (hydra_heads[j]->active >= 0 && (hydra_heads[j]->target_no == target_no || hydra_options.exit_found == 2)) { - if (hydra_brains.targets > hydra_brains.finished && hydra_options.exit_found < 2) - hydra_kill_head(j, 1, 0); // kill all heads working on the target - else - hydra_kill_head(j, 1, 2); // kill all heads working on the target - } - continue; - } - // fall through - case 'f': // username identified as invalid - hydra_targets[hydra_heads[head_no]->target_no]->ok = 1; - if (hydra_targets[hydra_heads[head_no]->target_no]->fail_count > 0) - hydra_targets[hydra_heads[head_no]->target_no]->fail_count--; - memset(buf, 0, sizeof(buf)); - read_safe(hydra_heads[head_no]->sp[0], buf, MAXBUF); - hydra_skip_user(hydra_heads[head_no]->target_no, buf); - fck = write(hydra_heads[head_no]->sp[1], "n", 1); // small hack - break; + case 'F': // valid password found + hydra_brains.found++; + if (colored_output) { + if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { + if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) + printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, + hydra_targets[hydra_heads[head_no]->target_no]->target); + else + printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\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_pass_ptr); + } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { + printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m\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("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\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); + } else { + if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { + if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) + printf("[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, + hydra_targets[hydra_heads[head_no]->target_no]->target); + else + printf("[%d][%s] host: %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_pass_ptr); + } 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 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, "%s\n\t{\"port\": %d, \"service\": \"%s\", \"host\": \"%s\", \"login\": \"%s\", \"password\": \"%s\"}", + hydra_brains.found == 1 ? "" : ",", // prefix a comma if not first finding + hydra_targets[hydra_heads[head_no]->target_no]->port, + hydra_options.service, + hydra_targets[hydra_heads[head_no]->target_no]->target !=NULL ? hydra_targets[hydra_heads[head_no]->target_no]->target : "", + hydra_heads[head_no]->current_login_ptr !=NULL ? hydra_string_replace(hydra_heads[head_no]->current_login_ptr,"\"","\\\"") : "", + hydra_heads[head_no]->current_pass_ptr != NULL ? hydra_string_replace(hydra_heads[head_no]->current_pass_ptr,"\"","\\\"") : "" + ); + fflush(hydra_brains.ofp); + } else if (hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { // else output format == 0 aka text + if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { + if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) + fprintf(hydra_brains.ofp, "[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, + hydra_targets[hydra_heads[head_no]->target_no]->target); + else + fprintf(hydra_brains.ofp, "[%d][%s] host: %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_pass_ptr); + } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { + fprintf(hydra_brains.ofp, "[%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 + fprintf(hydra_brains.ofp, "[%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); + fflush(hydra_brains.ofp); + } + + if (hydra_options.key != NULL && hydra_options.outfile_format == FORMAT_REDIS){ + sprintf(redis_output_tmp, "{\"port\": %d, \"service\": \"%s\", \"host\": \"%s\", \"login\": \"%s\", \"password\": \"%s\"}", + hydra_targets[hydra_heads[head_no]->target_no]->port, + hydra_options.service, + hydra_targets[hydra_heads[head_no]->target_no]->target !=NULL ? hydra_targets[hydra_heads[head_no]->target_no]->target : "", + hydra_heads[head_no]->current_login_ptr !=NULL ? hydra_string_replace(hydra_heads[head_no]->current_login_ptr,"\"","\\\"") : "", + hydra_heads[head_no]->current_pass_ptr != NULL ? hydra_string_replace(hydra_heads[head_no]->current_pass_ptr,"\"","\\\"") : "" + ); + lpush(hydra_options.map_key, redis_output_tmp); + } + if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found + if (hydra_targets[hydra_heads[head_no]->target_no]->done == TARGET_ACTIVE) { + hydra_targets[hydra_heads[head_no]->target_no]->done = TARGET_FINISHED; // mark target as done + hydra_brains.finished++; + printf("[STATUS] attack finished for %s (valid pair found)\n", hydra_targets[hydra_heads[head_no]->target_no]->target); + } + if (hydra_options.exit_found == 2) { + for (j = 0; j < hydra_brains.targets; j++) + if (hydra_targets[j]->done == TARGET_ACTIVE) { + hydra_targets[j]->done = TARGET_FINISHED; + hydra_brains.finished++; + } + } + for (j = 0; j < hydra_options.max_use; j++) + if (hydra_heads[j]->active >= 0 && (hydra_heads[j]->target_no == target_no || hydra_options.exit_found == 2)) { + if (hydra_brains.targets > hydra_brains.finished && hydra_options.exit_found < 2) + hydra_kill_head(j, 1, 0); // kill all heads working on the target + else + hydra_kill_head(j, 1, 2); // kill all heads working on the target + } + continue; + } + // fall through + case 'f': // username identified as invalid + hydra_targets[hydra_heads[head_no]->target_no]->ok = 1; + if (hydra_targets[hydra_heads[head_no]->target_no]->fail_count > 0) + hydra_targets[hydra_heads[head_no]->target_no]->fail_count--; + memset(buf, 0, sizeof(buf)); + read_safe(hydra_heads[head_no]->sp[0], buf, MAXBUF); + hydra_skip_user(hydra_heads[head_no]->target_no, buf); + fck = write(hydra_heads[head_no]->sp[1], "n", 1); // small hack + break; - // we do not make a difference between 'C' and 'E' results - yet - case 'E': // head reports protocol error - case 'C': // head reports connect error - fck = write(hydra_heads[head_no]->sp[0], "Q", 1); - if (debug) { - printf("[ATTEMPT-ERROR] target %s - login \"%s\" - pass \"%s\" - child %d - %lu of %lu\n", - hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no, - hydra_targets[hydra_heads[head_no]->target_no]->sent, hydra_brains.todo); - } - hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); - break; + // we do not make a difference between 'C' and 'E' results - yet + case 'E': // head reports protocol error + case 'C': // head reports connect error + fck = write(hydra_heads[head_no]->sp[0], "Q", 1); + if (debug) { + printf("[ATTEMPT-ERROR] target %s - login \"%s\" - pass \"%s\" - child %d - %lu of %lu\n", + hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr, head_no, + hydra_targets[hydra_heads[head_no]->target_no]->sent, hydra_brains.todo); + } + hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); + break; - case 'Q': // head reports its quitting - fck = write(hydra_heads[head_no]->sp[0], "Q", 1); - if (debug) - printf("[DEBUG] child %d reported it quit\n", head_no); - hydra_kill_head(head_no, 1, 0); - break; + case 'Q': // head reports its quitting + fck = write(hydra_heads[head_no]->sp[0], "Q", 1); + if (debug) + printf("[DEBUG] child %d reported it quit\n", head_no); + hydra_kill_head(head_no, 1, 0); + break; - default: - fprintf(stderr, "[ERROR] child %d sent nonsense data, killing and restarting it!\n", head_no); - hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); - } // end switch - } // readres - if (readres == -1) { - if (verbose) - fprintf(stderr, "[WARNING] child %d seems to have died, restarting (this only happens if a module is bad) ... \n", head_no); - hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); - } - } // end do_switch - } else { - if (hydra_heads[head_no]->last_seen + hydra_options.waittime > tmp_time) { - // check if recover of timed-out head is necessary - if (tmp_time > waittime + hydra_heads[head_no]->last_seen) { - if (kill(hydra_heads[head_no]->pid, 0) < 0) { - if (verbose) - fprintf(stderr, "[WARNING] child %d seems to be dead, restarting it ...\n", head_no); - hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); - } - } - // if we do not get to hear anything for a longer time assume its dead - if (tmp_time > waittime * 2 + hydra_heads[head_no]->last_seen) { - if (verbose) - fprintf(stderr, "[WARNING] timeout from child %d, restarting\n", head_no); - hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); - } - } - } - break; - default: - fprintf(stderr, "[ERROR] child %d in unknown state, restarting!\n", head_no); - hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); - } - } - //if (debug) printf("DEBUG: bug hunt: %lu %lu\n", hydra_brains.todo_all, hydra_brains.sent); + default: + fprintf(stderr, "[ERROR] child %d sent nonsense data, killing and restarting it!\n", head_no); + hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); + } // end switch + } // readres + if (readres == -1) { + if (verbose) + fprintf(stderr, "[WARNING] child %d seems to have died, restarting (this only happens if a module is bad) ... \n", head_no); + hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); + } + } // end do_switch + } else { + if (hydra_heads[head_no]->last_seen + hydra_options.waittime > tmp_time) { + // check if recover of timed-out head is necessary + if (tmp_time > waittime + hydra_heads[head_no]->last_seen) { + if (kill(hydra_heads[head_no]->pid, 0) < 0) { + if (verbose) + fprintf(stderr, "[WARNING] child %d seems to be dead, restarting it ...\n", head_no); + hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); + } + } + // if we do not get to hear anything for a longer time assume its dead + if (tmp_time > waittime * 2 + hydra_heads[head_no]->last_seen) { + if (verbose) + fprintf(stderr, "[WARNING] timeout from child %d, restarting\n", head_no); + hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); + } + } + } + break; + default: + fprintf(stderr, "[ERROR] child %d in unknown state, restarting!\n", head_no); + hydra_increase_fail_count(hydra_heads[head_no]->target_no, head_no); + } + } + //if (debug) printf("DEBUG: bug hunt: %lu %lu\n", hydra_brains.todo_all, hydra_brains.sent); - usleepn(USLEEP_LOOP); - (void) wait3(NULL, WNOHANG, NULL); - // write restore file and report status - if (process_restore == 1 && time(NULL) - elapsed_restore > 299) { - hydra_restore_write(0); - elapsed_restore = time(NULL); - } + usleepn(USLEEP_LOOP); + (void) wait3(NULL, WNOHANG, NULL); + // write restore file and report status + if (process_restore == 1 && time(NULL) - elapsed_restore > 299) { + hydra_restore_write(0); + elapsed_restore = time(NULL); + } - if (time(NULL) - elapsed_status > status_print) { - elapsed_status = time(NULL); - tmp_time = elapsed_status - starttime; - if (tmp_time < 1) - tmp_time = 1; - tmp_time = hydra_brains.sent / tmp_time; - if (tmp_time < 1) - tmp_time = 1; - if (debug == 0) { - if (status_print < 15 * 59) - status_print = ((status_print + 1) * 2) - 1; - if (status_print > 299 && ((hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / tmp_time < 1500) - status_print = 299; - if ((((hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / tmp_time) < 150) - status_print = 59; - } - k = 0; - for (j = 0; j < hydra_options.max_use; j++) - if (hydra_heads[j]->active >= HEAD_UNUSED) - k++; + if (time(NULL) - elapsed_status > status_print) { + elapsed_status = time(NULL); + tmp_time = elapsed_status - starttime; + if (tmp_time < 1) + tmp_time = 1; + tmp_time = hydra_brains.sent / tmp_time; + if (tmp_time < 1) + tmp_time = 1; + if (debug == 0) { + if (status_print < 15 * 59) + status_print = ((status_print + 1) * 2) - 1; + if (status_print > 299 && ((hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / tmp_time < 1500) + status_print = 299; + if ((((hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / tmp_time) < 150) + status_print = 59; + } + k = 0; + for (j = 0; j < hydra_options.max_use; j++) + if (hydra_heads[j]->active >= HEAD_UNUSED) + k++; /* I think we don't need this anymore - if ((hydra_brains.todo_all + total_redo_count) < hydra_brains.sent) { //in case of overflow of unsigned "-1" - for (i = 0; i < hydra_options.max_use; i++) - if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0) - hydra_kill_head(i, 1, 3); - printf("[BUG] %lu + %d < %lu\n", hydra_brains.todo_all, total_redo_count, hydra_brains.sent); - bail("[BUG] Weird bug detected where more tests were performed than possible. Please rerun with -d command line switch and post all output plus command line here: https://github.com/vanhauser-thc/thc-hydra/issues/113 or send it in an email to vh@thc.org"); - } + if ((hydra_brains.todo_all + total_redo_count) < hydra_brains.sent) { //in case of overflow of unsigned "-1" + for (i = 0; i < hydra_options.max_use; i++) + if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0) + hydra_kill_head(i, 1, 3); + printf("[BUG] %lu + %d < %lu\n", hydra_brains.todo_all, total_redo_count, hydra_brains.sent); + bail("[BUG] Weird bug detected where more tests were performed than possible. Please rerun with -d command line switch and post all output plus command line here: https://github.com/vanhauser-thc/thc-hydra/issues/113 or send it in an email to vh@thc.org"); + } */ - printf("[STATUS] %.2f tries/min, %lu tries in %02lu:%02luh, %lu to do in %02lu:%02luh, %d active\n", (1.0 * hydra_brains.sent) / (((elapsed_status - starttime) * 1.0) / 60), // tries/min - hydra_brains.sent, // tries - (uint64_t) ((elapsed_status - starttime) / 3600), // hours - (uint64_t) (((elapsed_status - starttime) % 3600) / 60), // minutes - (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent != 0 ? (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent : 1, // left todo - (uint64_t) (((double) (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / ((double) hydra_brains.sent / (elapsed_status - starttime)) - ) / 3600, // hours - (((uint64_t) (((double) (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / ((double) hydra_brains.sent / (elapsed_status - starttime)) - ) % 3600) / 60) + 1, // min - k); - hydra_debug(0, "STATUS"); - } + printf("[STATUS] %.2f tries/min, %lu tries in %02lu:%02luh, %lu to do in %02lu:%02luh, %d active\n", (1.0 * hydra_brains.sent) / (((elapsed_status - starttime) * 1.0) / 60), // tries/min + hydra_brains.sent, // tries + (uint64_t) ((elapsed_status - starttime) / 3600), // hours + (uint64_t) (((elapsed_status - starttime) % 3600) / 60), // minutes + (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent != 0 ? (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent : 1, // left todo + (uint64_t) (((double) (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / ((double) hydra_brains.sent / (elapsed_status - starttime)) + ) / 3600, // hours + (((uint64_t) (((double) (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / ((double) hydra_brains.sent / (elapsed_status - starttime)) + ) % 3600) / 60) + 1, // min + k); + hydra_debug(0, "STATUS"); + } - exit_condition = hydra_check_for_exit_condition(); + exit_condition = hydra_check_for_exit_condition(); } process_restore = 0; if (debug) - printf("[DEBUG] while loop left with %d\n", exit_condition); + printf("[DEBUG] while loop left with %d\n", exit_condition); j = k = error = 0; for (i = 0; i < hydra_brains.targets; i++) - switch (hydra_targets[i]->done) { - case TARGET_UNRESOLVED: - k++; - break; - case TARGET_ERROR: - if (hydra_targets[i]->ok == 0) - k++; - else - error++; - break; - case TARGET_FINISHED: - break; - case TARGET_ACTIVE: - if (hydra_targets[i]->ok == 0) - k++; - else - j++; - break; - default: - error++; - fprintf(stderr, "[ERROR] illegal target result value (%d=>%d)\n", i, hydra_targets[i]->done); - } + switch (hydra_targets[i]->done) { + case TARGET_UNRESOLVED: + k++; + break; + case TARGET_ERROR: + if (hydra_targets[i]->ok == 0) + k++; + else + error++; + break; + case TARGET_FINISHED: + break; + case TARGET_ACTIVE: + if (hydra_targets[i]->ok == 0) + k++; + else + j++; + break; + default: + error++; + fprintf(stderr, "[ERROR] illegal target result value (%d=>%d)\n", i, hydra_targets[i]->done); + } printf("%d of %d target%s%scompleted, %lu valid password", - hydra_brains.targets - j - k - error, hydra_brains.targets, hydra_brains.targets == 1 ? " " : "s ", - hydra_brains.found > 0 ? "successfully " : "", hydra_brains.found); + hydra_brains.targets - j - k - error, hydra_brains.targets, hydra_brains.targets == 1 ? " " : "s ", + hydra_brains.found > 0 ? "successfully " : "", hydra_brains.found); printf("%s", hydra_brains.found == 1 ? "" : "s"); printf(" found\n"); error += j; k = 0; for (j = 0; j < hydra_options.max_use; j++) - if (hydra_heads[j]->active == HEAD_ACTIVE) - k++; + if (hydra_heads[j]->active == HEAD_ACTIVE) + k++; if (error == 0 && k == 0) { - process_restore = 0; - unlink(RESTOREFILE); + process_restore = 0; + unlink(RESTOREFILE); } else { - if (hydra_options.cidr == 0 && k == 0) { - printf("[INFO] Writing restore file because %d server scan%s could not be completed\n", j + error, j + error == 1 ? "" : "s"); - hydra_restore_write(1); - } else if (k > 0) { - printf("[WARNING] Writing restore file because %d final worker threads did not complete until end.\n", k); - hydra_restore_write(1); - } + if (hydra_options.cidr == 0 && k == 0) { + printf("[INFO] Writing restore file because %d server scan%s could not be completed\n", j + error, j + error == 1 ? "" : "s"); + hydra_restore_write(1); + } else if (k > 0) { + printf("[WARNING] Writing restore file because %d final worker threads did not complete until end.\n", k); + hydra_restore_write(1); + } } if (debug) - printf("[DEBUG] killing all remaining children now that might be stuck\n"); + printf("[DEBUG] killing all remaining children now that might be stuck\n"); for (i = 0; i < hydra_options.max_use; i++) - if (hydra_heads[i]->active == HEAD_ACTIVE && hydra_heads[i]->pid > 0) - hydra_kill_head(i, 1, 3); + if (hydra_heads[i]->active == HEAD_ACTIVE && hydra_heads[i]->pid > 0) + hydra_kill_head(i, 1, 3); (void) wait3(NULL, WNOHANG, NULL); #define STRMAX (10*1024) @@ -4018,53 +4056,59 @@ int main(int argc, char *argv[]) { memset(json_error, 0, STRMAX+2); memset(tmp_str, 0, STRMAX+2); if (error) { - snprintf(tmp_str, STRMAX, "[ERROR] %d target%s disabled because of too many errors", error, error == 1 ? " was" : "s were"); - fprintf(stderr, "%s\n", tmp_str); - strncat(json_error,"\"",STRMAX); - strncat(json_error,tmp_str,STRMAX); - strncat(json_error,"\"",STRMAX); - error = 1; + snprintf(tmp_str, STRMAX, "[ERROR] %d target%s disabled because of too many errors", error, error == 1 ? " was" : "s were"); + fprintf(stderr, "%s\n", tmp_str); + strncat(json_error,"\"",STRMAX); + strncat(json_error,tmp_str,STRMAX); + strncat(json_error,"\"",STRMAX); + error = 1; } if (k) { - snprintf(tmp_str, STRMAX, "[ERROR] %d target%s did not resolve or could not be connected", k, k == 1 ? "" : "s"); - fprintf(stderr, "%s\n", tmp_str); - if (*json_error) { - strncat(json_error,", ", STRMAX); - } - strncat(json_error,"\"",STRMAX); - strncat(json_error,tmp_str,STRMAX); - strncat(json_error,"\"",STRMAX); - error = 1; - if (*json_error) { - strncat(json_error,", ", STRMAX); - } - error = 1; + snprintf(tmp_str, STRMAX, "[ERROR] %d target%s did not resolve or could not be connected", k, k == 1 ? "" : "s"); + fprintf(stderr, "%s\n", tmp_str); + if (*json_error) { + strncat(json_error,", ", STRMAX); + } + strncat(json_error,"\"",STRMAX); + strncat(json_error,tmp_str,STRMAX); + strncat(json_error,"\"",STRMAX); + error = 1; + if (*json_error) { + strncat(json_error,", ", STRMAX); + } + error = 1; } if (error) { - snprintf(tmp_str, STRMAX, "[ERROR] %d target%s did not complete", j, j == 1 ? "" : "s"); - fprintf(stderr, "%s\n", tmp_str); - if (*json_error) { - strncat(json_error,", ", STRMAX); - } - strncat(json_error,"\"",STRMAX); - strncat(json_error,tmp_str,STRMAX); - strncat(json_error,"\"",STRMAX); - error = 1; + snprintf(tmp_str, STRMAX, "[ERROR] %d target%s did not complete", j, j == 1 ? "" : "s"); + fprintf(stderr, "%s\n", tmp_str); + if (*json_error) { + strncat(json_error,", ", STRMAX); + } + strncat(json_error,"\"",STRMAX); + strncat(json_error,tmp_str,STRMAX); + strncat(json_error,"\"",STRMAX); + error = 1; } // yeah we did it printf("%s (%s) finished at %s\n", PROGRAM, RESOURCE, hydra_build_time()); if (hydra_brains.ofp != NULL && hydra_brains.ofp != stdout) { - if (hydra_options.outfile_format == FORMAT_JSONV1) { - fprintf(hydra_brains.ofp, "\n\t],\n\"success\": %s,\n\"errormessages\": [ %s ],\n\"quantityfound\": %lu }\n", - (error ? "false" : "true"), json_error, hydra_brains.found); - } - fclose(hydra_brains.ofp); + if (hydra_options.outfile_format == FORMAT_JSONV1) { + fprintf(hydra_brains.ofp, "\n\t],\n\"success\": %s,\n\"errormessages\": [ %s ],\n\"quantityfound\": %lu }\n", + (error ? "false" : "true"), json_error, hydra_brains.found); + } + fclose(hydra_brains.ofp); + }else if (hydra_options.outfile_format == FORMAT_REDIS && hydra_options.key != NULL) { + get(redis_output_tmp, hydra_options.key); + sprintf(redis_output_tmp + strlen(redis_output_tmp) - 1,",\"success\": \"%s\",\"errormessages\": [ %s ],\"quantityfound\": %lu }", (error ? "false" : "true"), json_error, hydra_brains.found); + redis_output_tmp = replace(redis_output_tmp, "running", "finished"); + set(hydra_options.key, redis_output_tmp); } + //set("output", output); redis_free(); fflush(NULL); if (error || j != 0 || exit_condition < 0) - return -1; + return -1; else - return 0; + return 0; } diff --git a/hydra.h b/hydra.h index 38bd7ba..6f6fd99 100755 --- a/hydra.h +++ b/hydra.h @@ -177,6 +177,7 @@ typedef enum { FORMAT_PLAIN_TEXT, FORMAT_JSONV1, FORMAT_JSONV2, + FORMAT_REDIS, FORMAT_XMLV1 } output_format_t; @@ -211,6 +212,8 @@ typedef struct { char *server; char *service; char bfg; + char *key; //redis save key + char *map_key; //redis save map key } hydra_option; #define _HYDRA_H diff --git a/output-redis.c b/output-redis.c index d3ef782..0de3aa2 100755 --- a/output-redis.c +++ b/output-redis.c @@ -9,32 +9,84 @@ #include "output-redis.h" void set(const unsigned char *key, const unsigned char *value) +{ + if (conn == NULL) + { + conn = redisConnect(REDIS_IP, REDIS_PORT); + } + if(conn != NULL && conn->err) + { + printf("connection error: %s\n",conn->errstr); + } + redisReply *reply = (redisReply*)redisCommand(conn,"set %s %s", key, value); + freeReplyObject(reply); +} + +void get(char *value, const unsigned char *key) +{ + if (conn == NULL) + { + conn = redisConnect(REDIS_IP, REDIS_PORT); + } + if(conn != NULL && conn->err) + { + printf("connection error: %s\n",conn->errstr); + } + redisReply *reply = redisCommand(conn,"get %s", key); + sprintf(value, "%s", reply->str); + freeReplyObject(reply); +} + +void lpush(const unsigned char *key, const unsigned char *value) { if (conn == NULL) { conn = redisConnect("127.0.0.1", 6379); } - if(conn != NULL && conn->err) - { - - printf("connection error: %s\n",conn->errstr); - } - redisReply *reply = (redisReply*)redisCommand(conn,"set %s %s", key, value); - freeReplyObject(reply); - - /*reply = redisCommand(conn,"get %s", key); - printf("%s\n",reply->str); - freeReplyObject(reply); */ - - + if(conn != NULL && conn->err) + { + printf("connection error: %s\n",conn->errstr); + } + redisReply *reply = (redisReply*)redisCommand(conn,"lpush %s %s", key, value); + freeReplyObject(reply); +} + +void key(char *key, const unsigned char *str){ + //随机种子 + srand(time(0)); + sprintf(key, "%s-%d", str, rand()); } void redis_free() { redisFree(conn); } +char *replace(char *src, char *sub, char *dst) +{ + int pos = 0; + int offset = 0; + int srcLen, subLen, dstLen; + char *pRet = NULL; + + srcLen = strlen(src); + subLen = strlen(sub); + dstLen = strlen(dst); + pRet = (char *)malloc(srcLen + dstLen - subLen + 1);//(外部是否该空间) + if (NULL != pRet) + { + pos = strstr(src, sub) - src; + memcpy(pRet, src, pos); + offset += pos; + memcpy(pRet + offset, dst, dstLen); + offset += dstLen; + memcpy(pRet + offset, src + pos + subLen, srcLen - pos - subLen); + offset += srcLen - pos - subLen; + *(pRet + offset) = '\0'; + } + return pRet; +} /*int main() { - set("a", "1"); + set("a", "1"); return 0; }*/ diff --git a/output-redis.h b/output-redis.h index 8f0d591..395de9e 100755 --- a/output-redis.h +++ b/output-redis.h @@ -1,15 +1,26 @@ // -// hydra-rtsp.c -// hydra-rtsp +// output-redis.c +// output-redis // -// Created by Javier zhukun on 03/04/18. +// Created by zhukun on 03/04/18. // // #include +#include +#include +#include #include "lib/hiredis/hiredis.h" +#define REDIS_IP "127.0.0.1" +#define REDIS_PORT 6379 + redisContext *conn; void set(const unsigned char *key, const unsigned char *value); -void redis_free(); \ No newline at end of file +void get(char *value, const unsigned char *key); +void lpush(const unsigned char *key, const unsigned char *value); +void key(char *map_key, const unsigned char *str); +void redis_free(); + +char *replace(char *src, char *sub, char *dst); \ No newline at end of file