1
mirror of https://github.com/carlospolop/PEASS-ng synced 2025-02-14 08:54:27 +01:00
This commit is contained in:
carlospolop 2022-07-30 12:06:10 +02:00
parent 56d71ae847
commit bbc22b3a91
26 changed files with 2236 additions and 896 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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<SystemCheck> _systemChecks;
private static readonly HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>();
@ -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

View File

@ -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<Action>
{
PrintYAMLSearchFiles
PrintYAMLSearchFiles,
PrintYAMLRegexesSearchFiles
}.ForEach(action => CheckRunner.Run(action, isDebug));
}
private static List<CustomFileInfo> InitializeFileSearch()
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles=true)
{
var files = new List<CustomFileInfo>();
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<CustomFileInfo> 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<CustomFileInfo> one_file_list = new List<CustomFileInfo>() { 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<string> SearchContent(string text, string regex_str, bool caseinsensitive)
{
List<string> foundMatches = new List<string>();
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<string> extra_no_extensions = new List<string>() { ".msi", ".exe", ".dll", ".pyc", ".pyi", ".lnk", ".css", ".hyb", ".etl", ".mo", ".xrm-ms", ".idl", ".vsix", ".mui", ".qml", ".tt" };
List<string> valid_extensions = new List<string>() {
// 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<string> invalid_names = new List<string>()
{
"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<string, Dictionary<string, Dictionary<string, List<string>>>> foundRegexes = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> { };
/*
* Useful for debbugging purposes to see the common file extensions found
Dictionary <string, int> dict_str = new Dictionary<string, int>();
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<string, int> 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<string> results = new List<string> { };
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<string, Dictionary<string, List<string>>> { };
if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { };
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<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes)
{
foreach (KeyValuePair<string, Dictionary<string, List<string>>> 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<string, List<string>> 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")
{

View File

@ -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",

View File

@ -14,7 +14,8 @@ namespace winPEAS.Checks
new List<Action>
{
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<Dictionary<string, string>> vulnHandlers = ProcessesInfo.GetVulnHandlers();
foreach (Dictionary<string, string> handler in vulnHandlers)
{
Dictionary<string, string> colors = new Dictionary<string, string>()
{
{ Checks.CurrentUserName, Beaprint.ansi_color_bad },
{ handler["Reason"], Beaprint.ansi_color_bad },
};
Beaprint.DictPrint(vulnHandlers, colors, true);
}
}
}
}

View File

@ -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<string, object> 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<string, string>
{
{namedPipe.CurrentUserPerms.Replace("[","\\[").Replace("]","\\]"), Beaprint.ansi_color_bad },
};
Beaprint.AnsiPrint(string.Format(formatString, namedPipe.Name, namedPipe.CurrentUserPerms, namedPipe.Sddl), colors);
}
}
catch (Exception ex)

View File

@ -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<string, string> ansi_colors_regexp)
{
if (to_print.Trim().Length > 0)
@ -269,7 +274,7 @@ namespace winPEAS.Helpers
{
foreach (KeyValuePair<string, string> 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<string, string> dicprint, bool delete_nulls)
{
if (dicprint.Count > 0)

View File

@ -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;
}
}

View File

@ -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<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> 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<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> handles = new List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX>();
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<string, string> GetProcU(Process p)
{
Dictionary<string, string> data = new Dictionary<string, string>();
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<string,string> 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;
}
}
}

View File

@ -0,0 +1,88 @@
using System;
using System.Text;
using System.Threading;
namespace winPEAS.Helpers
{
internal class ProgressBar : IDisposable, IProgress<double>
{
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();
}
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -20,6 +20,25 @@ namespace winPEAS.Helpers.Search
public static string SystemDrive = Environment.GetEnvironmentVariable("SystemDrive");
private static string GlobalPattern = "*";
public static List<string> StaticExtensions = new List<string>() {
// 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<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
{
ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
@ -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<DirectoryInfo>(directories);

View File

@ -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; }

View File

@ -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)

View File

@ -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));
}

View File

@ -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<Dictionary<string, string>> 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<Dictionary<string, string>> GetVulnHandlers()
{
List<Dictionary<string, string>> vulnHandlers = new List<Dictionary<string, string>>();
List<HandlesHelper.SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> handlers = HandlesHelper.GetAllHandlers();
List<string> interestingHandlerTypes = new List<string>() { "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<string, string> to_add = new Dictionary<string, string>();
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<string> 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<string> 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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<string> 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);
}
}
}

View File

@ -160,9 +160,13 @@ namespace winPEAS.Info.SystemInfo
{
Dictionary<string, string> results = new Dictionary<string, string>();
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())

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartArguments>fileAnalysis</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<StartArguments>debug</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<StartArguments>fast</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartArguments>fileanalysis</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<StartArguments>debug</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<StartArguments>fast</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project>