mirror of
https://github.com/carlospolop/PEASS-ng
synced 2025-02-14 08:54:27 +01:00
update
This commit is contained in:
parent
56d71ae847
commit
bbc22b3a91
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
{
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
601
winPEAS/winPEASexe/winPEAS/Helpers/HandlesHelper.cs
Normal file
601
winPEAS/winPEASexe/winPEAS/Helpers/HandlesHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
88
winPEAS/winPEASexe/winPEAS/Helpers/ProgressBar.cs
Normal file
88
winPEAS/winPEASexe/winPEAS/Helpers/ProgressBar.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
28
winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs
Normal file
28
winPEAS/winPEASexe/winPEAS/Native/Ntdll.cs
Normal 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);
|
||||
}
|
||||
}
|
@ -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
@ -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>
|
Loading…
Reference in New Issue
Block a user