mirror of
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite.git
synced 2025-12-15 04:49:01 +00:00
237 lines
11 KiB
C#
237 lines
11 KiB
C#
using Microsoft.Win32;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Management;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Principal;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using winPEAS.Helpers;
|
|
|
|
namespace winPEAS.Info.ProcessInfo
|
|
{
|
|
internal class ProcessesInfo
|
|
{
|
|
// TODO: check out https://github.com/harleyQu1nn/AggressorScripts/blob/master/ProcessColor.cna#L10
|
|
public static List<Dictionary<string, string>> GetProcInfo()
|
|
{
|
|
List<Dictionary<string, string>> f_results = new List<Dictionary<string, string>>();
|
|
try
|
|
{
|
|
var wmiQueRyStr = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
|
|
using (var srcher = new ManagementObjectSearcher(wmiQueRyStr))
|
|
using (var reslts = srcher.Get())
|
|
{
|
|
var queRy = from p in Process.GetProcesses()
|
|
join mo in reslts.Cast<ManagementObject>()
|
|
on p.Id equals (int)(uint)mo["ProcessId"]
|
|
select new
|
|
{
|
|
Proc = p,
|
|
Pth = (string)mo["ExecutablePath"],
|
|
CommLine = (string)mo["CommandLine"],
|
|
Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
|
};
|
|
|
|
foreach (var itm in queRy)
|
|
{
|
|
if (itm.Pth != null)
|
|
{
|
|
string companyName = "";
|
|
string isDotNet = "";
|
|
try
|
|
{
|
|
FileVersionInfo myFileVerInfo = FileVersionInfo.GetVersionInfo(itm.Pth);
|
|
//compName = myFileVerInfo.CompanyName;
|
|
isDotNet = MyUtils.CheckIfDotNet(itm.Pth) ? "isDotNet" : "";
|
|
}
|
|
catch
|
|
{
|
|
// Not enough privileges
|
|
}
|
|
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
|
{
|
|
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
|
to_add["Name"] = itm.Proc.ProcessName;
|
|
to_add["ProcessID"] = itm.Proc.Id.ToString();
|
|
to_add["ExecutablePath"] = itm.Pth;
|
|
to_add["Product"] = companyName;
|
|
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner;
|
|
to_add["isDotNet"] = isDotNet;
|
|
to_add["CommandLine"] = itm.CommLine;
|
|
f_results.Add(to_add);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Beaprint.PrintException(ex.Message);
|
|
}
|
|
return f_results;
|
|
}
|
|
|
|
public static List<Dictionary<string, string>> GetVulnHandlers()
|
|
{
|
|
List<Dictionary<string, string>> vulnHandlers = new List<Dictionary<string, string>>();
|
|
List<HandlesHelper.SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> handlers = HandlesHelper.GetAllHandlers();
|
|
List<string> interestingHandlerTypes = new List<string>() { "file", "key", "process", "thread" }; //section
|
|
|
|
foreach (HandlesHelper.SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX h in handlers)
|
|
{
|
|
// skip some objects to avoid getting stuck
|
|
// see: https://github.com/adamdriscoll/PoshInternals/issues/7
|
|
if (h.GrantedAccess == 0x0012019f
|
|
|| h.GrantedAccess == 0x00120189
|
|
|| h.GrantedAccess == 0x120089
|
|
|| h.GrantedAccess == 0x1A019F)
|
|
continue;
|
|
|
|
IntPtr dupHandle;
|
|
IntPtr _processHandle = Native.Kernel32.OpenProcess(HandlesHelper.ProcessAccessFlags.DupHandle | HandlesHelper.ProcessAccessFlags.QueryInformation, false, h.UniqueProcessId);
|
|
|
|
if (_processHandle == (IntPtr)0)
|
|
continue;
|
|
|
|
uint status = (uint)Native.Ntdll.NtDuplicateObject(
|
|
_processHandle,
|
|
h.HandleValue,
|
|
Native.Kernel32.GetCurrentProcess(),
|
|
out dupHandle,
|
|
0,
|
|
false,
|
|
HandlesHelper.DUPLICATE_SAME_ACCESS);
|
|
|
|
Native.Kernel32.CloseHandle(_processHandle);
|
|
|
|
if (status != 0)
|
|
continue;
|
|
|
|
string typeName = HandlesHelper.GetObjectType(dupHandle).ToLower();
|
|
if (interestingHandlerTypes.Contains(typeName))
|
|
{
|
|
HandlesHelper.VULNERABLE_HANDLER_INFO handlerExp = HandlesHelper.checkExploitaible(h, typeName);
|
|
if (handlerExp.isVuln == true)
|
|
{
|
|
HandlesHelper.PT_RELEVANT_INFO origProcInfo = HandlesHelper.getProcInfoById((int)h.UniqueProcessId);
|
|
if (!Checks.Checks.CurrentUserSiDs.ContainsKey(origProcInfo.userSid))
|
|
continue;
|
|
|
|
string hName = HandlesHelper.GetObjectName(dupHandle);
|
|
|
|
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
|
to_add["Handle Name"] = hName;
|
|
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")";
|
|
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName;
|
|
to_add["Reason"] = handlerExp.reason;
|
|
|
|
if (typeName == "process" || typeName == "thread")
|
|
{
|
|
HandlesHelper.PT_RELEVANT_INFO hInfo;
|
|
if (typeName == "process")
|
|
{
|
|
hInfo = HandlesHelper.getProcessHandlerInfo(dupHandle);
|
|
}
|
|
|
|
else //Thread
|
|
{
|
|
hInfo = HandlesHelper.getThreadHandlerInfo(dupHandle);
|
|
}
|
|
|
|
// If the privileged access is from a proc to itself, or to a process of the same user, not a privesc
|
|
if (hInfo.pid == 0 ||
|
|
(int)h.UniqueProcessId == hInfo.pid ||
|
|
origProcInfo.userSid == hInfo.userSid)
|
|
continue;
|
|
|
|
to_add["Handle PID"] = hInfo.pid.ToString() + "(" + hInfo.userName + ")";
|
|
}
|
|
|
|
else if (typeName == "file")
|
|
{
|
|
//StringBuilder filePath = new StringBuilder(2000);
|
|
//HandlersHelper.GetFinalPathNameByHandle(dupHandle, filePath, 2000, 0);
|
|
|
|
HandlesHelper.FILE_NAME_INFO fni = new HandlesHelper.FILE_NAME_INFO();
|
|
|
|
// Sometimes both GetFileInformationByHandle and GetFileInformationByHandleEx hangs
|
|
// So a timeput of 1s is put to the function to prevent that
|
|
var task = Task.Run(() =>
|
|
{
|
|
// FILE_NAME_INFO (2)
|
|
return Native.Kernel32.GetFileInformationByHandleEx(dupHandle, 2, out fni, (uint)Marshal.SizeOf(fni));
|
|
});
|
|
|
|
bool isCompletedSuccessfully = task.Wait(TimeSpan.FromMilliseconds(1000));
|
|
|
|
if (!isCompletedSuccessfully)
|
|
{
|
|
//throw new TimeoutException("The function has taken longer than the maximum time allowed.");
|
|
continue;
|
|
}
|
|
|
|
string sFilePath = fni.FileName;
|
|
if (sFilePath.Length == 0)
|
|
continue;
|
|
|
|
List<string> permsFile = PermissionsHelper.GetPermissionsFile(sFilePath, Checks.Checks.CurrentUserSiDs, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
|
try
|
|
{
|
|
System.Security.AccessControl.FileSecurity fs = System.IO.File.GetAccessControl(sFilePath);
|
|
IdentityReference sid = fs.GetOwner(typeof(SecurityIdentifier));
|
|
string ownerName = sid.Translate(typeof(NTAccount)).ToString();
|
|
|
|
// If current user already have permissions over that file or the proc belongs to the owner of the file,
|
|
// handler not interesting to elevate privs
|
|
if (permsFile.Count > 0 || origProcInfo.userSid == sid.Value)
|
|
continue;
|
|
|
|
to_add["File Path"] = sFilePath;
|
|
to_add["File Owner"] = ownerName;
|
|
}
|
|
catch (System.IO.FileNotFoundException)
|
|
{
|
|
// File wasn't found
|
|
continue;
|
|
}
|
|
catch (System.InvalidOperationException)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
}
|
|
|
|
else if (typeName == "key")
|
|
{
|
|
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
|
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0)
|
|
continue;
|
|
|
|
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
|
if (regKey == null)
|
|
continue;
|
|
|
|
List<string> permsReg = PermissionsHelper.GetMyPermissionsR(regKey, Checks.Checks.CurrentUserSiDs);
|
|
|
|
// If current user already have permissions over that reg, handle not interesting to elevate privs
|
|
if (permsReg.Count > 0)
|
|
continue;
|
|
|
|
to_add["Registry"] = kri.hive + "\\" + kri.path;
|
|
}
|
|
|
|
|
|
vulnHandlers.Add(to_add);
|
|
}
|
|
}
|
|
}
|
|
|
|
return vulnHandlers;
|
|
}
|
|
}
|
|
}
|