From 3cc53fe778a58425593a4b3fba5dc55224497ded Mon Sep 17 00:00:00 2001 From: motypi Date: Mon, 3 Mar 2025 13:00:37 +0100 Subject: [PATCH 1/8] created skip_password function --- hydra.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/hydra.c b/hydra.c index 30a8ece..a80f84f 100644 --- a/hydra.c +++ b/hydra.c @@ -1591,6 +1591,15 @@ char *hydra_reverse_login(int32_t head_no, char *login) { return hydra_heads[head_no]->reverse; } +void skip_passwords(int skips){ + for(int i=0; ipass_no >= hydra_brains.countpass) + while(*hydra_target[target_no]->pass_ptr != 0) + hydra_target[target_no]->pass_ptr++; + hydra_target[target_no]->pass_ptr++; + } +} + int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { // variables moved to save stack snpdone = 0; @@ -1750,9 +1759,7 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { 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++; + skip_passwords(1); } 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++; From a8f80debedf418c07efbc7b70a90ad0eb50d0252 Mon Sep 17 00:00:00 2001 From: motypi Date: Tue, 4 Mar 2025 10:34:23 +0100 Subject: [PATCH 2/8] added variables and applied skipping function --- hydra.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/hydra.c b/hydra.c index a80f84f..3d95cde 100644 --- a/hydra.c +++ b/hydra.c @@ -342,6 +342,8 @@ char *sck = NULL; int32_t prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed = 0; int32_t child_head_no = -1, child_socket; int32_t total_redo_count = 0; +int32_t total_distributed_machines = 2; +int32_t distributed_machine_rank = 2; // moved for restore feature int32_t process_restore = 0, dont_unlink; @@ -1591,12 +1593,12 @@ char *hydra_reverse_login(int32_t head_no, char *login) { return hydra_heads[head_no]->reverse; } -void skip_passwords(int skips){ +void skip_passwords(int32_t skips, int32_t target_no){ for(int i=0; ipass_no >= hydra_brains.countpass) - while(*hydra_target[target_no]->pass_ptr != 0) - hydra_target[target_no]->pass_ptr++; - hydra_target[target_no]->pass_ptr++; + //if(*hydra_targets[target_no]->pass_no >= hydra_brains.countpass) + while(*hydra_targets[target_no]->pass_ptr != 0) + hydra_targets[target_no]->pass_ptr++; + hydra_targets[target_no]->pass_ptr++; } } @@ -1752,6 +1754,9 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { hydra_targets[target_no]->login_ptr++; hydra_targets[target_no]->login_ptr++; hydra_targets[target_no]->pass_ptr = pass_ptr; + hydra_targets[target_no]->pass_ptr++; + //initialise the password to start with depending on the machine's rank if using distributed computing + skip_passwords(distributed_machine_rank-1, target_no); hydra_targets[target_no]->login_no++; hydra_targets[target_no]->pass_no = 0; hydra_targets[target_no]->pass_state = 0; @@ -1759,7 +1764,8 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { return hydra_send_next_pair(target_no, head_no); } else { hydra_targets[target_no]->pass_ptr++; - skip_passwords(1); + //number of passwords in the wordlist to skip depending on the number of parallel machines + skip_passwords(total_distributed_machines, target_no); } 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++; From 2c50bb8e6db34be37dfdbcc66c088c4b3fbd48fa Mon Sep 17 00:00:00 2001 From: motypi Date: Mon, 10 Mar 2025 13:58:09 +0100 Subject: [PATCH 3/8] added wordlist (password,login,colonfile) segmentation on the fly using cmd option -D --- hydra.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++--------- hydra.h | 1 + 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/hydra.c b/hydra.c index 3d95cde..033ede0 100644 --- a/hydra.c +++ b/hydra.c @@ -342,8 +342,8 @@ char *sck = NULL; int32_t prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed = 0; int32_t child_head_no = -1, child_socket; int32_t total_redo_count = 0; -int32_t total_distributed_machines = 2; -int32_t distributed_machine_rank = 2; +int32_t num_segments = 0; +int32_t my_segment = 0; // moved for restore feature int32_t process_restore = 0, dont_unlink; @@ -1593,14 +1593,66 @@ char *hydra_reverse_login(int32_t head_no, char *login) { return hydra_heads[head_no]->reverse; } -void skip_passwords(int32_t skips, int32_t target_no){ - for(int i=0; ipass_no >= hydra_brains.countpass) - while(*hydra_targets[target_no]->pass_ptr != 0) - hydra_targets[target_no]->pass_ptr++; - hydra_targets[target_no]->pass_ptr++; + +FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ + fprintf(stdout, "Dividing file...\n"); + + if(my_segment > num_segments){ + fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile); + return NULL; + } + + FILE *output_file; + char line[500]; + char output_file_name[20]; + + uint32_t line_number = 0; + + double total_lines; + if (total_lines = countlines(file,0)) + fprintf(stdout, "There are %f lines int the wordlist", total_lines); + else + fprintf(stderr, "Something went wrong in the counting of lines"); + + if(num_segments > total_lines){ + fprintf(stderr, "[ERROR] in option -D XofY, Y must not be greater than the total number of lines in the file to be divided: %s\n", hydra_options.passfile); + return NULL; } -} + + double segment_size_double = total_lines / num_segments; + + // round up segment_size_float to integer + uint64_t segment_size = (uint64_t)segment_size_double; + if(segment_size < segment_size_double) + segment_size++; + + uint64_t segment_start = segment_size * (my_segment - 1) + 1; + uint64_t segment_end = segment_size * my_segment; + + + sprintf(output_file_name, "segment_%d.txt", my_segment); + output_file = fopen(output_file_name, "w"); + + if(!output_file){ + fprintf(stderr, "[ERROR] Segment file empty: %s\n", hydra_options.passfile); + return NULL; + } + + while(fgets(line, sizeof line, file) != NULL && line_number < segment_end){ + line_number++; + + if(line_number >= segment_start && line_number <= segment_end) + fprintf(output_file, "%s", line); + + } + + rewind(file); + fclose(output_file); + output_file = fopen(output_file_name, "r"); + + return output_file; + + } int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { // variables moved to save stack @@ -1754,9 +1806,6 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { hydra_targets[target_no]->login_ptr++; hydra_targets[target_no]->login_ptr++; hydra_targets[target_no]->pass_ptr = pass_ptr; - hydra_targets[target_no]->pass_ptr++; - //initialise the password to start with depending on the machine's rank if using distributed computing - skip_passwords(distributed_machine_rank-1, target_no); hydra_targets[target_no]->login_no++; hydra_targets[target_no]->pass_no = 0; hydra_targets[target_no]->pass_state = 0; @@ -1764,8 +1813,9 @@ int32_t hydra_send_next_pair(int32_t target_no, int32_t head_no) { return hydra_send_next_pair(target_no, head_no); } else { hydra_targets[target_no]->pass_ptr++; - //number of passwords in the wordlist to skip depending on the number of parallel machines - skip_passwords(total_distributed_machines, target_no); + 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++; @@ -2184,7 +2234,7 @@ void process_proxy_line(int32_t type, char *string) { int main(int argc, char *argv[]) { char *proxy_string = NULL, *device = NULL, *memcheck; char *outfile_format_tmp; - FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp; + FILE *lfp = NULL, *pfp = NULL, *cfp = NULL, *ifp = NULL, *rfp = NULL, *proxyfp, *filecloser=NULL; size_t countinfile = 1, sizeinfile = 0; uint64_t math2; int32_t i = 0, j = 0, k, error = 0, modusage = 0, ignore_restore = 0, do_switch; @@ -2320,6 +2370,7 @@ int main(int argc, char *argv[]) { hydra_options.loginfile = NULL; hydra_options.pass = NULL; hydra_options.passfile = NULL; + hydra_options.distributed = NULL; hydra_options.tasks = TASKS; hydra_options.max_use = MAXTASKS; hydra_options.outfile_format = FORMAT_PLAIN_TEXT; @@ -2333,8 +2384,18 @@ int main(int argc, char *argv[]) { help(1); if (argc < 2) help(0); - while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) { + while ((i = getopt(argc, argv, "hIq64Rrde:vVl:fFg:D:L:p:OP:o:b:M:C:t:T:m:w:W:s:SUux:yc:K")) >= 0) { switch (i) { + case 'D': + hydra_options.distributed = optarg; + if (sscanf(hydra_options.distributed, "%dof%d", &my_segment, &num_segments) != 2) { + fprintf(stderr, "Invalid format. Expected format -D XofY where X and Y are integers.\n"); + exit(EXIT_FAILURE); + } + else{ + fprintf(stdout, "successfully set X to %d and Y to %d\n", my_segment, num_segments); + } + break; case 'h': help(1); break; @@ -3415,6 +3476,13 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for logins not found: %s\n", hydra_options.loginfile); exit(-1); } + else if (hydra_options.passfile == NULL){ + if(my_segment && num_segments){ + filecloser = lfp; + lfp = hydra_divide_file(lfp, my_segment, num_segments); + fclose(filecloser); + } + } hydra_brains.countlogin = countlines(lfp, 0); hydra_brains.sizelogin = size_of_data; if (hydra_brains.countlogin == 0) { @@ -3447,6 +3515,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for passwords not found: %s\n", hydra_options.passfile); exit(-1); } + else if(my_segment && num_segments){ + filecloser = pfp; + pfp = hydra_divide_file(pfp, my_segment, num_segments); + fclose(filecloser); + } hydra_brains.countpass = countlines(pfp, 0); hydra_brains.sizepass = size_of_data; if (hydra_brains.countpass == 0) { @@ -3501,6 +3574,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "[ERROR] File for colon files (login:pass) not found: %s\n", hydra_options.colonfile); exit(-1); } + else if(my_segment && num_segments){ + filecloser = cfp; + cfp = hydra_divide_file(cfp, my_segment, num_segments); + fclose(filecloser); + } hydra_brains.countlogin = countlines(cfp, 1); hydra_brains.sizelogin = size_of_data; if (hydra_brains.countlogin == 0) { @@ -4421,4 +4499,4 @@ int main(int argc, char *argv[]) { return -1; else return 0; -} +} \ No newline at end of file diff --git a/hydra.h b/hydra.h index 353b318..24b63e8 100644 --- a/hydra.h +++ b/hydra.h @@ -194,6 +194,7 @@ typedef struct { int32_t cidr; int32_t time_next_attempt; output_format_t outfile_format; + char *distributed; // Use distributed computing by splitting user files on the fly char *login; char *loginfile; char *pass; From f632c7231eafa000afc1b5ec1fd1e0c17cbf0036 Mon Sep 17 00:00:00 2001 From: motypi Date: Mon, 10 Mar 2025 22:41:50 +0100 Subject: [PATCH 4/8] added help for -D option --- hydra.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hydra.c b/hydra.c index 033ede0..2803fd8 100644 --- a/hydra.c +++ b/hydra.c @@ -521,6 +521,8 @@ void help(int32_t ext) { "instead of -L/-P options\n" " -M FILE list of servers to attack, one entry per " "line, ':' to specify port\n"); + PRINT_NORMAL(ext, " -D XofY Divide wordlist into Y segments and use the " + "Xth segment.\n"); PRINT_EXTEND(ext, " -o FILE write found login/password pairs to FILE instead of stdout\n" " -b FORMAT specify the format for the -o FILE: text(default), json, " "jsonv1\n" From 8faf1984d88016a96ac1dbe0c2591c40e21ab511 Mon Sep 17 00:00:00 2001 From: motypi Date: Mon, 10 Mar 2025 23:02:55 +0100 Subject: [PATCH 5/8] removed debug messages --- hydra.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hydra.c b/hydra.c index 2803fd8..e5f71a8 100644 --- a/hydra.c +++ b/hydra.c @@ -1597,7 +1597,6 @@ char *hydra_reverse_login(int32_t head_no, char *login) { FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ - fprintf(stdout, "Dividing file...\n"); if(my_segment > num_segments){ fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile); @@ -1610,11 +1609,7 @@ FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ uint32_t line_number = 0; - double total_lines; - if (total_lines = countlines(file,0)) - fprintf(stdout, "There are %f lines int the wordlist", total_lines); - else - fprintf(stderr, "Something went wrong in the counting of lines"); + double total_lines = countlines(file,0); if(num_segments > total_lines){ fprintf(stderr, "[ERROR] in option -D XofY, Y must not be greater than the total number of lines in the file to be divided: %s\n", hydra_options.passfile); @@ -2395,7 +2390,7 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } else{ - fprintf(stdout, "successfully set X to %d and Y to %d\n", my_segment, num_segments); + fprintf(stdout, "-D: successfully set X to %d and Y to %d\n", my_segment, num_segments); } break; case 'h': From 5eea263707a82ccf071b0e11d210c86f22b74bf8 Mon Sep 17 00:00:00 2001 From: motypi Date: Tue, 11 Mar 2025 14:10:52 +0100 Subject: [PATCH 6/8] remove segment files at exit --- hydra.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/hydra.c b/hydra.c index e5f71a8..bb75d96 100644 --- a/hydra.c +++ b/hydra.c @@ -342,8 +342,12 @@ char *sck = NULL; int32_t prefer_ipv6 = 0, conwait = 0, loop_cnt = 0, fck = 0, options = 0, killed = 0; int32_t child_head_no = -1, child_socket; int32_t total_redo_count = 0; -int32_t num_segments = 0; -int32_t my_segment = 0; + +// requred for distributed attack capability +uint32_t num_segments = 0; +uint32_t my_segment = 0; +uint32_t junk_file_count = 0; +char junk_files[20][16]; // moved for restore feature int32_t process_restore = 0, dont_unlink; @@ -1595,8 +1599,12 @@ char *hydra_reverse_login(int32_t head_no, char *login) { return hydra_heads[head_no]->reverse; } +void delete_junk_files(){ + for(int i=0; i num_segments){ fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile); @@ -1627,7 +1635,9 @@ FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ uint64_t segment_end = segment_size * my_segment; - sprintf(output_file_name, "segment_%d.txt", my_segment); + fprintf(stdout, "writing filename\n"); + sprintf(output_file_name, "segment_%d_%d.txt",target_no, my_segment); + fprintf(stdout, "writing successful\n"); output_file = fopen(output_file_name, "w"); if(!output_file){ @@ -1635,6 +1645,11 @@ FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ return NULL; } + if(strcpy(junk_files[junk_file_count], output_file_name)) + junk_file_count++; + + atexit(delete_junk_files); + while(fgets(line, sizeof line, file) != NULL && line_number < segment_end){ line_number++; @@ -2390,7 +2405,7 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } else{ - fprintf(stdout, "-D: successfully set X to %d and Y to %d\n", my_segment, num_segments); + fprintf(stdout, "Option \'D\': successfully set X to %d and Y to %d\n", my_segment, num_segments); } break; case 'h': @@ -3476,7 +3491,7 @@ int main(int argc, char *argv[]) { else if (hydra_options.passfile == NULL){ if(my_segment && num_segments){ filecloser = lfp; - lfp = hydra_divide_file(lfp, my_segment, num_segments); + lfp = hydra_divide_file(lfp, target_no, my_segment, num_segments); fclose(filecloser); } } @@ -3514,7 +3529,7 @@ int main(int argc, char *argv[]) { } else if(my_segment && num_segments){ filecloser = pfp; - pfp = hydra_divide_file(pfp, my_segment, num_segments); + pfp = hydra_divide_file(pfp, target_no, my_segment, num_segments); fclose(filecloser); } hydra_brains.countpass = countlines(pfp, 0); @@ -3573,7 +3588,7 @@ int main(int argc, char *argv[]) { } else if(my_segment && num_segments){ filecloser = cfp; - cfp = hydra_divide_file(cfp, my_segment, num_segments); + cfp = hydra_divide_file(cfp, target_no, my_segment, num_segments); fclose(filecloser); } hydra_brains.countlogin = countlines(cfp, 1); From 74b37e24c811c46576687d5f15fae484bdf10828 Mon Sep 17 00:00:00 2001 From: motypi Date: Wed, 12 Mar 2025 10:37:01 +0100 Subject: [PATCH 7/8] unique segment filename --- hydra.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hydra.c b/hydra.c index bb75d96..013c4d9 100644 --- a/hydra.c +++ b/hydra.c @@ -346,8 +346,7 @@ int32_t total_redo_count = 0; // requred for distributed attack capability uint32_t num_segments = 0; uint32_t my_segment = 0; -uint32_t junk_file_count = 0; -char junk_files[20][16]; +char junk_file[50]; // moved for restore feature int32_t process_restore = 0, dont_unlink; @@ -1600,11 +1599,10 @@ char *hydra_reverse_login(int32_t head_no, char *login) { } void delete_junk_files(){ - for(int i=0; i num_segments){ fprintf(stderr, "[ERROR] in option -D XofY, X must not be greater than Y: %s\n", hydra_options.passfile); @@ -1613,7 +1611,7 @@ FILE *hydra_divide_file(FILE *file, uint32_t target_no, uint32_t my_segment, uin FILE *output_file; char line[500]; - char output_file_name[20]; + char output_file_name[50]; uint32_t line_number = 0; @@ -1635,8 +1633,11 @@ FILE *hydra_divide_file(FILE *file, uint32_t target_no, uint32_t my_segment, uin uint64_t segment_end = segment_size * my_segment; - fprintf(stdout, "writing filename\n"); - sprintf(output_file_name, "segment_%d_%d.txt",target_no, my_segment); + + srand(time(NULL)); + int filetag = rand(); + + sprintf(output_file_name, "segment_%d_%d.txt",filetag, my_segment); fprintf(stdout, "writing successful\n"); output_file = fopen(output_file_name, "w"); @@ -1645,8 +1646,7 @@ FILE *hydra_divide_file(FILE *file, uint32_t target_no, uint32_t my_segment, uin return NULL; } - if(strcpy(junk_files[junk_file_count], output_file_name)) - junk_file_count++; + strcpy(junk_file, output_file_name); atexit(delete_junk_files); @@ -3491,7 +3491,7 @@ int main(int argc, char *argv[]) { else if (hydra_options.passfile == NULL){ if(my_segment && num_segments){ filecloser = lfp; - lfp = hydra_divide_file(lfp, target_no, my_segment, num_segments); + lfp = hydra_divide_file(lfp, my_segment, num_segments); fclose(filecloser); } } @@ -3529,7 +3529,7 @@ int main(int argc, char *argv[]) { } else if(my_segment && num_segments){ filecloser = pfp; - pfp = hydra_divide_file(pfp, target_no, my_segment, num_segments); + pfp = hydra_divide_file(pfp, my_segment, num_segments); fclose(filecloser); } hydra_brains.countpass = countlines(pfp, 0); @@ -3588,7 +3588,7 @@ int main(int argc, char *argv[]) { } else if(my_segment && num_segments){ filecloser = cfp; - cfp = hydra_divide_file(cfp, target_no, my_segment, num_segments); + cfp = hydra_divide_file(cfp, my_segment, num_segments); fclose(filecloser); } hydra_brains.countlogin = countlines(cfp, 1); From b8ea180d85fc391d5f349660081c3c8540b7b495 Mon Sep 17 00:00:00 2001 From: motypi Date: Wed, 12 Mar 2025 10:38:25 +0100 Subject: [PATCH 8/8] unique segment filename --- hydra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hydra.c b/hydra.c index 013c4d9..7def50a 100644 --- a/hydra.c +++ b/hydra.c @@ -1638,7 +1638,6 @@ FILE *hydra_divide_file(FILE *file, uint32_t my_segment, uint32_t num_segments){ int filetag = rand(); sprintf(output_file_name, "segment_%d_%d.txt",filetag, my_segment); - fprintf(stdout, "writing successful\n"); output_file = fopen(output_file_name, "w"); if(!output_file){