From 2e8c21a9ca422161d5d33e5cf07c0e04a552ecd5 Mon Sep 17 00:00:00 2001 From: Dario Lombardo Date: Tue, 30 Aug 2016 14:38:53 +0200 Subject: [PATCH 1/2] Change printf modifier. --- hydra.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/hydra.c b/hydra.c index 91b9e64..abe88e5 100644 --- a/hydra.c +++ b/hydra.c @@ -1025,7 +1025,7 @@ unsigned long int countlines(FILE * fd, int colonmode) { #else FILE *fp = fd; #endif - + size_of_data = 0; #ifdef HAVE_ZLIB @@ -1719,7 +1719,7 @@ char *hydra_reverse_login(int head_no, char *login) { // UTF stuff now start = hydra_heads[head_no]->reverse; pos = start + j; - + while(start < --pos) { switch( (*pos & 0xF0) >> 4 ) { case 0xF: /* U+010000-U+10FFFF: four bytes. */ @@ -3723,7 +3723,7 @@ int main(int argc, char *argv[]) { hydra_debug(0, "attack"); process_restore = 1; - // this is the big function which starts the attacking children, feeds login/password pairs, etc.! + // 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; @@ -3785,7 +3785,7 @@ int main(int argc, char *argv[]) { 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 + // 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) @@ -3839,9 +3839,9 @@ int main(int argc, char *argv[]) { 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); } - if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found + 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 == 0) { - hydra_targets[hydra_heads[head_no]->target_no]->done = 1; // mark target as done + hydra_targets[hydra_heads[head_no]->target_no]->done = 1; // 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); } @@ -3855,9 +3855,9 @@ int main(int argc, char *argv[]) { 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 + 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 + hydra_kill_head(j, 1, 2); // kill all heads working on the target } continue; } @@ -3872,7 +3872,7 @@ int main(int argc, char *argv[]) { 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 + // 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); @@ -3929,7 +3929,7 @@ int main(int argc, char *argv[]) { usleepn(USLEEP_LOOP); (void) wait3(NULL, WNOHANG, NULL); - // write restore file and report status + // write restore file and report status if (process_restore == 1 && time(NULL) - elapsed_restore > 299) { hydra_restore_write(0); elapsed_restore = time(NULL); @@ -3959,18 +3959,18 @@ int main(int argc, char *argv[]) { 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 + %lu < %lu\n", hydra_brains.todo_all, total_redo_count, hydra_brains.sent); + 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 - (long unsigned int) ((elapsed_status - starttime) / 3600), // hours - (long unsigned int) (((elapsed_status - starttime) % 3600) / 60), // minutes - (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent <= 0 ? 1 : (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent, // left todo + 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 + (long unsigned int) ((elapsed_status - starttime) / 3600), // hours + (long unsigned int) (((elapsed_status - starttime) % 3600) / 60), // minutes + (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent <= 0 ? 1 : (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent, // left todo (long unsigned int) (((double) (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / ((double) hydra_brains.sent / (elapsed_status - starttime)) - ) / 3600, // hours + ) / 3600, // hours (((long unsigned int) (((double) (hydra_brains.todo_all + total_redo_count) - hydra_brains.sent) / ((double) hydra_brains.sent / (elapsed_status - starttime)) - ) % 3600) / 60) + 1, // min + ) % 3600) / 60) + 1, // min k); hydra_debug(0, "STATUS"); } @@ -4036,7 +4036,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] %d target%s did not complete\n", j, j == 1 ? "" : "s"); error = 1; } - // yeah we did it + // 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) fclose(hydra_brains.ofp); From 712defcb406f9874a333eeb3210489d4c38149b9 Mon Sep 17 00:00:00 2001 From: Dario Lombardo Date: Tue, 30 Aug 2016 15:14:42 +0200 Subject: [PATCH 2/2] Add new option to disable placeholders. With -y the use of -x ?:?:aA1 has changed to "use a, A and 1", instead of "use all lowercase, uppercase letters and all numbers". --- bfg.c | 149 ++++++++++++++++++++++++++++++-------------------------- bfg.h | 1 + hydra.c | 16 ++++-- 3 files changed, 92 insertions(+), 74 deletions(-) diff --git a/bfg.c b/bfg.c index 5f1f163..4b1799d 100644 --- a/bfg.c +++ b/bfg.c @@ -14,6 +14,31 @@ bf_option bf_options; extern int debug; +static int add_single_char(char ch, char flags, int* crs_len) { + if ((ch >= '2' && ch <= '9') || ch == '0') { + if ((flags & BF_NUMS) > 0) { + printf("[ERROR] character %c defined in -x although the whole number range was already defined by '1', ignored\n", ch); + return 0; + } + printf("[WARNING] adding character %c for -x, note that '1' will add all numbers from 0-9\n", ch); + } + if (tolower((int) ch) >= 'b' && tolower((int) ch) <= 'z') { + if ((ch <= 'Z' && (flags & BF_UPPER) > 0) || (ch > 'Z' && (flags & BF_UPPER) > 0)) { + printf("[ERROR] character %c defined in -x although the whole letter range was already defined by '%c', ignored\n", ch, ch <= 'Z' ? 'A' : 'a'); + return 0; + } + printf("[WARNING] adding character %c for -x, note that '%c' will add all %scase letters\n", ch, ch <= 'Z' ? 'A' : 'a', ch <= 'Z' ? "up" : "low"); + } + (*crs_len)++; + if (BF_CHARSMAX - *crs_len < 1) { + free(bf_options.crs); + fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); + return 1; + } else { + bf_options.crs[*crs_len - 1] = ch; + bf_options.crs[*crs_len] = '\0'; + } +} // return values : 0 on success, 1 on error // // note that we check for -x .:.:ab but not for -x .:.:ba @@ -69,80 +94,64 @@ int bf_init(char *arg) { bf_options.crs[0] = 0; for (; tmp[i]; i++) { - switch (tmp[i]) { - case 'a': - crs_len += 26; - if (BF_CHARSMAX - crs_len < 1) { - free(bf_options.crs); - fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); + if (bf_options.disable_symbols) { + if (add_single_char(tmp[i], flags, &crs_len) == -1) return 1; - } else if (flags & BF_LOWER) { - free(bf_options.crs); - fprintf(stderr, "Error: 'a' specified more than once in charset!\n"); - return 1; - } else { - strcat(bf_options.crs, "abcdefghijklmnopqrstuvwxyz"); - flags |= BF_LOWER; - } - break; - - case 'A': - crs_len += 26; - if (BF_CHARSMAX - crs_len < 1) { - free(bf_options.crs); - fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); - return 1; - } else if (flags & BF_UPPER) { - free(bf_options.crs); - fprintf(stderr, "Error: 'A' specified more than once in charset!\n"); - return 1; - } else { - strcat(bf_options.crs, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - flags |= BF_UPPER; - } - break; - - case '1': - crs_len += 10; - if (BF_CHARSMAX - crs_len < 1) { - free(bf_options.crs); - fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); - return 1; - } else if (flags & BF_NUMS) { - free(bf_options.crs); - fprintf(stderr, "Error: '1' specified more than once in charset!\n"); - return 1; - } else { - strcat(bf_options.crs, "0123456789"); - flags |= BF_NUMS; - } - break; - - default: - if ((tmp[i] >= '2' && tmp[i] <= '9') || tmp[i] == '0') { - if ((flags & BF_NUMS) > 0) { - printf("[ERROR] character %c defined in -x although the whole number range was already defined by '1', ignored\n", tmp[i]); - continue; + } else { + switch (tmp[i]) { + case 'a': + crs_len += 26; + if (BF_CHARSMAX - crs_len < 1) { + free(bf_options.crs); + fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); + return 1; + } else if (flags & BF_LOWER) { + free(bf_options.crs); + fprintf(stderr, "Error: 'a' specified more than once in charset!\n"); + return 1; + } else { + strcat(bf_options.crs, "abcdefghijklmnopqrstuvwxyz"); + flags |= BF_LOWER; } - printf("[WARNING] adding character %c for -x, note that '1' will add all numbers from 0-9\n", tmp[i]); - } - if (tolower((int) tmp[i]) >= 'b' && tolower((int) tmp[i]) <= 'z') { - if ((tmp[i] <= 'Z' && (flags & BF_UPPER) > 0) || (tmp[i] > 'Z' && (flags & BF_UPPER) > 0)) { - printf("[ERROR] character %c defined in -x although the whole letter range was already defined by '%c', ignored\n", tmp[i], tmp[i] <= 'Z' ? 'A' : 'a'); - continue; + break; + + case 'A': + crs_len += 26; + if (BF_CHARSMAX - crs_len < 1) { + free(bf_options.crs); + fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); + return 1; + } else if (flags & BF_UPPER) { + free(bf_options.crs); + fprintf(stderr, "Error: 'A' specified more than once in charset!\n"); + return 1; + } else { + strcat(bf_options.crs, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + flags |= BF_UPPER; } - printf("[WARNING] adding character %c for -x, note that '%c' will add all %scase letters\n", tmp[i], tmp[i] <= 'Z' ? 'A' : 'a', tmp[i] <= 'Z' ? "up" : "low"); + break; + + case '1': + crs_len += 10; + if (BF_CHARSMAX - crs_len < 1) { + free(bf_options.crs); + fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); + return 1; + } else if (flags & BF_NUMS) { + free(bf_options.crs); + fprintf(stderr, "Error: '1' specified more than once in charset!\n"); + return 1; + } else { + strcat(bf_options.crs, "0123456789"); + flags |= BF_NUMS; + } + break; + + default: + if (add_single_char(tmp[i], flags, &crs_len) == -1) + return 1; + break; } - crs_len++; - if (BF_CHARSMAX - crs_len < 1) { - free(bf_options.crs); - fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX); - return 1; - } else { - bf_options.crs[crs_len - 1] = tmp[i]; - bf_options.crs[crs_len] = '\0'; - } - break; } } diff --git a/bfg.h b/bfg.h index 8b544ac..3ed42d2 100644 --- a/bfg.h +++ b/bfg.h @@ -40,6 +40,7 @@ typedef struct { char *arg; /* argument received for bfg commandline option */ char *crs; /* internal representation of charset */ char *ptr; /* ptr to the last generated password */ + unsigned int disable_symbols; } bf_option; extern bf_option bf_options; diff --git a/hydra.c b/hydra.c index abe88e5..a90a1f6 100644 --- a/hydra.c +++ b/hydra.c @@ -336,8 +336,10 @@ void help(int ext) { printf(" -l LOGIN or -L FILE login with LOGIN name, or load several logins from FILE\n"); printf(" -p PASS or -P FILE try password PASS, or load several passwords from FILE\n"); #ifdef HAVE_MATH_H - if (ext) + if (ext) { printf(" -x MIN:MAX:CHARSET password bruteforce generation, type \"-x -h\" to get help\n"); + printf(" -y disable use of symbols in bruteforce, see above\n"); + } #endif if (ext) printf(" -e nsr try \"n\" null password, \"s\" login as pass and/or \"r\" reversed login\n"); @@ -400,11 +402,13 @@ void help_bfg() { " 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\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 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"); printf("\nThe bruteforce mode was made by Jan Dlabal, http://houbysoft.com/bfg/\n"); exit(-1); } @@ -2306,13 +2310,14 @@ int main(int argc, char *argv[]) { hydra_brains.ofp = stdout; hydra_brains.targets = 1; hydra_options.waittime = waittime = WAITTIME; + bf_options.disable_symbols = 0; // command line processing if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) help(1); if (argc < 2) help(0); - while ((i = getopt(argc, argv, "hq64Rde:vVl:fFg:L:p:OP:o:M:C:t:T:m:w:W:s:SUux:")) >= 0) { + while ((i = getopt(argc, argv, "hq64Rde:vVl:fFg:L:p:OP:o:M:C:t:T:m:w:W:s:SUux:y")) >= 0) { switch (i) { case 'h': help(1); @@ -2447,6 +2452,9 @@ int main(int argc, char *argv[]) { hydra_options.loop_mode = 1; break; #endif + case 'y': + bf_options.disable_symbols = 1; + break; default: exit(-1); }