mirror of
https://github.com/cyberark/PipeViewer
synced 2026-06-06 15:34:28 +00:00
193 lines
9.8 KiB
C#
193 lines
9.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
using NtApiDotNet;
|
|
namespace PipeViewer.Control
|
|
{
|
|
static class Engine
|
|
{
|
|
public enum NamedPipeFunctionEndType
|
|
{
|
|
Server,
|
|
Client
|
|
}
|
|
|
|
public static NtNamedPipeFileBase GetNamedPipeObject(string i_NamedPipe, NamedPipeFunctionEndType e_EndType)
|
|
{
|
|
NtNamedPipeFileBase namedPipeFileObject = null;
|
|
|
|
i_NamedPipe = i_NamedPipe.Replace(@"\\.\pipe\", @"\Device\NamedPipe\");
|
|
FileShareMode ShareMode = FileShareMode.Read | FileShareMode.Write;
|
|
FileOpenOptions Options = FileOpenOptions.SynchronousIoNonAlert;
|
|
FileAccessRights Access = FileAccessRights.GenericRead | FileAccessRights.GenericWrite | FileAccessRights.Synchronize;
|
|
|
|
if (e_EndType == NamedPipeFunctionEndType.Client)
|
|
{
|
|
namedPipeFileObject = GetNamedPipeClientObject(i_NamedPipe, ShareMode, Options, Access);
|
|
} else {
|
|
namedPipeFileObject = GetNamedPipeServerObject(i_NamedPipe, ShareMode, Options, Access);
|
|
}
|
|
|
|
return namedPipeFileObject;
|
|
}
|
|
|
|
// https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/c02ed8ba04324e54a0a188ab9877ee6aa372dfac/NtObjectManager/Cmdlets/Object/GetNtNamedPipeFileCmdlet.cs
|
|
public static NtNamedPipeFileBase GetNamedPipeClientObject(string i_NamedPipe, FileShareMode i_ShareMode, FileOpenOptions i_Options, FileAccessRights i_Access)
|
|
{
|
|
NtNamedPipeFileBase namedPipeFileObject = null;
|
|
|
|
//i_NamedPipe = @"\Device\NamedPipe\Winsock2\CatalogChangeListener-5c0-0";
|
|
//i_NamedPipe = @"\Device\NamedPipe\WiFiNetworkManagerTask";
|
|
//i_NamedPipe = @"\Device\NamedPipe\initShutdown";
|
|
|
|
using (ObjectAttributes obj_attributes = new ObjectAttributes(i_NamedPipe))
|
|
{
|
|
try
|
|
{
|
|
// https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/issues/65
|
|
// https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/c02ed8ba04324e54a0a188ab9877ee6aa372dfac/NtObjectManager/Cmdlets/Object/GetNtNamedPipeFileCmdlet.cs
|
|
// https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/c02ed8ba04324e54a0a188ab9877ee6aa372dfac/NtObjectManager/Cmdlets/Object/GetNtFileCmdlet.cs
|
|
namedPipeFileObject = (NtNamedPipeFileBase)NtFile.Open(obj_attributes, i_Access, i_ShareMode, i_Options);
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// In the future we can write to log
|
|
}
|
|
|
|
};
|
|
|
|
return namedPipeFileObject;
|
|
}
|
|
|
|
public static NtNamedPipeFileBase GetNamedPipeServerObject(string i_NamedPipe, FileShareMode i_ShareMode, FileOpenOptions i_Options, FileAccessRights i_Access)
|
|
{
|
|
NtNamedPipeFileBase namedPipeFileObject = null;
|
|
|
|
using (ObjectAttributes obj_attributes = new ObjectAttributes(i_NamedPipe))
|
|
{
|
|
try
|
|
{
|
|
namedPipeFileObject = NtFile.CreateNamedPipe(obj_attributes, i_Access, i_ShareMode, i_Options, FileDisposition.Open, NamedPipeType.Bytestream,
|
|
NamedPipeReadMode.ByteStream, NamedPipeCompletionMode.CompleteOperation, 0, 0, 0, NtWaitTimeout.FromMilliseconds(0));
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// In the future we can write to log
|
|
}
|
|
};
|
|
|
|
return namedPipeFileObject;
|
|
}
|
|
|
|
|
|
/*
|
|
* These permissions are based on tests we did on files
|
|
* https://learn.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights
|
|
* https://blog.cjwdev.co.uk/2011/06/28/permissions-not-included-in-net-accessrule-filesystemrights-enum/
|
|
* https://www.installsetupconfig.com/win32programming/accesscontrollistacl2_1.html
|
|
* https://superuser.com/questions/1752766/what-are-the-access-rules-of-standard-access-rights-and-object-specific-acces
|
|
*
|
|
Read: 00000000 00010010 00000000 10001001 : 00120089
|
|
Read & Execute: 00000000 00010010 00000000 10101001 : 001200A9
|
|
Write: 00000000 00010000 00000001 00010110 : 00100116
|
|
Read & Write 00000000 00010010 00000001 10011111 : 0012019F
|
|
Read & Write & Execute 00000000 00010010 00000001 10111111 : 001201BF
|
|
Modify 00000000 00010011 00000001 10111111 : 001301BF
|
|
Full 00000000 00011111 00000001 11111111 : 001F01FF
|
|
|
|
Read ("Traverse folder / execute", "List folder / Read data",
|
|
"Read Attribute", "Read Extended Attributes", "Read permissions")
|
|
|
|
All advanced permissions separated:
|
|
List folder / Read data 00000000 00010000 00000000 00000001 : 00100001 -> R (accesschk.exe)
|
|
Read Attribute 00000000 00010000 00000000 10000000 : 00100080 -> no R (accesschk.exe)
|
|
Read Extended Attributes 00000000 00010000 00000000 00001000 : 00100008 -> no R (accesschk.exe)
|
|
Read permissions 00000000 00010010 00000000 00000000 : 00120000 -> no R (accesschk.exe)
|
|
Traverse folder / execute 00000000 00010000 00000000 00100000 : 00100020 -> R (accesschk.exe)
|
|
Create files / write data 00000000 00010000 00000000 00000010 : 00100002 -> W (accesschk.exe)
|
|
Create folders / append data 00000000 00010000 00000000 00000100 : 00100004 -> W (accesschk.exe)
|
|
Write attributes 00000000 00010000 00000001 00000000 : 00100100 -> no W (accesschk.exe)
|
|
Write Extended eattributes 00000000 00010000 00000000 00010000 : 00100010 -> no W (accesschk.exe)
|
|
Delete 00000000 00010001 00000000 00000000 : 00110000 -> W (accesschk.exe)
|
|
Change permissions 00000000 00010100 00000000 00000000 : 00140000 -> RW (accesschk.exe)
|
|
Change ownership 00000000 00011000 00000000 00000000 : 00180000 -> RW (accesschk.exe)
|
|
|
|
|
|
R ("List folder / Read data", "Traverse folder / execute") -> 00000000 00010000 00000000 00100001 : 0x100021 (bits 0, 5, and 20)
|
|
W ("Create files / write data", "Create folders / append data", "Delete") -> 00000000 00010001 00000000 00000110 : 0x110006 (bits 1, 2, 16, and 20)
|
|
RW ("Change permissions", "Change ownership") -> 00000000 00011100 00000000 00000000 : 0x1c0000 (bits 18, 19, and 20)
|
|
|
|
* */
|
|
enum PermissionsAccessMask
|
|
{
|
|
Read = 0x00120089,
|
|
ReadAndExecute = 0x001200A9,
|
|
Write = 0x00100116,
|
|
ReadWrite = 0x0012019F,
|
|
ReadWriteExecute = 0x001201BF,
|
|
Modify = 0x001301BF,
|
|
Full = 0x001F01FF,
|
|
ListFolderReadData = 0x00100001,
|
|
ReadAttribute = 0x00100080,
|
|
ReadExtendedAttributes = 0x00100008,
|
|
ReadPermissions = 0x00120000,
|
|
TraverseFolderExecute = 0x00100020,
|
|
CreateFilesWriteData = 0x00100002,
|
|
CreateFoldersAppendData = 0x00100004,
|
|
WriteAttributes = 0x00100100,
|
|
WriteExtendedAttributes = 0x00100010,
|
|
Delete = 0x00110000,
|
|
ChangePermissions = 0x00140000,
|
|
ChangeOwnership = 0x00180000
|
|
}
|
|
|
|
|
|
public static string ConvertAccessMaskToSimplePermissions(uint i_AccessMask)
|
|
{
|
|
// Eviatar: Should we consider bit number 20 ? On files it always set to 1 but on named pipe it's not.
|
|
// We currently left it 0.
|
|
string permissions = "";
|
|
|
|
//byte[] byteArray = BitConverter.GetBytes(i_AccessMask);
|
|
byte[] binaryArray = Convert.ToString(i_AccessMask, 2)
|
|
.PadLeft(32, '0')
|
|
.Select(c => byte.Parse(c.ToString()))
|
|
.Reverse()
|
|
.ToArray();
|
|
|
|
if ((binaryArray[0] == 1 || binaryArray[5] == 1))// && binaryArray[20] == 1)
|
|
{
|
|
permissions += "R";
|
|
}
|
|
|
|
if ((binaryArray[1] == 1 || binaryArray[2] == 1 || binaryArray[16] == 1))// && binaryArray[20] == 1)
|
|
{
|
|
permissions += "W";
|
|
}
|
|
|
|
if ((binaryArray[18] == 1 || binaryArray[19] == 1) )//&& binaryArray[20] == 1)
|
|
{
|
|
permissions = "RW";
|
|
}
|
|
|
|
//uint readPermissions = ((uint)PermissionsAccessMask.ListFolderReadData | (uint)PermissionsAccessMask.TraverseFolderExecute) & i_AccessMask;
|
|
|
|
return permissions;
|
|
}
|
|
|
|
//public static NtFile CreateNamedPipe(string name, NtObject root, FileAccessRights desired_access,
|
|
// FileShareMode share_access, FileOpenOptions open_options, FileDisposition disposition, NamedPipeType pipe_type,
|
|
// NamedPipeReadMode read_mode, NamedPipeCompletionMode completion_mode, int maximum_instances, int input_quota,
|
|
// int output_quota, NtWaitTimeout default_timeout)
|
|
//{
|
|
// using (ObjectAttributes obj_attributes = new ObjectAttributes(name, AttributeFlags.CaseInsensitive, root))
|
|
// {
|
|
// return NtFile.CreateNamedPipe(obj_attributes, desired_access, share_access, open_options, disposition, pipe_type,
|
|
// read_mode, completion_mode, maximum_instances, input_quota, output_quota, default_timeout);
|
|
// }
|
|
//}
|
|
|
|
}
|
|
}
|