1
mirror of https://github.com/carlospolop/PEASS-ng synced 2024-11-20 12:39:21 +01:00

- updated applocker implementation

- added logging to text file
- updated PermissionsHelper to allow searching only for write or equivalent permissions
- optimized StaticSID2GroupName
- updated printing in PrintCredManag
This commit is contained in:
makikvues 2021-01-23 16:38:35 +01:00
parent 4395b871d8
commit 39c71eb4a3
11 changed files with 615 additions and 118 deletions

View File

@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Security.Principal;
using winPEAS.Helpers;
using winPEAS.Helpers.AppLocker;
using winPEAS.Helpers.Search;
using winPEAS.Info.UserInfo;
@ -24,8 +26,6 @@ namespace winPEAS.Checks
public static string CurrentAdDomainName = "";
public static bool IsPartOfDomain = false;
public static bool IsCurrentUserLocal = true;
static SelectQuery _query = null;
static ManagementObjectSearcher _searcher = null;
public static ManagementObjectCollection Win32Users = null;
public static Dictionary<string, string> CurrentUserSiDs = new Dictionary<string, string>();
static string _paintActiveUsers = "";
@ -38,6 +38,9 @@ namespace winPEAS.Checks
private static List<SystemCheck> _systemChecks;
private static HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>();
public const string LogFile = "out.txt";
class SystemCheck
{
public string Key { get; }
@ -55,6 +58,9 @@ namespace winPEAS.Checks
//Check parameters
bool isAllChecks = true;
bool wait = false;
FileStream fileStream = null;
StreamWriter fileWriter = null;
TextWriter oldOut = Console.Out;
_systemChecks = new List<SystemCheck>
{
@ -82,6 +88,23 @@ namespace winPEAS.Checks
return;
}
if (string.Equals(arg, "log", StringComparison.CurrentCultureIgnoreCase))
{
try
{
fileStream = new FileStream(LogFile, FileMode.OpenOrCreate, FileAccess.Write);
fileWriter = new StreamWriter(fileStream);
}
catch (Exception ex)
{
Beaprint.PrintException($"Cannot open \"{LogFile}\" for writing:\n {ex.Message}");
return;
}
Beaprint.ColorPrint($"\"log\" argument present, redirecting output to file \"{LogFile}\"", Beaprint.ansi_color_good);
Console.SetOut(fileWriter);
}
if (string.Equals(arg, "cmd", StringComparison.CurrentCultureIgnoreCase))
{
ExecCmd = true;
@ -120,24 +143,34 @@ namespace winPEAS.Checks
}
}
CheckRunner.Run(() =>
try
{
//Start execution
if (IsNoColor)
CheckRunner.Run(() =>
{
Beaprint.DeleteColors();
}
else
{
CheckRegANSI();
}
//Start execution
if (IsNoColor)
{
Beaprint.DeleteColors();
}
else
{
CheckRegANSI();
}
CheckRunner.Run(CreateDynamicLists, IsDebug);
CheckRunner.Run(CreateDynamicLists, IsDebug);
Beaprint.PrintInit(IsDebug);
Beaprint.PrintInit(IsDebug);
RunChecks(isAllChecks, wait);
}, IsDebug, "Total time");
RunChecks(isAllChecks, wait);
}, IsDebug, "Total time");
}
finally
{
Console.SetOut(oldOut);
fileWriter?.Close();
fileStream?.Close();
}
}
private static void RunChecks(bool isAllChecks, bool wait)
@ -176,9 +209,12 @@ namespace winPEAS.Checks
try
{
Beaprint.GrayPrint(" - Getting Win32_UserAccount info...");
_query = new SelectQuery("Win32_UserAccount");
_searcher = new ManagementObjectSearcher(_query);
Win32Users = _searcher.Get();
var query = new SelectQuery("Win32_UserAccount");
using (var searcher = new ManagementObjectSearcher(query))
{
Win32Users = searcher.Get();
}
}
catch (Exception ex)
{
@ -245,6 +281,17 @@ namespace winPEAS.Checks
Beaprint.GrayPrint("Error while creating admin users groups list: " + ex);
}
//create AppLocker lists
try
{
Beaprint.GrayPrint(" - Creating AppLocker bypass list...");
AppLockerHelper.CreateLists();
}
catch (Exception ex)
{
Beaprint.GrayPrint("Error while creating AppLocker bypass list: " + ex);
}
//create the file lists
try
{
@ -254,7 +301,7 @@ namespace winPEAS.Checks
catch (Exception ex)
{
Beaprint.GrayPrint("Error while creating directory list: " + ex);
}
}
}
private static void CheckRegANSI()

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using winPEAS.Helpers;
using winPEAS.Helpers.AppLocker;
using winPEAS.Helpers.Search;
using winPEAS._3rdParty.Watson;
namespace winPEAS.Checks
@ -40,7 +41,7 @@ namespace winPEAS.Checks
PrintWSUS,
PrintAlwaysInstallElevated,
PrintLsaCompatiblityLevel,
PrintApplockerPolicy
AppLockerHelper.PrintAppLockerPolicy
}.ForEach(action => CheckRunner.Run(action, isDebug));
}
@ -523,36 +524,5 @@ namespace winPEAS.Checks
Beaprint.PrintException(ex.Message);
}
}
private static void PrintApplockerPolicy()
{
Beaprint.MainPrint("Checking AppLocker effective policy");
try
{
string[] ruleTypes = new string[] { "All" };
string ldapPath = "";
bool allowOnly = false;
bool denyOnly = false;
string applockerSettings = SharpAppLocker.GetAppLockerPolicy(SharpAppLocker.PolicyType.Effective, ruleTypes, ldapPath, allowOnly, denyOnly);
var colors = new Dictionary<string, string>()
{
{ "/>", Beaprint.DGRAY },
{ "<", Beaprint.DGRAY },
{ "NotConfigured", Beaprint.ansi_color_bad },
};
Beaprint.AnsiPrint(applockerSettings, colors);
}
catch (COMException ex)
{
Beaprint.ColorPrint(" AppLocker unsupported on this Windows version.", Beaprint.ansi_color_yellow);
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
}
}

View File

@ -98,7 +98,11 @@ namespace winPEAS.Checks
var credentials = CredentialManager.GetCredentials();
Beaprint.ListPrint(credentials, colorsC);
foreach (var credential in credentials)
{
Beaprint.AnsiPrint(credential, colorsC);
Beaprint.PrintLineSeparator();
}
}
}
catch (Exception ex)

View File

@ -0,0 +1,449 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace winPEAS.Helpers.AppLocker
{
internal static class AppLockerHelper
{
private static readonly HashSet<string> _appLockerByPassDirectoriesSet = new HashSet<string>
{
@"C:\Windows\Temp",
@"C:\Windows\System32\spool\drivers\color",
@"C:\Windows\Tasks",
@"C:\windows\tracing",
@"C:\Windows\Registration\CRMLog",
@"C:\Windows\System32\FxsTmp",
@"C:\Windows\System32\com\dmp",
@"C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys",
@"C:\Windows\System32\spool\PRINTERS",
@"C:\Windows\System32\spool\SERVERS",
@"C:\Windows\System32\Tasks\Microsoft\Windows\SyncCenter",
@"C:\Windows\System32\Tasks_Migrated",
@"C:\Windows\SysWOW64\FxsTmp",
@"C:\Windows\SysWOW64\com\dmp",
@"C:\Windows\SysWOW64\Tasks\Microsoft\Windows\SyncCenter",
@"C:\Windows\SysWOW64\Tasks\Microsoft\Windows\PLA\System",
};
// https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/working-with-applocker-rules
private static readonly Dictionary<string, HashSet<string>> _appLockerFileExtensionsByType = new Dictionary<string, HashSet<string>>()
{
{ "appx", new HashSet<string> { ".appx" } },
{ "dll", new HashSet<string> { ".dll", ".ocx" } },
{ "exe", new HashSet<string> { ".exe", ".com" } },
{ "msi", new HashSet<string> { ".msi", ".msp", ".mst" } },
{ "script", new HashSet<string> { ".ps1", ".bat", ".cmd", ".vbs", ".js"} },
};
private static Dictionary<string, HashSet<string>> _appLockerByPassDirectoriesByPath = null;
private const int FolderCheckMaxDepth = 3;
public static void CreateLists()
{
if (_appLockerByPassDirectoriesByPath != null) return;
_appLockerByPassDirectoriesByPath = new Dictionary<string, HashSet<string>>();
foreach (var appLockerByPassDirectory in _appLockerByPassDirectoriesSet)
{
string directoryLower = appLockerByPassDirectory.ToLower();
string currentDirectory = Directory.GetParent(directoryLower)?.FullName;
while (!string.IsNullOrEmpty(currentDirectory))
{
if (!_appLockerByPassDirectoriesByPath.ContainsKey(currentDirectory))
{
_appLockerByPassDirectoriesByPath[currentDirectory] = new HashSet<string>();
}
if (!_appLockerByPassDirectoriesByPath[currentDirectory].Contains(appLockerByPassDirectory))
{
_appLockerByPassDirectoriesByPath[currentDirectory].Add(appLockerByPassDirectory);
}
currentDirectory = Directory.GetParent(currentDirectory)?.FullName;
}
}
}
public static void PrintAppLockerPolicy()
{
Beaprint.MainPrint("Checking AppLocker effective policy");
try
{
string[] ruleTypes = { "All" };
var appLockerSettings = SharpAppLocker.GetAppLockerPolicy(SharpAppLocker.PolicyType.Effective, ruleTypes, string.Empty, false, false);
Beaprint.NoColorPrint($" AppLockerPolicy version: {appLockerSettings.Version}\n listing rules:\n\n");
foreach (var rule in appLockerSettings.RuleCollection)
{
PrintFileHashRules(rule);
PrintFilePathRules(rule);
PrintFilePublisherRules(rule);
}
}
catch (COMException)
{
Beaprint.ColorPrint(" AppLocker unsupported on this Windows version.", Beaprint.ansi_color_yellow);
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
private static void PrintFilePublisherRules(AppLockerPolicyRuleCollection rule)
{
if (rule?.FilePublisherRule == null) return;
foreach (var filePublisherRule in rule.FilePublisherRule)
{
Beaprint.GoodPrint($" File Publisher Rule\n");
Beaprint.NoColorPrint($" Rule Type: {rule.Type}\n" +
$" Enforcement Mode: {rule.EnforcementMode}\n" +
$" Name: {filePublisherRule.Name}\n" +
$" Description: {filePublisherRule.Description}\n" +
$" Action: {filePublisherRule.Action}");
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
Beaprint.ColorPrint($" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
Beaprint.GoodPrint($" Conditions");
foreach (var condition in filePublisherRule.Conditions)
{
Beaprint.NoColorPrint($" Binary Name: {condition.BinaryName}\n" +
$" Binary Version Range: ({condition.BinaryVersionRange.LowSection} - {condition.BinaryVersionRange.HighSection})\n" +
$" Product Name: {condition.ProductName}\n" +
$" Publisher Name: {condition.PublisherName}\n");
}
Beaprint.PrintLineSeparator();
}
}
private static void PrintFilePathRules(AppLockerPolicyRuleCollection rule)
{
if (rule?.FilePathRule == null) return;
foreach (var filePathRule in rule.FilePathRule)
{
Beaprint.GoodPrint($" File Path Rule\n");
var normalizedName = NormalizePath(filePathRule.Name);
Beaprint.NoColorPrint($" Rule Type: {rule.Type}\n" +
$" Enforcement Mode: {rule.EnforcementMode}\n" +
$" Name: {filePathRule.Name}\n" +
$" Translated Name: {normalizedName}\n" +
$" Description: {filePathRule.Description}\n" +
$" Action: {filePathRule.Action}");
var color = GetColorBySid(filePathRule.UserOrGroupSid);
Beaprint.ColorPrint($" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
Beaprint.GoodPrint($" Conditions");
foreach (var condition in filePathRule.Conditions)
{
// print wildcards as red and continue
if (condition.Path == "*" || condition.Path == "*.*")
{
Beaprint.ColorPrint($" Path: {condition.Path}", Beaprint.ansi_color_bad);
continue;
}
Beaprint.NoColorPrint($" Path: {condition.Path}");
// TODO
// cache permissions in a dictionary
var normalizedPath = NormalizePath(condition.Path);
// it's a file rule
if (IsFilePath(normalizedPath))
{
// TODO
// load permissions from cache
// check file
CheckFileWriteAccess(normalizedPath);
// check directories
string directory = Path.GetDirectoryName(normalizedPath);
CheckDirectoryAndParentsWriteAccess(directory);
}
// it's a directory rule
else
{
// TODO
// load permissions from cache
// does the directory exists?
if (Directory.Exists(normalizedPath))
{
// can we write to the directory ?
var folderPermissions = PermissionsHelper.GetPermissionsFolder(normalizedPath, Checks.Checks.CurrentUserSiDs, isOnlyWriteOrEquivalentCheck: true);
// we can write
if (folderPermissions.Count > 0)
{
Beaprint.BadPrint($" Directory \"{normalizedPath}\" Permissions: " + string.Join(",", folderPermissions));
}
// we cannot write to the folder
else
{
// first check well known AppLocker bypass locations
if (_appLockerByPassDirectoriesByPath.ContainsKey(normalizedPath))
{
// iterate over applocker bypass directories and check them
foreach (var subfolders in _appLockerByPassDirectoriesByPath[normalizedPath])
{
var subfolderPermissions = PermissionsHelper.GetPermissionsFolder(subfolders, Checks.Checks.CurrentUserSiDs, isOnlyWriteOrEquivalentCheck: true);
// we can write
if (subfolderPermissions.Count > 0)
{
Beaprint.BadPrint($" Directory \"{subfolders}\" Permissions: " + string.Join(",", subfolderPermissions));
break;
}
}
}
// the well-known bypass location does not contain the folder
// check file / subfolder write permissions
else
{
// start with the current directory
bool isFileOrSubfolderWriteAccess = CheckFilesAndSubfolders(normalizedPath, rule.Type, 0);
if (!isFileOrSubfolderWriteAccess)
{
Beaprint.ColorPrint($" No potential bypass found while recursively checking files/subfolders " +
$"for write or equivalent permissions with depth: {FolderCheckMaxDepth}\n" +
$" Check permissions manually.", Beaprint.YELLOW);
}
}
}
}
else
{
// do we have write access recursively for the parent folder(s)?
CheckDirectoryAndParentsWriteAccess(normalizedPath);
}
// TODO
// save to cache for faster next search
}
Beaprint.GoodPrint("");
}
Beaprint.PrintLineSeparator();
}
}
private static void PrintFileHashRules(AppLockerPolicyRuleCollection rule)
{
if (rule?.FileHashRule == null) return;
foreach (var fileHashRule in rule.FileHashRule)
{
Beaprint.GoodPrint($" File Hash Rule\n");
Beaprint.NoColorPrint($" Rule Type: {rule.Type}\n" +
$" Enforcement Mode: {rule.EnforcementMode}\n" +
$" Name: {fileHashRule.Name}\n" +
$" Description: {fileHashRule.Description}\n" +
$" Action: {fileHashRule.Action}");
var color = GetColorBySid(fileHashRule.UserOrGroupSid);
Beaprint.ColorPrint($" User Or Group Sid: {fileHashRule.UserOrGroupSid}\n", color);
Beaprint.GoodPrint($" Conditions");
foreach (var condition in fileHashRule.Conditions)
{
Beaprint.NoColorPrint($" Source File Name: {condition.FileHash.SourceFileName}\n" +
$" Data: {condition.FileHash.Data}\n" +
$" Source File Length: {condition.FileHash.SourceFileLength}\n" +
$" Type: {condition.FileHash.Type}\n");
}
Beaprint.PrintLineSeparator();
}
}
private static string GetColorBySid(string sid)
{
var color = Checks.Checks.CurrentUserSiDs.ContainsKey(sid)
? Beaprint.ansi_color_bad
: Beaprint.ansi_color_good;
return color;
}
private static string NormalizePath(string path)
{
if (string.IsNullOrWhiteSpace(path)) return string.Empty;
var systemDrive = Environment.GetEnvironmentVariable("SystemDrive");
path = path.Replace("%OSDRIVE%", systemDrive);
path = path.Replace("*", string.Empty);
path = path.TrimEnd('\\');
path = Environment.ExpandEnvironmentVariables(path);
path = path.ToLower();
return path;
}
private static bool CheckFilesAndSubfolders(string path, string ruleType, int depth)
{
if (string.IsNullOrWhiteSpace(ruleType)) throw new ArgumentNullException(nameof(ruleType));
if (depth == FolderCheckMaxDepth) return false;
try
{
var subfolders = Directory.GetDirectories(path);
var files = Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly);
ruleType = ruleType.ToLower();
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
{
throw new ArgumentException(nameof(ruleType));
}
var filteredFiles =
(from file in files
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
select file).ToList();
// first check write access for files
if (filteredFiles.Any(CheckFileWriteAccess))
{
return true;
}
// if we have not found any writable file,
// check subfolders for write access
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
{
return true;
}
// check recursively all the subfolders for files/sub-subfolders
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
{
return true;
}
}
catch (Exception e)
{
// unauthorized access ?
}
return false;
}
private static bool CheckFileWriteAccess(string path)
{
if (string.IsNullOrWhiteSpace(path)) return false;
if (File.Exists(path))
{
var filePermissions = PermissionsHelper.GetPermissionsFile(path, Checks.Checks.CurrentUserSiDs, isOnlyWriteOrEquivalentCheck: true);
if (filePermissions.Count > 0)
{
Beaprint.BadPrint($" File \"{path}\" Permissions: " + string.Join(",", filePermissions));
return true;
}
}
else
{
Beaprint.BadPrint($" File \"{path}\" does not exist.");
}
return false;
}
private static bool CheckDirectoryAndParentsWriteAccess(string directory)
{
while (!string.IsNullOrEmpty(directory))
{
// first check if we have write permission on the directory
if (CheckDirectoryWriteAccess(directory, out var isDirectoryExisting))
{
return true;
}
// the directory exists and we don't have write permissions
// we can return false;
if (isDirectoryExisting)
{
return false;
}
// if the current folder does not exists, check it's parent directory recursively
directory = Directory.GetParent(directory)?.FullName;
}
return false;
}
private static bool CheckDirectoryWriteAccess(string directory, out bool isDirectoryExisting, bool isGoodPrint = true)
{
isDirectoryExisting = true;
if (!Directory.Exists(directory))
{
Beaprint.BadPrint($" Directory \"{directory}\" does not exist.");
isDirectoryExisting = false;
}
else
{
var folderPermissions = PermissionsHelper.GetPermissionsFolder(directory, Checks.Checks.CurrentUserSiDs, isOnlyWriteOrEquivalentCheck: true);
if (folderPermissions.Count > 0)
{
Beaprint.BadPrint($" Directory \"{directory}\" Permissions: " + string.Join(",", folderPermissions));
}
else
{
if (isGoodPrint)
{
Beaprint.GoodPrint($" {directory}");
}
}
return folderPermissions.Count > 0;
}
return false;
}
private static bool IsFilePath(string path)
{
return !string.IsNullOrEmpty(path) &&
!string.IsNullOrWhiteSpace(Path.GetExtension(path));
}
}
}

View File

@ -28,9 +28,8 @@ namespace winPEAS.Helpers.AppLocker
}
public static string GetAppLockerPolicy(PolicyType policyType, string[] appLockerRuleTypes, string ldapPath = "", bool allowOnly = false, bool denyOnly = false)
public static AppLockerPolicy GetAppLockerPolicy(PolicyType policyType, string[] appLockerRuleTypes, string ldapPath = "", bool allowOnly = false, bool denyOnly = false)
{
// Create IAppIdPolicyHandler COM interface
IAppIdPolicyHandler IAppHandler = new AppIdPolicyHandlerClass();
string policies;
@ -50,14 +49,12 @@ namespace winPEAS.Helpers.AppLocker
throw new InvalidOperationException();
};
/*
var objectHolder = DeserializeToObject<AppLockerPolicy>(policies);
AppLockerPolicy appLockerPolicyFiltered = DeserializeToObject<AppLockerPolicy>(policies);
if (objectHolder?.RuleCollection?.Count() > 0)
{
//Null them all out to emtpy lists
//Null them all out to empty lists
for (int i = 0; i < appLockerPolicyFiltered.RuleCollection.Length; i++)
{
appLockerPolicyFiltered.RuleCollection[i].FileHashRule = new List<AppLockerPolicyRuleCollectionFileHashRule>() { };
@ -69,7 +66,8 @@ namespace winPEAS.Helpers.AppLocker
{
if (objectHolder?.RuleCollection[i].FilePathRule != null)
{
if (appLockerRuleTypes.Contains("All", StringComparer.InvariantCultureIgnoreCase) || appLockerRuleTypes.Contains("FilePathRule", StringComparer.InvariantCultureIgnoreCase))
if (appLockerRuleTypes.Contains("All", StringComparer.InvariantCultureIgnoreCase) ||
appLockerRuleTypes.Contains("FilePathRule", StringComparer.InvariantCultureIgnoreCase))
{
foreach (var pathRule in objectHolder?.RuleCollection[i].FilePathRule)
{
@ -78,13 +76,11 @@ namespace winPEAS.Helpers.AppLocker
if (pathRule.Action.Equals(allowOnly ? "Allow" : "Deny"))
{
appLockerPolicyFiltered.RuleCollection[i].FilePathRule.Add(pathRule);
//outputBuilder.Append(JsonConvert.SerializeObject(pathRule, Newtonsoft.Json.Formatting.Indented));
}
}
else
{
appLockerPolicyFiltered.RuleCollection[i].FilePathRule.Add(pathRule);
//outputBuilder.Append(JsonConvert.SerializeObject(pathRule, Newtonsoft.Json.Formatting.Indented));
}
}
}
@ -100,13 +96,11 @@ namespace winPEAS.Helpers.AppLocker
if (hashRule.Action.Equals(allowOnly ? "Allow" : "Deny"))
{
appLockerPolicyFiltered.RuleCollection[i].FileHashRule.Add(hashRule);
//outputBuilder.Append(JsonConvert.SerializeObject(pathRule, Newtonsoft.Json.Formatting.Indented));
}
}
else
{
appLockerPolicyFiltered.RuleCollection[i].FileHashRule.Add(hashRule);
//outputBuilder.Append(JsonConvert.SerializeObject(pathRule, Newtonsoft.Json.Formatting.Indented));
}
}
}
@ -122,13 +116,11 @@ namespace winPEAS.Helpers.AppLocker
if (pubRile.Action.Equals(allowOnly ? "Allow" : "Deny"))
{
appLockerPolicyFiltered.RuleCollection[i].FilePublisherRule.Add(pubRile);
//outputBuilder.Append(JsonConvert.SerializeObject(pathRule, Newtonsoft.Json.Formatting.Indented));
}
}
else
{
appLockerPolicyFiltered.RuleCollection[i].FilePublisherRule.Add(pubRile);
//outputBuilder.Append(JsonConvert.SerializeObject(pathRule, Newtonsoft.Json.Formatting.Indented));
}
}
}
@ -138,23 +130,14 @@ namespace winPEAS.Helpers.AppLocker
//Remove all the empty stuff
appLockerPolicyFiltered.RuleCollection = appLockerPolicyFiltered.RuleCollection.Where(x =>
x.FilePublisherRule.Count() > 0 ||
x.FilePathRule.Count() > 0 ||
x.FileHashRule.Count() > 0
x.FilePublisherRule.Any() ||
x.FilePathRule.Any() ||
x.FileHashRule.Any()
).ToArray();
return JsonConvert.SerializeObject(appLockerPolicyFiltered, Newtonsoft.Json.Formatting.Indented);
}
return JsonConvert.SerializeObject(objectHolder, Newtonsoft.Json.Formatting.Indented);
*/
policies = policies.Replace("><", ">\n<");
return policies;
return appLockerPolicyFiltered;
}
}
}

View File

@ -126,6 +126,7 @@ namespace winPEAS.Helpers
Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search files that can contains credentials" + NOCOLOR);
Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
Console.WriteLine(LBLUE + " log" + GRAY +$" Log all output to file \"{Checks.Checks.LogFile}\"" + NOCOLOR);
Console.WriteLine(YELLOW + " [+] " + LYELLOW + "By default all checks (except CMD checks) are executed" + NOCOLOR);
}
@ -217,6 +218,11 @@ namespace winPEAS.Helpers
}
}
internal static void NoColorPrint(string message)
{
AnsiPrint(message, new Dictionary<string, string>());
}
static string Regexansi(string to_match, string color, string rgxp)
{
if (to_match.Length == 0 || color.Length == 0 || rgxp.Length == 0)

View File

@ -27,12 +27,11 @@ namespace winPEAS.Helpers.CredentialManager
unicodeInfo = UnicodeInfoText;
}
string item = $"\nUsername: {credential.Username}\n" +
$"Password:{unicodeInfo} {clearTextPassword}\n" +
$"Target: {credential.Target}\n" +
$"PersistenceType: {credential.PersistenceType}\n" +
$"LastWriteTime: {credential.LastWriteTime}\n" +
"-------------------------------------------------------";
string item = $" Username: {credential.Username}\n" +
$" Password:{unicodeInfo} {clearTextPassword}\n" +
$" Target: {credential.Target}\n" +
$" PersistenceType: {credential.PersistenceType}\n" +
$" LastWriteTime: {credential.LastWriteTime}\n";
result.Add(item);
}

View File

@ -16,7 +16,7 @@ namespace winPEAS.Helpers
/// Get interesting permissions from Files, Folders and Registry
internal static class PermissionsHelper
{
public static List<string> GetPermissionsFile(string path, Dictionary<string, string> SIDs)
public static List<string> GetPermissionsFile(string path, Dictionary<string, string> SIDs, bool isOnlyWriteOrEquivalentCheck = false)
{
/*Permisos especiales para carpetas
*https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask-format?redirectedfrom=MSDN
@ -37,7 +37,7 @@ namespace winPEAS.Helpers
try
{
FileSecurity fSecurity = File.GetAccessControl(path);
results = GetMyPermissionsF(fSecurity, SIDs);
results = GetMyPermissionsF(fSecurity, SIDs, isOnlyWriteOrEquivalentCheck);
}
catch
{
@ -46,7 +46,7 @@ namespace winPEAS.Helpers
return results;
}
public static List<string> GetPermissionsFolder(string path, Dictionary<string, string> SIDs)
public static List<string> GetPermissionsFolder(string path, Dictionary<string, string> SIDs, bool isOnlyWriteOrEquivalentCheck = false)
{
List<string> results = new List<string>();
@ -66,7 +66,7 @@ namespace winPEAS.Helpers
}
FileSecurity fSecurity = File.GetAccessControl(path);
results = GetMyPermissionsF(fSecurity, SIDs);
results = GetMyPermissionsF(fSecurity, SIDs, isOnlyWriteOrEquivalentCheck);
}
catch
{
@ -75,7 +75,7 @@ namespace winPEAS.Helpers
return results;
}
public static List<string> GetMyPermissionsF(FileSecurity fSecurity, Dictionary<string, string> SIDs)
public static List<string> GetMyPermissionsF(FileSecurity fSecurity, Dictionary<string, string> SIDs, bool isOnlyWriteOrEquivalentCheck = false)
{
// Get interesting permissions in fSecurity (Only files and folders)
List<string> results = new List<string>();
@ -85,7 +85,7 @@ namespace winPEAS.Helpers
{
//First, check if the rule to check is interesting
int current_perm = (int)rule.FileSystemRights;
string current_perm_str = PermInt2Str(current_perm, false);
string current_perm_str = PermInt2Str(current_perm, isOnlyWriteOrEquivalentCheck);
if (current_perm_str == "")
{
continue;

View File

@ -9,6 +9,8 @@ using winPEAS.Helpers;
namespace winPEAS.Info.ApplicationInfo
{
// https://www.ghacks.net/2016/06/04/windows-automatic-startup-locations/
internal static class AutoRuns
{
public static List<Dictionary<string, string>> GetAutoRuns(Dictionary<string, string> NtAccountNames)

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Security.Principal;
using System.Text.RegularExpressions;
using winPEAS.Helpers;
@ -27,8 +29,7 @@ namespace winPEAS.Info.UserInfo
{ "S-1-5-1", "Dialup" }, //A group that includes all users who have logged on through a dial-up connection. Membership is controlled by the operating system.
{ "S-1-5-2", "Network" }, //A group that includes all users that have logged on through a network connection. Membership is controlled by the operating system.
{ "S-1-5-3", "Batch" }, //A group that includes all users that have logged on through a batch queue facility. Membership is controlled by the operating system.
{ "S-1-5-4", "Interactive" }, //A group that includes all users that have logged on interactively. Membership is controlled by the operating system.
{ "S-1-5-5-.+-.+", "Logon Session" }, //A logon session. The X and Y values for these SIDs are different for each session.
{ "S-1-5-4", "Interactive" }, //A group that includes all users that have logged on interactively. Membership is controlled by the operating system.
{ "S-1-5-6", "Service" }, //A group that includes all security principals that have logged on as a service. Membership is controlled by the operating system.
{ "S-1-5-7", "Anonymous" }, //A group that includes all users that have logged on anonymously. Membership is controlled by the operating system.
{ "S-1-5-9", "Enterprise Domain Controllers" }, //A group that includes all domain controllers in a forest that uses an Active Directory directory service. Membership is controlled by the operating system.
@ -41,22 +42,6 @@ namespace winPEAS.Info.UserInfo
{ "S-1-5-18", "Local System" }, //A service account that is used by the operating system.
{ "S-1-5-19", "NT Authority\\Local Service" },
{ "S-1-5-20", "NT Authority\\Network Service" },
{ "S-1-5-21.+-500", "Administrator" }, //A user account for the system administrator. By default, it is the only user account that is given full control over the system.
{ "S-1-5-21.+-501", "Guest" }, //A user account for people who do not have individual accounts. This user account does not require a password. By default, the Guest account is disabled.
{ "S-1-5-21.+-502", "KRBTGT" }, //A service account that is used by the Key Distribution Center (KDC) service.
{ "S-1-5-21.+-512", "Domain Admins" }, //A global group whose members are authorized to administer the domain. By default, the Domain Admins group is a member of the Administrators group on all computers that have joined a domain, including the domain controllers. Domain Admins is the default owner of any object that is created by any member of the group.
{ "S-1-5-21.+-513", "Domain Users" }, //A global group that, by default, includes all user accounts in a domain. When you create a user account in a domain, it is added to this group by default.
{ "S-1-5-21.+-514", "Domain Guests" }, //A global group that, by default, has only one member, the domain's built-in Guest account.
{ "S-1-5-21.+-515", "Domain Computers" }, //A global group that includes all clients and servers that have joined the domain.
{ "S-1-5-21.+-516", "Domain Controllers" }, //A global group that includes all domain controllers in the domain. New domain controllers are added to this group by default.
{ "S-1-5-21.+-517", "Cert Publishers" }, //A global group that includes all computers that are running an enterprise certification authority. Cert Publishers are authorized to publish certificates for User objects in Active Directory.
{ "S-1-5-21.+-518", "Schema Admins" }, //A universal group in a native-mode domain; a global group in a mixed-mode domain. The group is authorized to make schema changes in Active Directory. By default, the only member of the group is the Administrator account for the forest root domain.
{ "S-1-5-21.+-519", "Enterprise Admins" }, //A universal group in a native-mode domain; a global group in a mixed-mode domain. The group is authorized to make forest-wide changes in Active Directory, such as adding child domains. By default, the only member of the group is the Administrator account for the forest root domain.
{ "S-1-5-21.+-520", "Group Policy Creator Owners" }, //A global group that is authorized to create new Group Policy objects in Active Directory. By default, the only member of the group is Administrator.
{ "S-1-5-21.+-525", "Protected Users" }, //https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#protected-users
{ "S-1-5-21.+-526", "Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group.
{ "S-1-5-21.+-527", "Enterprise Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group.
{ "S-1-5-21.+-553", "RAS and IAS Servers" }, //A domain local group. By default, this group has no members. Servers in this group have Read Account Restrictions and Read Logon Information access to User objects in the Active Directory domain local group.
{ "S-1-5-32-544", "Administrators" }, //A built-in group. After the initial installation of the operating system, the only member of the group is the Administrator account. When a computer joins a domain, the Domain Admins group is added to the Administrators group. When a server becomes a domain controller, the Enterprise Admins group also is added to the Administrators group.
{ "S-1-5-32-545", "Users" }, //A built-in group. After the initial installation of the operating system, the only member is the Authenticated Users group. When a computer joins a domain, the Domain Users group is added to the Users group on the computer.
{ "S-1-5-32-546", "Guests" }, //A built-in group. By default, the only member is the Guest account. The Guests group allows occasional or one-time users to log on with limited privileges to a computer's built-in Guest account.
@ -85,10 +70,6 @@ namespace winPEAS.Info.UserInfo
{ "S-1-5-32-561", "Builtin\\Terminal Server License Servers" }, //An alias. A group for Terminal Server License Servers. When Windows Server 2003 Service Pack 1 is installed, a new local group is created.
{ "S-1-5-32-562", "Builtin\\Distributed COM Users" }, //An alias. A group for COM to provide computerwide access controls that govern access to all call, activation, or launch requests on the computer.
{ "S-1-2-1", "Console Logon" }, //A group that includes users who are logged on to the physical console.
{ "S-1-5-21.+-498", "Enterprise Read-only Domain Controllers" }, //A universal group. Members of this group are read-only domain controllers in the enterprise.
{ "S-1-5-21.+-521", "Read-only Domain Controllers" }, //A global group. Members of this group are read-only domain controllers in the domain.
{ "S-1-5-21.+-571", "Allowed RODC Password Replication Group" }, //A domain local group. Members in this group can have their passwords replicated to all read-only domain controllers in the domain.
{ "S-1-5-21.+-572", "Denied RODC Password Replication Group" }, //A domain local group. Members in this group cannot have their passwords replicated to any read-only domain controllers in the domain.
{ "S-1-5-32-569", " Builtin\\Cryptographic Operators" }, //A built-in local group. Members are authorized to perform cryptographic operations.
{ "S-1-5-32-573", "Builtin\\Event Log Readers" }, //A built-in local group. Members of this group can read event logs from local computer.
{ "S-1-5-32-574", "Builtin\\Certificate Service DCOM Access" }, //A built-in local group. Members of this group are allowed to connect to Certification Authorities in the enterprise.
@ -103,7 +84,6 @@ namespace winPEAS.Info.UserInfo
{ "S-1-16-16384", "System Mandatory Level" }, //A system integrity level.
{ "S-1-16-20480", "Protected Process Mandatory Level" }, //A protected-process integrity level.
{ "S-1-16-28672", "Secure Process Mandatory Level" }, //A secure process integrity level.
{ "S-1-5-21-.+-522", "Cloneable Domain Controllers" }, //A global group. Members of this group that are domain controllers may be cloned.
{ "S-1-5-32-575", "Builtin\\RDS Remote Access Servers" }, //A built-in local group. Servers in this group enable users of RemoteApp programs and personal virtual desktops access to these resources. In Internet-facing deployments, these servers are typically deployed in an edge network. This group needs to be populated on servers running RD Connection Broker. RD Gateway servers and RD Web Access servers used in the deployment need to be in this group.
{ "S-1-5-32-576", "Builtin\\RDS Endpoint Servers" }, //A built-in local group. Servers in this group run virtual machines and host sessions where users RemoteApp programs and personal virtual desktops run. This group needs to be populated on servers running RD Connection Broker. RD Session Host servers and RD Virtualization Host servers used in the deployment need to be in this group.
{ "S-1-5-32-577", "Builtin\\RDS Management Servers" }, //A builtin local group. Servers in this group can perform routine administrative actions on servers running Remote Desktop Services. This group needs to be populated on all servers in a Remote Desktop Services deployment. The servers running the RDS Central Management service must be included in this group.
@ -115,15 +95,55 @@ namespace winPEAS.Info.UserInfo
{ "S-1-5-64-36" , "Cloud Account Authentication" },
};
var knownDomainSidsDic = new Dictionary<string, string>()
{
// starts with "S-1-5-21"
{ "498", "Enterprise Read-only Domain Controllers" }, //A universal group. Members of this group are read-only domain controllers in the enterprise.
{ "500", "Administrator" }, //A user account for the system administrator. By default, it is the only user account that is given full control over the system.
{ "501", "Guest" }, //A user account for people who do not have individual accounts. This user account does not require a password. By default, the Guest account is disabled.
{ "502", "KRBTGT" }, //A service account that is used by the Key Distribution Center (KDC) service.
{ "512", "Domain Admins" }, //A global group whose members are authorized to administer the domain. By default, the Domain Admins group is a member of the Administrators group on all computers that have joined a domain, including the domain controllers. Domain Admins is the default owner of any object that is created by any member of the group.
{ "513", "Domain Users" }, //A global group that, by default, includes all user accounts in a domain. When you create a user account in a domain, it is added to this group by default.
{ "514", "Domain Guests" }, //A global group that, by default, has only one member, the domain's built-in Guest account.
{ "515", "Domain Computers" }, //A global group that includes all clients and servers that have joined the domain.
{ "516", "Domain Controllers" }, //A global group that includes all domain controllers in the domain. New domain controllers are added to this group by default.
{ "517", "Cert Publishers" }, //A global group that includes all computers that are running an enterprise certification authority. Cert Publishers are authorized to publish certificates for User objects in Active Directory.
{ "518", "Schema Admins" }, //A universal group in a native-mode domain; a global group in a mixed-mode domain. The group is authorized to make schema changes in Active Directory. By default, the only member of the group is the Administrator account for the forest root domain.
{ "519", "Enterprise Admins" }, //A universal group in a native-mode domain; a global group in a mixed-mode domain. The group is authorized to make forest-wide changes in Active Directory, such as adding child domains. By default, the only member of the group is the Administrator account for the forest root domain.
{ "520", "Group Policy Creator Owners" }, //A global group that is authorized to create new Group Policy objects in Active Directory. By default, the only member of the group is Administrator.
{ "521", "Read-only Domain Controllers" }, //A global group. Members of this group are read-only domain controllers in the domain.
{ "522", "Cloneable Domain Controllers" }, //A global group. Members of this group that are domain controllers may be cloned.
{ "525", "Protected Users" }, //https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#protected-users
{ "526", "Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group.
{ "527", "Enterprise Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group.
{ "553", "RAS and IAS Servers" }, //A domain local group. By default, this group has no members. Servers in this group have Read Account Restrictions and Read Logon Information access to User objects in the Active Directory domain local group.
{ "571", "Allowed RODC Password Replication Group" }, //A domain local group. Members in this group can have their passwords replicated to all read-only domain controllers in the domain.
{ "572", "Denied RODC Password Replication Group" }, //A domain local group. Members in this group cannot have their passwords replicated to any read-only domain controllers in the domain.
};
SID = SID.ToUpper();
try
{
foreach (KeyValuePair<string, string> kSidEntry in knownSidDic)
if (knownSidDic.ContainsKey(SID))
{
Match match = Regex.Match(SID, "^" + kSidEntry.Key + "$", RegexOptions.IgnoreCase);
if (!string.IsNullOrEmpty(match.Value))
return knownSidDic[SID];
}
if (SID.StartsWith("S-1-5-5-"))
{
return "Logon Session";
}
// domain SIDs
if (SID.StartsWith("S-1-5-21"))
{
var parts = SID.Split('-');
string lastId = parts[parts.Length - 1];
if (knownDomainSidsDic.ContainsKey(lastId))
{
return knownSidDic[kSidEntry.Key];
return knownDomainSidsDic[lastId];
}
}
@ -135,5 +155,21 @@ namespace winPEAS.Info.UserInfo
}
return "";
}
public static string DomainSId
{
get
{
var administratorAcount = new NTAccount(GetDomainName(), "Administrator");
var administratorSId = (SecurityIdentifier)administratorAcount.Translate(typeof(SecurityIdentifier));
return administratorSId.AccountDomainSid.Value;
}
}
internal static string GetDomainName()
{
//could be other way to get the domain name through Environment.UserDomainName etc...
return IPGlobalProperties.GetIPGlobalProperties().DomainName;
}
}
}

View File

@ -119,6 +119,7 @@
<Compile Include="Checks\SystemInfo.cs" />
<Compile Include="Checks\UserInfo.cs" />
<Compile Include="Checks\WindowsCreds.cs" />
<Compile Include="Helpers\AppLocker\AppLockerHelper.cs" />
<Compile Include="Helpers\AppLocker\AppLockerRules.cs" />
<Compile Include="Helpers\AppLocker\IAppIdPolicyHandler.cs" />
<Compile Include="Helpers\AppLocker\SharpAppLocker.cs" />