diff --git a/winPEAS/winPEASexe/README.md b/winPEAS/winPEASexe/README.md index e9c8590..0490e62 100755 --- a/winPEAS/winPEASexe/README.md +++ b/winPEAS/winPEASexe/README.md @@ -81,7 +81,7 @@ filesinfo Search files that can contains credentials eventsinfo Display interesting events information wait Wait for user input between checks debug Display debugging information - memory usage, method execution time -log Log all output to file "out.txt" +log=[logfile] Log all output to file defined as logfile, or to "out.txt" if not specified Additional checks (slower): -lolbas Run additional LOLBAS check diff --git a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs index 9ce51be..f386204 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs @@ -44,11 +44,11 @@ namespace winPEAS.Checks // github url for Linpeas.sh public static string LinpeasUrl = "https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh"; - public const string LogFile = "out.txt"; + public const string DefaultLogFile = "out.txt"; class SystemCheck - { + { public string Key { get; } public ISystemCheck Check { get; } @@ -96,20 +96,34 @@ namespace winPEAS.Checks return; } - if (string.Equals(arg, "log", StringComparison.CurrentCultureIgnoreCase)) + if (arg.StartsWith("log", StringComparison.CurrentCultureIgnoreCase)) { + // get logfile argument if present + string logFile = DefaultLogFile; + var parts = arg.Split('='); + if (parts.Length == 2) + { + logFile = parts[1]; + + if (string.IsNullOrWhiteSpace(logFile)) + { + Beaprint.PrintException("Please specify a valid log file."); + return; + } + } + try { - fileStream = new FileStream(LogFile, FileMode.OpenOrCreate, FileAccess.Write); + fileStream = new FileStream(logFile, FileMode.OpenOrCreate, FileAccess.Write); fileWriter = new StreamWriter(fileStream); } catch (Exception ex) { - Beaprint.PrintException($"Cannot open \"{LogFile}\" for writing:\n {ex.Message}"); + Beaprint.PrintException($"Cannot open \"{logFile}\" for writing:\n {ex.Message}"); return; } - Beaprint.ColorPrint($"\"log\" argument present, redirecting output to file \"{LogFile}\"", Beaprint.ansi_color_good); + Beaprint.ColorPrint($"\"log\" argument present, redirecting output to file \"{logFile}\"", Beaprint.ansi_color_good); Console.SetOut(fileWriter); } @@ -257,7 +271,7 @@ namespace winPEAS.Checks try { Beaprint.GrayPrint(" - Getting Win32_UserAccount info..."); - + // by default only enumerate local users SelectQuery query = new SelectQuery("Win32_UserAccount", "LocalAccount=true"); if (IsDomainEnumeration) diff --git a/winPEAS/winPEASexe/winPEAS/Checks/ServicesInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/ServicesInfo.cs index 288db6c..ec329bc 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/ServicesInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/ServicesInfo.cs @@ -15,13 +15,13 @@ namespace winPEAS.Checks Beaprint.GreatPrint("Services Information"); /// Start finding Modifiable services so any function could use them - + try { CheckRunner.Run(() => { modifiableServices = ServicesInfoHelper.GetModifiableServices(winPEAS.Checks.Checks.CurrentUserSiDs); - }, isDebug); + }, isDebug); } catch (Exception ex) { @@ -34,7 +34,7 @@ namespace winPEAS.Checks PrintModifiableServices, PrintWritableRegServices, PrintPathDllHijacking, - }.ForEach(action => CheckRunner.Run(action, isDebug)); + }.ForEach(action => CheckRunner.Run(action, isDebug)); } void PrintInterestingServices() @@ -124,10 +124,22 @@ namespace winPEAS.Checks Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can modify any service"); if (modifiableServices.Count > 0) { - Beaprint.BadPrint(" LOOKS LIKE YOU CAN MODIFY SOME SERVICE/s:"); + Beaprint.BadPrint(" LOOKS LIKE YOU CAN MODIFY OR START/STOP SOME SERVICE/s:"); Dictionary colorsMS = new Dictionary() { - { ".*", Beaprint.ansi_color_bad }, + // modify + { "AllAccess", Beaprint.ansi_color_bad }, + { "ChangeConfig", Beaprint.ansi_color_bad }, + { "WriteDac", Beaprint.ansi_color_bad }, + { "WriteOwner", Beaprint.ansi_color_bad }, + { "AccessSystemSecurity", Beaprint.ansi_color_bad }, + { "GenericAll", Beaprint.ansi_color_bad }, + { "GenericWrite (ChangeConfig)", Beaprint.ansi_color_bad }, + + // start/stop + { "GenericExecute (Start/Stop)", Beaprint.ansi_color_yellow }, + { "Start", Beaprint.ansi_color_yellow }, + { "Stop", Beaprint.ansi_color_yellow }, }; Beaprint.DictPrint(modifiableServices, colorsMS, false, true); } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs b/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs index 628b581..01d7a43 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/WindowsCreds.cs @@ -22,7 +22,7 @@ namespace winPEAS.Checks public void PrintInfo(bool isDebug) { Beaprint.GreatPrint("Windows Credentials"); - + new List { PrintVaultCreds, @@ -184,7 +184,7 @@ namespace winPEAS.Checks Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi"); var credFiles = KnownFileCredsInfo.GetCredFiles(); Beaprint.DictPrint(credFiles, false); - + if (credFiles.Count != 0) { Beaprint.InfoPrint("Follow the provided link for further instructions in how to decrypt the creds file"); @@ -201,11 +201,11 @@ namespace winPEAS.Checks try { Beaprint.MainPrint("Checking for RDCMan Settings Files"); - Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager", + Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager", "Dump credentials from Remote Desktop Connection Manager"); var rdcFiles = RemoteDesktop.GetRDCManFiles(); Beaprint.DictPrint(rdcFiles, false); - + if (rdcFiles.Count != 0) { Beaprint.InfoPrint("Follow the provided link for further instructions in how to decrypt the .rdg file"); @@ -252,6 +252,9 @@ namespace winPEAS.Checks try { Beaprint.MainPrint("Looking for saved Wifi credentials"); + + WlanClient wlanClient = new WlanClient(); + foreach (var @interface in new WlanClient().Interfaces) { foreach (var profile in @interface.GetProfiles()) @@ -276,6 +279,26 @@ namespace winPEAS.Checks catch (Exception ex) { Beaprint.PrintException(ex.Message); + + // revert to old way + Beaprint.NoColorPrint("Enumerating WLAN using wlanapi.dll failed, trying to enumerate using 'netsh'"); + + Dictionary networkConnections = Wifi.Wifi.Retrieve(); + Dictionary ansi_colors_regexp = new Dictionary(); + + if (networkConnections.Count > 0) + { + //Make sure the passwords are all flagged as ansi_color_bad. + foreach (var connection in networkConnections) + { + ansi_colors_regexp.Add(connection.Value, Beaprint.ansi_color_bad); + } + Beaprint.DictPrint(networkConnections, ansi_colors_regexp, false); + } + else + { + Beaprint.NoColorPrint("No saved Wifi credentials found"); + } } } @@ -302,7 +325,7 @@ namespace winPEAS.Checks Beaprint.NoColorPrint(" You must be an administrator to run this check"); return; } - + var script = AppCmd.GetExtractAppCmdCredsPowerShellScript(); string args = @$" {script}"; @@ -346,7 +369,7 @@ namespace winPEAS.Checks { Beaprint.MainPrint("Looking SSClient.exe"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#scclient-sccm"); - + if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe"))) { Beaprint.BadPrint(" SCClient.exe was found in " + Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe DLL Side loading?")); @@ -470,7 +493,7 @@ namespace winPEAS.Checks { 2, "Require Remote Credential Guard" }, { 3, "Require Restricted Admin or Remote Credential Guard" }, }; - + var str = $"{type} - Unknown"; if (types.ContainsKey(type.Value)) diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs index 89b2c3b..51d373a 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs @@ -31,7 +31,7 @@ namespace winPEAS.Helpers public static string ansi_users_disabled = BLUE; public static string ansi_current_user = MAGENTA; - private static string Advisory = + private static string Advisory = "winpeas should be used for authorized penetration testing and/or educational purposes only." + "Any misuse of this software will not be the responsibility of the author or of any other collaborator. " + "Use it at your own networks and/or with the network owner's permission."; @@ -43,7 +43,7 @@ namespace winPEAS.Helpers ///////////////////////////////// public static void PrintBanner() { - Console.WriteLine(BLUE + string.Format(@" + Console.WriteLine(BLUE + string.Format(@" {0}*((,.,/((((((((((((((((((((/, */ {0},/*,..*((((((((((((((((((((((((((((((((((, {0},*/((((((((((((((((((/, .*//((//**, .*(((((((* @@ -71,9 +71,9 @@ namespace winPEAS.Helpers {0}(((((((((/,. ,*//////*,. ./(((((((((((((((. {0}(((((((((((((((((((((((((((((/", LGREEN, GREEN, BLUE, NOCOLOR) + NOCOLOR); - Console.WriteLine(); - Console.WriteLine(LYELLOW + "ADVISORY: " + BLUE + Advisory); - Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(LYELLOW + "ADVISORY: " + BLUE + Advisory); + Console.WriteLine(); } public static void PrintMarketingBanner() @@ -140,13 +140,13 @@ namespace winPEAS.Helpers Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR); Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR); Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR); - Console.WriteLine(LBLUE + " log" + GRAY +$" Log all output to file \"{Checks.Checks.LogFile}\"" + NOCOLOR); + Console.WriteLine(LBLUE + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR); Console.WriteLine(); Console.WriteLine(LCYAN + " Additional checks (slower):"); Console.WriteLine(LBLUE + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR); Console.WriteLine(LBLUE + " -linpeas=[url]" + GRAY + $" Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL\n" + $" (default: {Checks.Checks.LinpeasUrl})" + NOCOLOR); - + } @@ -215,7 +215,7 @@ namespace winPEAS.Helpers internal static void PrintDebugLine(string log) { - Console.WriteLine(YELLOW + " [Debug] " + log + NOCOLOR); + Console.WriteLine(YELLOW + " [Debug] " + log + NOCOLOR); Console.WriteLine(); } @@ -228,7 +228,7 @@ namespace winPEAS.Helpers public static void PrintException(string message) { GrayPrint($" [X] Exception: {message}"); - } + } public static void AnsiPrint(string to_print, Dictionary ansi_colors_regexp) { diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/PermissionsHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/PermissionsHelper.cs index d85cd4b..0c070ad 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/PermissionsHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/PermissionsHelper.cs @@ -84,7 +84,7 @@ namespace winPEAS.Helpers return results; } - public static List GetMyPermissionsF(FileSecurity fSecurity, Dictionary SIDs, PermissionType permissionType = PermissionType.DEFAULT) + public static List GetMyPermissionsF(FileSecurity fSecurity, Dictionary SIDs, PermissionType permissionType = PermissionType.DEFAULT) { // Get interesting permissions in fSecurity (Only files and folders) List results = new List(); @@ -271,11 +271,15 @@ namespace winPEAS.Helpers else if (permissionType == PermissionType.WRITEABLE_OR_EQUIVALENT_SVC) { + // docs: + // https://docs.microsoft.com/en-us/windows/win32/services/service-security-and-access-rights + // https://docs.microsoft.com/en-us/troubleshoot/windows-server/windows-security/grant-users-rights-manage-services + interesting_perms = new Dictionary() { - { "AllAccess", 0xf01ff}, + { "AllAccess", 0xf01ff}, // full control //{"QueryConfig" , 1}, //Grants permission to query the service's configuration. - //{"ChangeConfig" , 2}, //Grants permission to change the service's permission. + {"ChangeConfig" , 2}, //Grants permission to change the service's permission. //{"QueryStatus" , 4}, //Grants permission to query the service's status. //{"EnumerateDependents" , 8}, //Grants permissionto enumerate the service's dependent services. //{"PauseContinue" , 64}, //Grants permission to pause/continue the service. @@ -283,15 +287,17 @@ namespace winPEAS.Helpers //{"UserDefinedControl" , 256}, //Grants permission to run the service's user-defined control. //{"Delete" , 65536}, //Grants permission to delete the service. //{"ReadControl" , 131072}, //Grants permission to query the service's security descriptor. - {"WriteDac" , 262144}, //Grants permission to set the service's discretionary access list. - {"WriteOwner" , 524288}, //Grants permission to modify the group and owner of a service. + {"WriteDac" , 0x40000}, //Grants permission to set the service's discretionary access list. + {"WriteOwner" , 0x80000}, //Grants permission to modify the group and owner of a service. //{"Synchronize" , 1048576}, {"AccessSystemSecurity" , 16777216}, //The right to get or set the SACL in the object security descriptor. - {"GenericAll" , 268435456}, - {"GenericWrite" , 1073741824}, - {"GenericExecute" , 536870912}, - {"Start" , 16}, //Grants permission to start the service. - {"Stop" , 32}, //Grants permission to stop the service. + {"GenericAll" , 0x1000_0000}, + //{"GenericWrite" , 0x4000_0000}, + //{"GenericExecute" , 0x2000_0000}, + {"GenericWrite (ChangeConfig)" , 0x2_0002}, + {"GenericExecute (Start/Stop)" , 0x2_01F0}, + {"Start" , 0x0010}, //Grants permission to start the service. + {"Stop" , 0x0020}, //Grants permission to stop the service. //{"GenericRead" , 2147483648} }; } @@ -302,8 +308,8 @@ namespace winPEAS.Helpers foreach (KeyValuePair entry in interesting_perms) { if ((entry.Value & current_perm) == entry.Value) - { - return entry.Key; + { + return entry.Key; } } }