2025-05-13 19:49:49 +03:00

300 lines
7.9 KiB
C

/*
* Process Hacker Extra Plugins -
* LSA Security Explorer Plugin
*
* Copyright (C) 2013 wj32
* Copyright (C) 2015-2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "explorer.h"
_Callback_ NTSTATUS SxpOpenLsaPolicy(
_Out_ PHANDLE Handle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ PVOID Context
)
{
return PhOpenLsaPolicy(Handle, DesiredAccess, NULL);
}
_Callback_ NTSTATUS SxpOpenSelectedLsaAccount(
_Out_ PHANDLE Handle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ PVOID Context
)
{
NTSTATUS status;
LSA_HANDLE policyHandle;
if (NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_LOOKUP_NAMES, NULL)))
{
status = LsaOpenAccount(policyHandle, SelectedAccount, DesiredAccess, Handle);
LsaClose(policyHandle);
}
return status;
}
_Callback_ NTSTATUS SxpOpenSelectedSamAccount(
_Out_ PHANDLE Handle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ PVOID Context
)
{
NTSTATUS status;
LSA_HANDLE policyHandle = NULL;
SAM_HANDLE serverHandle = NULL;
SAM_HANDLE domainHandle = NULL;
PPOLICY_ACCOUNT_DOMAIN_INFO policyDomainInfo = NULL;
__try
{
if (!NT_SUCCESS(status = PhOpenLsaPolicy(
&policyHandle,
POLICY_VIEW_LOCAL_INFORMATION,
NULL
)))
{
__leave;
}
if (!NT_SUCCESS(status = LsaQueryInformationPolicy(
policyHandle,
PolicyAccountDomainInformation,
&policyDomainInfo
)))
{
__leave;
}
if (!NT_SUCCESS(status = SamConnect(
NULL,
&serverHandle,
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
NULL
)))
{
__leave;
}
if (!NT_SUCCESS(status = SamOpenDomain(
serverHandle,
DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
policyDomainInfo->DomainSid,
&domainHandle
)))
{
__leave;
}
if (!NT_SUCCESS(status = SamOpenUser(
domainHandle,
DesiredAccess,
PtrToUlong(Context),
Handle
)))
{
__leave;
}
}
__finally
{
if (domainHandle)
{
SamFreeMemory(domainHandle);
}
if (serverHandle)
{
SamFreeMemory(serverHandle);
}
if (policyDomainInfo)
{
LsaFreeMemory(policyDomainInfo);
}
if (policyHandle)
{
LsaClose(policyHandle);
}
}
return status;
}
_Callback_ NTSTATUS SxStdGetObjectSecurity(
_Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_opt_ PVOID Context
)
{
NTSTATUS status;
PPH_STD_OBJECT_SECURITY stdObjectSecurity;
HANDLE handle;
stdObjectSecurity = (PPH_STD_OBJECT_SECURITY)Context;
if (
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaAccount", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaPolicy", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaSecret", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaTrusted", TRUE)
)
{
PSECURITY_DESCRIPTOR securityDescriptor;
status = stdObjectSecurity->OpenObject(
&handle,
PhGetAccessForGetSecurity(SecurityInformation),
stdObjectSecurity->Context
);
if (!NT_SUCCESS(status))
return status;
status = LsaQuerySecurityObject(
handle,
SecurityInformation,
&securityDescriptor
);
if (NT_SUCCESS(status))
{
*SecurityDescriptor = PhAllocateCopy(
securityDescriptor,
RtlLengthSecurityDescriptor(securityDescriptor)
);
LsaFreeMemory(securityDescriptor);
}
LsaClose(handle);
}
else if (
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamAlias", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamDomain", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamGroup", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamServer", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamUser", TRUE)
)
{
PSECURITY_DESCRIPTOR securityDescriptor;
status = stdObjectSecurity->OpenObject(
&handle,
PhGetAccessForGetSecurity(SecurityInformation),
stdObjectSecurity->Context
);
if (!NT_SUCCESS(status))
return status;
status = SamQuerySecurityObject(
handle,
SecurityInformation,
&securityDescriptor
);
if (NT_SUCCESS(status))
{
*SecurityDescriptor = PhAllocateCopy(
securityDescriptor,
RtlLengthSecurityDescriptor(securityDescriptor)
);
SamFreeMemory(securityDescriptor);
}
SamCloseHandle(handle);
}
else
{
status = PhStdGetObjectSecurity(SecurityDescriptor, SecurityInformation, Context);
}
return status;
}
_Callback_ NTSTATUS SxStdSetObjectSecurity(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_opt_ PVOID Context
)
{
NTSTATUS status;
PPH_STD_OBJECT_SECURITY stdObjectSecurity;
HANDLE handle;
stdObjectSecurity = (PPH_STD_OBJECT_SECURITY)Context;
if (
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaAccount", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaPolicy", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaSecret", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaTrusted", TRUE)
)
{
status = stdObjectSecurity->OpenObject(
&handle,
PhGetAccessForSetSecurity(SecurityInformation),
stdObjectSecurity->Context
);
if (!NT_SUCCESS(status))
return status;
status = LsaSetSecurityObject(
handle,
SecurityInformation,
SecurityDescriptor
);
LsaClose(handle);
}
else if (
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamAlias", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamDomain", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamGroup", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamServer", TRUE) ||
PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamUser", TRUE)
)
{
status = stdObjectSecurity->OpenObject(
&handle,
PhGetAccessForSetSecurity(SecurityInformation),
stdObjectSecurity->Context
);
if (!NT_SUCCESS(status))
return status;
status = SamSetSecurityObject(
handle,
SecurityInformation,
SecurityDescriptor
);
SamCloseHandle(handle);
}
else
{
status = PhStdSetObjectSecurity(SecurityDescriptor, SecurityInformation, Context);
}
return status;
}