From bbc22b3a9110ee2178e93130c358ed2eff0e4e3b Mon Sep 17 00:00:00 2001 From: carlospolop Date: Sat, 30 Jul 2022 12:06:10 +0200 Subject: [PATCH] update --- winPEAS/README.md | 4 - winPEAS/winPEASbat/README.md | 4 - winPEAS/winPEASexe/README.md | 18 +- winPEAS/winPEASexe/winPEAS/Checks/Checks.cs | 21 +- .../winPEASexe/winPEAS/Checks/FileAnalysis.cs | 263 ++- .../winPEASexe/winPEAS/Checks/NetworkInfo.cs | 11 + .../winPEASexe/winPEAS/Checks/ProcessInfo.cs | 22 +- .../winPEASexe/winPEAS/Checks/SystemInfo.cs | 59 +- .../winPEASexe/winPEAS/Helpers/Beaprint.cs | 82 +- .../winPEAS/Helpers/CustomFileInfo.cs | 4 +- .../winPEAS/Helpers/HandlesHelper.cs | 601 +++++++ .../winPEASexe/winPEAS/Helpers/ProgressBar.cs | 88 + .../Helpers/Registry/RegistryHelper.cs | 36 + .../winPEAS/Helpers/Search/SearchHelper.cs | 52 +- .../winPEAS/Helpers/YamlConfig/YamlConfig.cs | 19 + .../Helpers/YamlConfig/YamlConfigHelper.cs | 39 +- .../Info/NetworkInfo/NetworkInfoHelper.cs | 16 +- .../winPEAS/Info/ProcessInfo/ProcessesInfo.cs | 190 ++- .../SystemInfo/NamedPipes/NamedPipeInfo.cs | 4 +- .../Info/SystemInfo/NamedPipes/NamedPipes.cs | 8 +- .../winPEAS/Info/SystemInfo/SystemInfo.cs | 6 +- winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs | 30 + winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs | 28 + winPEAS/winPEASexe/winPEAS/Native/Psapi.cs | 7 + winPEAS/winPEASexe/winPEAS/winPEAS.csproj | 1454 +++++++++-------- .../winPEASexe/winPEAS/winPEAS.csproj.user | 66 +- 26 files changed, 2236 insertions(+), 896 deletions(-) create mode 100644 winPEAS/winPEASexe/winPEAS/Helpers/HandlesHelper.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Helpers/ProgressBar.cs create mode 100644 winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs diff --git a/winPEAS/README.md b/winPEAS/README.md index 91002be..6635535 100755 --- a/winPEAS/README.md +++ b/winPEAS/README.md @@ -14,10 +14,6 @@ Find the **latest versions of all the scripts and binaries in [the releases page - [Link to WinPEAS C# project (.exe)](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required) - **Please, read the Readme of that folder to learn how to execute winpeas from memory or how make colors work among other tricks** -## Please, if this tool has been useful for you consider to donate - -[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.patreon.com/peass) - ## PEASS Style Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/stores/peass)** and show your love for our favorite peas diff --git a/winPEAS/winPEASbat/README.md b/winPEAS/winPEASbat/README.md index 0df59d2..b45312b 100755 --- a/winPEAS/winPEASbat/README.md +++ b/winPEAS/winPEASbat/README.md @@ -129,10 +129,6 @@ This is the kind of outpuf that you have to look for when usnig the winPEAS.bat [More info about icacls here](https://ss64.com/nt/icacls.html) -## Please, if this tool has been useful for you consider to donate - -[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.patreon.com/peass) - ## Advisory All the scripts/binaries of the PEAS Suite 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. diff --git a/winPEAS/winPEASexe/README.md b/winPEAS/winPEASexe/README.md index 8993c39..9f3511b 100755 --- a/winPEAS/winPEASexe/README.md +++ b/winPEAS/winPEASexe/README.md @@ -66,8 +66,7 @@ winpeas.exe -lolbas #Execute also additional LOLBAS search check ## Help ``` -quiet Do not print banner -notcolor Don't use ansi colors (all white) +domain Enumerate domain information systeminfo Search system information userinfo Search user information processinfo Search processes information @@ -76,16 +75,21 @@ applicationsinfo Search installed applications information networkinfo Search network information windowscreds Search windows credentials browserinfo Search browser information -filesinfo Search files that can contains credentials +filesinfo Search generic files that can contains credentials +fileanalysis Search specific files that can contains credentials and for regexes inside files eventsinfo Display interesting events information + +quiet Do not print banner +notcolor Don't use ansi colors (all white) +searchpf Search credentials via regex also in Program Files folders wait Wait for user input between checks debug Display debugging information - memory usage, method execution time -log=[logfile] Log all output to file defined as logfile, or to "out.txt" if not specified +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 -linpeas=[url] Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL - (default: https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh) + (default: https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh) ``` ## Basic information @@ -276,10 +280,6 @@ If you find any issue, please report it using **[github issues](https://github.c **WinPEAS** is being **updated** every time I find something that could be useful to escalate privileges. -## Please, if this tool has been useful for you consider to donate - -[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.patreon.com/peass) - ## Advisory All the scripts/binaries of the PEAS Suite 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. diff --git a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs index 2128063..96f478c 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs @@ -21,6 +21,7 @@ namespace winPEAS.Checks public static bool IsDebug = false; public static bool IsLinpeas = false; public static bool IsLolbas = false; + public static bool SearchProgramFiles = false; // Create Dynamic blacklists public static readonly string CurrentUserName = Environment.UserName; @@ -37,6 +38,7 @@ namespace winPEAS.Checks //static string paint_lockoutUsers = ""; public static string PaintAdminUsers = ""; public static YamlConfig YamlConfig; + public static YamlRegexConfig RegexesYamlConfig; private static List _systemChecks; private static readonly HashSet _systemCheckSelectedKeysHashSet = new HashSet(); @@ -152,6 +154,11 @@ namespace winPEAS.Checks IsDomainEnumeration = true; } + if (string.Equals(arg, "searchpf", StringComparison.CurrentCultureIgnoreCase)) + { + SearchProgramFiles = true; + } + if (string.Equals(arg, "-lolbas", StringComparison.CurrentCultureIgnoreCase)) { IsLolbas = true; @@ -248,12 +255,22 @@ namespace winPEAS.Checks try { - Beaprint.GrayPrint(" - Loading YAML definitions file..."); + Beaprint.GrayPrint(" - Loading sensitive_files yaml definitions file..."); YamlConfig = YamlConfigHelper.GetWindowsSearchConfig(); } catch (Exception ex) { - Beaprint.GrayPrint("Error while getting AD info: " + ex); + Beaprint.GrayPrint("Error while getting sensitive_files yaml info: " + ex); + } + + try + { + Beaprint.GrayPrint(" - Loading regexes yaml definitions file..."); + RegexesYamlConfig = YamlConfigHelper.GetRegexesSearchConfig(); + } + catch (Exception ex) + { + Beaprint.GrayPrint("Error while getting regexes yaml info: " + ex); } try diff --git a/winPEAS/winPEASexe/winPEAS/Checks/FileAnalysis.cs b/winPEAS/winPEASexe/winPEAS/Checks/FileAnalysis.cs index d0dce53..e457870 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/FileAnalysis.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/FileAnalysis.cs @@ -3,12 +3,14 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; +using System.Threading.Tasks; using winPEAS.Helpers; using winPEAS.Helpers.Search; using static winPEAS.Helpers.YamlConfig.YamlConfig.SearchParameters; namespace winPEAS.Checks { + internal class FileAnalysis : ISystemCheck { private const int ListFileLimit = 70; @@ -19,11 +21,12 @@ namespace winPEAS.Checks new List { - PrintYAMLSearchFiles + PrintYAMLSearchFiles, + PrintYAMLRegexesSearchFiles }.ForEach(action => CheckRunner.Run(action, isDebug)); } - private static List InitializeFileSearch() + private static List InitializeFileSearch(bool useProgramFiles=true) { var files = new List(); var systemDrive = $"{SearchHelper.SystemDrive}\\"; @@ -56,8 +59,11 @@ namespace winPEAS.Checks // files.AddRange(SearchHelper.RootDirCurrentUser); // not needed, it's contained within RootDirUsers files.AddRange(SearchHelper.DocumentsAndSettings); files.AddRange(SearchHelper.GroupPolicyHistory); // TODO maybe not needed here - files.AddRange(SearchHelper.ProgramFiles); - files.AddRange(SearchHelper.ProgramFilesX86); + if (useProgramFiles) + { + files.AddRange(SearchHelper.ProgramFiles); + files.AddRange(SearchHelper.ProgramFilesX86); + } return files; } @@ -65,25 +71,47 @@ namespace winPEAS.Checks private static bool[] Search(List files, string fileName, FileSettings fileSettings, ref int resultsCount, string searchName, bool somethingFound) { bool isRegexSearch = fileName.Contains("*"); + bool isFolder = fileSettings.files != null; string pattern = string.Empty; + if (isRegexSearch) { pattern = GetRegexpFromString(fileName); - } - + } + foreach (var file in files) { - bool isFileFound; - if (isRegexSearch) - { - isFileFound = Regex.IsMatch(file.Filename, pattern, RegexOptions.IgnoreCase); + bool isFileFound = false; + + if (isFolder) + { + if (pattern == string.Empty) + { + isFileFound = file.FullPath.ToLower().Contains($"\\{fileName}\\"); + } + else + { + foreach (var fold in file.FullPath.Split('\\').Skip(1)) + { + isFileFound = Regex.IsMatch(fold, pattern, RegexOptions.IgnoreCase); + if (isFileFound) break; + } + } } else { - isFileFound = file.Filename.ToLower() == fileName; + if (pattern == String.Empty) + { + isFileFound = file.Filename.ToLower() == fileName.ToLower(); + } + else + { + isFileFound = Regex.IsMatch(file.Filename, pattern, RegexOptions.IgnoreCase); + } } + if (isFileFound) { if (!somethingFound) { @@ -91,8 +119,7 @@ namespace winPEAS.Checks somethingFound = true; } - // there are no inner sections - if (fileSettings.files == null) + if (!isFolder) { var isProcessed = ProcessResult(file, fileSettings, ref resultsCount); if (!isProcessed) @@ -105,18 +132,8 @@ namespace winPEAS.Checks { foreach (var innerFileToSearch in fileSettings.files) { - // search for inner files/folders by inner file/folder name - var innerFiles = SearchHelper.GetFilesFast(file.FullPath, innerFileToSearch.name, isFoldersIncluded: true); - - foreach (var innerFile in innerFiles) - { - // process inner file/folder - var isProcessed = ProcessResult(innerFile, innerFileToSearch.value, ref resultsCount); - if (!isProcessed) - { - return new bool[] { true, somethingFound }; - } - } + List one_file_list = new List() { file }; + Search(one_file_list, innerFileToSearch.name, innerFileToSearch.value, ref resultsCount, searchName, somethingFound); } } } @@ -124,22 +141,52 @@ namespace winPEAS.Checks return new bool[] { false, somethingFound }; } - + + private static List SearchContent(string text, string regex_str, bool caseinsensitive) + { + List foundMatches = new List(); + + try + { + Regex rgx; + if (caseinsensitive) + rgx = new Regex(regex_str.Trim(), RegexOptions.IgnoreCase); + else + rgx = new Regex(regex_str.Trim()); + + int cont = 0; + foreach (Match match in rgx.Matches(text)) + { + if (cont > 4) break; + + if (match.Value.Length < 400 && match.Value.Trim().Length > 2) + foundMatches.Add(match.Value); + + cont++; + } + } + catch (Exception e) + { + Beaprint.GrayPrint($"Error looking for regex {regex_str} inside files: {e}"); + } + + //} + + return foundMatches; + } + private static void PrintYAMLSearchFiles() { try { var files = InitializeFileSearch(); - var folders = files.Where(f => f.IsDirectory).ToList(); + //var folders = files.Where(f => f.IsDirectory).ToList(); var config = Checks.YamlConfig; var defaults = config.defaults; - var searchItems = config.search.Where(i => i.value.config.auto_check && - (i.value.disable == null || !i.value.disable.Contains("winpeas"))); + var searchItems = config.search.Where(i => !(i.value.disable != null && i.value.disable.Contains("winpeas"))); foreach (var searchItem in searchItems) { - if (searchItem.name != "Wifi Connections") - continue; var searchName = searchItem.name; var value = searchItem.value; var searchConfig = value.config; @@ -155,9 +202,8 @@ namespace winPEAS.Checks { var fileName = file.name.ToLower(); var fileSettings = file.value; - var itemsToSearch = fileSettings.type == "f" ? files : folders; - results = Search(itemsToSearch, fileName, fileSettings, ref resultsCount, searchName, somethingFound); + results = Search(files, fileName, fileSettings, ref resultsCount, searchName, somethingFound); isSearchFinished = results[0]; somethingFound = results[1]; @@ -175,6 +221,146 @@ namespace winPEAS.Checks } } + private static void PrintYAMLRegexesSearchFiles() + { + try + { + //List extra_no_extensions = new List() { ".msi", ".exe", ".dll", ".pyc", ".pyi", ".lnk", ".css", ".hyb", ".etl", ".mo", ".xrm-ms", ".idl", ".vsix", ".mui", ".qml", ".tt" }; + + List valid_extensions = new List() { + // text + ".txt", ".text", ".md", ".markdown", ".toml", ".rtf", + + // config + ".conf", ".config", ".json", ".yml", ".yaml", ".xml", ".xaml", + + // dev + ".py", ".js", ".html", ".c", ".cpp", ".pl", ".rb", ".smali", ".java", ".php", ".bat", ".ps1", + + // hidden + ".id_rsa", ".id_dsa", ".bash_history", ".rsa", + }; + + List invalid_names = new List() + { + "eula.rtf", "changelog.md" + }; + + // No dirs, less thatn 1MB, only interesting extensions and not false positives files. + var files = InitializeFileSearch(Checks.SearchProgramFiles).Where(f => !f.IsDirectory && valid_extensions.Contains(f.Extension.ToLower()) && !invalid_names.Contains(f.Filename.ToLower()) && f.Size > 0 && f.Size < 1000000).ToList(); + var config = Checks.RegexesYamlConfig; // Get yaml info + Dictionary>>> foundRegexes = new Dictionary>>> { }; + + /* + * Useful for debbugging purposes to see the common file extensions found + Dictionary dict_str = new Dictionary(); + foreach (var f in files) + { + if (dict_str.ContainsKey(f.Extension)) + dict_str[f.Extension] += 1; + else + dict_str[f.Extension] = 1; + } + + var sortedDict = from entry in dict_str orderby entry.Value descending select entry; + + foreach (KeyValuePair kvp in sortedDict) + { + Console.WriteLine(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value)); + }*/ + + double pb = 0; + using (var progress = new ProgressBar()) + { + CheckRunner.Run(() => + { + int num_threads = 8; + try + { + num_threads = Environment.ProcessorCount; + } + catch (Exception ex) { } + + Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f => + { + //foreach (var f in files) + //{ + foreach (var regex_obj in config.regular_expresions) + { + foreach (var regex in regex_obj.regexes) + { + if (regex.disable != null && regex.disable.ToLower().Contains("winpeas")) + { + continue; + } + + List results = new List { }; + + try + { + string text = System.IO.File.ReadAllText(f.FullPath); + + results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive); + if (results.Count > 0) + { + if (!foundRegexes.ContainsKey(regex_obj.name)) foundRegexes[regex_obj.name] = new Dictionary>> { }; + if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary> { }; + + foundRegexes[regex_obj.name][regex.name][f.FullPath] = results; + } + } + catch (System.IO.IOException) + { + // Cannot read the file + } + } + } + pb += (double)100 / files.Count; + progress.Report(pb / 100); //Value must be in [0..1] range + }); + //} + }, Checks.IsDebug); + } + + // Print results + foreach (KeyValuePair>>> item in foundRegexes) + { + foreach (KeyValuePair>> item2 in item.Value) + { + string masterCategory = item.Key; + string regexCategory = item2.Key; + int limit = 70; + + string msg = $"Found {masterCategory}-{regexCategory} Regexes"; + if (item2.Value.Count > limit) + msg += $" (limited to {limit})"; + + Beaprint.MainPrint(msg); + + int cont = 0; + foreach (KeyValuePair> item3 in item2.Value) + { + if (cont > limit) + break; + + foreach (string regexMatch in item3.Value) + { + string filePath = item3.Key; + Beaprint.PrintNoNL($"{filePath}: "); + Beaprint.BadPrint(regexMatch); + } + + cont++; + } + } + } + } + catch (Exception e) + { + Beaprint.GrayPrint($"Error looking for regexes inside files: {e}"); + } + } + private static string GetRegexpFromString(string str) { // we need to update the regexp to work here @@ -199,7 +385,16 @@ namespace winPEAS.Checks resultsCount++; if (resultsCount > ListFileLimit) return false; - + + // If contains undesireable string, stop processing + if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0) + { + foreach(var rem_path in fileSettings.remove_path.Split('|')) + { + if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower())) + return false; + } + } if (fileSettings.type == "f") { diff --git a/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs index 7e3710c..83eb4b7 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/NetworkInfo.cs @@ -21,6 +21,7 @@ namespace winPEAS.Checks { { badIps, Beaprint.ansi_color_bad }, { @"\[\:\:1\]", Beaprint.ansi_color_bad }, + { @"\[\:\:\]", Beaprint.ansi_color_bad }, }; public void PrintInfo(bool isDebug) @@ -223,6 +224,11 @@ namespace winPEAS.Checks foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv4, processesByPid)) { + if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes + { + continue; + } + Beaprint.AnsiPrint( string.Format(formatString, " UDP", @@ -254,6 +260,11 @@ namespace winPEAS.Checks foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv6, processesByPid)) { + if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes + { + continue; + } + Beaprint.AnsiPrint( string.Format(formatString, " UDP", diff --git a/winPEAS/winPEASexe/winPEAS/Checks/ProcessInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/ProcessInfo.cs index d9b230f..07a27dc 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/ProcessInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/ProcessInfo.cs @@ -14,7 +14,8 @@ namespace winPEAS.Checks new List { - PrintInterestingProcesses, + //PrintInterestingProcesses, + PrintVulnLeakedHandlers, }.ForEach(action => CheckRunner.Run(action, isDebug)); } @@ -83,5 +84,24 @@ namespace winPEAS.Checks Beaprint.GrayPrint(ex.Message); } } + + void PrintVulnLeakedHandlers() + { + Beaprint.MainPrint("Vulnerable Leaked Handlers"); + Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/leaked-handle-exploitation"); + + List> vulnHandlers = ProcessesInfo.GetVulnHandlers(); + foreach (Dictionary handler in vulnHandlers) + { + Dictionary colors = new Dictionary() + { + { Checks.CurrentUserName, Beaprint.ansi_color_bad }, + { handler["Reason"], Beaprint.ansi_color_bad }, + }; + + Beaprint.DictPrint(vulnHandlers, colors, true); + } + + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs index 19e3666..1723ed5 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs @@ -79,6 +79,8 @@ namespace winPEAS.Checks PrintInetInfo, PrintDrivesInfo, PrintWSUS, + PrintKrbRelayUp, + PrintInsideContainer, PrintAlwaysInstallElevated, PrintLSAInfo, PrintNtlmSettings, @@ -586,6 +588,52 @@ namespace winPEAS.Checks } } + static void PrintKrbRelayUp() + { + try + { + Beaprint.MainPrint("Checking KrbRelayUp"); + Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#krbrelayup"); + + if (Checks.CurrentAdDomainName.Length > 0) + { + Beaprint.BadPrint(" The system is inside a domain (" + Checks.CurrentAdDomainName + ") so it could be vulnerable."); + Beaprint.InfoPrint("You can try https://github.com/DecOne/KrbRelayUp to escalate privileges"); + } + else + { + Beaprint.GoodPrint(" The system isn't inside a domain, so it isn't vulnerable"); + } + } + catch (Exception ex) + { + Beaprint.PrintException(ex.Message); + } + } + + static void PrintInsideContainer() + { + try + { + Beaprint.MainPrint("Checking If Inside Container"); + Beaprint.LinkPrint("", "If the binary cexecsvc.exe or associated service exists, you are inside Docker"); + Dictionary regVal = RegistryHelper.GetRegValues("HKLM", @"System\CurrentControlSet\Services\cexecsvc"); + bool cexecsvcExist = File.Exists(Environment.SystemDirectory + @"\cexecsvc.exe"); + if (regVal != null || cexecsvcExist) + { + Beaprint.BadPrint("You are inside a container"); + } + else + { + Beaprint.GoodPrint("You are NOT inside a container"); + } + } + catch (Exception ex) + { + Beaprint.PrintException(ex.Message); + } + } + static void PrintAlwaysInstallElevated() { try @@ -721,13 +769,18 @@ namespace winPEAS.Checks try { - string formatString = " {0,-100} {1}\n"; + string formatString = " {0,-100} {1,-70} {2}\n"; - Beaprint.NoColorPrint(string.Format($"{formatString}", "Name", "Sddl")); + Beaprint.NoColorPrint(string.Format($"{formatString}", "Name", "CurrentUserPerms", "Sddl")); foreach (var namedPipe in NamedPipes.GetNamedPipeInfos()) { - Beaprint.BadPrint(string.Format(formatString, namedPipe.Name, namedPipe.Sddl)); + var colors = new Dictionary + { + {namedPipe.CurrentUserPerms.Replace("[","\\[").Replace("]","\\]"), Beaprint.ansi_color_bad }, + }; + + Beaprint.AnsiPrint(string.Format(formatString, namedPipe.Name, namedPipe.CurrentUserPerms, namedPipe.Sddl), colors); } } catch (Exception ex) diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs index 4772b9a..f6182f6 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs @@ -34,9 +34,7 @@ namespace winPEAS.Helpers 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."; - - private static string Version = "ng"; + "Use it at your own devices and/or with the device owner's permission."; ///////////////////////////////// ///////// PRINT THINGS ///////// @@ -46,27 +44,27 @@ namespace winPEAS.Helpers Console.WriteLine(BLUE + string.Format(@" {0}(((((((((((((((((((((((((((((((( {0}((((((((((((((((((((((((((((((((((((((((((( - {0}(((((((((((((({2}**********/{1}##########{0}.(((((((((((( - {0}(((((((((((/{2}********************/{1}#######{0}.(((((((((( - {0}(((((((.{2}******************{3}/@@@@@/{0}{2}****{1}######{0}.((((((((( - {0}(((((.{2}********************{3}@@@@@@@@@@/{0}{2}***,{1}####{0}.((((((((( - {0}((((.{2}********************{3}/@@@@@%@@@@{0}{2}/********{1}##{0}((((((((( - {0}.(({1}############{2}*********{3}/%@@@@@@@@@{0}{2}/************{0}.((((((( - {0}.({1}##################(/{2}******{3}/@@@@@{0}{2}/***************{0}.((((( - {0}.({1}#########################(/{2}**********************{0}.(((( - {0}.({1}##############################(/{2}*****************{0}.(((( - {0}.({1}###################################(/{2}************{0}.(((( - {0}.({1}#######################################({2}*********{0}.(((( - {0}.({1}#######(,.***.,(###################(..***.{2}*******{0}.(((( - {0}.({1}#######*(#####((##################((######/({2}*****{0}.(((( - {0}.({1}###################(/***********(##############({0}).(((( - {0}.(({1}#####################/*******(################{0})(((((( - {0}.((({1}############################################{0}).((((( - {0}..((({1}##########################################{0}).(((((( - {0}....(({1}########################################{0}).(((((( - {0}......(({1}####################################{0}).((((((( - {0}((((((((({1}#################################{0}).(((((((( - {0}(((((((((/{1}##########################{0}).(((((((( + {0}(((((((((((((({2}**********/{1}##########{0}((((((((((((( + {0}(((((((((((({2}********************/{1}#######{0}((((((((((( + {0}(((((((({2}******************{3}/@@@@@/{0}{2}****{1}######{0}(((((((((( + {0}(((((({2}********************{3}@@@@@@@@@@/{0}{2}***,{1}####{0}(((((((((( + {0}((((({2}********************{3}/@@@@@%@@@@/{0}{2}********{1}##{0}((((((((( + {0}((({1}############{2}*********{3}/%@@@@@@@@@/{0}{2}************{0}(((((((( + {0}(({1}##################(/{2}******{3}/@@@@@/{0}{2}***************{0}(((((( + {0}(({1}#########################(/{2}**********************{0}((((( + {0}(({1}##############################(/{2}*****************{0}((((( + {0}(({1}###################################(/{2}************{0}((((( + {0}(({1}#######################################({2}*********{0}((((( + {0}(({1}#######(,.***.,(###################(..***.{2}*******{0}((((( + {0}(({1}#######*(#####((##################((######/({2}*****{0}((((( + {0}(({1}###################(/***********(##############({0})((((( + {0}((({1}#####################/*******(################{0})(((((( + {0}(((({1}############################################{0})(((((( + {0}((((({1}##########################################{0})((((((( + {0}(((((({1}########################################{0})((((((( + {0}(((((((({1}####################################{0})(((((((( + {0}((((((((({1}#################################{0})((((((((( + {0}(((((((((({1}##########################{0})((((((((( {0}(((((((((((((((((((((((((((((((((((((( {0}((((((((((((((((((((((((((((((", LGREEN, GREEN, BLUE, NOCOLOR) + NOCOLOR); @@ -81,15 +79,15 @@ namespace winPEAS.Helpers // Patreon link Console.WriteLine(GREEN + string.Format(@" - /---------------------------------------------------------------------------\ - | {1}Do you like PEASS?{0} | - |---------------------------------------------------------------------------| - | {3}Get latest WinPEAS{0} : {2}https://github.com/sponsors/carlospolop{0} | - | {3}Follow on Twitter{0} : {2}@carlospolopm{0} | - | {3}Respect on HTB{0} : {2}SirBroccoli & makikvues{0} | - |---------------------------------------------------------------------------| - | {1}Thank you!{0} | - \---------------------------------------------------------------------------/ + /---------------------------------------------------------------------------------\ + | {1}Do you like PEASS?{0} | + |---------------------------------------------------------------------------------| + | {3}Get the latest version{0} : {2}https://github.com/sponsors/carlospolop{0} | + | {3}Follow on Twitter{0} : {2}@carlospolopm{0} | + | {3}Respect on HTB{0} : {2}SirBroccoli {0} | + |---------------------------------------------------------------------------------| + | {1}Thank you!{0} | + \---------------------------------------------------------------------------------/ ", GREEN, BLUE, RED, YELLOW) + NOCOLOR); } @@ -101,7 +99,7 @@ namespace winPEAS.Helpers PrintBanner(); } - Console.WriteLine(YELLOW + " WinPEAS" + GREEN + Version + NOCOLOR + YELLOW + " by @carlospolopm, makikvues(makikvues2[at]gmail[dot]com)" + NOCOLOR); + Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @carlospolopm" + NOCOLOR); PrintMarketingBanner(); @@ -124,8 +122,6 @@ namespace winPEAS.Helpers public static void PrintUsage() { Console.WriteLine(YELLOW + " [*] " + GREEN + "WinPEAS is a binary to enumerate possible paths to escalate privileges locally" + NOCOLOR); - Console.WriteLine(LBLUE + " quiet" + GRAY + " Do not print banner" + NOCOLOR); - Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR); Console.WriteLine(LBLUE + " domain" + GRAY + " Enumerate domain information" + NOCOLOR); Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR); Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR); @@ -136,8 +132,12 @@ namespace winPEAS.Helpers Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR); Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR); Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search generic files that can contains credentials" + NOCOLOR); - Console.WriteLine(LBLUE + " fileanalysis" + GRAY + " Search specific files that can contains credentials" + NOCOLOR); + Console.WriteLine(LBLUE + " fileanalysis" + GRAY + " Search specific files that can contains credentials and for regexes inside files" + NOCOLOR); Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR); + Console.WriteLine(); + Console.WriteLine(LBLUE + " quiet" + GRAY + " Do not print banner" + NOCOLOR); + Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR); + Console.WriteLine(LBLUE + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + 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[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR); @@ -230,6 +230,11 @@ namespace winPEAS.Helpers GrayPrint($" [X] Exception: {message}"); } + public static void PrintNoNL(string message) + { + Console.Write(message); + } + public static void AnsiPrint(string to_print, Dictionary ansi_colors_regexp) { if (to_print.Trim().Length > 0) @@ -269,7 +274,7 @@ namespace winPEAS.Helpers { foreach (KeyValuePair entry in dicprint) { - if (delete_nulls && string.IsNullOrEmpty(entry.Value.Trim())) + if (delete_nulls && (entry.Value == null || string.IsNullOrEmpty(entry.Value.Trim()))) { continue; } @@ -295,6 +300,7 @@ namespace winPEAS.Helpers Console.WriteLine(line); } } + public static void DictPrint(Dictionary dicprint, bool delete_nulls) { if (dicprint.Count > 0) diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/CustomFileInfo.cs b/winPEAS/winPEASexe/winPEAS/Helpers/CustomFileInfo.cs index b020e3b..d177d9d 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/CustomFileInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/CustomFileInfo.cs @@ -5,13 +5,15 @@ public string Filename { get; } public string Extension { get; } public string FullPath { get; } + public long Size { get; } public bool IsDirectory { get; } - public CustomFileInfo(string filename, string extension, string fullPath, bool isDirectory) + public CustomFileInfo(string filename, string extension, string fullPath, long size, bool isDirectory) { Filename = filename; Extension = extension; FullPath = fullPath; + Size = size; IsDirectory = isDirectory; } } diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/HandlesHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/HandlesHelper.cs new file mode 100644 index 0000000..143555d --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Helpers/HandlesHelper.cs @@ -0,0 +1,601 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace winPEAS.Helpers +{ + internal class HandlesHelper + { + private const int CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION = 64; + public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; + public const int DUPLICATE_SAME_ACCESS = 0x2; + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct FILE_NAME_INFO + { + public int FileNameLength; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1000)] + public string FileName; + } + + [StructLayout(LayoutKind.Sequential)] + public struct THREAD_BASIC_INFORMATION + { + public uint ExitStatus; + public IntPtr TebBaseAdress; + public CLIENT_ID ClientId; + public uint AffinityMask; + public uint Priority; + public uint BasePriority; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CLIENT_ID + { + public int UniqueProcess; + public int UniqueThread; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PROCESS_BASIC_INFORMATION + { + public int ExitStatus; + public IntPtr PebBaseAddress; + public IntPtr AffinityMask; + public int BasePriority; + public IntPtr UniqueProcessId; + public IntPtr InheritedFromUniqueProcessId; + } + + [StructLayout(LayoutKind.Sequential)] + public struct SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX + { + public IntPtr Object; + public UIntPtr UniqueProcessId; + public IntPtr HandleValue; + public uint GrantedAccess; + public ushort CreatorBackTraceIndex; + public ushort ObjectTypeIndex; + public uint HandleAttributes; + public uint Reserved; + } + + [Flags] + public enum ProcessAccessFlags : uint + { + All = 0x001F0FFF, + Terminate = 0x00000001, + CreateThread = 0x00000002, + VMOperation = 0x00000008, + VMRead = 0x00000010, + VMWrite = 0x00000020, + DupHandle = 0x00000040, + SetInformation = 0x00000200, + QueryInformation = 0x00000400, + QueryLimitedInformation = 0x1000, + Synchronize = 0x00100000 + } + + [StructLayout(LayoutKind.Sequential)] + public struct OBJECT_BASIC_INFORMATION + { // Information Class 0 + public int Attributes; + public int GrantedAccess; + public int HandleCount; + public int PointerCount; + public int PagedPoolUsage; + public int NonPagedPoolUsage; + public int Reserved1; + public int Reserved2; + public int Reserved3; + public int NameInformationLength; + public int TypeInformationLength; + public int SecurityDescriptorLength; + public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime; + } + + [StructLayout(LayoutKind.Sequential)] + public struct UNICODE_STRING + { + public ushort Length; + public ushort MaximumLength; + public IntPtr Buffer; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct OBJECT_NAME_INFORMATION + { // Information Class 1 + public UNICODE_STRING Name; + } + + [StructLayout(LayoutKind.Sequential)] + public struct OBJECT_TYPE_INFORMATION + { // Information Class 1 + public UNICODE_STRING Name; + public ulong TotalNumberOfObjects; + public ulong TotalNumberOfHandles; + } + + public enum ObjectInformationClass : int + { + ObjectBasicInformation = 0, + ObjectNameInformation = 1, + ObjectTypeInformation = 2, + ObjectAllTypesInformation = 3, + ObjectHandleInformation = 4 + } + + public struct VULNERABLE_HANDLER_INFO + { + public string handlerType; + public bool isVuln; + public string reason; + } + + public struct PT_RELEVANT_INFO + { + public int pid; + public string name; + public string imagePath; + public string userName; + public string userSid; + } + + public struct KEY_RELEVANT_INFO + { + public string hive; + public string path; + } + + + + + + + + + + + // Check if the given handler is exploitable + public static VULNERABLE_HANDLER_INFO checkExploitaible(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX h, string typeName) + { + VULNERABLE_HANDLER_INFO vulnHandler = new VULNERABLE_HANDLER_INFO(); + vulnHandler.handlerType = typeName; + + if (typeName == "process") + { + // Hex perms from https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights and https://github.com/buffer/maltracer/blob/master/defines.py + + //PROCESS_ALL_ACCESS + if ((h.GrantedAccess & 0x001F0FFF) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "PROCESS_ALL_ACCESS"; + } + + //PROCESS_CREATE_PROCESS + else if ((h.GrantedAccess & 0x0080) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "PROCESS_CREATE_PROCESS"; + } + + //PROCESS_CREATE_THREAD + else if ((h.GrantedAccess & 0x0002) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "PROCESS_CREATE_THREAD"; + } + + //PROCESS_DUP_HANDLE + else if ((h.GrantedAccess & 0x0040) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "PROCESS_DUP_HANDLE"; + } + + //PROCESS_VM_WRITE + else if ((h.GrantedAccess & 0x0020) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "PROCESS_VM_WRITE"; + + if ((h.GrantedAccess & 0x0010) == h.GrantedAccess) + vulnHandler.reason += "& PROCESS_VM_READ"; + + if ((h.GrantedAccess & 0x0008) == h.GrantedAccess) + vulnHandler.reason += "& PROCESS_VM_OPERATION"; + } + } + + else if (typeName == "thread") + { + // Codes from https://docs.microsoft.com/en-us/windows/win32/procthread/thread-security-and-access-rights and https://github.com/x0r19x91/code-injection/blob/master/inject.asm + + //THREAD_ALL_ACCESS + if ((h.GrantedAccess & 0x1f03ff) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "THREAD_ALL_ACCESS"; + } + + //THREAD_DIRECT_IMPERSONATION + else if ((h.GrantedAccess & 0x0200) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "THREAD_DIRECT_IMPERSONATION"; + } + + //THREAD_GET_CONTEXT & THREAD_SET_CONTEXT + else if (((h.GrantedAccess & 0x0008) == h.GrantedAccess) && ((h.GrantedAccess & 0x0010) == h.GrantedAccess)) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "THREAD_GET_CONTEXT & THREAD_SET_CONTEXT"; + } + } + + else if (typeName == "file") + { + + string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT); + if (perm != null && perm.Length> 0) + { + vulnHandler.isVuln = true; + vulnHandler.reason = perm; + } + } + + else if (typeName == "key") + { + string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT_REG); + if (perm != null && perm.Length > 0) + { + vulnHandler.isVuln = true; + vulnHandler.reason = perm; + } + } + + else if (typeName == "section") + { + // Perms from + // https://docs.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights + // https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask-format + // https://github.com/lab52io/LeakedHandlesFinder/blob/master/LeakedHandlesFinder/LeakedHandlesFinder.cpp + + + //MAP_WRITE + if ((h.GrantedAccess & 0x2) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "MAP_WRITE (Research Needed)"; + } + //DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER = STANDARD_RIGHTS_ALL + else if ((h.GrantedAccess & 0xf0000) == h.GrantedAccess) + { + vulnHandler.isVuln = true; + vulnHandler.reason = "STANDARD_RIGHTS_ALL (Research Needed)"; + } + } + + return vulnHandler; + } + + // Given a found handler get what type is it. + public static string GetObjectType(IntPtr handle) + { + OBJECT_TYPE_INFORMATION basicType = new OBJECT_TYPE_INFORMATION(); + + try + { + IntPtr _basic = IntPtr.Zero; + string name; + int nameLength = 0; + + try + { + _basic = Marshal.AllocHGlobal(0x1000); + + Native.Ntdll.NtQueryObject(handle, (int)ObjectInformationClass.ObjectTypeInformation, _basic, 0x1000, ref nameLength); + basicType = (OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(_basic, basicType.GetType()); + name = Marshal.PtrToStringUni(basicType.Name.Buffer, basicType.Name.Length >> 1); + return name; + } + finally + { + if (_basic != IntPtr.Zero) + Marshal.FreeHGlobal(_basic); + } + } + catch { } + + return null; + } + + // Get the name of the handler (if any) + public static string GetObjectName(IntPtr handle) + { + OBJECT_BASIC_INFORMATION basicInfo = new OBJECT_BASIC_INFORMATION(); + try + { + + IntPtr _basic = IntPtr.Zero; + int nameLength = 0; + + try + { + _basic = Marshal.AllocHGlobal(Marshal.SizeOf(basicInfo)); + + Native.Ntdll.NtQueryObject(handle, (int)ObjectInformationClass.ObjectBasicInformation, _basic, Marshal.SizeOf(basicInfo), ref nameLength); + basicInfo = (OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(_basic, basicInfo.GetType()); + nameLength = basicInfo.NameInformationLength; + } + finally + { + if (_basic != IntPtr.Zero) + Marshal.FreeHGlobal(_basic); + } + + if (nameLength == 0) + { + return null; + } + + OBJECT_NAME_INFORMATION nameInfo = new OBJECT_NAME_INFORMATION(); + IntPtr _objectName = Marshal.AllocHGlobal(nameLength); + + try + { + while ((uint)(Native.Ntdll.NtQueryObject(handle, (int)ObjectInformationClass.ObjectNameInformation, _objectName, nameLength, ref nameLength)) == STATUS_INFO_LENGTH_MISMATCH) + { + Marshal.FreeHGlobal(_objectName); + _objectName = Marshal.AllocHGlobal(nameLength); + } + nameInfo = (OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(_objectName, nameInfo.GetType()); + } + finally + { + Marshal.FreeHGlobal(_objectName); + } + + try + { + if (nameInfo.Name.Length > 0) + return Marshal.PtrToStringUni(nameInfo.Name.Buffer, nameInfo.Name.Length >> 1); + } + catch + { + + } + + return null; + } + catch { return null; } + } + + // Get all handlers inside the system + public static List GetAllHandlers() + { + bool is_64 = Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false; + int infoLength = 0x10000; + int length = 0; + IntPtr _info = Marshal.AllocHGlobal(infoLength); + IntPtr _handle = IntPtr.Zero; + long handleCount = 0; + + + // Try to find the size + while ((Native.Ntdll.NtQuerySystemInformation(CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION, _info, infoLength, ref length)) == STATUS_INFO_LENGTH_MISMATCH) + { + infoLength = length; + Marshal.FreeHGlobal(_info); + _info = Marshal.AllocHGlobal(infoLength); + } + + + if (is_64) + { + handleCount = Marshal.ReadInt64(_info); + _handle = new IntPtr(_info.ToInt64() + 16); + } + else + { + handleCount = Marshal.ReadInt32(_info); + _handle = new IntPtr(_info.ToInt32() + 8); + } + + SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = new SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX(); + List handles = new List(); + + int infoSize = Marshal.SizeOf(handleInfo); + Type infoType = handleInfo.GetType(); + + + for (long i = 0; i < handleCount; i++) + { + if (is_64) + { + handleInfo = (SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)Marshal.PtrToStructure(_handle, infoType); + _handle = new IntPtr(_handle.ToInt64() + infoSize); + } + else + { + handleInfo = (SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)Marshal.PtrToStructure(_handle, infoType); + _handle = new IntPtr(_handle.ToInt32() + infoSize); + } + + handles.Add(handleInfo); + } + + return handles; + } + + // Get the owner of a process given the PID + public static Dictionary GetProcU(Process p) + { + Dictionary data = new Dictionary(); + data["name"] = ""; + data["sid"] = ""; + IntPtr pHandle = IntPtr.Zero; + try + { + Native.Advapi32.OpenProcessToken(p.Handle, 8, out pHandle); + WindowsIdentity WI = new WindowsIdentity(pHandle); + string uSEr = WI.Name; + string sid = WI.User.Value; + data["name"] = uSEr.Contains(@"\") ? uSEr.Substring(uSEr.IndexOf(@"\") + 1) : uSEr; + data["sid"] = sid; + return data; + } + catch + { + return data; + } + finally + { + if (pHandle != IntPtr.Zero) + { + Native.Kernel32.CloseHandle(pHandle); + } + } + } + + // Get info of the process given the PID + public static PT_RELEVANT_INFO getProcInfoById(int pid) + { + PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO(); + + Process proc = Process.GetProcessById(pid); + Dictionary user = GetProcU(proc); + + StringBuilder fileName = new StringBuilder(2000); + Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000); + + pri.pid = pid; + pri.name = proc.ProcessName; + pri.userName = user["name"]; + pri.userSid = user["sid"]; + pri.imagePath = fileName.ToString(); + + return pri; + } + + // Get information of a handler of type process + public static PT_RELEVANT_INFO getProcessHandlerInfo(IntPtr handle) + { + PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO(); + PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); + IntPtr[] pbi_arr = new IntPtr[6]; + int pid; + + + int retLength = 0; + + // Try to find the size + uint status = (uint)Native.Ntdll.NtQueryInformationProcess(handle, 0, pbi_arr, 48, ref retLength); + if (status == 0) + { + + //pbi.ExitStatus = (int)pbi_arr[0]; + //pbi.PebBaseAddress = pbi_arr[1]; + //pbi.AffinityMask = pbi_arr[2]; + //pbi.BasePriority = (int)pbi_arr[3]; + pbi.UniqueProcessId = pbi_arr[4]; + //pbi.InheritedFromUniqueProcessId = pbi_arr[5]; + pid = (int)pbi.UniqueProcessId; + } + else + { + pid = (int)Native.Kernel32.GetProcessId(handle); + } + + if (pid == 0) + return pri; + + return getProcInfoById(pid); + } + + // Get information of a handler of type thread + public static PT_RELEVANT_INFO getThreadHandlerInfo(IntPtr handle) + { + PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO(); + THREAD_BASIC_INFORMATION tbi = new THREAD_BASIC_INFORMATION(); + IntPtr[] tbi_arr = new IntPtr[6]; + int pid; + + + /* You could also get the PID using this method + int retLength = 0; + uint status = (uint)NtQueryInformationThread(handle, 0, tbi_arr, 48, ref retLength); + if (status != 0) + { + return pri; + } + + pid = (int)GetProcessIdOfThread(handle); + + CLIENT_ID ci = new CLIENT_ID(); + + tbi.ExitStatus = (uint)tbi_arr[0]; + tbi.TebBaseAdress = tbi_arr[1]; + tbi.ClientId = tbi_arr[2]; + tbi.AffinityMask = (uint)tbi_arr[3]; + tbi.Priority = (uint)tbi_arr[4]; + tbi.BasePriority = (uint)tbi_arr[5];*/ + + pid = (int)Native.Kernel32.GetProcessIdOfThread(handle); + if (pid == 0) + return pri; + + return getProcInfoById(pid); + } + + // Get information of a handler of type key + public static KEY_RELEVANT_INFO getKeyHandlerInfo(IntPtr handle) + { + KEY_RELEVANT_INFO kri = new KEY_RELEVANT_INFO(); + int retLength = 0; + + // Get KeyNameInformation (3) + uint status = (uint)Native.Ntdll.NtQueryKey(handle, 3, null, 0, ref retLength); + var keyInformation = new byte[retLength]; + status = (uint)Native.Ntdll.NtQueryKey(handle, 3, keyInformation, retLength, ref retLength); + + string path = Encoding.Unicode.GetString(keyInformation, 4, keyInformation.Length - 4).ToLower(); + string hive = ""; + + // https://groups.google.com/g/comp.os.ms-windows.programmer.win32/c/nCs-9zFRm6I + if (path.StartsWith(@"\registry\machine")) + { + path = path.Replace(@"\registry\machine", ""); + hive = "HKLM"; + } + + else if (path.StartsWith(@"\registry\user")) + { + path = path.Replace(@"\registry\user", ""); + hive = "HKU"; + } + + else + { // This shouldn't be needed + if (path.StartsWith("\\")) + path = path.Substring(1); + hive = Helpers.Registry.RegistryHelper.CheckIfExists(path); + } + + if (path.StartsWith("\\")) + path = path.Substring(1); + + kri.hive = hive; + kri.path = path; + + return kri; + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/ProgressBar.cs b/winPEAS/winPEASexe/winPEAS/Helpers/ProgressBar.cs new file mode 100644 index 0000000..81e05e6 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Helpers/ProgressBar.cs @@ -0,0 +1,88 @@ +using System; +using System.Text; +using System.Threading; + +namespace winPEAS.Helpers +{ + internal class ProgressBar : IDisposable, IProgress + { + private const int blockCount = 10; + private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8); + private const string animation = @"|/-\"; + + private readonly Timer timer; + + private double currentProgress = 0; + private string currentText = string.Empty; + private bool disposed = false; + private int animationIndex = 0; + + public ProgressBar() + { + timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval); + } + + public void Report(double value) + { + // Make sure value is in [0..1] range + value = Math.Max(0, Math.Min(1, value)); + Interlocked.Exchange(ref currentProgress, value); + } + + private void TimerHandler(object state) + { + lock (timer) + { + if (disposed) return; + + int progressBlockCount = (int)(currentProgress * blockCount); + int percent = (int)(currentProgress * 100); + string text = string.Format("[{0}{1}] {2,3}% {3}", + new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount), + percent, + animation[animationIndex++ % animation.Length]); + UpdateText(text); + } + } + + private void UpdateText(string text) + { + // Get length of common portion + int commonPrefixLength = 0; + int commonLength = Math.Min(currentText.Length, text.Length); + while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength]) + { + commonPrefixLength++; + } + + // Backtrack to the first differing character + StringBuilder outputBuilder = new StringBuilder(); + outputBuilder.Append('\b', currentText.Length - commonPrefixLength); + + // Output new suffix + outputBuilder.Append(text.Substring(commonPrefixLength)); + + // If the new text is shorter than the old one: delete overlapping characters + int overlapCount = currentText.Length - text.Length; + if (overlapCount > 0) + { + outputBuilder.Append(' ', overlapCount); + outputBuilder.Append('\b', overlapCount); + } + + Console.Write(outputBuilder); + currentText = text; + } + + public void Dispose() + { + lock (timer) + { + disposed = true; + UpdateText(string.Empty); + timer.Dispose(); + } + } + + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs index c584c27..b86987a 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Registry/RegistryHelper.cs @@ -12,6 +12,18 @@ namespace winPEAS.Helpers.Registry /////////////////////////////////////////// /// Functions related to obtain keys and values from the registry /// Some parts adapted from Seatbelt + public static Microsoft.Win32.RegistryKey GetReg(string hive, string path) + { + if (hive == "HKCU") + return Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path); + + else if (hive == "HKU") + return Microsoft.Win32.Registry.Users.OpenSubKey(path); + + else + return Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); + } + public static string GetRegValue(string hive, string path, string value) { // returns a single registry value under the specified path in the specified hive (HKLM/HKCU) @@ -174,5 +186,29 @@ namespace winPEAS.Helpers.Registry return null; } + + public static string CheckIfExists(string path) + { + try + { + var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); + if (key != null) + return "HKLM"; + + key = Microsoft.Win32.Registry.Users.OpenSubKey(path); + if (key != null) + return "HKU"; + + key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path); + if (key != null) + return "HKCU"; + + return null; + } + catch + { + return null; + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs index 2eb0abc..0cab174 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Search/SearchHelper.cs @@ -20,6 +20,25 @@ namespace winPEAS.Helpers.Search public static string SystemDrive = Environment.GetEnvironmentVariable("SystemDrive"); private static string GlobalPattern = "*"; + public static List StaticExtensions = new List() { + // archives + ".7z", ".tar", ".zip", ".gz", + + // audio/video + ".avi", ".mp3", ".mp4", ".wav", ".wmf", ".wmv", ".ts", ".pak", + + // icons + ".ico", + + // fonts + ".eot", ".fnt", ".fon", ".otf", ".odttf", ".ttc", ".ttf", ".woff", "woff2", "woff3", + + // images + ".bmp", ".emf", ".gif", ".pm", + ".jif", ".jfi", ".jfif", ".jpe", ".jpeg", ".jpg", + ".png", ".psd", ".raw", ".svg", ".svgz", ".tif", ".tiff", ".webp", + }; + public static List GetFilesFast(string folder, string pattern = "*", HashSet excludedDirs = null, bool isFoldersIncluded = false) { ConcurrentBag files = new ConcurrentBag(); @@ -52,17 +71,25 @@ namespace winPEAS.Helpers.Search Parallel.ForEach(GetStartDirectories(d.FullName, files, pattern, isFoldersIncluded), (dir) => { GetFiles(dir.FullName, pattern).ForEach( - (f) => { - CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, false); - files.Add(file_info); - - CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, true); - if (!known_dirs.Contains(file_dir.FullPath)) - { - known_dirs.Add(file_dir.FullPath); - files.Add(file_dir); - } + (f) => + { + if (!StaticExtensions.Contains(f.Extension.ToLower())) + { + // It should always be lesss than 260, but some times it isn't so this will bypass that file + if (f.FullName.Length <= 260) + { + CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false); + files.Add(file_info); + + CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true); + if (!known_dirs.Contains(file_dir.FullPath)) + { + known_dirs.Add(file_dir.FullPath); + files.Add(file_dir); + } + } } + } ) ; }); }); @@ -142,13 +169,14 @@ namespace winPEAS.Helpers.Search { foreach (var directory in directories) { - files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, true)); + files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, 0, true)); } } foreach (var f in dirInfo.GetFiles(pattern)) { - files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, false)); + if (!StaticExtensions.Contains(f.Extension.ToLower())) + files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false)); } if (directories.Length > 1) return new List(directories); diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfig.cs b/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfig.cs index 4590a40..ab1a824 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfig.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfig.cs @@ -2,6 +2,24 @@ namespace winPEAS.Helpers.YamlConfig { + public class YamlRegexConfig + { + public class RegularExpressions + { + public string name { get; set; } + public RegularExpression[] regexes { get; set; } + public class RegularExpression { + public string name { get; set; } + public string regex { get; set; } + + public bool caseinsensitive { get; set; } + + public string disable { get; set; } + } + } + + public RegularExpressions[] regular_expresions { get; set; } + } public class YamlConfig { @@ -24,6 +42,7 @@ namespace winPEAS.Helpers.YamlConfig public bool? remove_empty_lines { get; set; } // public string remove_path { get; set; } // not used in Winpeas public string remove_regex { get; set; } + public string remove_path { get; set; } // public string[] search_in { get; set; } // not used in Winpeas public string type { get; set; } public FileParam[] files { get; set; } diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfigHelper.cs b/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfigHelper.cs index 702566a..a1f4bc3 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfigHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/YamlConfig/YamlConfigHelper.cs @@ -4,13 +4,49 @@ using System.IO; using System.Reflection; using System.Linq; using static winPEAS.Helpers.YamlConfig.YamlConfig; +using static winPEAS.Helpers.YamlConfig.YamlRegexConfig; + namespace winPEAS.Helpers.YamlConfig { internal class YamlConfigHelper { + const string REGEXES_FILES = "regexes.yaml"; const string SENSITIVE_FILES = "sensitive_files.yaml"; + public static YamlRegexConfig GetRegexesSearchConfig() + { + var assembly = Assembly.GetExecutingAssembly(); + var resourceName = assembly.GetManifestResourceNames().Where(i => i.EndsWith(REGEXES_FILES)).FirstOrDefault(); + + try + { + using (Stream stream = assembly.GetManifestResourceStream(resourceName)) + using (StreamReader reader = new StreamReader(stream)) + { + string configFileContent = reader.ReadToEnd(); + + YamlSerializer yamlSerializer = new YamlSerializer(); + YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0]; + + // check + if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0) + { + throw new System.Exception("No configuration was read"); + } + + return yamlConfig; + + } + } + catch (System.Exception e) + { + Beaprint.PrintException($"An exception occured while parsing regexes.yaml configuration file: {e.Message}"); + + throw; + } + } + public static YamlConfig GetWindowsSearchConfig() { var assembly = Assembly.GetExecutingAssembly(); @@ -52,7 +88,7 @@ namespace winPEAS.Helpers.YamlConfig } catch (System.Exception e) { - Beaprint.PrintException($"An exception occured while parsing YAML configuration file: {e.Message}"); + Beaprint.PrintException($"An exception occured while parsing sensitive_files.yaml configuration file: {e.Message}"); throw; } @@ -78,6 +114,7 @@ namespace winPEAS.Helpers.YamlConfig value.only_bad_lines = GetValueOrDefault(value.only_bad_lines, defaults.only_bad_lines); value.remove_empty_lines = GetValueOrDefault(value.remove_empty_lines, defaults.remove_empty_lines); value.remove_regex = GetValueOrDefault(value.remove_regex, defaults.remove_regex); + value.remove_path = GetValueOrDefault(value.remove_path, defaults.remove_path); value.type = GetValueOrDefault(value.type, defaults.type).ToLower(); if (value.files != null) diff --git a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/NetworkInfoHelper.cs b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/NetworkInfoHelper.cs index c9cbe21..5512c47 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/NetworkInfoHelper.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/NetworkInfo/NetworkInfoHelper.cs @@ -348,6 +348,12 @@ namespace winPEAS.Info.NetworkInfo MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCPROW_OWNER_PID)); // Add row to list of TcpConnetions. + string proc_name = GetProcessNameByPid(tcpRow.owningPid, processesByPid); + if (proc_name == "Idle") + { //Sometime too many Idle connections that doesn't provide sensitive info + continue; + } + tcpTableRecords.Add(new TcpConnectionInfo( Protocol.TCP, new IPAddress(tcpRow.localAddr), @@ -360,7 +366,7 @@ namespace winPEAS.Info.NetworkInfo tcpRow.remotePort[0] }, 0), tcpRow.owningPid, tcpRow.state, - GetProcessNameByPid(tcpRow.owningPid, processesByPid))); + proc_name)); tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow)); } @@ -377,6 +383,12 @@ namespace winPEAS.Info.NetworkInfo { MIB_TCP6ROW_OWNER_PID tcpRow = (MIB_TCP6ROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCP6ROW_OWNER_PID)); + string proc_name = GetProcessNameByPid(tcpRow.owningPid, processesByPid); + if (proc_name == "Idle") + { //Sometime too many Idle connections that doesn't provide sensitive info + continue; + } + tcpTableRecords.Add(new TcpConnectionInfo( Protocol.TCP, new IPAddress(tcpRow.localAddr, tcpRow.localScopeId), @@ -389,7 +401,7 @@ namespace winPEAS.Info.NetworkInfo tcpRow.remotePort[0] }, 0), tcpRow.owningPid, tcpRow.state, - GetProcessNameByPid(tcpRow.owningPid, processesByPid))); + proc_name)); tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow)); } diff --git a/winPEAS/winPEASexe/winPEAS/Info/ProcessInfo/ProcessesInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/ProcessInfo/ProcessesInfo.cs index d8e714c..00e0315 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/ProcessInfo/ProcessesInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/ProcessInfo/ProcessesInfo.cs @@ -1,40 +1,20 @@ -using System; +using Microsoft.Win32; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Management; +using System.Runtime.InteropServices; using System.Security.Principal; +using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; using winPEAS.Helpers; -using winPEAS.Native; namespace winPEAS.Info.ProcessInfo { internal class ProcessesInfo { - private static string GetProcU(Process p) - { - IntPtr pHandle = IntPtr.Zero; - try - { - Advapi32.OpenProcessToken(p.Handle, 8, out pHandle); - WindowsIdentity WI = new WindowsIdentity(pHandle); - String uSEr = WI.Name; - return uSEr.Contains(@"\") ? uSEr.Substring(uSEr.IndexOf(@"\") + 1) : uSEr; - } - catch - { - return null; - } - finally - { - if (pHandle != IntPtr.Zero) - { - Kernel32.CloseHandle(pHandle); - } - } - } - // TODO: check out https://github.com/harleyQu1nn/AggressorScripts/blob/master/ProcessColor.cna#L10 public static List> GetProcInfo() { @@ -53,7 +33,7 @@ namespace winPEAS.Info.ProcessInfo Proc = p, Pth = (string)mo["ExecutablePath"], CommLine = (string)mo["CommandLine"], - Owner = GetProcU(p), //Needed inside the next foreach + Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach }; foreach (var itm in queRy) @@ -94,5 +74,163 @@ namespace winPEAS.Info.ProcessInfo } return f_results; } + + public static List> GetVulnHandlers() + { + List> vulnHandlers = new List>(); + List handlers = HandlesHelper.GetAllHandlers(); + List interestingHandlerTypes = new List() { "file", "key", "process", "thread" }; //section + + foreach (HandlesHelper.SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX h in handlers) + { + // skip some objects to avoid getting stuck + // see: https://github.com/adamdriscoll/PoshInternals/issues/7 + if (h.GrantedAccess == 0x0012019f + || h.GrantedAccess == 0x00120189 + || h.GrantedAccess == 0x120089 + || h.GrantedAccess == 0x1A019F) + continue; + + IntPtr dupHandle; + IntPtr _processHandle = Native.Kernel32.OpenProcess(HandlesHelper.ProcessAccessFlags.DupHandle | HandlesHelper.ProcessAccessFlags.QueryInformation, false, h.UniqueProcessId); + + if (_processHandle == (IntPtr)0) + continue; + + uint status = (uint)Native.Ntdll.NtDuplicateObject( + _processHandle, + h.HandleValue, + Native.Kernel32.GetCurrentProcess(), + out dupHandle, + 0, + false, + HandlesHelper.DUPLICATE_SAME_ACCESS); + + Native.Kernel32.CloseHandle(_processHandle); + + if (status != 0) + continue; + + string typeName = HandlesHelper.GetObjectType(dupHandle).ToLower(); + if (interestingHandlerTypes.Contains(typeName)) + { + HandlesHelper.VULNERABLE_HANDLER_INFO handlerExp = HandlesHelper.checkExploitaible(h, typeName); + if (handlerExp.isVuln == true) + { + HandlesHelper.PT_RELEVANT_INFO origProcInfo = HandlesHelper.getProcInfoById((int)h.UniqueProcessId); + if (!Checks.Checks.CurrentUserSiDs.ContainsKey(origProcInfo.userSid)) + continue; + + string hName = HandlesHelper.GetObjectName(dupHandle); + + Dictionary to_add = new Dictionary(); + to_add["Handle Name"] = hName; + to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")"; + to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName; + to_add["Reason"] = handlerExp.reason; + + if (typeName == "process" || typeName == "thread") + { + HandlesHelper.PT_RELEVANT_INFO hInfo; + if (typeName == "process") + { + hInfo = HandlesHelper.getProcessHandlerInfo(dupHandle); + } + + else //Thread + { + hInfo = HandlesHelper.getThreadHandlerInfo(dupHandle); + } + + // If the privileged access is from a proc to itself, or to a process of the same user, not a privesc + if (hInfo.pid == 0 || + (int)h.UniqueProcessId == hInfo.pid || + origProcInfo.userSid == hInfo.userSid) + continue; + + to_add["Handle PID"] = hInfo.pid.ToString() + "(" + hInfo.userName + ")"; + } + + else if (typeName == "file") + { + //StringBuilder filePath = new StringBuilder(2000); + //HandlersHelper.GetFinalPathNameByHandle(dupHandle, filePath, 2000, 0); + + HandlesHelper.FILE_NAME_INFO fni = new HandlesHelper.FILE_NAME_INFO(); + + // Sometimes both GetFileInformationByHandle and GetFileInformationByHandleEx hangs + // So a timeput of 1s is put to the function to prevent that + var task = Task.Run(() => + { + // FILE_NAME_INFO (2) + return Native.Kernel32.GetFileInformationByHandleEx(dupHandle, 2, out fni, (uint)Marshal.SizeOf(fni)); + }); + + bool isCompletedSuccessfully = task.Wait(TimeSpan.FromMilliseconds(1000)); + + if (!isCompletedSuccessfully) + { + //throw new TimeoutException("The function has taken longer than the maximum time allowed."); + continue; + } + + string sFilePath = fni.FileName; + if (sFilePath.Length == 0) + continue; + + List permsFile = PermissionsHelper.GetPermissionsFile(sFilePath, Checks.Checks.CurrentUserSiDs, PermissionType.WRITEABLE_OR_EQUIVALENT); + try + { + System.Security.AccessControl.FileSecurity fs = System.IO.File.GetAccessControl(sFilePath); + IdentityReference sid = fs.GetOwner(typeof(SecurityIdentifier)); + string ownerName = sid.Translate(typeof(NTAccount)).ToString(); + + // If current user already have permissions over that file or the proc belongs to the owner of the file, + // handler not interesting to elevate privs + if (permsFile.Count > 0 || origProcInfo.userSid == sid.Value) + continue; + + to_add["File Path"] = sFilePath; + to_add["File Owner"] = ownerName; + } + catch (System.IO.FileNotFoundException) + { + // File wasn't found + continue; + } + catch (System.InvalidOperationException) + { + continue; + } + + } + + else if (typeName == "key") + { + HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle); + if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0) + continue; + + RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path); + if (regKey == null) + continue; + + List permsReg = PermissionsHelper.GetMyPermissionsR(regKey, Checks.Checks.CurrentUserSiDs); + + // If current user already have permissions over that reg, handle not interesting to elevate privs + if (permsReg.Count > 0) + continue; + + to_add["Registry"] = kri.hive + "\\" + kri.path; + } + + + vulnHandlers.Add(to_add); + } + } + } + + return vulnHandlers; + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipeInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipeInfo.cs index 0e977b2..260c783 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipeInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipeInfo.cs @@ -4,11 +4,13 @@ { public string Name { get; } public string Sddl { get; } + public string CurrentUserPerms { get; } - public NamedPipeInfo(string name, string sddl) + public NamedPipeInfo(string name, string sddl, string currentUserPerms) { Name = name; Sddl = sddl; + CurrentUserPerms = currentUserPerms; } } } diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipes.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipes.cs index 17c7d1c..5dd56f9 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipes.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/NamedPipes/NamedPipes.cs @@ -3,6 +3,8 @@ using System.IO; using System.Runtime.InteropServices; using System.Security.AccessControl; using winPEAS.Native; +using System.Security.Principal; + namespace winPEAS.Info.SystemInfo.NamedPipes { @@ -42,22 +44,26 @@ namespace winPEAS.Info.SystemInfo.NamedPipes foreach (var namedPipe in namedPipes) { string sddl; + string currentUserPerms; bool isError = false; try { var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}"); sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All); + List currentUserPermsList = winPEAS.Helpers.PermissionsHelper.GetMyPermissionsF(security, winPEAS.Checks.Checks.CurrentUserSiDs); + currentUserPerms = string.Join(", ", currentUserPermsList); } catch { isError = true; sddl = "ERROR"; + currentUserPerms = "ERROR"; } if (!isError && !string.IsNullOrEmpty(sddl)) { - yield return new NamedPipeInfo(namedPipe, sddl); + yield return new NamedPipeInfo(namedPipe, sddl, currentUserPerms); } } } diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs index ef4f81d..c3b67aa 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/SystemInfo.cs @@ -160,9 +160,13 @@ namespace winPEAS.Info.SystemInfo { Dictionary results = new Dictionary(); string whitelistpaths = ""; + try { - whitelistpaths = String.Join("\n ", RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths").Keys); + var keys = RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths"); + if (keys != null) + whitelistpaths = String.Join("\n ", keys.Keys); + using (ManagementObjectSearcher wmiData = new ManagementObjectSearcher(@"root\SecurityCenter2", "SELECT * FROM AntiVirusProduct")) { using (var data = wmiData.Get()) diff --git a/winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs b/winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs index 09d0e12..3f3e08f 100644 --- a/winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs +++ b/winPEAS/winPEASexe/winPEAS/Native/Kernel32.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; +using System.Text; using winPEAS.Info.SystemInfo.NamedPipes; namespace winPEAS.Native @@ -67,5 +68,34 @@ namespace winPEAS.Native [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] internal static extern int GetPrivateProfileString(string? section, string? key, string defaultValue, [In, Out] char[] value, int size, string filePath); + [DllImport("kernel32.dll")] + public static extern IntPtr OpenProcess(Helpers.HandlesHelper.ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); + + [DllImport("kernel32.dll")] + public static extern IntPtr OpenProcess(Helpers.HandlesHelper.ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, UIntPtr dwProcessId); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern uint GetProcessIdOfThread(IntPtr handle); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern uint GetProcessId(IntPtr handle); + + [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] + public static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern uint GetFileInformationByHandleEx(IntPtr hFile, int infoClass, out Helpers.HandlesHelper.FILE_NAME_INFO lpFileInformation, uint dwBufferSize); + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern unsafe int GetFullPathName(string lpFileName, int nBufferLength, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpBuffer, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpFilePart); + } } diff --git a/winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs b/winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs new file mode 100644 index 0000000..95523a5 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using winPEAS.Info.SystemInfo.NamedPipes; + +namespace winPEAS.Native +{ + internal class Ntdll + { + [DllImport("ntdll.dll")] + public static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength); + + [DllImport("ntdll.dll")] + public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength); + + [DllImport("ntdll.dll")] + internal static extern int NtQueryInformationProcess(IntPtr ProcessHandle, int ProcessInformationClass, IntPtr[] ProcessInformation, int ProcessInformationLength, ref int ReturnLength); + + [DllImport("ntdll.dll")] + internal static extern int NtQueryInformationThread(IntPtr hThread, int ThreadInformationClass, IntPtr[] ThreadInformation, int ThreadInformationLength, ref int ReturnLength); + + [DllImport("ntdll.dll")] + internal static extern int NtDuplicateObject(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, ulong dwOptions); + + [DllImport("ntdll.dll")] + public static extern uint NtQueryKey(IntPtr KeyHandle, int KeyInformationClass, byte[] KeyInformation, int Length, ref int ResultLength); + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Native/Psapi.cs b/winPEAS/winPEASexe/winPEAS/Native/Psapi.cs index 07ef958..08385e3 100644 --- a/winPEAS/winPEASexe/winPEAS/Native/Psapi.cs +++ b/winPEAS/winPEASexe/winPEAS/Native/Psapi.cs @@ -26,5 +26,12 @@ namespace winPEAS.Native StringBuilder name, UInt32 nameSize ); + + [DllImport("psapi.dll")] + internal static extern uint GetProcessImageFileName( + IntPtr hProcess, + [Out] StringBuilder lpImageFileName, + [In][MarshalAs(UnmanagedType.U4)] int nSize + ); } } diff --git a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj index 736f2d1..eb90fe8 100755 --- a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj +++ b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj @@ -1,724 +1,732 @@ - - - - - Debug - AnyCPU - {D934058E-A7DB-493F-A741-AE8E3DF867F4} - Exe - winPEAS - winPEAS - v4.5.2 - 512 - true - - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - AnyCPU - true - full - false - bin\Debug\ - TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF - prompt - 4 - false - 8.0 - true - - - AnyCPU - pdbonly - true - bin\Release\ - TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF - prompt - 4 - false - 8.0 - false - MinimumRecommendedRules.ruleset - true - - - true - - - true - bin\x64\Debug\ - TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF - full - AnyCPU - 8.0 - prompt - MinimumRecommendedRules.ruleset - false - true - 0168 ; 0169; 0414; 0618; 0649 - - - bin\x64\Release\ - TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF - true - pdbonly - x64 - 8.0 - prompt - MinimumRecommendedRules.ruleset - false - true - - - true - bin\x86\Debug\ - TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF - full - x86 - 8.0 - prompt - MinimumRecommendedRules.ruleset - false - true - - - bin\x86\Release\ - TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF - true - pdbonly - x86 - 8.0 - prompt - MinimumRecommendedRules.ruleset - false - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - Designer - - - - - - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - - False - Microsoft .NET Framework 4.5.2 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - + + + + + Debug + AnyCPU + {D934058E-A7DB-493F-A741-AE8E3DF867F4} + Exe + winPEAS + winPEAS + v4.5.2 + 512 + true + + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF + prompt + 4 + false + 8.0 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF + prompt + 4 + false + 8.0 + false + MinimumRecommendedRules.ruleset + true + + + true + + + true + bin\x64\Debug\ + TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF + full + AnyCPU + 8.0 + prompt + MinimumRecommendedRules.ruleset + false + true + 0168 ; 0169; 0414; 0618; 0649 + + + bin\x64\Release\ + TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF + true + pdbonly + x64 + 8.0 + prompt + MinimumRecommendedRules.ruleset + false + true + + + true + bin\x86\Debug\ + TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF + full + x86 + 8.0 + prompt + MinimumRecommendedRules.ruleset + false + true + + + bin\x86\Release\ + TRUE WIN32 _MSC_VER NDEBUG NO_TCL SQLITE_ASCII SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC VDBE_PROFILE_OFF + true + pdbonly + x86 + 8.0 + prompt + MinimumRecommendedRules.ruleset + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + regexes.yaml + + + sensitive_files.yaml + + + + Designer + + + Designer + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + False + Microsoft .NET Framework 4.5.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + \ No newline at end of file diff --git a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj.user b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj.user index da1df40..7c81c6a 100755 --- a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj.user +++ b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj.user @@ -1,34 +1,34 @@ - - - - - - - - fileAnalysis - - - debug - - - fast - - - - - - - - - - - publish\ - - - - - - en-US - false - + + + + + + + + fileanalysis + + + debug + + + fast + + + + + + + + + + + publish\ + + + + + + en-US + false + \ No newline at end of file