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:
wj32
2015-05-25 00:19:02 +00:00
parent a5d6afb98e
commit 3ec0df169c
12 changed files with 277 additions and 9 deletions
+1 -1
View File
@@ -286,7 +286,7 @@ BOOLEAN PhpShowErrorAndConnectToPhSvc(
* attempt failed.
*/
BOOLEAN PhUiConnectToPhSvc(
_In_ HWND hWnd,
_In_opt_ HWND hWnd,
_In_ BOOLEAN ConnectOnly
)
{
+1 -1
View File
@@ -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,
+4 -2
View File
@@ -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
);
+12
View File
@@ -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;
};
};
+10
View File
@@ -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
+71
View File
@@ -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;
}
+117 -1
View File
@@ -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;
}
+16 -1
View File
@@ -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
+31 -1
View File
@@ -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
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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,