From cc42786833022a44f7cbd1e11e0d3e2a66be3bb6 Mon Sep 17 00:00:00 2001 From: blue Date: Thu, 15 Aug 2019 21:29:27 +0100 Subject: [PATCH 1/5] Use a PSCredential to run remote console Stop credentials appearing on the command line. --- SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs b/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs index 8bfac75..1d712e4 100644 --- a/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs +++ b/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs @@ -810,13 +810,23 @@ private void btOpenPSConsole_Click(object sender, RoutedEventArgs e) string sPS = string.Format(Properties.Settings.Default.OpenPSConsoleCommand, oAgent.TargetHostname, tb_wsmanport.Text); if (!string.IsNullOrEmpty(tb_Username.Text)) { - sCred = string.Format("$creds = New-Object System.Management.Automation.PSCredential ('{0}', (ConvertTo-SecureString '{1}' -AsPlainText -Force))", tb_Username.Text, common.Decrypt(pb_Password.Password, Application.ResourceAssembly.ManifestModule.Name)) + ";"; + System.Security.SecureString passwordString = new System.Security.SecureString(); + foreach (char c in common.Decrypt(pb_Password.Password, Application.ResourceAssembly.ManifestModule.Name).ToCharArray()) + { + passwordString.AppendChar(c); + } + System.Management.Automation.PSCredential credential = new System.Management.Automation.PSCredential(tb_Username.Text, passwordString); + sCred = System.Management.Automation.PSSerializer.Serialize(credential); + string filename = System.IO.Path.GetTempFileName(); + File.WriteAllText(filename, sCred); + string creds = "(Import-Clixml " + filename + ")"; + //creds += "; rm " + filename; if ((bool)cb_ssl.IsChecked) - Explorer.StartInfo.Arguments = @"-NoExit -Command " + sCred + sPS + " -UseSSL -Credential $creds)"; + Explorer.StartInfo.Arguments = @"-NoExit -Command " + sPS + " -UseSSL -Credential " + creds; else - Explorer.StartInfo.Arguments = @"-NoExit -Command " + sCred + sPS + " -Credential $creds"; + Explorer.StartInfo.Arguments = @"-NoExit -Command " + sPS + " -Credential " + creds; } else From d967248f2cc05517d2dab3ac7cdee2410a84a0b6 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 17 Aug 2019 00:07:42 +0100 Subject: [PATCH 2/5] Use only SecureStrings for passwords internally `new SCCMAgent()` still requires a string, so one is present there. This needs to be resolved in sccmclictrlib first. --- SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs | 21 ++++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs b/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs index 1d712e4..e1e3703 100644 --- a/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs +++ b/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs @@ -265,9 +265,6 @@ public MainPage() } catch { } - pb_Password.Password = Properties.Settings.Default.Password; - tb_Username.Text = Properties.Settings.Default.Username; - Common.Hostname = tb_TargetComputer.Text.Trim(); try @@ -319,7 +316,9 @@ public MainPage() if (!string.IsNullOrEmpty(sUser) && !string.IsNullOrEmpty(sPW)) { tb_Username.Text = sUser; - pb_Password.Password = common.Encrypt(sPW, Application.ResourceAssembly.ManifestModule.Name); + Properties.Settings.Default.Username = tb_Username.Text; //Binding is not yet syncing these, so do it manually. + pb_Password.Password = sPW; //Not ideal but works + //pb_Password.SecurePassword is read-only so another variable with one-way binding is required. sUser = ""; sPW = ""; } @@ -477,7 +476,7 @@ private void bt_Connect_Click(object sender, RoutedEventArgs e) { Properties.Settings.Default.Password = common.Encrypt(pb_Password.Password, Application.ResourceAssembly.ManifestModule.Name); Properties.Settings.Default.Save(); - pb_Password.Password = Properties.Settings.Default.Password; + //pb_Password.Password = Properties.Settings.Default.Password; bPasswordChanged = false; } @@ -506,7 +505,7 @@ private void bt_Connect_Click(object sender, RoutedEventArgs e) { if (sTarget != "127.0.0.1") { - if (string.IsNullOrEmpty(tb_Username.Text) | string.IsNullOrEmpty(pb_Password.Password)) + if (string.IsNullOrEmpty(tb_Username.Text) | pb_Password.SecurePassword.Length == 0) { MessageBox.Show("connecting an IP Address requires Username and Password", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); } @@ -527,7 +526,8 @@ private void bt_Connect_Click(object sender, RoutedEventArgs e) { tb_Username.Text = Environment.UserDomainName + @"\" + tb_Username.Text; } - string sPW = common.Decrypt(pb_Password.Password, Application.ResourceAssembly.ManifestModule.Name); + //Hack to handle switing over to securestrings while sccmclictrlib only takes strings. Obviously this defeats the point of SecureStrings. + string sPW = new System.Net.NetworkCredential(string.Empty, pb_Password.SecurePassword).Password; oAgent = new SCCMAgent(sTarget, tb_Username.Text, sPW, int.Parse(tb_wsmanport.Text), false, cb_ssl.IsChecked ?? false); sPW = ""; } @@ -810,12 +810,7 @@ private void btOpenPSConsole_Click(object sender, RoutedEventArgs e) string sPS = string.Format(Properties.Settings.Default.OpenPSConsoleCommand, oAgent.TargetHostname, tb_wsmanport.Text); if (!string.IsNullOrEmpty(tb_Username.Text)) { - System.Security.SecureString passwordString = new System.Security.SecureString(); - foreach (char c in common.Decrypt(pb_Password.Password, Application.ResourceAssembly.ManifestModule.Name).ToCharArray()) - { - passwordString.AppendChar(c); - } - System.Management.Automation.PSCredential credential = new System.Management.Automation.PSCredential(tb_Username.Text, passwordString); + System.Management.Automation.PSCredential credential = new System.Management.Automation.PSCredential(tb_Username.Text, pb_Password.SecurePassword); sCred = System.Management.Automation.PSSerializer.Serialize(credential); string filename = System.IO.Path.GetTempFileName(); File.WriteAllText(filename, sCred); From d2db2b5f4e1c31837c59ea8187463f2b1822aa34 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 17 Aug 2019 02:30:01 +0100 Subject: [PATCH 3/5] Remove manual password change tracking WPF is now doing the important bits automatically. --- SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml | 2 +- SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml.cs | 16 +--------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml b/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml index 3a45a0c..af4fe76 100644 --- a/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml +++ b/SCCMCliCtrWPF/SCCMCliCtrWPF/MainPage.xaml @@ -51,7 +51,7 @@