/* Restore a session Threads must be setup and spawned manually after that */ hash_stat session_restore(char *sessionname) { #ifdef HAVE_JSON_JSON_H FILE *sesfile; char sesname[1024]; char readline[512]; char username[HASHFILE_MAX_LINE_LENGTH]; char hash[HASHFILE_MAX_LINE_LENGTH]; char salt[HASHFILE_MAX_LINE_LENGTH]; char salt2[HASHFILE_MAX_LINE_LENGTH]; uid_t uid; struct passwd *pwd; char fname[255]; int flag = 0; int cnt; json_object *jobj; pwd = getpwuid(getuid()); snprintf(sesname,1024,"%s/.hashkill/sessions/%s.session", pwd->pw_dir, sessionname); /* Parse the <session>..</session> info */ sesfile = fopen(sesname, "r"); if (!sesfile) { elog("Cannot open session file : %s\n",sesname); return hash_err; } hlog("Restoring session from: %s\n",sesname); fclose(sesfile); root_node = json_object_from_file(sesname); main_header_node = json_object_object_get(root_node,"main"); set_current_plugin(json_object_get_string(json_object_object_get(main_header_node,"plugin"))); if (load_plugin() == hash_err) exit(EXIT_FAILURE); attack_method = json_object_get_int(json_object_object_get(main_header_node,"attacktype")); additional_options = malloc(strlen(json_object_get_string(json_object_object_get(main_header_node,"addopts")))+1); strcpy(additional_options,json_object_get_string(json_object_object_get(main_header_node,"addopts"))); process_addopts(json_object_get_string(json_object_object_get(main_header_node,"addopts"))); out_cracked_file=malloc(strlen(json_object_get_string(json_object_object_get(main_header_node,"outcrackedfile")))+1); out_uncracked_file=malloc(strlen(json_object_get_string(json_object_object_get(main_header_node,"outuncrackedfile")))+1); if (strlen(json_object_get_string(json_object_object_get(main_header_node,"outcrackedfile")))>1) strcpy(out_cracked_file,json_object_get_string(json_object_object_get(main_header_node,"outcrackedfile"))); else { free(out_cracked_file); out_cracked_file=NULL; } if (strlen(json_object_get_string(json_object_object_get(main_header_node,"outuncrackedfile")))>1) strcpy(out_uncracked_file,json_object_get_string(json_object_object_get(main_header_node,"outuncrackedfile"))); else { free(out_uncracked_file); out_uncracked_file=NULL; } strcpy(readline,json_object_get_string(json_object_object_get(main_header_node,"workdir"))); if (chdir(readline) != 0) { elog("Cannot set working directory to %s\n",readline); return hash_err; } else { hlog("Change to working directory: %s\n",readline); } hash_ret_len = json_object_get_int(json_object_object_get(main_header_node,"hashlen")); ocl_gpu_platform = json_object_get_int(json_object_object_get(main_header_node,"gpuplatform")); strcpy(hashlist_file, json_object_get_string(json_object_object_get(main_header_node,"hashlistfile"))); if (hash_plugin_is_special()) load_hashes_file(hashlist_file); switch (json_object_get_int(json_object_object_get(main_header_node,"attacktype"))) { case attack_method_simple_bruteforce: attack_header_node = json_object_object_get(root_node,"bruteforce"); bruteforce_start=json_object_get_int(json_object_object_get(attack_header_node,"start")); bruteforce_end=json_object_get_int(json_object_object_get(attack_header_node,"end")); strcpy(bruteforce_charset, json_object_get_string(json_object_object_get(attack_header_node,"charset"))); attack_current_count = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"currentcount"))); attack_overall_count = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"overallcount"))); break; case attack_method_markov: attack_header_node = json_object_object_get(root_node,"markov"); strcpy(markov_statfile,json_object_get_string(json_object_object_get(attack_header_node,"statfile"))); markov_threshold = json_object_get_int(json_object_object_get(attack_header_node,"threshold")); markov_max_len = json_object_get_int(json_object_object_get(attack_header_node,"maxlen")); attack_current_count = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"currentcount"))); attack_overall_count = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"overallcount"))); break; case attack_method_rule: attack_header_node = json_object_object_get(root_node,"rule"); rule_file=malloc(strlen(json_object_get_string(json_object_object_get(attack_header_node,"rulefile")))+1); strcpy(rule_file,json_object_get_string(json_object_object_get(attack_header_node,"rulefile"))); rule_current_elem = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"currentelem"))); rule_overall_elem = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"overall"))); attack_current_count = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"currentcount"))); attack_overall_count = (uint64_t)atoll(json_object_get_string(json_object_object_get(attack_header_node,"overallcount"))); break; default: elog("Unknown attack type%s!\n",""); return hash_err; break; } if (hash_plugin_is_special() == 0) { hash_list_node = json_object_object_get(root_node,"hashlist"); flag = json_object_array_length(hash_list_node); for (cnt=0;cnt<flag;cnt++) { jobj = json_object_array_get_idx(hash_list_node, cnt); strcpy(username, json_object_get_string(json_object_object_get(jobj,"username"))); strcpy(readline, json_object_get_string(json_object_object_get(jobj,"hash"))); hex2str(hash, readline, hash_ret_len*2); strcpy(salt, json_object_get_string(json_object_object_get(jobj,"salt"))); if (add_hash_list(username, hash, salt, "") == hash_err) { wlog("Wrong session file hashlist (corrupted session file?)%s\n",""); exit(EXIT_FAILURE); } } if (flag<1) load_hashes_file(hashlist_file); cracked_list_node = json_object_object_get(root_node,"crackedlist"); if (cracked_list_node) flag = json_object_array_length(cracked_list_node); if (cracked_list_node) for (cnt=0;cnt<flag;cnt++) { jobj = json_object_array_get_idx(cracked_list_node, cnt); strcpy(username, json_object_get_string(json_object_object_get(jobj,"username"))); strcpy(readline, json_object_get_string(json_object_object_get(jobj,"hash"))); hex2str(hash,readline,hash_ret_len*2); strcpy(salt, json_object_get_string(json_object_object_get(jobj,"salt"))); if (add_hash_list(username, hash, salt, "") == hash_err) { wlog("Wrong session file hashlist (corrupted session file?)%s\n",""); exit(EXIT_FAILURE); } strcpy(readline, json_object_get_string(json_object_object_get(jobj,"salt2"))); strcpy(salt2, readline); if (add_cracked_list(username, hash, salt, salt2) == hash_err) { wlog("Wrong session file hashlist (corrupted session file?)%s\n",""); exit(EXIT_FAILURE); } } } cpuonly=1; if (strstr(sessionname, "-gpu")) { cpuonly=0; /* rename session */ uid = getuid(); if (!pwd) { elog("Cannot get username for uid %d (%s)\n", (int)uid, strerror(errno)); return hash_err; } snprintf(fname, 255, "%s/.hashkill/sessions/%s.session", pwd->pw_dir, sessionname); unlink(fname); hlog("Session %s will be renamed to %d-gpu\n", sessionname, getpid()); session_restore_flag = 1; endpwent(); /* Load scheduler data */ session_load_scheduler_parameters(); return hash_ok; } /* Load scheduler data */ session_load_scheduler_parameters(); /* rename session */ uid = getuid(); pwd = getpwuid(uid); if (!pwd) { elog("Cannot get username for uid %d (%s)\n", (int)uid, strerror(errno)); return hash_err; } snprintf(fname, 255, "%s/.hashkill/sessions/%s.session", pwd->pw_dir, sessionname); unlink(fname); hlog("Session %s will be renamed to %d\n", sessionname, getpid()); session_restore_flag = 1; endpwent(); return hash_ok; #else wlog("This build does not support sessions. Please reconfigure with --with-json and rebuild%s\n",""); return hash_err; #endif }
/* Program entrypoint */ int main(int argc, char *argv[]) { unsigned long tempqueuesize=0; char *fvalue = NULL; char *dvalue = NULL; int option,option_index; int pflag=0, bflag = 0, rflag=0; int cpu_thread_factor=0; int cnt; int hash_num_threads=0; struct option long_options[] = { {"plugin-info", 2, 0, 'P'}, {"plugin", 1, 0, 'p'}, {"session-info", 2, 0, 'S'}, {"session", 1, 0, 's'}, {"hashlist", 1, 0, 'f'}, {"brute", 2, 0, 'b'}, {"outfile", 1, 0, 'o'}, {"uncrackedfile", 1, 0, 'O'}, {"markov-info", 0, 0, 'M'}, {"markov", 1, 0, 'm'}, {"markov-threshold", 1, 0, 'n'}, {"markov-limit", 1, 0, 'N'}, {"rule", 1, 0, 'r'}, {"rule-print", 1, 0, 'R'}, {"help", 0, 0, 'h'}, {"cpu", 0, 0, 'c'}, {"fast-markov",0,0,'F'}, {"gpu-threads", 1, 0, 'G'}, {"cpu-threads", 1, 0, 'C'}, {"gpu-double", 0, 0, 'D'}, {"gpu-temp", 0, 0, 'T'}, {"gpu-platform", 0, 0, 't'}, {"add-opts", 0, 0, 'a'}, {"plugin-opts", 0, 0, 'A'}, {0, 0, 0, 0} }; /* initialize */ printf("\n"); hlog("Version %s\n", PACKAGE_VERSION); session_restore_flag = 0; hash_plugin_parse_hash = NULL; hash_plugin_check_hash = NULL; hash_list = NULL; cracked_list = NULL; attack_method = -1; markov_attack_init(); attack_method = attack_method_markov; OpenSSL_add_all_algorithms(); fast_markov = 0; cpuonly=0; hashgen_stdout_mode=0; cnt=0; out_cracked_file=NULL; out_uncracked_file=NULL; markovstat = NULL; attack_checkpoints=0; attack_avgspeed=0; additional_options=malloc(1); additional_options[0]=0; padditional_options=malloc(1); padditional_options[0]=0; /* Detect CPU features and setup optimized routines */ if (cpu_feat_setup() == hash_err) { elog("No x86 CPU found! %s\n",""); exit(1); } while ((argv[cnt])&&(cnt<MAXARGV)) { session_argv[cnt]=malloc(strlen(argv[cnt])+1); strcpy(session_argv[cnt],argv[cnt]); cnt++; } have_ocl=0; nwthreads=0; /* Init scheduler */ scheduler_init(); ocl_user_threads=0; ocl_gpu_double=0; ocl_gpu_tempthreshold=90; ocl_gpu_platform=100; interactive_mode=0; /* Set AMD OpenCL secret envvars */ //setenv("GPU_MAX_ALLOC_PERCENT","100",1); //setenv("GPU_USE_SYNC_OBJECTS","1",1); // Bug in AMD Catalyst 13.4 setenv("GPU_FLUSH_ON_EXECUTION","1",1); /* See if someone tried to pipe to stdin */ detect_pipe(); disable_term_linebuffer(); #ifndef HAVE_JSON_JSON_H wlog("This hashkill build has session save/restore support disabled. Please reconfigure with --with-json and rebuild\n%s",""); #endif /* now store the command line parameters to be used by sessions module */ attack_over = 0; ctrl_c_pressed=0; session_put_commandline(argv); /* install SIGINT handler */ signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); opterr = 0; while ((option = getopt_long(argc, argv, "p:f:d:P::b::t:T:S::s:o:O:N:n:M::m:hicFDG:C:a:T:r:RA:",long_options, &option_index)) != -1) switch (option) { case 'r': if (optarg) { hlog("Rule based attack, using rule:%s\n",optarg); attack_method = attack_method_rule; rflag=1; rule_file=alloca(1024); strcpy(rule_file,optarg); } else { usage(argv[0]); exit(EXIT_FAILURE); } rflag = 1; break; case 'R': hashgen_stdout_mode=1; break; case 'h': usage(argv[0]); exit(EXIT_SUCCESS); break; case 'G': ocl_user_threads = atoi(optarg); if (ocl_user_threads>8) ocl_user_threads = 0; break; case 'C': cpu_thread_factor = atoi(optarg); if ((cpu_thread_factor>256)||(cpu_thread_factor<1)) cpu_thread_factor=16; break; case 's': if (!optarg) { usage(argv[0]); exit(EXIT_FAILURE); } else { if (session_restore(optarg) == hash_err) exit(EXIT_FAILURE); pflag = 1; } break; case 'P': if (!optarg) (void)print_plugins_summary(DATADIR"/hashkill/plugins"); else print_plugin_detailed(optarg); exit(EXIT_SUCCESS); break; case 'a': free(padditional_options); padditional_options = malloc(strlen(optarg)+1); strcpy(padditional_options,optarg); process_addopts(optarg); break; case 'A': free(additional_options); additional_options = malloc(strlen(optarg)+1); strcpy(additional_options,optarg); break; case 'c': cpuonly = 1; break; case 'i': hlog("interactive mode turned on!%s\n",""); interactive_mode = 1; break; case 'F': fast_markov = 1; break; case 'T': ocl_gpu_tempthreshold=atoi(optarg); break; case 'b': if (optarg) { if (parse_bruteforce_args(optarg) == hash_err) { exit(EXIT_FAILURE); } } else { char *tempopt = NULL; tempopt = malloc(100); strcpy(tempopt,"1:8:lalphanum:"); if (parse_bruteforce_args(tempopt) == hash_err) { free(tempopt); exit(EXIT_FAILURE); } free(tempopt); hlog("Using 1:8:lalpha defaults. Use -b<params> (no whitespaces) to specify them%s\n",""); } bflag = 1; break; case 'm': if (optarg) { if (markov_load_statfile(optarg) == hash_err) { exit(EXIT_FAILURE); } else { markovstat = malloc(64); strcpy(markovstat,optarg); attack_method = attack_method_markov; } } else { usage(argv[0]); exit(EXIT_FAILURE); } break; case 'S': if (!optarg) (void)print_sessions_summary(); else print_session_detailed(optarg); exit(EXIT_SUCCESS); break; case 'p': set_current_plugin(optarg); if (load_plugin()==hash_err) { elog("Cannot load plugin (%s)\n",optarg); exit(EXIT_FAILURE); } pflag=1; break; case 'N': markov_max_len = atoi(optarg); break; case 'D': ocl_gpu_double = 1; //setenv("GPU_MAX_HEAP_SIZE", "196", 1); hlog("Using GPU double mode\n%s",""); break; case 'n': markov_threshold = atoi(optarg); break; case 't': ocl_gpu_platform = atoi(optarg); break; case 'M': markov_print_statfiles(); exit(EXIT_SUCCESS); break; case 'f': fvalue = optarg; break; case 'd': dvalue = optarg; break; case 'o': out_cracked_file=malloc(strlen(optarg)+1); strcpy(out_cracked_file,optarg); break; case 'O': out_uncracked_file=malloc(strlen(optarg)+1); strcpy(out_uncracked_file,optarg); break; case '?': if ((optopt == 'f') || (optopt == 'P') || (optopt == 'd')) { fprintf(stderr, "Option -%c requires an argument.\n", optopt); } default: break; } /* First check if out_cracked_file and out_uncracked_file are good */ if (out_cracked_file) if (hash_err == check_out_file(out_cracked_file)) exit(1); if (out_uncracked_file) if (hash_err == check_out_file(out_uncracked_file)) exit(1); if (fvalue) { strncpy(hashlist_file,fvalue,254); hashlist_file[254] = 0; if (pflag==0) { if (detect_plugin(DATADIR"/hashkill/plugins",hashlist_file,NULL) == hash_err) { elog("Cannot detect hash type%s\n",""); exit(EXIT_FAILURE); } } (void)load_hashes_file(fvalue); } /* Do we have argument (hash)? */ if (argv[optind]) { if (pflag==0) { if (detect_plugin(DATADIR"/hashkill/plugins",NULL,argv[optind])==hash_err) { elog("Cannot detect hash type%s\n",""); exit(EXIT_FAILURE); } } strncpy(hash_cmdline,argv[optind],HASHFILE_MAX_LINE_LENGTH); if (load_single_hash(hash_cmdline) == hash_err) { if (!fvalue) { elog("Cannot load hash: %s\n",argv[optind]); exit(EXIT_FAILURE); } } } if (strcmp(get_current_plugin(),"bitcoin")!=0) { /* Hashes num */ hashes_count = get_hashes_num(); /* Bruteforce? */ if ((bflag)&&(!dvalue)&&(!rflag)) { fast_markov = 0; // do not mess with the charset in the opencl code attack_method = attack_method_simple_bruteforce; } /* sl3 plugin is an exception: bruteforce only! */ if (strcmp(get_current_plugin(),"sl3")==0) { attack_method = attack_method_simple_bruteforce; } if ((attack_method != attack_method_simple_bruteforce) && ((attack_method != attack_method_markov)) && (attack_method != attack_method_rule)) { usage(argv[0]); exit(EXIT_FAILURE); } /* threads sizing */ if ((get_hashes_num() == 0)&&(hashgen_stdout_mode==0)) { elog("No hashes loaded!%s (try --help)\n",""); exit(EXIT_FAILURE); } if (cpu_thread_factor==0) { hash_num_threads = hash_num_cpu(); } else hash_num_threads = cpu_thread_factor; } else attack_method = attack_method_simple_bruteforce; time1=time(NULL); /* CPU optimize single hacks */ if (strcmp(get_current_plugin(),"md5")==0) { if ((attack_method==attack_method_simple_bruteforce)&&(bruteforce_end>7)) cpu_optimize_single=2; else if ((attack_method==attack_method_markov)&&(markov_max_len>7)) cpu_optimize_single=2; } if ((hash_list)&&(hash_list->next)) cpu_optimize_single=0; have_ocl = initialize_opencl(); if ((have_ocl==hash_ok)&&(cpuonly==0)) have_ocl = ocl_get_device(); if (cpuonly==1) { wlog("GPU acceleration available, but -c option was provided. Running on CPUs would likely be slower.\n%s",""); } /* Markov? */ if (attack_method == attack_method_markov) { if (!markovstat) { markov_load_statfile("rockyou"); markovstat = malloc(64); strcpy(markovstat,"rockyou"); } if ((cpuonly==0) && (have_ocl == hash_ok)) { if ((ocl_markov() != hash_ok) && (attack_over==0)) { if (tempqueuesize > HASHKILL_MAXQUEUESIZE) tempqueuesize = HASHKILL_MAXQUEUESIZE; (void)main_thread_markov(hash_num_threads); } } else main_thread_markov(hash_num_threads); } /* Rule-based */ if (attack_method == attack_method_rule) { if (hash_err==rule_preprocess(rule_file)) {exit(1);} if ((cpuonly==0) && (have_ocl == hash_ok)) { if ((ocl_rule() != hash_ok) && (attack_over==0)) { nwthreads = hash_num_threads; if (tempqueuesize > HASHKILL_MAXQUEUESIZE) tempqueuesize = HASHKILL_MAXQUEUESIZE; main_thread_rule(hash_num_threads); } } else main_thread_rule(hash_num_threads); } /* Bruteforce? */ if (attack_method == attack_method_simple_bruteforce) { if (strcmp(get_current_plugin(),"bitcoin")!=0) hlog("Bruteforce charset (size=%d): %s\n",strlen(bruteforce_charset),bruteforce_charset); if ((have_ocl == hash_ok) && (cpuonly==0)) { if ( (ocl_bruteforce() != hash_ok) && (attack_over==0)) { if (tempqueuesize > HASHKILL_MAXQUEUESIZE) tempqueuesize = HASHKILL_MAXQUEUESIZE; (void)main_thread_bruteforce(hash_num_threads); } } else main_thread_bruteforce(hash_num_threads); } /* We delete session file ONLY when attack is over */ if (ctrl_c_pressed==0) { session_unlink_file(); if (have_ocl==hash_ok) session_unlink_file_ocl(); } if (get_cracked_num() > 0) print_cracked_list(); if (out_cracked_file) { print_cracked_list_to_file(out_cracked_file); } if ((hash_plugin_is_special)&&(hash_plugin_is_special()==0)) { if (out_uncracked_file) { print_uncracked_list_to_file(out_uncracked_file); } } time2=time(NULL); printf("\n"); hlog("Attack took %u seconds.\n",(unsigned int)(time2-time1)); hlog("Bye bye :)\n\n%s",""); // thread_attack_cleanup(); // cleanup_lists(); return 0; }