Skip to content

Commit

Permalink
Merge pull request #149 from crondaemon/cron
Browse files Browse the repository at this point in the history
Fix issue #148.
  • Loading branch information
vanhauser-thc committed Aug 30, 2016
2 parents 6444712 + 712defc commit 8d981c0
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 93 deletions.
149 changes: 79 additions & 70 deletions bfg.c
Expand Up @@ -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
Expand Down Expand Up @@ -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);
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);
if (bf_options.disable_symbols) {
if (add_single_char(tmp[i], flags, &crs_len) == -1)
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");
}
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;

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;
}
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions bfg.h
Expand Up @@ -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;
Expand Down
54 changes: 31 additions & 23 deletions hydra.c
Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -1025,7 +1029,7 @@ unsigned long int countlines(FILE * fd, int colonmode) {
#else
FILE *fp = fd;
#endif

size_of_data = 0;

#ifdef HAVE_ZLIB
Expand Down Expand Up @@ -1719,7 +1723,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. */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -3723,7 +3731,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;
Expand Down Expand Up @@ -3785,7 +3793,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)
Expand Down Expand Up @@ -3839,9 +3847,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);
}
Expand All @@ -3855,9 +3863,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;
}
Expand All @@ -3872,7 +3880,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);
Expand Down Expand Up @@ -3929,7 +3937,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);
Expand Down Expand Up @@ -3959,18 +3967,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");
}
Expand Down Expand Up @@ -4036,7 +4044,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);
Expand Down

0 comments on commit 8d981c0

Please sign in to comment.