mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
Move SID-getting code into a separate function so it can be shared by
make_private_security_descriptor and a new function protectprocess().
protectprocess() opens the running PuTTY process and adjusts the
Everyone and user access control entries in its ACL to deny a
selection of permissions which malicious processes running as the same
user could use to hijack PuTTY.
(cherry picked from commit aba7234bc1
)
This commit is contained in:
parent
906f8ed262
commit
e80b1b8a34
@ -12,6 +12,10 @@
|
||||
#define WINSECUR_GLOBAL
|
||||
#include "winsecur.h"
|
||||
|
||||
/* Initialised once, then kept around to reuse forever */
|
||||
static PSID worldsid, networksid, usersid;
|
||||
|
||||
|
||||
int got_advapi(void)
|
||||
{
|
||||
static int attempted = FALSE;
|
||||
@ -99,6 +103,52 @@ PSID get_user_sid(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getsids(char *error)
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
|
||||
SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
|
||||
int ret;
|
||||
|
||||
error=NULL;
|
||||
|
||||
if (!usersid) {
|
||||
if ((usersid = get_user_sid()) == NULL) {
|
||||
error = dupprintf("unable to construct SID for current user: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!worldsid) {
|
||||
if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
|
||||
0, 0, 0, 0, 0, 0, 0, &worldsid)) {
|
||||
error = dupprintf("unable to construct SID for world: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!networksid) {
|
||||
if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
|
||||
0, 0, 0, 0, 0, 0, 0, &networksid)) {
|
||||
error = dupprintf("unable to construct SID for "
|
||||
"local same-user access only: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret=TRUE;
|
||||
|
||||
cleanup:
|
||||
if (ret) {
|
||||
sfree(error);
|
||||
error = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int make_private_security_descriptor(DWORD permissions,
|
||||
PSECURITY_DESCRIPTOR *psd,
|
||||
PACL *acl,
|
||||
@ -110,44 +160,13 @@ int make_private_security_descriptor(DWORD permissions,
|
||||
int acl_err;
|
||||
int ret = FALSE;
|
||||
|
||||
/* Initialised once, then kept around to reuse forever */
|
||||
static PSID worldsid, networksid, usersid;
|
||||
|
||||
*psd = NULL;
|
||||
*acl = NULL;
|
||||
*error = NULL;
|
||||
|
||||
if (!got_advapi()) {
|
||||
*error = dupprintf("unable to load advapi32.dll");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!usersid) {
|
||||
if ((usersid = get_user_sid()) == NULL) {
|
||||
*error = dupprintf("unable to construct SID for current user: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!worldsid) {
|
||||
if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
|
||||
0, 0, 0, 0, 0, 0, 0, &worldsid)) {
|
||||
*error = dupprintf("unable to construct SID for world: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!networksid) {
|
||||
if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
|
||||
0, 0, 0, 0, 0, 0, 0, &networksid)) {
|
||||
*error = dupprintf("unable to construct SID for "
|
||||
"local same-user access only: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (!getsids(*error))
|
||||
goto cleanup;
|
||||
|
||||
memset(ea, 0, sizeof(ea));
|
||||
ea[0].grfAccessPermissions = permissions;
|
||||
@ -218,4 +237,74 @@ int make_private_security_descriptor(DWORD permissions,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int protectprocess(char *error)
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
|
||||
SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
|
||||
EXPLICIT_ACCESS ea[2];
|
||||
int acl_err;
|
||||
int ret=FALSE;
|
||||
PACL acl = NULL;
|
||||
|
||||
static const nastyace=WRITE_DAC | WRITE_OWNER |
|
||||
PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
||||
PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION |
|
||||
PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
|
||||
PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE |
|
||||
PROCESS_SUSPEND_RESUME;
|
||||
|
||||
if (!getsids(error))
|
||||
goto cleanup;
|
||||
|
||||
memset(ea, 0, sizeof(ea));
|
||||
|
||||
/* Everyone: deny */
|
||||
ea[0].grfAccessPermissions = nastyace;
|
||||
ea[0].grfAccessMode = DENY_ACCESS;
|
||||
ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||||
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
|
||||
|
||||
/* User: user ace */
|
||||
ea[1].grfAccessPermissions = ~nastyace & 0x1fff;
|
||||
ea[1].grfAccessMode = GRANT_ACCESS;
|
||||
ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||||
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea[1].Trustee.ptstrName = (LPTSTR)usersid;
|
||||
|
||||
acl_err = p_SetEntriesInAclA(2, ea, NULL, &acl);
|
||||
|
||||
if (acl_err != ERROR_SUCCESS || acl == NULL) {
|
||||
error = dupprintf("unable to construct ACL: %s",
|
||||
win_strerror(acl_err));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS !=
|
||||
SetSecurityInfo(
|
||||
GetCurrentProcess(),
|
||||
SE_KERNEL_OBJECT,
|
||||
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||
usersid,
|
||||
NULL,
|
||||
acl,
|
||||
NULL
|
||||
)) {
|
||||
error=dupprintf("Unable to set process ACL: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
ret=TRUE;
|
||||
|
||||
cleanup:
|
||||
if (!ret) {
|
||||
if (acl) {
|
||||
LocalFree(acl);
|
||||
acl = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !defined NO_SECURITY */
|
||||
|
Loading…
Reference in New Issue
Block a user