diff --git a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs index ceacf03..992878f 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/Checks.cs @@ -37,6 +37,9 @@ namespace winPEAS.Checks private static List _systemChecks; private static HashSet _systemCheckSelectedKeysHashSet = new HashSet(); + // github url for Linpeas.sh + public static string LinpeasUrl = "https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh"; + public const string LogFile = "out.txt"; @@ -130,6 +133,18 @@ namespace winPEAS.Checks IsDebug = true; } + if (arg.StartsWith("linpeasUrl", StringComparison.CurrentCultureIgnoreCase)) + { + var parts = arg.Split('='); + if (parts.Length != 2 || string.IsNullOrEmpty(parts[1])) + { + Beaprint.PrintUsage(); + return; + } + + LinpeasUrl = parts[1]; + } + string argToLower = arg.ToLower(); if (systemCheckAllKeys.Contains(argToLower)) { diff --git a/winPEAS/winPEASexe/winPEAS/Checks/EventsInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/EventsInfo.cs index cd85b59..1c175d7 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/EventsInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/EventsInfo.cs @@ -35,10 +35,10 @@ namespace winPEAS.Checks foreach (var info in powerShellEventInfos) { Beaprint.NoColorPrint($" User Id : {info.UserId}\n" + - $" Event Id : {info.EventId}\n" + - $" Context : {info.Context}\n" + - $" Created At : {info.CreatedAt}\n" + - $" Command line : {info.Match}\n"); + $" Event Id : {info.EventId}\n" + + $" Context : {info.Context}\n" + + $" Created At : {info.CreatedAt}\n" + + $" Command line : {info.Match}\n"); Beaprint.PrintLineSeparator(); } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs index a0ba16d..184a0a6 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/FilesInfo.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using winPEAS.Helpers; using winPEAS.Helpers.Registry; using winPEAS.Helpers.Search; using winPEAS.Info.FilesInfo.Certificates; using winPEAS.Info.FilesInfo.McAfee; +using winPEAS.Info.FilesInfo.WSL; using winPEAS.Info.UserInfo; using winPEAS.InterestingFiles; using winPEAS.KnownFileCreds; @@ -123,7 +126,6 @@ namespace winPEAS.Checks PrintUnattendFiles, PrintSAMBackups, PrintMcAffeSitelistFiles, - PrintLinuxShells, PrintCachedGPPPassword, PrintPossCredsRegs, PrintUserCredsFiles, @@ -138,6 +140,7 @@ namespace winPEAS.Checks PrintHiddenFilesAndFolders, PrintOtherUsersInterestingFiles, PrintExecutablesInNonDefaultFoldersWithWritePermissions, + PrintWSLDistributions, }.ForEach(action => CheckRunner.Run(action, isDebug)); SearchHelper.CleanLists(); @@ -242,12 +245,13 @@ namespace winPEAS.Checks } } - void PrintLinuxShells() + void PrintWSLDistributions() { Beaprint.MainPrint("Looking for Linux shells/distributions - wsl.exe, bash.exe"); List linuxShells = InterestingFiles.InterestingFiles.GetLinuxShells(); string hive = "HKCU"; string basePath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss"; + const string linpeas = "linpeas.sh"; if (linuxShells.Any()) { @@ -264,13 +268,11 @@ namespace winPEAS.Checks if (wslKeys.Any()) { - const string linpeas = "linpeas.sh"; const string distribution = "Distribution"; const string rootDirectory = "Root directory"; const string runWith = "Run command"; - - Dictionary colors = new Dictionary(); + var colors = new Dictionary(); new List { linpeas, @@ -298,6 +300,19 @@ namespace winPEAS.Checks } catch (Exception) { } } + + // try to run linpeas.sh in the default distribution + Beaprint.ColorPrint($" Running {linpeas} in the default distribution\n" + + $" Using linpeas.sh URL: {Checks.LinpeasUrl}", Beaprint.LBLUE); + + try + { + WSL.RunLinpeas(Checks.LinpeasUrl); + } + catch (Exception ex) + { + Beaprint.PrintException($" Unable to run linpeas.sh: {ex.Message}"); + } } else { diff --git a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs index 7f4c4ec..d5ada44 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs @@ -16,6 +16,7 @@ using winPEAS.Helpers.Extensions; using winPEAS.Helpers.Registry; using winPEAS.Info.SystemInfo.AuditPolicies; using winPEAS.Info.SystemInfo.DotNet; +using winPEAS.Info.SystemInfo.GroupPolicy; using winPEAS.Info.SystemInfo.WindowsDefender; namespace winPEAS.Checks @@ -74,7 +75,9 @@ namespace winPEAS.Checks PrintDrivesInfo, PrintWSUS, PrintAlwaysInstallElevated, + PrintLSAInfo, PrintLsaCompatiblityLevel, + PrintLocalGroupPolicy, AppLockerHelper.PrintAppLockerPolicy, PrintPrintersWMIInfo, PrintNamedPipes, @@ -964,5 +967,85 @@ namespace winPEAS.Checks { } } + + private static void PrintLSAInfo() + { + try + { + Beaprint.MainPrint("Enumerate LSA settings - auth packages included\n"); + + var settings = RegistryHelper.GetRegValues("HKLM", "SYSTEM\\CurrentControlSet\\Control\\Lsa"); + + if ((settings != null) && (settings.Count != 0)) + { + foreach (var kvp in settings) + { + var val = string.Empty; + + if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.String")) + { + val = string.Join(",", (string[])kvp.Value); + } + else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte")) + { + val = System.BitConverter.ToString((byte[])kvp.Value); + } + else + { + val = kvp.Value.ToString(); + } + + var key = kvp.Key; + + Beaprint.NoColorPrint($" {key,-30} : {val}"); + + if (Regex.IsMatch(key, "Security Packages") && Regex.IsMatch(val, @".*wdigest.*")) + { + Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!"); + } + + if (key.Equals("RunAsPPL", System.StringComparison.InvariantCultureIgnoreCase) && val == "1") + { + Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily."); + } + + if (key.Equals("DisableRestrictedAdmin", System.StringComparison.InvariantCultureIgnoreCase) && val == "0") + { + Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system."); + } + } + } + } + catch (Exception ex) + { + } + } + + private static void PrintLocalGroupPolicy() + { + try + { + Beaprint.MainPrint("Display Local Group Policy settings - local users/machine" ); + + var infos = GroupPolicy.GetLocalGroupPolicyInfos(); + + foreach (var info in infos) + { + Beaprint.NoColorPrint($" Type : {info.GPOType}\n" + + $" Display Name : {info.DisplayName}\n" + + $" Name : {info.GPOName}\n" + + $" Extensions : {info.Extensions}\n" + + $" File Sys Path : {info.FileSysPath}\n" + + $" Link : {info.Link}\n" + + $" GPO Link : {info.GPOLink.GetDescription()}\n" + + $" Options : {info.Options.GetDescription()}\n"); + + Beaprint.PrintLineSeparator(); + } + } + catch (Exception ex) + { + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs index b65a9ca..c6179e2 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/UserInfo.cs @@ -8,6 +8,7 @@ using winPEAS.Info.UserInfo; using winPEAS.Info.UserInfo.LogonSessions; using winPEAS.Info.UserInfo.Token; using winPEAS.Native; +using winPEAS.Native.Enums; using winPEAS.Native.Structs; namespace winPEAS.Checks @@ -43,6 +44,7 @@ namespace winPEAS.Checks PrintTokenP, PrintClipboardText, PrintLoggedUsers, + PrintLocalUsers, PrintRdpSessions, PrintEverLoggedUsers, PrintHomeFolders, @@ -54,7 +56,7 @@ namespace winPEAS.Checks Dictionary ColorsU() { - Dictionary usersColors = new Dictionary() + var usersColors = new Dictionary() { { Checks.PaintActiveUsersNoAdministrator, Beaprint.ansi_users_active }, { Checks.CurrentUserName + "|"+ Checks.CurrentUserDomainName, Beaprint.ansi_current_user }, @@ -336,5 +338,58 @@ namespace winPEAS.Checks { } } + + private static void PrintLocalUsers() + { + try + { + Beaprint.MainPrint("Display information about local users"); + + var computerName = Environment.GetEnvironmentVariable("COMPUTERNAME"); + + var localUsers = User.GetLocalUsers(computerName); + + var colors = new Dictionary + { + { "Administrator", Beaprint.ansi_color_bad }, + { "Guest", Beaprint.YELLOW }, + { "False", Beaprint.ansi_color_good }, + { "True", Beaprint.ansi_color_bad }, + }; + + foreach (var localUser in localUsers) + { + var enabled = ((localUser.flags >> 1) & 1) == 0; + var pwdLastSet = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + var lastLogon = new DateTime(1970, 1, 1, 0, 0, 0); + + if (localUser.passwordAge != 0) + { + pwdLastSet = DateTime.Now.AddSeconds(-localUser.passwordAge); + } + + if (localUser.last_logon != 0) + { + lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime(); + } + + Beaprint.AnsiPrint( $" Computer Name : {computerName}\n" + + $" User Name : {localUser.name}\n" + + $" User Id : {localUser.user_id}\n" + + $" Is Enabled : {enabled}\n" + + $" User Type : {(UserPrivType)localUser.priv}\n" + + $" Comment : {localUser.comment}\n" + + $" Last Logon : {lastLogon}\n" + + $" Logons Count : {localUser.num_logons}\n" + + $" Password Last Set : {pwdLastSet}\n", + colors); + + Beaprint.PrintLineSeparator(); + } + } + catch (Exception ex) + { + } + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs b/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs index 292bd1d..828f7a8 100644 --- a/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs +++ b/winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs @@ -106,22 +106,23 @@ 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 + " cmd" + GRAY + " Obtain wifi, cred manager and clipboard information executing CMD commands" + NOCOLOR); - Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR); - Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR); - Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR); - Console.WriteLine(LBLUE + " processinfo" + GRAY + " Search processes information" + NOCOLOR); - Console.WriteLine(LBLUE + " servicesinfo" + GRAY + " Search services information" + NOCOLOR); - Console.WriteLine(LBLUE + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR); - Console.WriteLine(LBLUE + " networkinfo" + GRAY + " Search network information" + NOCOLOR); - Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR); - Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR); - Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search files that can contains credentials" + NOCOLOR); - Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR); - Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR); - Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR); - Console.WriteLine(LBLUE + " log" + GRAY +$" Log all output to file \"{Checks.Checks.LogFile}\"" + NOCOLOR); + Console.WriteLine(LBLUE + " quiet" + GRAY + " Do not print banner" + NOCOLOR); + Console.WriteLine(LBLUE + " cmd" + GRAY + " Obtain wifi, cred manager and clipboard information executing CMD commands" + NOCOLOR); + Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR); + Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR); + Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR); + Console.WriteLine(LBLUE + " processinfo" + GRAY + " Search processes information" + NOCOLOR); + Console.WriteLine(LBLUE + " servicesinfo" + GRAY + " Search services information" + NOCOLOR); + Console.WriteLine(LBLUE + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR); + Console.WriteLine(LBLUE + " networkinfo" + GRAY + " Search network information" + NOCOLOR); + Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR); + Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR); + Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search files that can contains credentials" + NOCOLOR); + Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR); + Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR); + Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR); + Console.WriteLine(LBLUE + " log" + GRAY +$" Log all output to file \"{Checks.Checks.LogFile}\"" + NOCOLOR); + Console.WriteLine(LBLUE + " linpeasUrl=" + GRAY + $" Provide linpeas.sh URL for WSL checks (default: {Checks.Checks.LinpeasUrl})" + NOCOLOR); Console.WriteLine(YELLOW + " [+] " + LYELLOW + "By default all checks (except CMD checks) are executed" + NOCOLOR); } diff --git a/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/WSL/WSL.cs b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/WSL/WSL.cs new file mode 100644 index 0000000..749d60b --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/FilesInfo/WSL/WSL.cs @@ -0,0 +1,80 @@ +using System; +using System.Diagnostics; +using System.Text; + +namespace winPEAS.Info.FilesInfo.WSL +{ + public class WSL + { + public static void RunLinpeas(string linpeasUrl) + { + string linpeasCmd = $"curl {linpeasUrl} --silent | sh"; + string command = Environment.Is64BitProcess ? + $@"bash -c ""{linpeasCmd}""" : + Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\""; + + ExecuteCommandLine(command); + } + + private static void ExecuteCommandLine(string fullCommandLine, + string workingFolder = null, + string verb = "OPEN") + { + string executable = fullCommandLine; + string args = null; + + if (executable.StartsWith("\"")) + { + int at = executable.IndexOf("\" "); + if (at > 0) + { + args = executable.Substring(at + 1).Trim(); + executable = executable.Substring(0, at); + } + } + else + { + int at = executable.IndexOf(" "); + if (at > 0) + { + if (executable.Length > at + 1) + { + args = executable.Substring(at + 1).Trim(); + } + executable = executable.Substring(0, at); + } + } + + var processStartInfo = new ProcessStartInfo + { + UseShellExecute = false, + Verb = verb, + CreateNoWindow = true, + FileName = executable, + WorkingDirectory = workingFolder, + Arguments = args, + RedirectStandardOutput = true, + RedirectStandardError = true, + StandardOutputEncoding = Encoding.UTF8 + }; + + using (var process = Process.Start(processStartInfo)) + { + if (process != null) + { + while (!process.StandardOutput.EndOfStream) + { + string line = process.StandardOutput.ReadLine(); + Console.WriteLine(line); + } + + while (!process.StandardError.EndOfStream) + { + string line = process.StandardError.ReadLine(); + Console.WriteLine(line); + } + } + } + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/GroupPolicy/GroupPolicy.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/GroupPolicy/GroupPolicy.cs new file mode 100644 index 0000000..0397e6e --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/GroupPolicy/GroupPolicy.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using Microsoft.Win32; +using winPEAS.Helpers.Registry; +using winPEAS.Native.Enums; + +namespace winPEAS.Info.SystemInfo.GroupPolicy +{ + internal class GroupPolicy + { + public static IEnumerable GetLocalGroupPolicyInfos() + { + // reference - https://specopssoft.com/blog/things-work-group-policy-caching/ + + // local machine GPOs + var basePath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\DataStore\Machine\0"; + var machineIDs = RegistryHelper.GetRegSubkeys("HKLM", basePath) ?? new string[] { }; + + foreach (var id in machineIDs) + { + var settings = RegistryHelper.GetRegValues("HKLM", $"{basePath}\\{id}"); + + yield return new LocalGroupPolicyInfo( + settings["GPOName"], + "machine", + settings["DisplayName"], + settings["Link"], + settings["FileSysPath"], + (GPOOptions)settings["Options"], + (GPOLink)settings["GPOLink"], + settings["Extensions"] + ); + } + + // local user GPOs + var userGpOs = new Dictionary>(); + + var sids = Registry.Users.GetSubKeyNames(); + foreach (var sid in sids) + { + if (!sid.StartsWith("S-1-5") || sid.EndsWith("_Classes")) + { + continue; + } + + var extensions = RegistryHelper.GetRegSubkeys("HKU", $"{sid}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History"); + if ((extensions == null) || (extensions.Length == 0)) + { + continue; + } + + foreach (var extension in extensions) + { + var path = $"{sid}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History\\{extension}"; + var userIDs = RegistryHelper.GetRegSubkeys("HKU", path) ?? new string[] { }; + + foreach (var id in userIDs) + { + var settings = RegistryHelper.GetRegValues("HKU", $"{path}\\{id}"); + + if (userGpOs.ContainsKey($"{settings["GPOName"]}")) + { + continue; + } + + userGpOs.Add($"{settings["GPOName"]}", settings); + } + } + } + + foreach (var userGPO in userGpOs) + { + yield return new LocalGroupPolicyInfo( + userGPO.Value["GPOName"], + "user", + userGPO.Value["DisplayName"], + userGPO.Value["Link"], + userGPO.Value["FileSysPath"], + (GPOOptions)userGPO.Value["Options"], + (GPOLink)userGPO.Value["GPOLink"], + userGPO.Value["Extensions"] + ); + } + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/GroupPolicy/LocalGroupPolicyInfo.cs b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/GroupPolicy/LocalGroupPolicyInfo.cs new file mode 100644 index 0000000..207e4df --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Info/SystemInfo/GroupPolicy/LocalGroupPolicyInfo.cs @@ -0,0 +1,36 @@ +using winPEAS.Native.Enums; + +namespace winPEAS.Info.SystemInfo.GroupPolicy +{ + class LocalGroupPolicyInfo + { + public object GPOName { get; } + public object GPOType { get; } + public object DisplayName { get; } + public object Link { get; set; } + public object FileSysPath { get; } + public GPOOptions Options { get; } + public GPOLink GPOLink { get; } + public object Extensions { get; } + + public LocalGroupPolicyInfo( + object gpoName, + object gpoType, + object displayName, + object link, + object fileSysPath, + GPOOptions options, + GPOLink gpoLink, + object extensions) + { + GPOName = gpoName; + GPOType = gpoType; + DisplayName = displayName; + Link = link; + FileSysPath = fileSysPath; + Options = options; + GPOLink = gpoLink; + Extensions = extensions; + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Info/UserInfo/User.cs b/winPEAS/winPEASexe/winPEAS/Info/UserInfo/User.cs index 7803dcb..0bfc743 100644 --- a/winPEAS/winPEASexe/winPEAS/Info/UserInfo/User.cs +++ b/winPEAS/winPEASexe/winPEAS/Info/UserInfo/User.cs @@ -1,11 +1,15 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.DirectoryServices.AccountManagement; using System.IO; using System.Management; +using System.Runtime.InteropServices; using System.Security.Principal; using winPEAS.Helpers; using winPEAS.KnownFileCreds; +using winPEAS.Native; +using winPEAS.Native.Structs; namespace winPEAS.Info.UserInfo { @@ -228,5 +232,42 @@ namespace winPEAS.Info.UserInfo return result; } + + public static IEnumerable GetLocalUsers(string computerName) + { + uint MAX_PREFERRED_LENGTH = unchecked((uint)-1); + + // Returns local users + // FILTER_NORMAL_ACCOUNT == 2 + var users = new List(); + var retVal = Netapi32.NetUserEnum(computerName, 3, 2, out var bufPtr, MAX_PREFERRED_LENGTH, out var entriesRead, out var totalEntries, out var resume); + + if (retVal != 0) + { + var errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; + throw new Exception("Error code " + retVal + ": " + errorMessage); + } + + if (entriesRead == 0) + { + return users; + } + + var names = new string[entriesRead]; + var userInfo = new USER_INFO_3[entriesRead]; + var iter = bufPtr; + + for (var i = 0; i < entriesRead; i++) + { + userInfo[i] = (USER_INFO_3)Marshal.PtrToStructure(iter, typeof(USER_INFO_3)); + users.Add(userInfo[i]); + + //x64 safe + iter = new IntPtr(iter.ToInt64() + Marshal.SizeOf(typeof(USER_INFO_3))); + } + Netapi32.NetApiBufferFree(bufPtr); + + return users; + } } } diff --git a/winPEAS/winPEASexe/winPEAS/Native/Enums/GPOLink.cs b/winPEAS/winPEASexe/winPEAS/Native/Enums/GPOLink.cs new file mode 100644 index 0000000..40a0fdf --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Native/Enums/GPOLink.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace winPEAS.Native.Enums +{ + enum GPOLink + { + [Description("No Link Information")] + NO_LINK_INFORMATION = 0, + + [Description("Local Machine")] + LOCAL_MACHINE = 1, + + [Description("Site")] + SITE = 2, + + [Description("Domain")] + DOMAIN = 3, + + [Description("Organizational Unit")] + ORGANIZATIONAL_UNIT = 4 + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Native/Enums/GPOOptions.cs b/winPEAS/winPEASexe/winPEAS/Native/Enums/GPOOptions.cs new file mode 100644 index 0000000..1772093 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Native/Enums/GPOOptions.cs @@ -0,0 +1,19 @@ +using System.ComponentModel; + +namespace winPEAS.Native.Enums +{ + enum GPOOptions + { + [Description("All Sections Enabled")] + ALL_SECTIONS_ENABLED = 0, + + [Description("User Section Disbled")] + USER_SECTION_DISABLED = 1, + + [Description("Computer Section Disable")] + COMPUTER_SECTION_DISABLE = 2, + + [Description("All Sections Disabled")] + ALL_SECTIONS_DISABLED = 3 + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Native/Enums/UserPrivType.cs b/winPEAS/winPEASexe/winPEAS/Native/Enums/UserPrivType.cs new file mode 100644 index 0000000..1deca03 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Native/Enums/UserPrivType.cs @@ -0,0 +1,9 @@ +namespace winPEAS.Native.Enums +{ + public enum UserPrivType + { + Guest = 0, + User = 1, + Administrator = 2 + } +} diff --git a/winPEAS/winPEASexe/winPEAS/Native/Netapi32.cs b/winPEAS/winPEASexe/winPEAS/Native/Netapi32.cs index ad2431f..57224db 100644 --- a/winPEAS/winPEASexe/winPEAS/Native/Netapi32.cs +++ b/winPEAS/winPEASexe/winPEAS/Native/Netapi32.cs @@ -31,5 +31,16 @@ namespace winPEAS.Native [DllImport("Netapi32", SetLastError = true), SuppressUnmanagedCodeSecurity] internal static extern int NetApiBufferFree(IntPtr pBuf); - } + + [DllImport("Netapi32.dll")] + internal static extern uint NetUserEnum( + [MarshalAs(UnmanagedType.LPWStr)] string serverName, + uint level, + uint filter, + out IntPtr bufPtr, + uint preferredMaxLength, + out uint entriesRead, + out uint totalEntries, + out IntPtr resumeHandle); + } } diff --git a/winPEAS/winPEASexe/winPEAS/Native/Structs/USER_INFO_3.cs b/winPEAS/winPEASexe/winPEAS/Native/Structs/USER_INFO_3.cs new file mode 100644 index 0000000..907e31a --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/Native/Structs/USER_INFO_3.cs @@ -0,0 +1,39 @@ +using System; +using System.Runtime.InteropServices; + +namespace winPEAS.Native.Structs +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct USER_INFO_3 + { + [MarshalAs(UnmanagedType.LPWStr)] public string name; + [MarshalAs(UnmanagedType.LPWStr)] public string password; + public uint passwordAge; + public uint priv; + [MarshalAs(UnmanagedType.LPWStr)] public string home_dir; + [MarshalAs(UnmanagedType.LPWStr)] public string comment; + public uint flags; + [MarshalAs(UnmanagedType.LPWStr)] public string script_path; + public uint auth_flags; + [MarshalAs(UnmanagedType.LPWStr)] public string full_name; + [MarshalAs(UnmanagedType.LPWStr)] public string usr_comment; + [MarshalAs(UnmanagedType.LPWStr)] public string parms; + [MarshalAs(UnmanagedType.LPWStr)] public string workstations; + public uint last_logon; + public uint last_logoff; + public uint acct_expires; + public uint max_storage; + public uint units_per_week; + public IntPtr logon_hours; + public uint bad_pw_count; + public uint num_logons; + [MarshalAs(UnmanagedType.LPWStr)] public string logon_server; + public uint country_code; + public uint code_page; + public uint user_id; + public uint primary_group_id; + [MarshalAs(UnmanagedType.LPWStr)] public string profile; + [MarshalAs(UnmanagedType.LPWStr)] public string home_dir_drive; + public uint password_expired; + } +} diff --git a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj index c4e50fa..1eb61c0 100755 --- a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj +++ b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj @@ -417,6 +417,7 @@ + @@ -441,6 +442,8 @@ + + @@ -512,6 +515,8 @@ + + @@ -521,6 +526,7 @@ + @@ -537,6 +543,7 @@ +