public void Add(string session, string hash, string text, HashingMethod method) { using (var reader = ExecReader (SELECT_COLLISION_ID, hash.ToSQLiteParam ("@hash"))) { if (!reader.HasRows) { ExecNonQuery ( INSERT_COLLISION, hash.ToSQLiteParam ("@hash"), text.ToSQLiteParam ("@text"), session.ToSQLiteParam ("@session"), method.Algorithm.ToString ().ToSQLiteParam ("@type") ); } else { using (var reader2 = ExecReader (SELECT_SESSION_ID, session.ToSQLiteParam ("@session"))) { if (!reader2.HasRows) { ExecNonQuery ( INSERT_COLLISION_FROM_SESSION, session.ToSQLiteParam ("@session"), hash.ToSQLiteParam ("@hash") ); } } } } }
public void Add(string session, string hash, string text, HashingMethod method) { using (var reader = ExecReader(SELECT_COLLISION_ID, hash.ToSQLiteParam("@hash"))) { if (!reader.HasRows) { ExecNonQuery( INSERT_COLLISION, hash.ToSQLiteParam("@hash"), text.ToSQLiteParam("@text"), session.ToSQLiteParam("@session"), method.Algorithm.ToString().ToSQLiteParam("@type") ); } else { using (var reader2 = ExecReader(SELECT_SESSION_ID, session.ToSQLiteParam("@session"))) { if (!reader2.HasRows) { ExecNonQuery( INSERT_COLLISION_FROM_SESSION, session.ToSQLiteParam("@session"), hash.ToSQLiteParam("@hash") ); } } } } }
public static void Run(string[] hashes, HashingMethod method, string alphabet, int length = 6) { #if LIBNOTIFYNET Notification.Send ("Hashlecter", "Started bruteforce attack.", 5000); #endif // Stopwatch for measuring time var watch = Stopwatch.StartNew (); if (!MainClass.options.silent) { // Update_Screen task var update = Task.Factory.StartNew (() => Update_Screen (watch)); // Update_Stats task var update_avg = Task.Factory.StartNew (Update_Stats); } string output; var alphabet_first = alphabet.First (); var alphabet_last = alphabet.Last (); for (var ihash = 0; ihash < hashes.Length; ihash++) { // Skip comments if (hashes [ihash].StartsWith ("#")) continue; current_hash = hashes [ihash]; // Incremental bruteforce if (MainClass.options.incremental) { // Calculate maximum for (var i = 1; i <= length; i++) bruteforce_max += Math.Pow (i, alphabet.Length); for (var curlen = 1; curlen <= length; ++curlen) { // Initialize buffer var accum = new StringBuilder (new String (alphabet_first, curlen)); while (true) { ++generated; ++avg_tmp; var value = accum.ToString (); current_str = value; var success = method.CheckHash (current_hash, value, out output); if (success) { ++cracked; MainClass.db.Add (MainClass.session, current_hash, value, method); #if LIBNOTIFYNET var _libnotifynet_format = string.Format ("Successfully cracked {0} hash:\n{1}\nValue was: {2}", method.Name, current_hash, output); Notification.Send ("Hashlecter", _libnotifynet_format, 7500, 250, 100); #endif done = true; goto end; } if (value.All (val => val == alphabet_last)) break; // TODO: Parallelize this for (var i = curlen - 1; i >= 0; --i) { if (accum [i] != alphabet_last) { accum [i] = alphabet [alphabet.IndexOf (accum [i]) + 1]; break; } else accum [i] = alphabet_first; } } } } // Fixed-length bruteforce else { // Calculated maximum bruteforce_max = Math.Pow (length, alphabet.Length); // Initialize buffer var accum = new StringBuilder (new String (alphabet_first, length)); while (true) { ++generated; ++avg_tmp; var value = accum.ToString (); current_str = value; var success = method.CheckHash (current_hash, value, out output); if (success) { ++cracked; MainClass.db.Add (MainClass.session, current_hash, value, method); #if LIBNOTIFYNET var _libnotifynet_format = string.Format ("Successfully cracked {0} hash:\n{1}\nValue was: {2}", method.Name, current_hash, output); Notification.Send ("Hashlecter", _libnotifynet_format, 7500, 250, 100); #endif done = true; goto end; } if (value.All (val => val == alphabet_last)) break; // TODO: Parallelize this for (var i = length - 1; i >= 0; --i) { if (accum [i] != alphabet_last) { accum [i] = alphabet [alphabet.IndexOf (accum [i]) + 1]; break; } else accum [i] = alphabet_first; } } } end: {} } watch.Stop (); // Display the correct stats after exiting if (!MainClass.options.silent) { Update_Screen (watch, force: true); } }
public static void Run(string[] hashes, HashingMethod method, string dictionary_path) { #if LIBNOTIFYNET Notification.Send("Hashlecter", "Started dictionary attack.", 5000); #endif // Dictionary buffer string[] dict = new string[BUFFER_SZ]; // Stopwatch for measuring time var watch = Stopwatch.StartNew(); if (!MainClass.options.silent) { // Update_Screen task var update = Task.Factory.StartNew(() => Update_Screen(watch)); // Update_Stats task var update_avg = Task.Factory.StartNew(Update_Stats); } // Open dictionary file for reading using (var fdict = File.OpenRead(dictionary_path)) using (var reader = new StreamReader(fdict)) { // Iterate over all hashes in the array for (var i = 0; i < hashes.Length; i++) { // Skip comments if (hashes[i].StartsWith("#")) { continue; } current_hash = hashes[i]; // Check if there is still something in the dictionary to read while (reader.BaseStream.Position < reader.BaseStream.Length) { // Iterate over all values in [0..BUFFER_SZ] for (var j = 0; j < BUFFER_SZ; j++) { // Add the next line from the dictionary to the buffer dict[j] = reader.ReadLine(); // Increment the loaded variable if the line is valid if (dict[j] != null) { dict[j] = dict[j].Replace("\r", ""); loaded++; } } var breakout = false; // Use parallel processing to iterate over all entries in the dictionary buffer Parallel.ForEach <string> (dict, (dict_entry, loopstate_inner) => { // Get the current hash var hash = hashes[i]; // Create a variable for storing the output (if valid) string output; // Get the current dictionary entry // (for the Update_Screen task) dict_current = dict_entry; // Try to collide the hashes var success = method.CheckHash(hash, dict_entry, out output); // Increment the statistically relevant variables ++processed; ++avg_tmp; // Check if the collision succeeded if (success) { // Increment the amount of successfully collided hashes // (for the Update_Screen task) ++cracked; // Add the collision to the database MainClass.db.Add(MainClass.session, hash, output, method); #if LIBNOTIFYNET var _libnotifynet_format = string.Format("Successfully cracked {0} hash:\n{1}\nValue was: {2}", method.Name, hash, output); Notification.Send("Hashlecter", _libnotifynet_format, 7500, 250, 100); #endif if (!MainClass.options.exp_single_cont) { // Break out of the loop breakout = true; loopstate_inner.Stop(); } } }); if (breakout) { break; } } // Reset the dictionary position to 0 // for processing the next hash reader.BaseStream.Position = 0; // Reset the loaded = 0; } // We're done! // Tell all tasks to stop done = true; watch.Stop(); } // Display the correct stats after exiting if (!MainClass.options.silent) { Update_Screen(watch, force: true); } }
// // This is an experimental method. // Enable using the --exp-lazy-eval switch // public static void RunLazy(string[] hashes, HashingMethod method, string dictionary_path) { // Dictionary buffer IEnumerable <string> dict; // Stopwatch for measuring time var watch = Stopwatch.StartNew(); if (!MainClass.options.silent) { // Update_Screen task var update = Task.Factory.StartNew(() => Update_Screen(watch)); // Update_Stats task var update_avg = Task.Factory.StartNew(Update_Stats); } // Lazy approach var dictionary = File.ReadLines(dictionary_path); var dictionary_pos = 0; var dictionary_count = dictionary.Count(); // Iterate over all hashes in the array for (var i = 0; i < hashes.Length; i++) { // Skip comments if (hashes[i].StartsWith("#")) { continue; } current_hash = hashes[i]; //while (dictionary_pos <= dictionary_count) { while (dictionary_pos < dictionary_count) { dict = dictionary.Skip(dictionary_pos).Take(BUFFER_SZ); dictionary_pos += BUFFER_SZ; loaded = dictionary_pos; var breakout = false; // Use parallel processing to iterate over all entries in the dictionary buffer Parallel.ForEach <string> (dict, (dict_entry, loopstate_inner) => { // Get the current hash var hash = hashes[i]; // Create a variable for storing the output (if valid) string output; // Get the current dictionary entry // (for the Update_Screen task) dict_current = dict_entry; // Try to collide the hashes var success = method.CheckHash(hash, dict_entry, out output); // Increment the statistically relevant variables ++processed; ++avg_tmp; // Check if the collision succeeded if (success) { // Increment the amount of successfully collided hashes // (for the Update_Screen task) ++cracked; // Add the collision to the database MainClass.db.Add(MainClass.session, hash, output, method); // Break out of the loop breakout = true; loopstate_inner.Stop(); } }); if (breakout) { break; } } dictionary_pos = 0; } done = true; watch.Stop(); // Display the correct stats after exiting if (!MainClass.options.silent) { Update_Screen(watch, force: true); } }
/// <summary> /// The entry point of the program, where the program control starts and ends. /// </summary> /// <param name="args">The command-line arguments.</param> public static void Main(string[] args) { foreach (var x in args) { Console.WriteLine(x); } // Create a hashset for storing the hashing methods methods = new HashSet <HashingMethod> { #if MD5 HashingMethod.New <hMD5> (), HashingMethod.New <hMD5_Double> (), HashingMethod.New <hMD5_Salted> (), HashingMethod.New <hMD5_Salted2> (), HashingMethod.New <hMD5_MyBB> (), #endif #if SHA1 HashingMethod.New <hSHA1> (), HashingMethod.New <hSHA1_Double> (), #endif #if SHA256 HashingMethod.New <hSHA256> (), HashingMethod.New <hSHA256_Double> (), #endif #if SHA384 HashingMethod.New <hSHA384> (), #endif #if SHA512 HashingMethod.New <hSHA512> (), #endif #if RIPEMD160 HashingMethod.New <hRIPEMD160> (), #endif #if WHIRLPOOL HashingMethod.New <hWhirlpool> (), #endif #if JHASH HashingMethod.New <hJHash> (), #endif }; // Parse command-line arguments using libArgument options = ArgumentParser.Parse <Options> (args); // Use wizard if lecter was started directly options.wizard |= args.Length == 0; // Get or create a session identifier session = string.IsNullOrEmpty(options.session) ? GenerateSession() : options.session; // Connect to the SQLite database db = Database.Factory.CreateSQLite(SQLITE_DB); // Return if the user just wanted to make // sure that the db got created if (options.create_db) { Environment.Exit(0); } // Display help else if (options.help) { PreHelp(); ArgumentParser.Help(); Help(); Environment.Exit(0); } // Show all the cracked hashes else if (options.show) { db.Show(string.IsNullOrEmpty(options.session) ? string.Empty : session); Environment.Exit(0); } // Call the magician else if (options.wizard) { Wizard(); } // Null-check the method if (string.IsNullOrEmpty(options.method)) { // Fall back to MD5 options.method = "md5"; } // Get the method used for cracking the hashes var method = methods.FirstOrDefault(m => m.Name == options.method.ToLowerInvariant()); // Check if the cracking method is valid if (method == null || method == default(HashingMethod)) { Console.Error.WriteLine("Please specify a valid hashing method."); Console.Error.WriteLine("Run lecter --help to get a list of valid hashing methods."); Environment.Exit(0); } // Check if we need to generate a hash if (options.gen) { // Read input string from -i/--input argument if (!string.IsNullOrEmpty(options.input_file)) { Console.WriteLine(method.Hash(options.input_file)); } // Hash an empty string if no string is given else { Console.WriteLine(method.Hash(string.Empty)); } // Exit Environment.Exit(0); } string[] input_hashes = null; // Grab input from stdin if (options.input_stdin) { input_hashes = FromStdin(); } // Grab input from file else if (!string.IsNullOrEmpty(options.input_file)) { input_hashes = FromFile(options.input_file); } // Perform dictionary attack if (!string.IsNullOrEmpty(options.input_dict)) { // Null-check the input file if (input_hashes == null) { Console.Error.WriteLine("No input was specified."); Environment.Exit(0); } // Experimental lazy evaluation if (options.exp_lazy_eval) { DictionaryAttack.RunLazy(input_hashes, method, options.input_dict); } // Stable evaluation else { DictionaryAttack.Run(input_hashes, method, options.input_dict); } } // Perform bruteforce attack else { // Null-check the input file if (input_hashes == null) { Console.Error.WriteLine("No input was specified."); Environment.Exit(0); } string default_alphabet = BruteforceAttack.NUMERIC + BruteforceAttack.LOWER_ALPHANUMERIC; if (options.len == 0) { options.len = 6; } if (!string.IsNullOrEmpty(options.alphabet)) { // Build alphabet var alphabet = options.alphabet .Replace("$$", "\0") .Replace("$n", BruteforceAttack.NUMERIC) .Replace("$l", BruteforceAttack.LOWER_ALPHANUMERIC) .Replace("$u", BruteforceAttack.UPPER_ALPHANUMERIC) .Replace("$s+", BruteforceAttack.SPECIAL_ADVANCED) .Replace("$s", BruteforceAttack.SPECIAL_BASIC) .Replace("\0", "$") .ToList(); options.alphabet = new string (alphabet.ToArray()); } else { options.alphabet = default_alphabet; } BruteforceAttack.Run(input_hashes, method, options.alphabet, options.len); } if (!options.silent) { db.Show(session); if (options.wizard) { Console.Read(); } } #if LIBNOTIFYNET Task.Factory.StartNew(() => { NotificationManager.Instance.ShutdownWait(); }).Wait(7500); #endif }
public static void Run(string[] hashes, HashingMethod method, string dictionary_path) { #if LIBNOTIFYNET Notification.Send ("Hashlecter", "Started dictionary attack.", 5000); #endif // Dictionary buffer string[] dict = new string[BUFFER_SZ]; // Stopwatch for measuring time var watch = Stopwatch.StartNew (); if (!MainClass.options.silent) { // Update_Screen task var update = Task.Factory.StartNew (() => Update_Screen (watch)); // Update_Stats task var update_avg = Task.Factory.StartNew (Update_Stats); } // Open dictionary file for reading using (var fdict = File.OpenRead (dictionary_path)) using (var reader = new StreamReader (fdict)) { // Iterate over all hashes in the array for (var i = 0; i < hashes.Length; i++) { // Skip comments if (hashes[i].StartsWith ("#")) continue; current_hash = hashes[i]; // Check if there is still something in the dictionary to read while (reader.BaseStream.Position < reader.BaseStream.Length) { // Iterate over all values in [0..BUFFER_SZ] for (var j = 0; j < BUFFER_SZ; j++) { // Add the next line from the dictionary to the buffer dict[j] = reader.ReadLine (); // Increment the loaded variable if the line is valid if (dict[j] != null) { dict[j] = dict[j].Replace ("\r", ""); loaded++; } } var breakout = false; // Use parallel processing to iterate over all entries in the dictionary buffer Parallel.ForEach<string> (dict, (dict_entry, loopstate_inner) => { // Get the current hash var hash = hashes[i]; // Create a variable for storing the output (if valid) string output; // Get the current dictionary entry // (for the Update_Screen task) dict_current = dict_entry; // Try to collide the hashes var success = method.CheckHash (hash, dict_entry, out output); // Increment the statistically relevant variables ++processed; ++avg_tmp; // Check if the collision succeeded if (success) { // Increment the amount of successfully collided hashes // (for the Update_Screen task) ++cracked; // Add the collision to the database MainClass.db.Add (MainClass.session, hash, output, method); #if LIBNOTIFYNET var _libnotifynet_format = string.Format ("Successfully cracked {0} hash:\n{1}\nValue was: {2}", method.Name, hash, output); Notification.Send ("Hashlecter", _libnotifynet_format, 7500, 250, 100); #endif if (!MainClass.options.exp_single_cont) { // Break out of the loop breakout = true; loopstate_inner.Stop (); } } }); if (breakout) break; } // Reset the dictionary position to 0 // for processing the next hash reader.BaseStream.Position = 0; // Reset the loaded = 0; } // We're done! // Tell all tasks to stop done = true; watch.Stop (); } // Display the correct stats after exiting if (!MainClass.options.silent) { Update_Screen (watch, force: true); } }
// // This is an experimental method. // Enable using the --exp-lazy-eval switch // public static void RunLazy(string[] hashes, HashingMethod method, string dictionary_path) { // Dictionary buffer IEnumerable<string> dict; // Stopwatch for measuring time var watch = Stopwatch.StartNew (); if (!MainClass.options.silent) { // Update_Screen task var update = Task.Factory.StartNew (() => Update_Screen (watch)); // Update_Stats task var update_avg = Task.Factory.StartNew (Update_Stats); } // Lazy approach var dictionary = File.ReadLines (dictionary_path); var dictionary_pos = 0; var dictionary_count = dictionary.Count (); // Iterate over all hashes in the array for (var i = 0; i < hashes.Length; i++) { // Skip comments if (hashes[i].StartsWith ("#")) continue; current_hash = hashes[i]; //while (dictionary_pos <= dictionary_count) { while (dictionary_pos < dictionary_count) { dict = dictionary.Skip (dictionary_pos).Take (BUFFER_SZ); dictionary_pos += BUFFER_SZ; loaded = dictionary_pos; var breakout = false; // Use parallel processing to iterate over all entries in the dictionary buffer Parallel.ForEach<string> (dict, (dict_entry, loopstate_inner) => { // Get the current hash var hash = hashes[i]; // Create a variable for storing the output (if valid) string output; // Get the current dictionary entry // (for the Update_Screen task) dict_current = dict_entry; // Try to collide the hashes var success = method.CheckHash (hash, dict_entry, out output); // Increment the statistically relevant variables ++processed; ++avg_tmp; // Check if the collision succeeded if (success) { // Increment the amount of successfully collided hashes // (for the Update_Screen task) ++cracked; // Add the collision to the database MainClass.db.Add (MainClass.session, hash, output, method); // Break out of the loop breakout = true; loopstate_inner.Stop (); } }); if (breakout) break; } dictionary_pos = 0; } done = true; watch.Stop (); // Display the correct stats after exiting if (!MainClass.options.silent) { Update_Screen (watch, force: true); } }
public static void Run(string[] hashes, HashingMethod method, string alphabet, int length = 6) { #if LIBNOTIFYNET Notification.Send("Hashlecter", "Started bruteforce attack.", 5000); #endif // Stopwatch for measuring time var watch = Stopwatch.StartNew(); if (!MainClass.options.silent) { // Update_Screen task var update = Task.Factory.StartNew(() => Update_Screen(watch)); // Update_Stats task var update_avg = Task.Factory.StartNew(Update_Stats); } string output; var alphabet_first = alphabet.First(); var alphabet_last = alphabet.Last(); for (var ihash = 0; ihash < hashes.Length; ihash++) { // Skip comments if (hashes [ihash].StartsWith("#")) { continue; } current_hash = hashes [ihash]; // Incremental bruteforce if (MainClass.options.incremental) { // Calculate maximum for (var i = 1; i <= length; i++) { bruteforce_max += Math.Pow(i, alphabet.Length); } for (var curlen = 1; curlen <= length; ++curlen) { // Initialize buffer var accum = new StringBuilder(new String(alphabet_first, curlen)); while (true) { ++generated; ++avg_tmp; var value = accum.ToString(); current_str = value; var success = method.CheckHash(current_hash, value, out output); if (success) { ++cracked; MainClass.db.Add(MainClass.session, current_hash, value, method); #if LIBNOTIFYNET var _libnotifynet_format = string.Format("Successfully cracked {0} hash:\n{1}\nValue was: {2}", method.Name, current_hash, output); Notification.Send("Hashlecter", _libnotifynet_format, 7500, 250, 100); #endif done = true; goto end; } if (value.All(val => val == alphabet_last)) { break; } // TODO: Parallelize this for (var i = curlen - 1; i >= 0; --i) { if (accum [i] != alphabet_last) { accum [i] = alphabet [alphabet.IndexOf(accum [i]) + 1]; break; } else { accum [i] = alphabet_first; } } } } } // Fixed-length bruteforce else { // Calculated maximum bruteforce_max = Math.Pow(length, alphabet.Length); // Initialize buffer var accum = new StringBuilder(new String(alphabet_first, length)); while (true) { ++generated; ++avg_tmp; var value = accum.ToString(); current_str = value; var success = method.CheckHash(current_hash, value, out output); if (success) { ++cracked; MainClass.db.Add(MainClass.session, current_hash, value, method); #if LIBNOTIFYNET var _libnotifynet_format = string.Format("Successfully cracked {0} hash:\n{1}\nValue was: {2}", method.Name, current_hash, output); Notification.Send("Hashlecter", _libnotifynet_format, 7500, 250, 100); #endif done = true; goto end; } if (value.All(val => val == alphabet_last)) { break; } // TODO: Parallelize this for (var i = length - 1; i >= 0; --i) { if (accum [i] != alphabet_last) { accum [i] = alphabet [alphabet.IndexOf(accum [i]) + 1]; break; } else { accum [i] = alphabet_first; } } } } end : {} } watch.Stop(); // Display the correct stats after exiting if (!MainClass.options.silent) { Update_Screen(watch, force: true); } }