1
mirror of https://github.com/carlospolop/PEASS-ng synced 2024-11-24 01:26:22 +01:00

Check service permissions

This commit is contained in:
carlospolop 2020-01-27 15:32:35 -05:00
parent 011836926c
commit 7f822eeab1
26 changed files with 237 additions and 53 deletions

0
linPEAS/linpeas.sh Executable file → Normal file
View File

View File

@ -106,9 +106,9 @@ namespace winPEAS
return results;
}
public static List<Dictionary<string, string>> GetAutoRuns()
public static List<Dictionary<string, string>> GetAutoRuns(List<string> NtAccountNames)
{
List<Dictionary<string, string>> reg_autorus = ServicesInfo.GetRegistryAutoRuns();
List<Dictionary<string, string>> reg_autorus = ServicesInfo.GetRegistryAutoRuns(NtAccountNames);
List<Dictionary<string, string>> file_autorus = GetAutoRunsFolder();
reg_autorus.AddRange(file_autorus);
return reg_autorus;

View File

@ -9,16 +9,16 @@ namespace winPEAS
{
class Beaprint
{
public static string GRAY = "\x1b[1;30m";
static string RED = "\x1b[31m";
public static string GRAY = "\x1b[1;90m";
static string RED = "\x1b[1;31m";
public static string LRED = "\x1b[1;31m";
static string GREEN = "\x1b[32m";
static string GREEN = "\x1b[1;32m";
static string LGREEN = "\x1b[1;32m";
public static string YELLOW = "\x1b[33m";
static string LYELLOW = "\x1b[1;33m";
static string BLUE = "\x1b[34m";
public static string LBLUE = "\x1b[1;34m";
static string MAGENTA = "\x1b[35m";
static string MAGENTA = "\x1b[1:35m";
static string LMAGENTA = "\x1b[1;35m";
static string CYAN = "\x1b[36m";
static string LCYAN = "\x1b[1;36m";
@ -182,7 +182,7 @@ namespace winPEAS
try
{
System.Console.WriteLine();
System.Console.WriteLine(YELLOW + " [+] " + LRED + toPrint + YELLOW + "(" + GRAY + attackid + YELLOW + ")" + NOCOLOR);
System.Console.WriteLine(YELLOW + " [+] " + GREEN + toPrint + YELLOW + "(" + GRAY + attackid + YELLOW + ")" + NOCOLOR);
}
catch (Exception ex)
{

View File

@ -433,24 +433,41 @@ namespace winPEAS
return results;
}
public static string permInt2Str(int current_perm)
public static string permInt2Str(int current_perm, bool only_write_or_equivalent=false)
{
Dictionary<string, int> interesting_perms = new Dictionary<string, int>()
{
{ "AllAccess", 0xf01ff},
{ "GenericAll", 0x10000000},
{ "FullControl", (int)FileSystemRights.FullControl },
{ "TakeOwnership", (int)FileSystemRights.TakeOwnership },
{ "GenericWrite", 0x40000000 },
{ "WriteData/CreateFiles", (int)FileSystemRights.WriteData },
{ "Modify", (int)FileSystemRights.Modify },
{ "Write", (int)FileSystemRights.Write },
{ "ChangePermissions", (int)FileSystemRights.ChangePermissions },
{ "Delete", (int)FileSystemRights.Delete },
{ "DeleteSubdirectoriesAndFiles", (int)FileSystemRights.DeleteSubdirectoriesAndFiles },
{ "AppendData/CreateDirectories", (int)FileSystemRights.AppendData },
{ "WriteAttributes", (int)FileSystemRights.WriteAttributes },
{ "WriteExtendedAttributes", (int)FileSystemRights.WriteExtendedAttributes },
};
if (only_write_or_equivalent)
{
{ "GenericAll", 268435456},
{ "FullControl", (int)FileSystemRights.FullControl },
{ "TakeOwnership", (int)FileSystemRights.TakeOwnership },
{ "GenericWrite", 1073741824 },
{ "WriteData/CreateFiles", (int)FileSystemRights.WriteData },
{ "Modify", (int)FileSystemRights.Modify },
{ "Write", (int)FileSystemRights.Write },
{ "ChangePermissions", (int)FileSystemRights.ChangePermissions },
{ "Delete", (int)FileSystemRights.Delete },
{ "DeleteSubdirectoriesAndFiles", (int)FileSystemRights.DeleteSubdirectoriesAndFiles },
{ "AppendData/CreateDirectories", (int)FileSystemRights.AppendData },
{ "WriteAttributes", (int)FileSystemRights.WriteAttributes },
{ "WriteExtendedAttributes", (int)FileSystemRights.WriteExtendedAttributes },
};
interesting_perms = new Dictionary<string, int>()
{
{ "AllAccess", 0xf01ff},
{ "GenericAll", 0x10000000},
{ "FullControl", (int)FileSystemRights.FullControl },
{ "TakeOwnership", (int)FileSystemRights.TakeOwnership },
{ "GenericWrite", 0x40000000 },
{ "WriteData/CreateFiles", (int)FileSystemRights.WriteData },
{ "Modify", (int)FileSystemRights.Modify },
{ "Write", (int)FileSystemRights.Write },
{ "ChangePermissions", (int)FileSystemRights.ChangePermissions },
};
}
try
{
@ -526,24 +543,42 @@ namespace winPEAS
public IntPtr dacl;
}
public static bool CheckWriteAccessReg(string root_name, string reg_path)
public static List<string> CheckAccessReg(RegistryKey key, List<string> NtAccountNames)
{
IntPtr key;
IntPtr root = HKEY_LOCAL_MACHINE;
if (root_name.Contains("HKCU") || root_name.Contains("CURRENT_USER"))
root = HKEY_CURRENT_USER;
else if (root_name.Contains("HKLM") || root_name.Contains("LOCAL_MACHINE"))
root = HKEY_LOCAL_MACHINE;
List<string> results = new List<string>();
if (RegOpenKeyEx(root, reg_path, 0, KEY_ALL_ACCESS, out key) != 0)
try
{
if (RegOpenKeyEx(root, reg_path, 0, KEY_WRITE, out key) != 0)
var security = key.GetAccessControl();
//Go through the rules returned from the DirectorySecurity
foreach (RegistryAccessRule rule in security.GetAccessRules(true, true, typeof(NTAccount)))
{
if (RegOpenKeyEx(root, reg_path, 0, KEY_SET_VALUE, out key) != 0)
return false;
int current_perm = (int)rule.RegistryRights;
string current_perm_str = permInt2Str(current_perm, true);
if (current_perm_str == "" || current_perm_str == "WriteExtendedAttributes")
continue;
//If we find one that matches the identity we are looking for
foreach (string name in NtAccountNames)
{
if (rule.IdentityReference.Value.ToLower().Contains(name.ToLower()))
{
string to_add = String.Format("{0} [{1}]", rule.IdentityReference.Value, current_perm_str);
if (!results.Contains(to_add))
{
results.Add(to_add);
break;
}
}
}
}
}
return true;
catch (Exception ex)
{
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
}
return results;
}

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Text.RegularExpressions;
using System.Security.Principal;
namespace winPEAS
{
@ -38,7 +39,7 @@ namespace winPEAS
// Create Dynamic blacklists
static string currentUserName = Environment.UserName;
public static List<string> interestingUsersGroups = new List<string> { "Everyone", "Users", "Todos", currentUserName }; //Authenticated Users (Authenticated left behin to avoid repetitions)
public static List<string> interestingUsersGroups = new List<string> { "Everyone", @"Builtin\Users", "Todos", currentUserName }; //Authenticated Users (Authenticated left behin to avoid repetitions)
public static string currentUserDomainName = Environment.UserDomainName;
public static string currentADDomainName = "";
public static bool partofdomain = false;
@ -93,7 +94,7 @@ namespace winPEAS
try
{
Beaprint.GrayPrint(" - Creating cctive users list...");
Beaprint.GrayPrint(" - Creating active users list...");
paint_activeUsers = String.Join("|", UserInfo.GetMachineUsers(true, false, false, false, false));
paint_activeUsers_no_Administrator = paint_activeUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
}
@ -707,6 +708,16 @@ namespace winPEAS
/////////////////////////////////////////////////
private static void PrintInfoServices()
{
Dictionary<string, string> mod_services = new Dictionary<string, string>();
try
{
mod_services = ServicesInfo.GetModifiableServices();
}
catch (Exception ex)
{
Beaprint.GrayPrint(String.Format("{0}", ex));
}
void PrintInterestingServices()
{
/* Colors Code
@ -721,13 +732,17 @@ namespace winPEAS
{
Beaprint.MainPrint("Interesting Services -non Microsoft-", "T1007");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can overwrite some service binary or perform a DLL hijacking, also cehck for unquoted paths");
List<Dictionary<string, string>> services_info = ServicesInfo.GetNonstandardServices();
if (services_info.Count < 1)
services_info = ServicesInfo.GetNonstandardServicesFromReg();
foreach (Dictionary<string, string> service_info in services_info)
{
List<string> file_rights = MyUtils.GetPermissionsFile(service_info["FilteredPath"], interestingUsersGroups);
List<string> dir_rights = new List<string>();
if (service_info["FilteredPath"] != null && service_info["FilteredPath"] != "")
dir_rights = MyUtils.GetPermissionsFolder(Path.GetDirectoryName(service_info["FilteredPath"]), interestingUsersGroups);
@ -749,6 +764,8 @@ namespace winPEAS
formString += " - {6}";
if (no_quotes_and_space)
formString += " - {7}";
if (mod_services.ContainsKey(service_info["Name"]))
formString += "\n YOU CAN MODIFY THIS SERVICE: "+ mod_services[service_info["Name"]];
if (file_rights.Count > 0)
formString += "\n File Permissions: {8}";
if (dir_rights.Count > 0)
@ -762,10 +779,13 @@ namespace winPEAS
{ "File Permissions:.*", Beaprint.ansi_color_bad },
{ "Possible DLL Hijacking.*", Beaprint.ansi_color_bad },
{ "No quotes and Space detected", Beaprint.ansi_color_bad },
{ "YOU CAN MODIFY THIS SERVICE:.*", Beaprint.ansi_color_bad },
{ service_info["PathName"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+"), (file_rights.Count > 0 || dir_rights.Count > 0 || no_quotes_and_space) ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
};
Beaprint.AnsiPrint(String.Format(formString, service_info["Name"], service_info["CompanyName"], service_info["DisplayName"], service_info["PathName"], service_info["StartMode"], service_info["State"], service_info["isDotNet"], "No quotes and Space detected", String.Join(", ", file_rights), dir_rights.Count > 0 ? Path.GetDirectoryName(service_info["FilteredPath"]) : "", String.Join(", ", dir_rights), service_info["Description"]), colorsS);
}
Beaprint.PrintLineSeparator();
}
}
@ -775,19 +795,51 @@ namespace winPEAS
}
}
void PrintModifiableServices()
{
try
{
Beaprint.MainPrint("Modifiable Services", "T1007");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can modify any service");
if (mod_services.Count > 0)
{
Beaprint.BadPrint(" LOOKS LIKE YOU CAN MODIFY SOME SERVICE/s:");
Dictionary<string, string> colorsMS = new Dictionary<string, string>()
{
{ ".*", Beaprint.ansi_color_bad },
};
Beaprint.DictPrint(mod_services, colorsMS, false, true);
}
else
Beaprint.GoodPrint(" You cannot modify any service");
}
catch (Exception ex)
{
Beaprint.GrayPrint(String.Format("{0}", ex));
}
}
void PrintWritableRegServices()
{
try
{
Beaprint.MainPrint("Looking if you can modify any service registry", "");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
List<string> overWriteServs = ServicesInfo.GetWriteServiceRegs();
if (overWriteServs.Count <= 0)
List<Dictionary<string, string>> regPerms = ServicesInfo.GetWriteServiceRegs(interestingUsersGroups);
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
{
{ @"\(.*\)", Beaprint.ansi_color_bad },
};
if (regPerms.Count <= 0)
Beaprint.GoodPrint(" [-] Looks like you cannot change the registry of any service...");
else
{
foreach (string writeServReg in overWriteServs)
Beaprint.BadPrint(" [!] Looks like you can change the binpath the service in " + writeServReg + " !!");
foreach (Dictionary<string,string> writeServReg in regPerms)
Beaprint.AnsiPrint(String.Format(" {0} ({1})", writeServReg["Path"], writeServReg["Permissions"]), colorsWR);
}
}
catch (Exception ex)
@ -819,7 +871,9 @@ namespace winPEAS
Beaprint.GreatPrint("Services Information");
PrintInterestingServices();
PrintModifiableServices();
PrintWritableRegServices();
PrintPathDLLHijacking();
}
@ -914,7 +968,7 @@ namespace winPEAS
{
Beaprint.MainPrint("Autorun Applications", "T1010");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#run-at-startup", "Check if you can modify other users AutoRuns binaries");
List<Dictionary<string, string>> apps = ApplicationInfo.GetAutoRuns();
List<Dictionary<string, string>> apps = ApplicationInfo.GetAutoRuns(interestingUsersGroups);
foreach (Dictionary<string, string> app in apps)
{
@ -923,10 +977,10 @@ namespace winPEAS
{ "FolderPerms:.*", Beaprint.ansi_color_bad },
{ "FilePerms:.*", Beaprint.ansi_color_bad },
{ "(Unquoted and Space detected)", Beaprint.ansi_color_bad },
{ ".*(RegPath is writable)", Beaprint.ansi_color_bad },
{ "RegPerms: .*", Beaprint.ansi_color_bad },
{ (app["Folder"].Length > 0) ? app["Folder"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+") : "ouigyevb2uivydi2u3id2ddf3", !String.IsNullOrEmpty(app["interestingFolderRights"]) ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
{ (app["File"].Length > 0) ? app["File"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+") : "adu8v298hfubibuidiy2422r", !String.IsNullOrEmpty(app["interestingFileRights"]) ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
{ (app["Reg"].Length > 0) ? app["Reg"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+") : "o8a7eduia37ibduaunbf7a4g7ukdhk4ua", (app["isWritableReg"].ToLower() == "true") ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
{ (app["Reg"].Length > 0) ? app["Reg"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+") : "o8a7eduia37ibduaunbf7a4g7ukdhk4ua", (app["RegPermissions"].Length > 0) ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
};
string line = "";
@ -951,8 +1005,8 @@ namespace winPEAS
if (!String.IsNullOrEmpty(app["Reg"]))
line += "\n RegPath: " + app["Reg"];
if (app["isWritableReg"].ToLower() == "true")
line += " (RegPath is writable)";
if (app["RegPermissions"].Length > 0)
line += "\n RegPerms: "+ app["RegPermissions"];
Beaprint.AnsiPrint(line, colorsA);
Beaprint.PrintLineSeparator();
@ -1941,8 +1995,6 @@ namespace winPEAS
[STAThread]
static void Main(string[] args)
{
//AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) => { if (arg.Name.StartsWith("Colorful.Console")) return Assembly.Load(Properties.Resources.String1); return null; };
//Check parameters
bool check_all = true;
bool check_si = false;

View File

@ -5,6 +5,11 @@ using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Text.RegularExpressions;
using System.ServiceProcess;
using System.Reflection;
using System.Security.AccessControl;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace winPEAS
{
@ -141,16 +146,23 @@ namespace winPEAS
return results;
}
public static List<string> GetWriteServiceRegs()
public static List<Dictionary<string, string>> GetWriteServiceRegs(List<string> NtAccountNames)
{
List<string> results = new List<string>();
List<Dictionary<string,string>> results = new List<Dictionary<string, string>>();
try
{
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
foreach (string serviceRegName in regKey.GetSubKeyNames())
{
if (MyUtils.CheckWriteAccessReg("HKLM", @"system\currentcontrolset\services\" + serviceRegName))
results.Add(@"HKLM\system\currentcontrolset\services\" + serviceRegName);
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services\" + serviceRegName);
List<string> perms = MyUtils.CheckAccessReg(key, NtAccountNames);
if (perms.Count > 0)
{
results.Add(new Dictionary<string, string> {
{ "Path", @"HKLM\system\currentcontrolset\services\" + serviceRegName },
{ "Permissions", string.Join(", ", perms) }
});
}
}
}
catch (Exception ex)
@ -160,7 +172,8 @@ namespace winPEAS
return results;
}
public static List<Dictionary<string, string>> GetRegistryAutoRuns()
public static List<Dictionary<string, string>> GetRegistryAutoRuns(List<string> NtAccountNames)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
try
@ -183,13 +196,15 @@ namespace winPEAS
{
foreach (KeyValuePair<string, object> kvp in settings)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(autorunLocation);
string filepath = Environment.ExpandEnvironmentVariables(String.Format("{0}", kvp.Value));
string folder = System.IO.Path.GetDirectoryName(filepath.Replace("'", "").Replace("\"", ""));
results.Add(new Dictionary<string, string>() {
{ "Reg", "HKLM\\"+autorunLocation },
{ "Folder", folder },
{ "File", filepath },
{ "isWritableReg", MyUtils.CheckWriteAccessReg("HKLM", autorunLocation).ToString()},
{ "RegPermissions", string.Join(", ", MyUtils.CheckAccessReg(key, NtAccountNames)) },
{ "interestingFolderRights", String.Join(", ", MyUtils.GetPermissionsFolder(folder, Program.interestingUsersGroups))},
{ "interestingFileRights", String.Join(", ", MyUtils.GetPermissionsFile(filepath, Program.interestingUsersGroups))},
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(filepath).ToString() }
@ -222,5 +237,86 @@ namespace winPEAS
}
return results;
}
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool QueryServiceObjectSecurity(
IntPtr serviceHandle,
System.Security.AccessControl.SecurityInfos secInfo,
byte[] lpSecDesrBuf,
uint bufSize,
out uint bufSizeNeeded);
public static Dictionary<string,string> GetModifiableServices()
{
Dictionary<string, string> results = new Dictionary<string, string>();
ServiceController[] scServices;
scServices = ServiceController.GetServices();
var GetServiceHandle = typeof(System.ServiceProcess.ServiceController).GetMethod("GetServiceHandle", BindingFlags.Instance | BindingFlags.NonPublic);
object[] readRights = { 0x00020000 };
foreach (ServiceController sc in scServices)
{
try
{
IntPtr handle = (IntPtr)GetServiceHandle.Invoke(sc, readRights);
ServiceControllerStatus status = sc.Status;
byte[] psd = new byte[0];
uint bufSizeNeeded;
bool ok = QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, 0, out bufSizeNeeded);
if (!ok)
{
int err = Marshal.GetLastWin32Error();
if (err == 122 || err == 0)
{ // ERROR_INSUFFICIENT_BUFFER
// expected; now we know bufsize
psd = new byte[bufSizeNeeded];
ok = QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, bufSizeNeeded, out bufSizeNeeded);
}
else
{
//throw new ApplicationException("error calling QueryServiceObjectSecurity() to get DACL for " + _name + ": error code=" + err);
continue;
}
}
if (!ok)
{
//throw new ApplicationException("error calling QueryServiceObjectSecurity(2) to get DACL for " + _name + ": error code=" + Marshal.GetLastWin32Error());
continue;
}
// get security descriptor via raw into DACL form so ACE ordering checks are done for us.
RawSecurityDescriptor rsd = new RawSecurityDescriptor(psd, 0);
RawAcl racl = rsd.DiscretionaryAcl;
DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, racl);
WindowsIdentity identity = WindowsIdentity.GetCurrent();
string permissions = "";
foreach (System.Security.AccessControl.CommonAce ace in dacl)
{
if (identity.Groups.Contains(ace.SecurityIdentifier))
{
int serviceRights = ace.AccessMask;
string current_perm_str = MyUtils.permInt2Str(serviceRights, true);
if (!String.IsNullOrEmpty(current_perm_str))
permissions += current_perm_str;
}
}
if (!String.IsNullOrEmpty(permissions))
results.Add(sc.ServiceName, permissions);
}
catch (Exception ex)
{
//Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
}
}
return results;
}
}
}

View File

@ -99,6 +99,7 @@
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />