mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
Elevate service permissions changes if possible
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5945 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -286,7 +286,7 @@ BOOLEAN PhpShowErrorAndConnectToPhSvc(
|
||||
* attempt failed.
|
||||
*/
|
||||
BOOLEAN PhUiConnectToPhSvc(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ BOOLEAN ConnectOnly
|
||||
)
|
||||
{
|
||||
|
||||
@@ -1205,7 +1205,7 @@ VOID PhWritePhTextHeader(
|
||||
}
|
||||
|
||||
BOOLEAN PhShellProcessHacker(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ PWSTR Parameters,
|
||||
_In_ ULONG ShowWindowType,
|
||||
_In_ ULONG Flags,
|
||||
|
||||
@@ -351,7 +351,7 @@ VOID PhWritePhTextHeader(
|
||||
|
||||
PHAPPAPI
|
||||
BOOLEAN PhShellProcessHacker(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ PWSTR Parameters,
|
||||
_In_ ULONG ShowWindowType,
|
||||
_In_ ULONG Flags,
|
||||
@@ -1113,11 +1113,13 @@ typedef enum _PH_ACTION_ELEVATION_LEVEL
|
||||
AlwaysElevateAction = 2
|
||||
} PH_ACTION_ELEVATION_LEVEL;
|
||||
|
||||
PHAPPAPI
|
||||
BOOLEAN PhUiConnectToPhSvc(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ BOOLEAN ConnectOnly
|
||||
);
|
||||
|
||||
PHAPPAPI
|
||||
VOID PhUiDisconnectFromPhSvc(
|
||||
VOID
|
||||
);
|
||||
|
||||
@@ -116,6 +116,13 @@ NTSTATUS PhSvcCaptureSid(
|
||||
_Out_ PSID *CapturedSid
|
||||
);
|
||||
|
||||
NTSTATUS PhSvcCaptureSecurityDescriptor(
|
||||
_In_ PPH_RELATIVE_STRINGREF String,
|
||||
_In_ BOOLEAN AllowNull,
|
||||
_In_ SECURITY_INFORMATION RequiredInformation,
|
||||
_Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
|
||||
);
|
||||
|
||||
NTSTATUS PhSvcApiDefault(
|
||||
_In_ PPHSVC_CLIENT Client,
|
||||
_Inout_ PPHSVC_API_MSG Message
|
||||
@@ -196,4 +203,9 @@ NTSTATUS PhSvcApiCreateProcessIgnoreIfeoDebugger(
|
||||
_Inout_ PPHSVC_API_MSG Message
|
||||
);
|
||||
|
||||
NTSTATUS PhSvcApiSetServiceSecurity(
|
||||
_In_ PPHSVC_CLIENT Client,
|
||||
_Inout_ PPHSVC_API_MSG Message
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@ typedef enum _PHSVC_API_NUMBER
|
||||
PhSvcPostMessageApiNumber = 14,
|
||||
PhSvcSendMessageApiNumber = 15,
|
||||
PhSvcCreateProcessIgnoreIfeoDebuggerApiNumber = 16,
|
||||
PhSvcSetServiceSecurityApiNumber = 17,
|
||||
PhSvcMaximumApiNumber
|
||||
} PHSVC_API_NUMBER, *PPHSVC_API_NUMBER;
|
||||
|
||||
@@ -214,6 +215,16 @@ typedef union _PHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER
|
||||
} i;
|
||||
} PHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER, *PPHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER;
|
||||
|
||||
typedef union _PHSVC_API_SETSERVICESECURITY
|
||||
{
|
||||
struct
|
||||
{
|
||||
PH_RELATIVE_STRINGREF ServiceName;
|
||||
SECURITY_INFORMATION SecurityInformation;
|
||||
PH_RELATIVE_STRINGREF SecurityDescriptor;
|
||||
} i;
|
||||
} PHSVC_API_SETSERVICESECURITY, *PPHSVC_API_SETSERVICESECURITY;
|
||||
|
||||
typedef struct _PHSVC_API_MSG
|
||||
{
|
||||
PORT_MESSAGE h;
|
||||
@@ -240,6 +251,7 @@ typedef struct _PHSVC_API_MSG
|
||||
PHSVC_API_ISSUEMEMORYLISTCOMMAND IssueMemoryListCommand;
|
||||
PHSVC_API_POSTMESSAGE PostMessage;
|
||||
PHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER CreateProcessIgnoreIfeoDebugger;
|
||||
PHSVC_API_SETSERVICESECURITY SetServiceSecurity;
|
||||
} u;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -46,6 +46,7 @@ NTSTATUS PhSvcCallCreateService(
|
||||
_In_opt_ PWSTR Password
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
NTSTATUS PhSvcCallChangeServiceConfig(
|
||||
_In_ PWSTR ServiceName,
|
||||
_In_ ULONG ServiceType,
|
||||
@@ -60,6 +61,7 @@ NTSTATUS PhSvcCallChangeServiceConfig(
|
||||
_In_opt_ PWSTR DisplayName
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
NTSTATUS PhSvcCallChangeServiceConfig2(
|
||||
_In_ PWSTR ServiceName,
|
||||
_In_ ULONG InfoLevel,
|
||||
@@ -89,6 +91,7 @@ NTSTATUS PhSvcCallIssueMemoryListCommand(
|
||||
_In_ SYSTEM_MEMORY_LIST_COMMAND Command
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
NTSTATUS PhSvcCallPostMessage(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ UINT Msg,
|
||||
@@ -96,6 +99,7 @@ NTSTATUS PhSvcCallPostMessage(
|
||||
_In_ LPARAM lParam
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
NTSTATUS PhSvcCallSendMessage(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ UINT Msg,
|
||||
@@ -107,4 +111,10 @@ NTSTATUS PhSvcCallCreateProcessIgnoreIfeoDebugger(
|
||||
_In_ PWSTR FileName
|
||||
);
|
||||
|
||||
NTSTATUS PhSvcCallSetServiceSecurity(
|
||||
_In_ PWSTR ServiceName,
|
||||
_In_ SECURITY_INFORMATION SecurityInformation,
|
||||
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -806,3 +806,74 @@ NTSTATUS PhSvcCallCreateProcessIgnoreIfeoDebugger(
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
PSECURITY_DESCRIPTOR PhpAbsoluteToSelfRelativeSD(
|
||||
_In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
|
||||
_Out_ PULONG BufferSize
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG bufferSize = 0;
|
||||
PSECURITY_DESCRIPTOR selfRelativeSecurityDescriptor;
|
||||
|
||||
status = RtlAbsoluteToSelfRelativeSD(AbsoluteSecurityDescriptor, NULL, &bufferSize);
|
||||
|
||||
if (status != STATUS_BUFFER_TOO_SMALL)
|
||||
return NULL;
|
||||
|
||||
selfRelativeSecurityDescriptor = PhAllocate(bufferSize);
|
||||
status = RtlAbsoluteToSelfRelativeSD(AbsoluteSecurityDescriptor, selfRelativeSecurityDescriptor, &bufferSize);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
PhFree(selfRelativeSecurityDescriptor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*BufferSize = bufferSize;
|
||||
|
||||
return selfRelativeSecurityDescriptor;
|
||||
}
|
||||
|
||||
NTSTATUS PhSvcCallSetServiceSecurity(
|
||||
_In_ PWSTR ServiceName,
|
||||
_In_ SECURITY_INFORMATION SecurityInformation,
|
||||
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PHSVC_API_MSG m;
|
||||
PSECURITY_DESCRIPTOR selfRelativeSecurityDescriptor = NULL;
|
||||
ULONG bufferSize;
|
||||
PVOID serviceName = NULL;
|
||||
PVOID copiedSelfRelativeSecurityDescriptor = NULL;
|
||||
|
||||
if (!PhSvcClPortHandle)
|
||||
return STATUS_PORT_DISCONNECTED;
|
||||
|
||||
selfRelativeSecurityDescriptor = PhpAbsoluteToSelfRelativeSD(SecurityDescriptor, &bufferSize);
|
||||
|
||||
if (!selfRelativeSecurityDescriptor)
|
||||
{
|
||||
status = STATUS_BAD_DESCRIPTOR_FORMAT;
|
||||
goto CleanupExit;
|
||||
}
|
||||
|
||||
m.ApiNumber = PhSvcSetServiceSecurityApiNumber;
|
||||
m.u.SetServiceSecurity.i.SecurityInformation = SecurityInformation;
|
||||
status = STATUS_NO_MEMORY;
|
||||
|
||||
if (!(serviceName = PhSvcpCreateString(ServiceName, -1, &m.u.SetServiceSecurity.i.ServiceName)))
|
||||
goto CleanupExit;
|
||||
if (!(copiedSelfRelativeSecurityDescriptor = PhSvcpCreateString(selfRelativeSecurityDescriptor, bufferSize, &m.u.SetServiceSecurity.i.SecurityDescriptor)))
|
||||
goto CleanupExit;
|
||||
|
||||
status = PhSvcpCallServer(&m);
|
||||
|
||||
CleanupExit:
|
||||
if (selfRelativeSecurityDescriptor) PhFree(selfRelativeSecurityDescriptor);
|
||||
if (serviceName) PhSvcpFreeHeap(serviceName);
|
||||
if (copiedSelfRelativeSecurityDescriptor) PhSvcpFreeHeap(copiedSelfRelativeSecurityDescriptor);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <phapp.h>
|
||||
#include <phsvc.h>
|
||||
#include <accctrl.h>
|
||||
|
||||
typedef struct _PHSVCP_CAPTURED_RUNAS_SERVICE_PARAMETERS
|
||||
{
|
||||
@@ -51,7 +52,8 @@ PPHSVC_API_PROCEDURE PhSvcApiCallTable[] =
|
||||
PhSvcApiIssueMemoryListCommand,
|
||||
PhSvcApiPostMessage,
|
||||
PhSvcApiSendMessage,
|
||||
PhSvcApiCreateProcessIgnoreIfeoDebugger
|
||||
PhSvcApiCreateProcessIgnoreIfeoDebugger,
|
||||
PhSvcApiSetServiceSecurity
|
||||
};
|
||||
C_ASSERT(sizeof(PhSvcApiCallTable) / sizeof(PPHSVC_API_PROCEDURE) == PhSvcMaximumApiNumber - 1);
|
||||
|
||||
@@ -214,6 +216,59 @@ NTSTATUS PhSvcCaptureSid(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS PhSvcCaptureSecurityDescriptor(
|
||||
_In_ PPH_RELATIVE_STRINGREF String,
|
||||
_In_ BOOLEAN AllowNull,
|
||||
_In_ SECURITY_INFORMATION RequiredInformation,
|
||||
_Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PSECURITY_DESCRIPTOR securityDescriptor;
|
||||
ULONG bufferSize;
|
||||
|
||||
if (!NT_SUCCESS(status = PhSvcCaptureBuffer(String, AllowNull, &securityDescriptor)))
|
||||
return status;
|
||||
|
||||
if (securityDescriptor)
|
||||
{
|
||||
if (!RtlValidRelativeSecurityDescriptor(securityDescriptor, String->Length, RequiredInformation))
|
||||
{
|
||||
PhFree(securityDescriptor);
|
||||
return STATUS_INVALID_SECURITY_DESCR;
|
||||
}
|
||||
|
||||
bufferSize = String->Length;
|
||||
status = RtlSelfRelativeToAbsoluteSD2(securityDescriptor, &bufferSize);
|
||||
|
||||
if (status == STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
PVOID newBuffer;
|
||||
|
||||
newBuffer = PhAllocate(bufferSize);
|
||||
memcpy(newBuffer, securityDescriptor, String->Length);
|
||||
PhFree(securityDescriptor);
|
||||
securityDescriptor = newBuffer;
|
||||
|
||||
status = RtlSelfRelativeToAbsoluteSD2(securityDescriptor, &bufferSize);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
PhFree(securityDescriptor);
|
||||
return status;
|
||||
}
|
||||
|
||||
*CapturedSecurityDescriptor = securityDescriptor;
|
||||
}
|
||||
else
|
||||
{
|
||||
*CapturedSecurityDescriptor = NULL;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS PhSvcApiDefault(
|
||||
_In_ PPHSVC_CLIENT Client,
|
||||
_Inout_ PPHSVC_API_MSG Message
|
||||
@@ -946,3 +1001,64 @@ NTSTATUS PhSvcApiCreateProcessIgnoreIfeoDebugger(
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS PhSvcApiSetServiceSecurity(
|
||||
_In_ PPHSVC_CLIENT Client,
|
||||
_Inout_ PPHSVC_API_MSG Message
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PPH_STRING serviceName;
|
||||
PSECURITY_DESCRIPTOR securityDescriptor;
|
||||
ACCESS_MASK desiredAccess;
|
||||
SC_HANDLE serviceHandle;
|
||||
|
||||
if (NT_SUCCESS(status = PhSvcCaptureString(&Message->u.SetServiceSecurity.i.ServiceName, FALSE, &serviceName)))
|
||||
{
|
||||
if (NT_SUCCESS(status = PhSvcCaptureSecurityDescriptor(&Message->u.SetServiceSecurity.i.SecurityDescriptor, FALSE, 0, &securityDescriptor)))
|
||||
{
|
||||
desiredAccess = 0;
|
||||
|
||||
if ((Message->u.SetServiceSecurity.i.SecurityInformation & OWNER_SECURITY_INFORMATION) ||
|
||||
(Message->u.SetServiceSecurity.i.SecurityInformation & GROUP_SECURITY_INFORMATION))
|
||||
{
|
||||
desiredAccess |= WRITE_OWNER;
|
||||
}
|
||||
|
||||
if (Message->u.SetServiceSecurity.i.SecurityInformation & DACL_SECURITY_INFORMATION)
|
||||
{
|
||||
desiredAccess |= WRITE_DAC;
|
||||
}
|
||||
|
||||
if (Message->u.SetServiceSecurity.i.SecurityInformation & SACL_SECURITY_INFORMATION)
|
||||
{
|
||||
desiredAccess |= ACCESS_SYSTEM_SECURITY;
|
||||
}
|
||||
|
||||
if (serviceHandle = PhOpenService(serviceName->Buffer, desiredAccess))
|
||||
{
|
||||
if (!PhSetSeObjectSecurity(
|
||||
serviceHandle,
|
||||
SE_SERVICE,
|
||||
Message->u.SetServiceSecurity.i.SecurityInformation,
|
||||
securityDescriptor
|
||||
))
|
||||
{
|
||||
status = PhGetLastWin32ErrorAsNtStatus();
|
||||
}
|
||||
|
||||
CloseServiceHandle(serviceHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = PhGetLastWin32ErrorAsNtStatus();
|
||||
}
|
||||
|
||||
PhFree(securityDescriptor);
|
||||
}
|
||||
|
||||
PhDereferenceObject(serviceName);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ PhWritePhTextHeader(
|
||||
|
||||
PHAPPAPI
|
||||
BOOLEAN PhShellProcessHacker(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ PWSTR Parameters,
|
||||
_In_ ULONG ShowWindowType,
|
||||
_In_ ULONG Flags,
|
||||
@@ -997,6 +997,21 @@ PhFormatLogEntry(
|
||||
|
||||
// actions
|
||||
|
||||
PHAPPAPI
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
PhUiConnectToPhSvc(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ BOOLEAN ConnectOnly
|
||||
);
|
||||
|
||||
PHAPPAPI
|
||||
VOID
|
||||
NTAPI
|
||||
PhUiDisconnectFromPhSvc(
|
||||
VOID
|
||||
);
|
||||
|
||||
PHAPPAPI
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
|
||||
@@ -60,6 +60,36 @@ static NTSTATUS PhpOpenService(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static _Callback_ NTSTATUS PhpSetServiceSecurity(
|
||||
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
_In_ SECURITY_INFORMATION SecurityInformation,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PPH_STD_OBJECT_SECURITY stdObjectSecurity;
|
||||
|
||||
stdObjectSecurity = (PPH_STD_OBJECT_SECURITY)Context;
|
||||
|
||||
status = PhStdSetObjectSecurity(SecurityDescriptor, SecurityInformation, Context);
|
||||
|
||||
if ((status == STATUS_ACCESS_DENIED || status == NTSTATUS_FROM_WIN32(ERROR_ACCESS_DENIED)) && !PhElevated)
|
||||
{
|
||||
// Elevate using phsvc.
|
||||
if (PhUiConnectToPhSvc(NULL, FALSE))
|
||||
{
|
||||
status = PhSvcCallSetServiceSecurity(
|
||||
((PPH_SERVICE_ITEM)stdObjectSecurity->Context)->Name->Buffer,
|
||||
SecurityInformation,
|
||||
SecurityDescriptor
|
||||
);
|
||||
PhUiDisconnectFromPhSvc();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
VOID PhShowServiceProperties(
|
||||
_In_ HWND ParentWindowHandle,
|
||||
_In_ PPH_SERVICE_ITEM ServiceItem
|
||||
@@ -108,7 +138,7 @@ VOID PhShowServiceProperties(
|
||||
pages[propSheetHeader.nPages++] = PhCreateSecurityPage(
|
||||
ServiceItem->Name->Buffer,
|
||||
PhStdGetObjectSecurity,
|
||||
PhStdSetObjectSecurity,
|
||||
PhpSetServiceSecurity,
|
||||
&stdObjectSecurity,
|
||||
accessEntries,
|
||||
numberOfAccessEntries
|
||||
|
||||
@@ -2579,7 +2579,7 @@ VOID PhShellExecute(
|
||||
|
||||
PHLIBAPI
|
||||
BOOLEAN PhShellExecuteEx(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ PWSTR FileName,
|
||||
_In_opt_ PWSTR Parameters,
|
||||
_In_ ULONG ShowWindowType,
|
||||
|
||||
@@ -3232,7 +3232,7 @@ VOID PhShellExecute(
|
||||
* \param ProcessHandle A variable which receives a handle to the new process.
|
||||
*/
|
||||
BOOLEAN PhShellExecuteEx(
|
||||
_In_ HWND hWnd,
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_ PWSTR FileName,
|
||||
_In_opt_ PWSTR Parameters,
|
||||
_In_ ULONG ShowWindowType,
|
||||
|
||||
Reference in New Issue
Block a user