Files
privilege-escalation-awesom…/winPEAS/winPEASexe/winPEAS/Info/ProcessInfo/ProcessesInfo.cs
carlospolop bbc22b3a91 update
2022-07-30 12:06:10 +02:00

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