summaryrefslogtreecommitdiff
path: root/psutil/arch/windows
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2019-02-25 02:35:07 -0800
committerGitHub <noreply@github.com>2019-02-25 02:35:07 -0800
commitf326539daa5bbd9153db79b508b6aaede731a154 (patch)
tree1b2b4c473155dae88dd8014259f802957509fad1 /psutil/arch/windows
parent7a2572268168e96c8841ca83ab1a89735ec02c3a (diff)
downloadpsutil-f326539daa5bbd9153db79b508b6aaede731a154.tar.gz
Process SE DEBUG mode was not set on Windows (#1429)
Diffstat (limited to 'psutil/arch/windows')
-rw-r--r--psutil/arch/windows/security.c253
-rw-r--r--psutil/arch/windows/security.h4
2 files changed, 85 insertions, 172 deletions
diff --git a/psutil/arch/windows/security.c b/psutil/arch/windows/security.c
index d5f8f8d3..4e2c7435 100644
--- a/psutil/arch/windows/security.c
+++ b/psutil/arch/windows/security.c
@@ -4,134 +4,44 @@
* found in the LICENSE file.
*
* Security related functions for Windows platform (Set privileges such as
- * SeDebug), as well as security helper functions.
+ * SE DEBUG).
*/
#include <windows.h>
#include <Python.h>
+#include "../../_psutil_common.h"
-/*
- * Convert a process handle to a process token handle.
- */
-HANDLE
-psutil_token_from_handle(HANDLE hProcess) {
- HANDLE hToken = NULL;
-
- if (! OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
- return PyErr_SetFromWindowsErr(0);
- return hToken;
-}
-
-
-/*
- * http://www.ddj.com/windows/184405986
- *
- * There's a way to determine whether we're running under the Local System
- * account. However (you guessed it), we have to call more Win32 functions to
- * determine this. Backing up through the code listing, we need to make another
- * call to GetTokenInformation, but instead of passing through the TOKEN_USER
- * constant, we pass through the TOKEN_PRIVILEGES constant. This value returns
- * an array of privileges that the account has in the environment. Iterating
- * through the array, we call the function LookupPrivilegeName looking for the
- * string “SeTcbPrivilege. If the function returns this string, then this
- * account has Local System privileges
- */
-int
-psutil_has_system_privilege(HANDLE hProcess) {
- DWORD i;
- DWORD dwSize = 0;
- DWORD dwRetval = 0;
- TCHAR privName[256];
- DWORD dwNameSize = 256;
- // PTOKEN_PRIVILEGES tp = NULL;
- BYTE *pBuffer = NULL;
- TOKEN_PRIVILEGES *tp = NULL;
- HANDLE hToken = psutil_token_from_handle(hProcess);
-
- if (NULL == hToken)
- return -1;
- // call GetTokenInformation first to get the buffer size
- if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) {
- dwRetval = GetLastError();
- // if it failed for a reason other than the buffer, bail out
- if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) {
- PyErr_SetFromWindowsErr(dwRetval);
- return 0;
- }
- }
-
- // allocate buffer and call GetTokenInformation again
- // tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize);
- pBuffer = (BYTE *) malloc(dwSize);
- if (pBuffer == NULL) {
- PyErr_NoMemory();
- return -1;
- }
-
- if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer,
- dwSize, &dwSize))
- {
- PyErr_SetFromWindowsErr(0);
- free(pBuffer);
- return -1;
- }
-
- // convert the BYTE buffer to a TOKEN_PRIVILEGES struct pointer
- tp = (TOKEN_PRIVILEGES *)pBuffer;
-
- // check all the privileges looking for SeTcbPrivilege
- for (i = 0; i < tp->PrivilegeCount; i++) {
- // reset the buffer contents and the buffer size
- strcpy(privName, "");
- dwNameSize = sizeof(privName) / sizeof(TCHAR);
- if (! LookupPrivilegeName(NULL,
- &tp->Privileges[i].Luid,
- (LPTSTR)privName,
- &dwNameSize))
- {
- PyErr_SetFromWindowsErr(0);
- free(pBuffer);
- return -1;
- }
-
- // if we find the SeTcbPrivilege then it's a LocalSystem process
- if (! lstrcmpi(privName, TEXT("SeTcbPrivilege"))) {
- free(pBuffer);
- return 1;
- }
- }
-
- free(pBuffer);
- return 0;
-}
-
-
-BOOL
+static BOOL
psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
- if (!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
+ if (! LookupPrivilegeValue(NULL, Privilege, &luid)) {
+ PyErr_SetFromOSErrnoWithSyscall("LookupPrivilegeValue");
+ return 1;
+ }
// first pass. get current privilege setting
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
- AdjustTokenPrivileges(
- hToken,
- FALSE,
- &tp,
- sizeof(TOKEN_PRIVILEGES),
- &tpPrevious,
- &cbPrevious
- );
-
- if (GetLastError() != ERROR_SUCCESS) return FALSE;
- // second pass. set privilege based on previous setting
+ if (! AdjustTokenPrivileges(
+ hToken,
+ FALSE,
+ &tp,
+ sizeof(TOKEN_PRIVILEGES),
+ &tpPrevious,
+ &cbPrevious))
+ {
+ PyErr_SetFromOSErrnoWithSyscall("AdjustTokenPrivileges");
+ return 1;
+ }
+
+ // Second pass. Set privilege based on previous setting.
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
@@ -141,81 +51,88 @@ psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes ^=
(SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
- AdjustTokenPrivileges(
- hToken,
- FALSE,
- &tpPrevious,
- cbPrevious,
- NULL,
- NULL
- );
-
- if (GetLastError() != ERROR_SUCCESS) return FALSE;
+ if (! AdjustTokenPrivileges(
+ hToken,
+ FALSE,
+ &tpPrevious,
+ cbPrevious,
+ NULL,
+ NULL))
+ {
+ PyErr_SetFromOSErrnoWithSyscall("AdjustTokenPrivileges");
+ return 1;
+ }
- return TRUE;
+ return 0;
}
-int
-psutil_set_se_debug() {
- HANDLE hToken;
- if (!OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken)
- ) {
- if (GetLastError() == ERROR_NO_TOKEN) {
- if (!ImpersonateSelf(SecurityImpersonation)) {
- CloseHandle(hToken);
- return 0;
+static HANDLE
+psutil_get_thisproc_token() {
+ HANDLE hToken = NULL;
+ HANDLE me = GetCurrentProcess();
+
+ if (! OpenProcessToken(
+ me, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ {
+ if (GetLastError() == ERROR_NO_TOKEN)
+ {
+ if (! ImpersonateSelf(SecurityImpersonation)) {
+ PyErr_SetFromOSErrnoWithSyscall("ImpersonateSelf");
+ return NULL;
}
- if (!OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken)
- ) {
- RevertToSelf();
- CloseHandle(hToken);
- return 0;
+ if (! OpenProcessToken(
+ me, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ {
+ PyErr_SetFromOSErrnoWithSyscall("OpenProcessToken");
+ return NULL;
}
}
+ else {
+ PyErr_SetFromOSErrnoWithSyscall("OpenProcessToken");
+ return NULL;
+ }
}
- // enable SeDebugPrivilege (open any process)
- if (! psutil_set_privilege(hToken, SE_DEBUG_NAME, TRUE)) {
- RevertToSelf();
- CloseHandle(hToken);
- return 0;
- }
+ return hToken;
+}
- RevertToSelf();
- CloseHandle(hToken);
- return 1;
+
+static void
+psutil_print_err() {
+ char *msg = "psutil module couldn't set SE DEBUG mode for this process; " \
+ "please file an issue against psutil bug tracker";
+ psutil_debug(msg);
+ if (GetLastError() != ERROR_ACCESS_DENIED)
+ PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1);
+ PyErr_Clear();
}
+/*
+ * Set this process in SE DEBUG mode so that we have more chances of
+ * querying processes owned by other users, including many owned by
+ * Administrator and Local System.
+ * https://docs.microsoft.com/windows-hardware/drivers/debugger/debug-privilege
+ * This is executed on module import and we don't crash on error.
+ */
int
-psutil_unset_se_debug() {
+psutil_set_se_debug() {
HANDLE hToken;
- if (!OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken)
- ) {
- if (GetLastError() == ERROR_NO_TOKEN) {
- if (! ImpersonateSelf(SecurityImpersonation))
- return 0;
- if (!OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken))
- {
- return 0;
- }
- }
- }
+ int err = 1;
- // now disable SeDebug
- if (! psutil_set_privilege(hToken, SE_DEBUG_NAME, FALSE))
+ if ((hToken = psutil_get_thisproc_token()) == NULL) {
+ // "return 1;" to get an exception
+ psutil_print_err();
return 0;
+ }
+
+ if (psutil_set_privilege(hToken, SE_DEBUG_NAME, TRUE) != 0) {
+ // "return 1;" to get an exception
+ psutil_print_err();
+ }
+ RevertToSelf();
CloseHandle(hToken);
- return 1;
+ return 0;
}
-
diff --git a/psutil/arch/windows/security.h b/psutil/arch/windows/security.h
index aa8a22ad..8d4ddb00 100644
--- a/psutil/arch/windows/security.h
+++ b/psutil/arch/windows/security.h
@@ -9,9 +9,5 @@
#include <windows.h>
-BOOL psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege);
-HANDLE psutil_token_from_handle(HANDLE hProcess);
-int psutil_has_system_privilege(HANDLE hProcess);
int psutil_set_se_debug();
-int psutil_unset_se_debug();