From 343b8bb96b7933a40a3d4a26ef3f2f6112348ba7 Mon Sep 17 00:00:00 2001 From: makikvues Date: Sun, 7 Feb 2021 23:13:14 +0100 Subject: [PATCH] - refactoring/cleanup - added .net versions check - added PrintMappedDrivesWMI - added PrintMicrosoftUpdatesCOM - added PrintSystemLastShutdownTime - added PrintCurrentUserIdleTime - added PowerShell Core Version check - updated ListCloudCreds - updated GetMcAfeeSitelistFiles - added PrintMachineAndUserCertificateFiles --- winPEAS/winPEASexe/winPEAS/Checks/Checks.cs | 1 + .../winPEASexe/winPEAS/Checks/FilesInfo.cs | 82 +++++- .../winPEASexe/winPEAS/Checks/NetworkInfo.cs | 33 +++ .../winPEASexe/winPEAS/Checks/SystemInfo.cs | 145 ++++++++++- winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs | 30 +++ .../winPEASexe/winPEAS/Checks/WindowsCreds.cs | 1 + winPEAS/winPEASexe/winPEAS/Helpers/MyUtils.cs | 11 + .../Helpers/Registry/RegistryHelper.cs | 29 ++- .../winPEAS/Helpers/Search/SearchHelper.cs | 44 ++-- .../winPEAS/Info/ApplicationInfo/AutoRuns.cs | 1 + .../Info/ApplicationInfo/InstalledApps.cs | 1 + .../winPEAS/Info/EventsInfo/Common.cs | 2 +- .../FilesInfo/Certificates/CertificateInfo.cs | 19 ++ .../FilesInfo/Certificates/Certificates.cs | 76 ++++++ .../winPEAS/Info/FilesInfo/McAfee/McAfee.cs | 156 ++++++++++++ .../Info/FilesInfo/McAfee/McAfeeSiteInfo.cs | 37 +++ .../FilesInfo/McAfee/McAfeeSitelistInfo.cs | 19 ++ .../Info/NetworkInfo/Enums/MibTcpState.cs | 2 +- .../Structs/MIB_TCP6ROW_OWNER_PID.cs | 1 + .../Structs/MIB_TCPROW_OWNER_PID.cs | 1 + .../Info/ServicesInfo/ServicesInfoHelper.cs | 1 + .../winPEAS/Info/SystemInfo/DotNet/DotNet.cs | 71 ++++++ .../Info/SystemInfo/DotNet/DotNetInfo.cs | 37 +++ .../winPEAS/Info/SystemInfo/SysMon/SysMon.cs | 1 + .../winPEAS/Info/SystemInfo/SystemInfo.cs | 12 + .../WindowsDefenderSettings.cs | 1 + .../winPEAS/Info/UserInfo/UserInfoHelper.cs | 1 + .../InterestingFiles/InterestingFiles.cs | 22 -- .../Browsers/InternetExplorer.cs | 1 + .../KnownFileCreds/KnownFileCredsInfo.cs | 237 +++++------------- .../winPEAS/KnownFileCreds/Putty.cs | 1 + .../winPEAS/KnownFileCreds/RemoteDesktop.cs | 1 + .../winPEAS/Native/Structs/LastInputInfo.cs | 8 + winPEAS/winPEASexe/winPEAS/Native/User32.cs | 6 + winPEAS/winPEASexe/winPEAS/winPEAS.csproj | 8 + 35 files changed, 850 insertions(+), 249 deletions(-) create mode 100644 winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/CertificateInfo.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/Certificates.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfee.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSiteInfo.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSitelistInfo.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNet.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNetInfo.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Native/Structs/LastInputInfo.cs diff --git a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs index df08382..ceacf03 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs @@ -6,6 +6,7 @@ using System.Management; using System.Security.Principal; using winPEAS.Helpers; using winPEAS.Helpers.AppLocker; +using winPEAS.Helpers.Registry; using winPEAS.Helpers.Search; using winPEAS.Info.UserInfo; diff --git a/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs index 38c5300..d722398 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs @@ -4,7 +4,10 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; using winPEAS.Helpers.Search; +using winPEAS.Info.FilesInfo.Certificates; +using winPEAS.Info.FilesInfo.McAfee; using winPEAS.Info.UserInfo; using winPEAS.InterestingFiles; using winPEAS.KnownFileCreds; @@ -126,6 +129,7 @@ namespace winPEAS.Checks PrintUserCredsFiles, PrintOracleSQLDeveloperConfigFiles, Slack.PrintInfo, + PrintMachineAndUserCertificateFiles, PrintUsersInterestingFiles, PrintUsersDocsKeys, PrintRecentFiles, @@ -199,17 +203,37 @@ namespace winPEAS.Checks } } - void PrintMcAffeSitelistFiles() + private static void PrintMcAffeSitelistFiles() { try { Beaprint.MainPrint("Looking for McAfee Sitelist.xml Files"); - List sam_files = InterestingFiles.InterestingFiles.GetMcAfeeSitelistFiles(); - foreach (string path in sam_files) - { - Beaprint.BadPrint(" " + path); - } + var sitelistFilesInfos = McAfee.GetMcAfeeSitelistInfos(); + foreach (var sitelistFilesInfo in sitelistFilesInfos) + { + Beaprint.NoColorPrint($" Path: {sitelistFilesInfo.Path}"); + + if (!string.IsNullOrEmpty(sitelistFilesInfo.ParseException)) + { + Beaprint.NoColorPrint($" Parse Exception: {sitelistFilesInfo.ParseException}"); + } + + foreach (var site in sitelistFilesInfo.Sites) + { + Beaprint.BadPrint($" ShareName : {site.ShareName}\n" + + $" UserName : {site.UserName}\n" + + $" Server : {site.Server}\n" + + $" EncPassword : {site.EncPassword}\n" + + $" DecPassword : {site.DecPassword}\n" + + $" DomainName : {site.DomainName}\n" + + $" Name : {site.Name}\n" + + $" Type : {site.Type}\n" + + $" RelativePath : {site.RelativePath}\n"); + } + + Beaprint.PrintLineSeparator(); + } } catch (Exception ex) { @@ -716,7 +740,7 @@ namespace winPEAS.Checks } } - private void PrintOracleSQLDeveloperConfigFiles() + private static void PrintOracleSQLDeveloperConfigFiles() { Beaprint.MainPrint($"Searching for Oracle SQL Developer config files\n"); @@ -747,5 +771,49 @@ namespace winPEAS.Checks } } } + + private static void PrintMachineAndUserCertificateFiles() + { + Beaprint.MainPrint($"Enumerating machine and user certificate files\n"); + + try + { + var certificateInfos = Certificates.GetCertificateInfos(); + + foreach (var certificateInfo in certificateInfos) + { + + Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" + + $" Subject : {certificateInfo.Subject}\n" + + $" ValidDate : {certificateInfo.ValidDate}\n" + + $" ExpiryDate : {certificateInfo.ExpiryDate}\n" + + $" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" + + $" StoreLocation : {certificateInfo.StoreLocation}\n" + + $" KeyExportable : {certificateInfo.KeyExportable}\n" + + $" Thumbprint : {certificateInfo.Thumbprint}\n"); + + if (!string.IsNullOrEmpty(certificateInfo.Template)) + { + Beaprint.NoColorPrint($" Template : {certificateInfo.Template}"); + } + + if (certificateInfo.EnhancedKeyUsages?.Count > 0) + { + Beaprint.ColorPrint(" Enhanced Key Usages", Beaprint.LBLUE); + + foreach (var keyUsages in certificateInfo.EnhancedKeyUsages) + { + var info = keyUsages == "Client Authentication" ? " [*] Certificate is used for client authentication!" : string.Empty; + + Beaprint.NoColorPrint($" {keyUsages}{info}"); + } + } + Beaprint.PrintLineSeparator(); + } + } + catch (Exception ex) + { + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs index 0c3d484..e981d10 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Management; using winPEAS.Helpers; using winPEAS.Helpers.Extensions; using winPEAS.Info.NetworkInfo; @@ -28,6 +29,7 @@ namespace winPEAS.Checks new List { PrintNetShares, + PrintMappedDrivesWMI, PrintHostsFile, PrintNetworkIfaces, PrintListeningPorts, @@ -333,5 +335,36 @@ namespace winPEAS.Checks Beaprint.PrintException(ex.Message); } } + + private static void PrintMappedDrivesWMI() + { + try + { + Beaprint.MainPrint("Enumerate Network Mapped Drives (WMI)"); + + using (var wmiData = new ManagementObjectSearcher(@"root\cimv2", "SELECT * FROM win32_networkconnection")) + { + using (var data = wmiData.Get()) + { + foreach (ManagementObject result in data) + { + Beaprint.NoColorPrint($" Local Name : {result["LocalName"]}\n" + + $" Remote Name : {result["RemoteName"]}\n" + + $" Remote Path : {result["RemotePath"]}\n" + + $" Status : {result["Status"]}\n" + + $" Connection State : {result["ConnectionState"]}\n" + + $" Persistent : {result["Persistent"]}\n" + + $" UserName : {result["UserName"]}\n" + + $" Description : {result["Description"]}\n"); + + Beaprint.PrintLineSeparator(); + } + } + } + } + catch (Exception e) + { + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs index ac5afd0..2714ff0 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs @@ -2,6 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using winPEAS.Helpers; using winPEAS.Helpers.AppLocker; using winPEAS._3rdParty.Watson; @@ -10,6 +13,8 @@ using winPEAS.Info.SystemInfo.NamedPipes; using winPEAS.Info.SystemInfo; using winPEAS.Info.SystemInfo.SysMon; using winPEAS.Helpers.Extensions; +using winPEAS.Helpers.Registry; +using winPEAS.Info.SystemInfo.DotNet; using winPEAS.Info.SystemInfo.WindowsDefender; namespace winPEAS.Checks @@ -47,6 +52,8 @@ namespace winPEAS.Checks new List { PrintBasicSystemInfo, + PrintMicrosoftUpdatesCOM, + PrintSystemLastShutdownTime, PrintUserEV, PrintSystemEV, PrintAuditInfo, @@ -70,11 +77,12 @@ namespace winPEAS.Checks PrintPrintersWMIInfo, PrintNamedPipes, PrintAMSIProviders, - PrintSysmon + PrintSysmon, + PrintDotNetVersions }.ForEach(action => CheckRunner.Run(action, isDebug)); } - static void PrintBasicSystemInfo() + private static void PrintBasicSystemInfo() { try { @@ -99,6 +107,61 @@ namespace winPEAS.Checks } } + private static void PrintMicrosoftUpdatesCOM() + { + try + { + Beaprint.MainPrint("Showing All Microsoft Updates"); + + var searcher = Type.GetTypeFromProgID("Microsoft.Update.Searcher"); + var searcherObj = Activator.CreateInstance(searcher); + + // get the total number of updates + var count = (int)searcherObj.GetType().InvokeMember("GetTotalHistoryCount", BindingFlags.InvokeMethod, null, searcherObj, new object[] { }); + + // get the pointer to the update collection + var results = searcherObj.GetType().InvokeMember("QueryHistory", BindingFlags.InvokeMethod, null, searcherObj, new object[] { 0, count }); + + for (int i = 0; i < count; ++i) + { + // get the actual update item + var item = searcherObj.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, results, new object[] { i }); + + // get our properties + // ref - https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatehistoryentry + var title = searcherObj.GetType().InvokeMember("Title", BindingFlags.GetProperty, null, item, new object[] { }).ToString(); + var date = searcherObj.GetType().InvokeMember("Date", BindingFlags.GetProperty, null, item, new object[] { }); + var description = searcherObj.GetType().InvokeMember("Description", BindingFlags.GetProperty, null, item, new object[] { }); + var clientApplicationID = searcherObj.GetType().InvokeMember("ClientApplicationID", BindingFlags.GetProperty, null, item, new object[] { }); + + string hotfixId = ""; + Regex reg = new Regex(@"KB\d+"); + var matches = reg.Matches(title); + if (matches.Count > 0) + { + hotfixId = matches[0].ToString(); + } + + Beaprint.NoColorPrint($" HotFix ID : {hotfixId}\n" + + $" Installed At (UTC) : {Convert.ToDateTime(date.ToString()).ToUniversalTime()}\n" + + $" Title : {title}\n" + + $" Client Application ID : {clientApplicationID}\n" + + $" Description : {description}\n"); + + Beaprint.PrintLineSeparator(); + + Marshal.ReleaseComObject(item); + } + + Marshal.ReleaseComObject(results); + Marshal.ReleaseComObject(searcherObj); + } + catch (Exception ex) + { + Beaprint.PrintException(ex.Message); + } + } + static void PrintPSInfo() { try @@ -703,8 +766,6 @@ namespace winPEAS.Checks { Beaprint.MainPrint("Windows Defender configuration"); - - void DisplayDefenderSettings(WindowsDefenderSettings settings) { var pathExclusions = settings.PathExclusions; @@ -797,5 +858,81 @@ namespace winPEAS.Checks { } } + + private static void PrintDotNetVersions() + { + try + { + Beaprint.MainPrint("Installed .NET versions\n"); + + var info = DotNet.GetDotNetInfo(); + + Beaprint.ColorPrint(" CLR Versions", Beaprint.LBLUE); + foreach (var version in info.ClrVersions) + { + Beaprint.NoColorPrint($" {version}"); + } + + Beaprint.ColorPrint("\n .NET Versions", Beaprint.LBLUE); + foreach (var version in info.DotNetVersions) + { + Beaprint.NoColorPrint($" {version}"); + } + + var colors = new Dictionary + { + { "True", Beaprint.ansi_color_good }, + { "False", Beaprint.ansi_color_bad }, + }; + + Beaprint.ColorPrint("\n .NET & AMSI (Anti-Malware Scan Interface) support", Beaprint.LBLUE); + Beaprint.AnsiPrint($" .NET version supports AMSI : {info.IsAmsiSupportedByDotNet}\n" + + $" OS supports AMSI : {info.IsAmsiSupportedByOs}", + colors); + + var highestVersion = info.HighestVersion; + var lowestVersion = info.LowestVersion; + + if ((highestVersion.Major == DotNetInfo.AmsiSupportedByDotNetMinMajorVersion) && (highestVersion.Minor >= DotNetInfo.AmsiSupportedByDotNetMinMinorVersion)) + { + Beaprint.NoColorPrint($" [!] The highest .NET version is enrolled in AMSI!"); + } + + if ( + info.IsAmsiSupportedByOs && + info.IsAmsiSupportedByDotNet && + (( + (lowestVersion.Major == DotNetInfo.AmsiSupportedByDotNetMinMajorVersion - 1) + ) || + ((lowestVersion.Major == DotNetInfo.AmsiSupportedByDotNetMinMajorVersion) && (lowestVersion.Minor < DotNetInfo.AmsiSupportedByDotNetMinMinorVersion))) + ) + { + Beaprint.NoColorPrint($" [-] You can invoke .NET version {lowestVersion.Major}.{lowestVersion.Minor} to bypass AMSI."); + } + } + catch (Exception e) + { + } + } + + private static void PrintSystemLastShutdownTime() + { + try + { + Beaprint.MainPrint("System Last Shutdown Date/time (from Registry)\n"); + + var shutdownBytes = RegistryHelper.GetRegValueBytes("HKLM", "SYSTEM\\ControlSet001\\Control\\Windows", "ShutdownTime"); + if (shutdownBytes != null) + { + var shutdownInt = BitConverter.ToInt64(shutdownBytes, 0); + var shutdownTime = DateTime.FromFileTime(shutdownInt); + + Beaprint.NoColorPrint($" Last Shutdown Date/time : {shutdownTime}"); + } + } + catch (Exception ex) + { + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs index 907ee38..b65a9ca 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs @@ -1,10 +1,14 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.InteropServices; using System.Security.Principal; using winPEAS.Helpers; using winPEAS.Info.UserInfo; using winPEAS.Info.UserInfo.LogonSessions; using winPEAS.Info.UserInfo.Token; +using winPEAS.Native; +using winPEAS.Native.Structs; namespace winPEAS.Checks { @@ -35,6 +39,7 @@ namespace winPEAS.Checks new List { PrintCU, + PrintCurrentUserIdleTime, PrintTokenP, PrintClipboardText, PrintLoggedUsers, @@ -306,5 +311,30 @@ namespace winPEAS.Checks { } } + + private static void PrintCurrentUserIdleTime() + { + try + { + Beaprint.MainPrint("Current User Idle Time"); + + var lastInputInfo = new LastInputInfo(); + lastInputInfo.Size = (uint)Marshal.SizeOf(lastInputInfo); + + if (User32.GetLastInputInfo(ref lastInputInfo)) + { + var currentUser = WindowsIdentity.GetCurrent().Name; + var idleTimeMiliSeconds = (uint) Environment.TickCount - lastInputInfo.Time; + var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds); + var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms"; + + Beaprint.NoColorPrint($" Current User : {currentUser}\n" + + $" Idle Time : {idleTimeString}"); + } + } + catch (Exception ex) + { + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs b/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs index 84a804b..0fc8fc1 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Xml; using winPEAS.Helpers; using winPEAS.Helpers.CredentialManager; +using winPEAS.Helpers.Registry; using winPEAS.KnownFileCreds; using winPEAS.KnownFileCreds.Kerberos; using winPEAS.KnownFileCreds.SecurityPackages; diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/MyUtils.cs b/winPEAS/winPEASexe/winPEAS/Helpers/MyUtils.cs index 5533cff..16faf7e 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/MyUtils.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/MyUtils.cs @@ -8,6 +8,7 @@ using System.Reflection; using System.Security.Principal; using System.Text; using System.Text.RegularExpressions; +using winPEAS.Helpers.Registry; namespace winPEAS.Helpers { @@ -84,6 +85,12 @@ namespace winPEAS.Helpers return binaryPath; } + internal static bool IsBase64String(string text) + { + text = text.Trim(); + return (text.Length % 4 == 0) && Regex.IsMatch(text, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); + } + public static string ReconstructExecPath(string path) { if (!path.Contains(".exe") && !path.Contains(".dll") && !path.Contains(".sys")) @@ -136,6 +143,10 @@ namespace winPEAS.Helpers return dirs.ToList(); } + internal static byte[] CombineArrays(byte[] first, byte[] second) + { + return first.Concat(second).ToArray(); + } //From Seatbelt public static bool IsHighIntegrity() diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs index c91b4c4..fada162 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs @@ -1,10 +1,9 @@ - -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Win32; -namespace winPEAS.Helpers +namespace winPEAS.Helpers.Registry { static class RegistryHelper { @@ -19,7 +18,7 @@ namespace winPEAS.Helpers string regKeyValue = ""; if (hive == "HKCU") { - var regKey = Registry.CurrentUser.OpenSubKey(path); + var regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path); if (regKey != null) { regKeyValue = string.Format("{0}", regKey.GetValue(value)); @@ -28,7 +27,7 @@ namespace winPEAS.Helpers } else if (hive == "HKU") { - var regKey = Registry.Users.OpenSubKey(path); + var regKey = Microsoft.Win32.Registry.Users.OpenSubKey(path); if (regKey != null) { regKeyValue = string.Format("{0}", regKey.GetValue(value)); @@ -37,7 +36,7 @@ namespace winPEAS.Helpers } else { - var regKey = Registry.LocalMachine.OpenSubKey(path); + var regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); if (regKey != null) { regKeyValue = string.Format("{0}", regKey.GetValue(value)); @@ -54,7 +53,7 @@ namespace winPEAS.Helpers { if (hive == "HKCU") { - using (var regKeyValues = Registry.CurrentUser.OpenSubKey(path)) + using (var regKeyValues = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path)) { if (regKeyValues != null) { @@ -65,7 +64,7 @@ namespace winPEAS.Helpers } else if (hive == "HKU") { - using (var regKeyValues = Registry.Users.OpenSubKey(path)) + using (var regKeyValues = Microsoft.Win32.Registry.Users.OpenSubKey(path)) { if (regKeyValues != null) { @@ -76,7 +75,7 @@ namespace winPEAS.Helpers } else { - using (var regKeyValues = Registry.LocalMachine.OpenSubKey(path)) + using (var regKeyValues = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path)) { if (regKeyValues != null) { @@ -99,7 +98,7 @@ namespace winPEAS.Helpers byte[] regKeyValue = null; if (hive == "HKCU") { - var regKey = Registry.CurrentUser.OpenSubKey(path); + var regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path); if (regKey != null) { regKeyValue = (byte[])regKey.GetValue(value); @@ -108,7 +107,7 @@ namespace winPEAS.Helpers } else if (hive == "HKU") { - var regKey = Registry.Users.OpenSubKey(path); + var regKey = Microsoft.Win32.Registry.Users.OpenSubKey(path); if (regKey != null) { regKeyValue = (byte[])regKey.GetValue(value); @@ -117,7 +116,7 @@ namespace winPEAS.Helpers } else { - var regKey = Registry.LocalMachine.OpenSubKey(path); + var regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); if (regKey != null) { regKeyValue = (byte[])regKey.GetValue(value); @@ -134,15 +133,15 @@ namespace winPEAS.Helpers RegistryKey myKey = null; if (hive == "HKLM") { - myKey = Registry.LocalMachine.OpenSubKey(path); + myKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); } else if (hive == "HKU") { - myKey = Registry.Users.OpenSubKey(path); + myKey = Microsoft.Win32.Registry.Users.OpenSubKey(path); } else { - myKey = Registry.CurrentUser.OpenSubKey(path); + myKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path); } String[] subkeyNames = myKey.GetSubKeyNames(); return myKey.GetSubKeyNames(); diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs index 82e058f..2a7ea00 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs @@ -17,6 +17,9 @@ namespace winPEAS.Helpers.Search private static List DocumentsAndSettings; private static List GroupPolicyHistory; + private static string SystemDrive = Environment.GetEnvironmentVariable("SystemDrive"); + private static string GlobalPattern = "*"; + public static List GetFilesFast(string folder, string pattern = "*", HashSet excludedDirs = null, bool isFoldersIncluded = false) { ConcurrentBag files = new ConcurrentBag(); @@ -166,37 +169,34 @@ namespace winPEAS.Helpers.Search internal static void CreateSearchDirectoriesList() { - string globalPattern = "*"; - string systemDrive = Environment.GetEnvironmentVariable("SystemDrive"); - // c:\users - string rootUsersSearchPath = $"{systemDrive}\\Users\\"; - SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, globalPattern, isFoldersIncluded: true); + string rootUsersSearchPath = $"{SystemDrive}\\Users\\"; + SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true); // c:\users\current_user string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE"); - SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, globalPattern); + SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern); // c:\Program Files\ - string rootProgramFiles = $"{systemDrive}\\Program Files\\"; - SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, globalPattern); + string rootProgramFiles = $"{SystemDrive}\\Program Files\\"; + SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, GlobalPattern); // c:\Program Files (x86)\ - string rootProgramFilesX86 = $"{systemDrive}\\Program Files (x86)\\"; - SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, globalPattern); + string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\"; + SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern); // c:\Documents and Settings\ - string documentsAndSettings = $"{systemDrive}\\Documents and Settings\\"; - SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, globalPattern); + string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\"; + SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, GlobalPattern); // c:\ProgramData\Microsoft\Group Policy\History - string groupPolicyHistory = $"{systemDrive}\\ProgramData\\Microsoft\\Group Policy\\History"; - SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, globalPattern); + string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History"; + SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, GlobalPattern); // c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History"; //SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern); - var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern); + var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern); SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles); } @@ -304,18 +304,20 @@ namespace winPEAS.Helpers.Search return result; } - internal static List SearchMcAfeeSitelistFiles() + internal static IEnumerable SearchMcAfeeSitelistFiles() { - var result = new List(); - - HashSet allowedFilenames = new HashSet() + var allowedFilenames = new HashSet { "sitelist.xml" }; + string programDataPath = $"{SystemDrive}\\ProgramData\\"; + var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern); + var searchFiles = new List(); searchFiles.AddRange(SearchHelper.ProgramFiles); searchFiles.AddRange(SearchHelper.ProgramFilesX86); + searchFiles.AddRange(programData); searchFiles.AddRange(SearchHelper.DocumentsAndSettings); searchFiles.AddRange(SearchHelper.RootDirUsers); @@ -327,12 +329,10 @@ namespace winPEAS.Helpers.Search if (allowedFilenames.Contains(filenameToLower)) { - result.Add(file.FullPath); + yield return file.FullPath; } } } - - return result; } internal static List SearchCurrentUserDocs() diff --git a/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/AutoRuns.cs b/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/AutoRuns.cs index cc12662..665bf20 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/AutoRuns.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/AutoRuns.cs @@ -6,6 +6,7 @@ using System.Management; using System.Text.RegularExpressions; using Microsoft.Win32; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.Info.ApplicationInfo { diff --git a/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/InstalledApps.cs b/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/InstalledApps.cs index 08e967f..85f561b 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/InstalledApps.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/ApplicationInfo/InstalledApps.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.Info.ApplicationInfo { diff --git a/winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Common.cs b/winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Common.cs index bd5f86c..bd7c815 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Common.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/EventsInfo/Common.cs @@ -1,6 +1,6 @@ using System.Text.RegularExpressions; -namespace winPEAS.Info.EventsInfo.PowerShell +namespace winPEAS.Info.EventsInfo { internal static class Common { diff --git a/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/CertificateInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/CertificateInfo.cs new file mode 100644 index 0000000..3937f8c --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/CertificateInfo.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace winPEAS.Info.FilesInfo.Certificates +{ + internal class CertificateInfo + { + public string StoreLocation { get; set; } + public string Issuer { get; set; } + public string Subject { get; set; } + public DateTime ValidDate { get; set; } + public DateTime ExpiryDate { get; set; } + public bool HasPrivateKey { get; set; } + public bool? KeyExportable { get; set; } + public string Thumbprint { get; set; } + public string Template { get; set; } + public List EnhancedKeyUsages { get; set; } = new List(); + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/Certificates.cs b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/Certificates.cs new file mode 100644 index 0000000..ab7e694 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Certificates/Certificates.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; + +namespace winPEAS.Info.FilesInfo.Certificates +{ + internal class Certificates + { + public static IEnumerable GetCertificateInfos() + { + foreach (var storeLocation in new[] { StoreLocation.CurrentUser, StoreLocation.LocalMachine }) + { + var store = new X509Store(StoreName.My, storeLocation); + store.Open(OpenFlags.ReadOnly); + + foreach (var certificate in store.Certificates) + { + var template = ""; + var enhancedKeyUsages = new List(); + bool? keyExportable = false; + + try + { + certificate.PrivateKey.ToXmlString(true); + keyExportable = true; + } + catch (Exception e) + { + keyExportable = !e.Message.Contains("not valid for use in specified state"); + } + + foreach (var ext in certificate.Extensions) + { + switch (ext.Oid.FriendlyName) + { + case "Enhanced Key Usage": + { + var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages; + + if (extUsages.Count == 0) + continue; + + foreach (var extUsage in extUsages) + { + enhancedKeyUsages.Add(extUsage.FriendlyName); + } + + break; + } + case "Certificate Template Name": + case "Certificate Template Information": + template = ext.Format(false); + break; + } + } + + yield return new CertificateInfo + { + StoreLocation = $"{storeLocation}", + Issuer = certificate.Issuer, + Subject = certificate.Subject, + ValidDate = certificate.NotBefore, + ExpiryDate = certificate.NotAfter, + HasPrivateKey = certificate.HasPrivateKey, + KeyExportable = keyExportable, + Template = template, + Thumbprint = certificate.Thumbprint, + EnhancedKeyUsages = enhancedKeyUsages + }; + } + + store.Close(); + } + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfee.cs b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfee.cs new file mode 100644 index 0000000..0c85f5b --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfee.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Xml; +using winPEAS.Helpers; +using winPEAS.Helpers.Search; + +namespace winPEAS.Info.FilesInfo.McAfee +{ + internal class McAfee + { + public static IList GetMcAfeeSitelistInfos() + { + var result = new List(); + var sitelistFiles = SearchHelper.SearchMcAfeeSitelistFiles()?.ToList(); + + if (sitelistFiles != null) + { + foreach (var sitelistFile in sitelistFiles) + { + try + { + var xmlString = File.ReadAllText(sitelistFile); + xmlString = xmlString.Replace("", ""); + var xmlDoc = new XmlDocument(); + + xmlDoc.LoadXml(xmlString); + + var sites = xmlDoc.GetElementsByTagName("SiteList"); + + if (sites[0].ChildNodes.Count == 0) + { + continue; + } + + var mcAfeeSites = new List(); + + foreach (XmlNode site in sites[0].ChildNodes) + { + if (site.Attributes["Name"] == null || site.Attributes["Server"] == null) + { + continue; + } + + var server = site.Attributes["Server"].Value; + var name = site.Attributes["Name"].Value; + var type = site.Name; + + var encPassword = string.Empty; + var decPassword = string.Empty; + var relativePath = string.Empty; + var shareName = string.Empty; + var user = string.Empty; + var domainName = string.Empty; + + foreach (XmlElement attribute in site.ChildNodes) + { + switch (attribute.Name) + { + case "UserName": + user = attribute.InnerText; + break; + + case "Password": + if (MyUtils.IsBase64String(attribute.InnerText)) + { + encPassword = attribute.InnerText; + decPassword = DecryptPassword(encPassword); + } + else + { + decPassword = attribute.InnerText; + } + break; + + case "DomainName": + domainName = attribute.InnerText; + break; + + case "RelativePath": + relativePath = attribute.InnerText; + break; + + case "ShareName": + shareName = attribute.InnerText; + break; + + default: + break; + } + } + + var config = new McAfeeSiteInfo(type, name, server, relativePath, shareName, user, domainName, encPassword, decPassword); + + mcAfeeSites.Add(config); + } + + if (mcAfeeSites.Count > 0) + { + //yield return new McAfeeSitelistInfo(sitelistFile, mcAfeeSites); + result.Add(new McAfeeSitelistInfo(sitelistFile, mcAfeeSites)); + } + } + catch (Exception ex) + { + result.Add(new McAfeeSitelistInfo(sitelistFile, new List(), ex.Message)); + } + } + } + + return result; + } + + private static string DecryptPassword(string base64password) + { + // Adapted from PowerUp: https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1#L4128-L4326 + + // References: + // https://github.com/funoverip/mcafee-sitelist-pwd-decryption/ + // https://funoverip.net/2016/02/mcafee-sitelist-xml-password-decryption/ + // https://github.com/tfairane/HackStory/blob/master/McAfeePrivesc.md + // https://www.syss.de/fileadmin/dokumente/Publikationen/2011/SySS_2011_Deeg_Privilege_Escalation_via_Antivirus_Software.pdf + + // static McAfee key XOR key LOL + byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 }; + + // xor the input b64 string with the static XOR key + var passwordBytes = System.Convert.FromBase64String(base64password); + for (var i = 0; i < passwordBytes.Length; i++) + { + passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]); + } + + SHA1 crypto = new SHA1CryptoServiceProvider(); + + var tDESKey = MyUtils.CombineArrays(crypto.ComputeHash(System.Text.Encoding.ASCII.GetBytes("")), new byte[] { 0x00, 0x00, 0x00, 0x00 }); + + // set the options we need + var tDESalg = new TripleDESCryptoServiceProvider(); + tDESalg.Mode = CipherMode.ECB; + tDESalg.Padding = PaddingMode.None; + tDESalg.Key = tDESKey; + + // decrypt the unXor'ed block + var decrypted = tDESalg.CreateDecryptor().TransformFinalBlock(passwordBytes, 0, passwordBytes.Length); + var end = Array.IndexOf(decrypted, (byte)0x00); + + // return the final password string + var password = System.Text.Encoding.ASCII.GetString(decrypted, 0, end); + + return password; + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSiteInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSiteInfo.cs new file mode 100644 index 0000000..3d2e22b --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSiteInfo.cs @@ -0,0 +1,37 @@ +namespace winPEAS.Info.FilesInfo.McAfee +{ + internal class McAfeeSiteInfo + { + public string Type { get; set; } + public string Name { get; set; } + public string Server { get; set; } + public string RelativePath { get; set; } + public string ShareName { get; set; } + public string UserName { get; set; } + public string DomainName { get; set; } + public string EncPassword { get; set; } + public string DecPassword { get; set; } + + public McAfeeSiteInfo( + string type, + string name, + string server, + string relativePath, + string shareName, + string userName, + string domainName, + string encPassword, + string decPassword) + { + Type = type; + Name = name; + Server = server; + RelativePath = relativePath; + ShareName = shareName; + UserName = userName; + DomainName = domainName; + EncPassword = encPassword; + DecPassword = decPassword; + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSitelistInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSitelistInfo.cs new file mode 100644 index 0000000..315db2f --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfeeSitelistInfo.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace winPEAS.Info.FilesInfo.McAfee +{ + internal class McAfeeSitelistInfo + { + public string Path { get; set; } + public List Sites { get; set; } + + public string ParseException { get; set; } + + public McAfeeSitelistInfo(string path, List sites, string parseException = null) + { + Path = path; + Sites = sites ?? new List(); + ParseException = parseException; + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Enums/MibTcpState.cs b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Enums/MibTcpState.cs index c139ec8..c49b8bb 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Enums/MibTcpState.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Enums/MibTcpState.cs @@ -1,6 +1,6 @@ using System.ComponentModel; -namespace winPEAS.Info.NetworkInfo +namespace winPEAS.Info.NetworkInfo.Enums { public enum MibTcpState { diff --git a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCP6ROW_OWNER_PID.cs b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCP6ROW_OWNER_PID.cs index b1c5272..f114d11 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCP6ROW_OWNER_PID.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCP6ROW_OWNER_PID.cs @@ -1,4 +1,5 @@ using System.Runtime.InteropServices; +using winPEAS.Info.NetworkInfo.Enums; namespace winPEAS.Info.NetworkInfo.Structs { diff --git a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCPROW_OWNER_PID.cs b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCPROW_OWNER_PID.cs index 9757ef0..d44fff7 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCPROW_OWNER_PID.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/Structs/MIB_TCPROW_OWNER_PID.cs @@ -1,4 +1,5 @@ using System.Runtime.InteropServices; +using winPEAS.Info.NetworkInfo.Enums; namespace winPEAS.Info.NetworkInfo.Structs { diff --git a/winPEAS/winPEASexe/winPEAS/Info/ServicesInfo/ServicesInfoHelper.cs b/winPEAS/winPEASexe/winPEAS/Info/ServicesInfo/ServicesInfoHelper.cs index f5e4540..98bfde4 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/ServicesInfo/ServicesInfoHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/ServicesInfo/ServicesInfoHelper.cs @@ -10,6 +10,7 @@ using System.ServiceProcess; using System.Text.RegularExpressions; using Microsoft.Win32; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; using winPEAS.KnownFileCreds; using winPEAS.Native; diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNet.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNet.cs new file mode 100644 index 0000000..2a1714c --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNet.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Management; +using winPEAS.Helpers.Registry; + +namespace winPEAS.Info.SystemInfo.DotNet +{ + internal class DotNet + { + public static DotNetInfo GetDotNetInfo() + { + var installedDotNetVersions = new List(); + var installedClrVersions = new List(); + installedClrVersions.AddRange(GetClrVersions()); + + var dotNet35Version = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5", "Version"); + if (!string.IsNullOrEmpty(dotNet35Version)) + { + installedDotNetVersions.Add(dotNet35Version); + } + + var dotNet4Version = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", "Version"); + if (!string.IsNullOrEmpty(dotNet4Version)) + { + installedDotNetVersions.Add(dotNet4Version); + } + + var osVersion = GetOSVersion().Split('.')[0]; + int osVersionMajor = int.Parse(osVersion); + + return new DotNetInfo( + installedClrVersions, + installedDotNetVersions, + osVersionMajor + ); + } + + private static string GetOSVersion() + { + + try + { + using (var wmiData = new ManagementObjectSearcher(@"root\cimv2", "SELECT Version FROM Win32_OperatingSystem")) + { + using (var data = wmiData.Get()) + { + foreach (var os in data) + { + return os["Version"].ToString(); + } + } + } + } + catch { } + + return string.Empty; + } + + private static IEnumerable GetClrVersions() + { + var dirs = Directory.EnumerateDirectories("\\Windows\\Microsoft.Net\\Framework\\"); + + return (from dir in dirs + where File.Exists($"{dir}\\System.dll") + select Path.GetFileName(dir.TrimEnd(Path.DirectorySeparatorChar)) + into fileName + select fileName.TrimStart('v')).ToList(); + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNetInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNetInfo.cs new file mode 100644 index 0000000..4bad889 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNetInfo.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace winPEAS.Info.SystemInfo.DotNet +{ + internal class DotNetInfo + { + public const int AmsiSupportedByDotNetMinMajorVersion = 4; + public const int AmsiSupportedByDotNetMinMinorVersion = 8; + + private const int AmsiSupportedByOsMinVersion = 10; + + public IEnumerable ClrVersions { get; } + public IEnumerable DotNetVersions { get; } + public bool IsAmsiSupportedByOs { get; } + public bool IsAmsiSupportedByDotNet { get; } + public Version LowestVersion { get; set; } + public Version HighestVersion { get; set; } + + public DotNetInfo( + IEnumerable installedClrVersions, + IEnumerable installedDotNetVersions, + int osVersionMajor) + { + ClrVersions = (installedClrVersions ?? new List()).ToList(); + DotNetVersions = (installedDotNetVersions ?? new List()).ToList(); ; + IsAmsiSupportedByOs = osVersionMajor >= AmsiSupportedByOsMinVersion; + + LowestVersion = DotNetVersions.Min(v => (new Version(v))); + HighestVersion = DotNetVersions.Max(v => (new Version(v))); + + IsAmsiSupportedByDotNet = (HighestVersion.Major >= AmsiSupportedByDotNetMinMajorVersion) && + (LowestVersion.Minor >= AmsiSupportedByDotNetMinMinorVersion); + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SysMon/SysMon.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SysMon/SysMon.cs index 70f0575..3a43b0f 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SysMon/SysMon.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SysMon/SysMon.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics.Eventing.Reader; using System.Text.RegularExpressions; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.Info.SystemInfo.SysMon { diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs index 76035c4..ef4f81d 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs @@ -2,11 +2,13 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Management; using System.Net; using System.Net.NetworkInformation; using System.Windows.Forms; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; using winPEAS.KnownFileCreds; namespace winPEAS.Info.SystemInfo @@ -229,6 +231,7 @@ namespace winPEAS.Info.SystemInfo { results["PowerShell v2 Version"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine", "PowerShellVersion"); results["PowerShell v5 Version"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine", "PowerShellVersion"); + results["PowerShell Core Version"] = string.Join(", ", GetPowerShellCoreVersions()); results["Transcription Settings"] = ""; results["Module Logging Settings"] = ""; results["Scriptblock Logging Settings"] = ""; @@ -331,6 +334,15 @@ namespace winPEAS.Info.SystemInfo return results; } + private static IEnumerable GetPowerShellCoreVersions() + { + var keys = RegistryHelper.GetRegSubkeys("HKLM", @"SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\") ?? new string[] { }; + + return keys.Select(key => + RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\" + key, "SemanticVersion")) + .Where(version => version != null).ToList(); + } + // From seatbelt public static Dictionary GetAuditSettings() { diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/WindowsDefender/WindowsDefenderSettings.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/WindowsDefender/WindowsDefenderSettings.cs index b31b879..6a37867 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/WindowsDefender/WindowsDefenderSettings.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/WindowsDefender/WindowsDefenderSettings.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Microsoft.Win32; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.Info.SystemInfo.WindowsDefender { diff --git a/winPEAS/winPEASexe/winPEAS/Info/UserInfo/UserInfoHelper.cs b/winPEAS/winPEASexe/winPEAS/Info/UserInfo/UserInfoHelper.cs index fe1ea6c..6cc8dd6 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/UserInfo/UserInfoHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/UserInfo/UserInfoHelper.cs @@ -4,6 +4,7 @@ using System.DirectoryServices.AccountManagement; using System.Runtime.InteropServices; using System.Windows.Forms; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; using winPEAS.Info.UserInfo.SAM; using winPEAS.KnownFileCreds; using winPEAS.Native; diff --git a/winPEAS/winPEASexe/winPEAS/InterestingFiles/InterestingFiles.cs b/winPEAS/winPEASexe/winPEAS/InterestingFiles/InterestingFiles.cs index ee0f8e6..a7a60f3 100644 --- a/winPEAS/winPEASexe/winPEAS/InterestingFiles/InterestingFiles.cs +++ b/winPEAS/winPEASexe/winPEAS/InterestingFiles/InterestingFiles.cs @@ -37,28 +37,6 @@ namespace winPEAS.InterestingFiles return results; } - public static List GetMcAfeeSitelistFiles() - { - //From SharpUP - List results = new List(); - - try - { - - - results = SearchHelper.SearchMcAfeeSitelistFiles(); - - //results.AddRange( - // searchLocations.SelectMany( - // searchLocation => SearchHelper.FindFiles(searchLocation, "SiteList.xml"))); - } - catch (Exception ex) - { - Beaprint.PrintException(ex.Message); - } - return results; - } - public static List GetLinuxShells() { var results = new List(); diff --git a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Browsers/InternetExplorer.cs b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Browsers/InternetExplorer.cs index 44c4525..56bb733 100644 --- a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Browsers/InternetExplorer.cs +++ b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Browsers/InternetExplorer.cs @@ -8,6 +8,7 @@ using System.Text.RegularExpressions; using Microsoft.Win32; using winPEAS.Checks; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; using winPEAS.KnownFileCreds.Browsers.Models; namespace winPEAS.KnownFileCreds.Browsers diff --git a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/KnownFileCredsInfo.cs b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/KnownFileCredsInfo.cs index 932b421..8f79826 100644 --- a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/KnownFileCredsInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/KnownFileCredsInfo.cs @@ -8,6 +8,7 @@ using System.Text; using System.Text.RegularExpressions; using Microsoft.Win32; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.KnownFileCreds { @@ -42,198 +43,80 @@ namespace winPEAS.KnownFileCreds // adapted from https://twitter.com/cmaddalena's SharpCloud project (https://github.com/chrismaddalena/SharpCloud/) try { + var cloudCredsDict = new Dictionary + { + // AWS + { ".aws\\credentials", "AWS keys file" }, + + // Google Cloud + { "AppData\\Roaming\\gcloud\\credentials.db", "GC Compute creds" }, + { "AppData\\Roaming\\gcloud\\legacy_credentials", "GC Compute creds legacy" }, + { "AppData\\Roaming\\gcloud\\access_tokens.db", "GC Compute tokens" }, + + // Azure + { ".azure\\accessTokens.json", "Azure tokens" }, + { ".azure\\azureProfile.json", "Azure profile" }, + { ".azure\\TokenCache.dat", "Azure Token Cache" }, + { ".azure\\AzureRMContext.json", "Azure RM Context" }, + { "AppData\\Roaming\\Windows Azure Powershell\\TokenCache.dat", "Azure PowerShell Token Cache" }, + { "AppData\\Roaming\\Windows Azure Powershell\\AzureRMContext.json", "Azure PowerShell RM Context" }, + + // Bluemix + { ".bluemix\\config.json", "Bluemix Config" }, + { ".bluemix\\.cf\\config.json", "Bluemix Alternate Config" }, + }; + + IEnumerable userDirs; + if (MyUtils.IsHighIntegrity()) { - string userFolder = string.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive")); - var dirs = Directory.EnumerateDirectories(userFolder); - foreach (string dir in dirs) - { - string[] parts = dir.Split('\\'); - string userName = parts[parts.Length - 1]; - if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users"))) - { - string awsKeyFile = string.Format("{0}\\.aws\\credentials", dir); - if (System.IO.File.Exists(awsKeyFile)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(awsKeyFile); - DateTime lastModified = System.IO.File.GetLastWriteTime(awsKeyFile); - long size = new System.IO.FileInfo(awsKeyFile).Length; - results.Add(new Dictionary() { - { "file", awsKeyFile }, - { "Description", "AWS credentials file" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string computeCredsDb = string.Format("{0}\\AppData\\Roaming\\gcloud\\credentials.db", dir); - if (System.IO.File.Exists(computeCredsDb)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeCredsDb); - DateTime lastModified = System.IO.File.GetLastWriteTime(computeCredsDb); - long size = new System.IO.FileInfo(computeCredsDb).Length; - results.Add(new Dictionary() { - { "file", computeCredsDb }, - { "Description", "GC Compute creds" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string computeLegacyCreds = string.Format("{0}\\AppData\\Roaming\\gcloud\\legacy_credentials", dir); - if (System.IO.File.Exists(computeLegacyCreds)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeLegacyCreds); - DateTime lastModified = System.IO.File.GetLastWriteTime(computeLegacyCreds); - long size = new System.IO.FileInfo(computeLegacyCreds).Length; - results.Add(new Dictionary() { - { "file", computeLegacyCreds }, - { "Description", "GC Compute creds legacy" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string computeAccessTokensDb = string.Format("{0}\\AppData\\Roaming\\gcloud\\access_tokens.db", dir); - if (System.IO.File.Exists(computeAccessTokensDb)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeAccessTokensDb); - DateTime lastModified = System.IO.File.GetLastWriteTime(computeAccessTokensDb); - long size = new System.IO.FileInfo(computeAccessTokensDb).Length; - results.Add(new Dictionary() { - { "file", computeAccessTokensDb }, - { "Description", "GC Compute tokens" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string azureTokens = string.Format("{0}\\.azure\\accessTokens.json", dir); - if (System.IO.File.Exists(azureTokens)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureTokens); - DateTime lastModified = System.IO.File.GetLastWriteTime(azureTokens); - long size = new System.IO.FileInfo(azureTokens).Length; - results.Add(new Dictionary() { - { "file", azureTokens }, - { "Description", "Azure tokens" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string azureProfile = string.Format("{0}\\.azure\\azureProfile.json", dir); - if (System.IO.File.Exists(azureProfile)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureProfile); - DateTime lastModified = System.IO.File.GetLastWriteTime(azureProfile); - long size = new System.IO.FileInfo(azureProfile).Length; - results.Add(new Dictionary() { - { "file", azureProfile }, - { "Description", "Azure profile" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - } - } + string userFolders = $"{Environment.GetEnvironmentVariable("SystemDrive")}\\Users\\"; + userDirs = Directory.EnumerateDirectories(userFolders); } else { - string awsKeyFile = string.Format("{0}\\.aws\\credentials", System.Environment.GetEnvironmentVariable("USERPROFILE")); - if (System.IO.File.Exists(awsKeyFile)) + var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE"); + userDirs = new List{ currentUserDir }; + } + + foreach (var userDir in userDirs) + { + foreach (var item in cloudCredsDict) { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(awsKeyFile); - DateTime lastModified = System.IO.File.GetLastWriteTime(awsKeyFile); - long size = new System.IO.FileInfo(awsKeyFile).Length; - results.Add(new Dictionary() { - { "file", awsKeyFile }, - { "Description", "AWS keys file" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string computeCredsDb = string.Format("{0}\\AppData\\Roaming\\gcloud\\credentials.db", System.Environment.GetEnvironmentVariable("USERPROFILE")); - if (System.IO.File.Exists(computeCredsDb)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeCredsDb); - DateTime lastModified = System.IO.File.GetLastWriteTime(computeCredsDb); - long size = new System.IO.FileInfo(computeCredsDb).Length; - results.Add(new Dictionary() { - { "file", computeCredsDb }, - { "Description", "GC Compute creds" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string computeLegacyCreds = string.Format("{0}\\AppData\\Roaming\\gcloud\\legacy_credentials", System.Environment.GetEnvironmentVariable("USERPROFILE")); - if (System.IO.File.Exists(computeLegacyCreds)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeLegacyCreds); - DateTime lastModified = System.IO.File.GetLastWriteTime(computeLegacyCreds); - long size = new System.IO.FileInfo(computeLegacyCreds).Length; - results.Add(new Dictionary() { - { "file", computeLegacyCreds }, - { "Description", "GC Compute creds legacy" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string computeAccessTokensDb = string.Format("{0}\\AppData\\Roaming\\gcloud\\access_tokens.db", System.Environment.GetEnvironmentVariable("USERPROFILE")); - if (System.IO.File.Exists(computeAccessTokensDb)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeAccessTokensDb); - DateTime lastModified = System.IO.File.GetLastWriteTime(computeAccessTokensDb); - long size = new System.IO.FileInfo(computeAccessTokensDb).Length; - results.Add(new Dictionary() { - { "file", computeAccessTokensDb }, - { "Description", "GC Compute tokens" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string azureTokens = string.Format("{0}\\.azure\\accessTokens.json", System.Environment.GetEnvironmentVariable("USERPROFILE")); - if (System.IO.File.Exists(azureTokens)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureTokens); - DateTime lastModified = System.IO.File.GetLastWriteTime(azureTokens); - long size = new System.IO.FileInfo(azureTokens).Length; - results.Add(new Dictionary() { - { "file", azureTokens }, - { "Description", "Azure tokens" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); - } - string azureProfile = string.Format("{0}\\.azure\\azureProfile.json", System.Environment.GetEnvironmentVariable("USERPROFILE")); - if (System.IO.File.Exists(azureProfile)) - { - DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureProfile); - DateTime lastModified = System.IO.File.GetLastWriteTime(azureProfile); - long size = new System.IO.FileInfo(azureProfile).Length; - results.Add(new Dictionary() { - { "file", azureProfile }, - { "Description", "Azure profile" }, - { "Accessed", string.Format("{0}", lastAccessed) }, - { "Modified", string.Format("{0}", lastModified) }, - { "Size", string.Format("{0}", size) } - }); + var file = item.Key; + var description = item.Value; + + var fullFilePath = Path.Combine(userDir, file); + + AddCloudCredentialFromFile(fullFilePath, description, results); } } } catch (Exception ex) { - Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex)); + Beaprint.PrintException(ex.Message); } return results; } + private static void AddCloudCredentialFromFile(string filePath, string description, ICollection> results) + { + if (File.Exists(filePath)) + { + DateTime lastAccessed = File.GetLastAccessTime(filePath); + DateTime lastModified = File.GetLastWriteTime(filePath); + long size = new FileInfo(filePath).Length; + + results?.Add(new Dictionary + { + { "file", filePath }, + { "Description", description }, + { "Accessed", $"{lastAccessed}"}, + { "Modified", $"{lastModified}"}, + { "Size", $"{size}"} + }); + } + } public static List> GetRecentFiles() { diff --git a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Putty.cs b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Putty.cs index 938a042..4849239 100644 --- a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Putty.cs +++ b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/Putty.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Microsoft.Win32; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.KnownFileCreds { diff --git a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/RemoteDesktop.cs b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/RemoteDesktop.cs index b721127..6ccb429 100644 --- a/winPEAS/winPEASexe/winPEAS/KnownFileCreds/RemoteDesktop.cs +++ b/winPEAS/winPEASexe/winPEAS/KnownFileCreds/RemoteDesktop.cs @@ -4,6 +4,7 @@ using System.IO; using System.Xml; using Microsoft.Win32; using winPEAS.Helpers; +using winPEAS.Helpers.Registry; namespace winPEAS.KnownFileCreds { diff --git a/winPEAS/winPEASexe/winPEAS/Native/Structs/LastInputInfo.cs b/winPEAS/winPEASexe/winPEAS/Native/Structs/LastInputInfo.cs new file mode 100644 index 0000000..b134d5a --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Native/Structs/LastInputInfo.cs @@ -0,0 +1,8 @@ +namespace winPEAS.Native.Structs +{ + internal struct LastInputInfo + { + public uint Size; + public uint Time; + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Native/User32.cs b/winPEAS/winPEASexe/winPEAS/Native/User32.cs index ab53888..485eab3 100644 --- a/winPEAS/winPEASexe/winPEAS/Native/User32.cs +++ b/winPEAS/winPEASexe/winPEAS/Native/User32.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Text; +using winPEAS.Native.Structs; namespace winPEAS.Native { @@ -12,5 +13,10 @@ namespace winPEAS.Native [DllImport("user32.dll")] internal static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); + [DllImport("User32.dll")] + public static extern bool GetLastInputInfo(ref LastInputInfo lastInputInfo); + + [DllImport("user32.dll")] + public static extern bool SetProcessDPIAware(); } } diff --git a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj index 6b6f8f6..ec91849 100755 --- a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj +++ b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj @@ -410,6 +410,11 @@ + + + + + @@ -428,6 +433,8 @@ + + @@ -514,6 +521,7 @@ +