我有一个进程(让我们称之为ProcessX),默认情况下只运行Terminate
,Synchronize
和Query Limited Information
权限。
当我在Process Hacker中查看ProcessX时,我可以看到权限(ACE, Owner等)。我可以看到我是ProcessX的所有者,我可以看到与它相关的3个有限权限(Terminate
,Synchronize
和Query Limited Information
),我甚至可以编辑权限(例如,设置Full Control
)。
但是,当我运行下面的代码来检查ProcessX的DACL时,拥有ProcessX的同一用户,我在GetSecurityInfo()
函数上得到错误代码5 (Access Denied)。
与ProcessX上的AccessChk和Process Explorer结果相同。
然而,Process Hacker完全能够读取ProcessX的DACL并修改它。
我不明白。这怎么可能呢?为什么我的代码无法读取ProcessX的DACL ?
我在MS文档中读到,要读取DACL,我必须使用OpenProcess()
和READ_CONTROL
。
但是READ_CONTROL
对我的用户来说不是进程上可用的ACE。所以,我不能用它打开进程(OpenProcess()
错误,如果我尝试,这是合乎逻辑的)。
所以,我是进程的所有者,但是我不能修改ACE,但是进程黑客可以。
有人能帮我理解吗?#include <windows.h>
#include <accctrl.h>
#include <aclapi.h>
#include <winnt.h>
#include <stdio.h>
#include <lmcons.h>
DWORD AddAceToObjectsSecurityDescriptor (
HANDLE pszObjName, // name of object
SE_OBJECT_TYPE ObjectType, // type of object
LPTSTR pszTrustee, // trustee for new ACE
TRUSTEE_FORM TrusteeForm, // format of trustee structure
DWORD dwAccessRights, // access mask for new ACE
ACCESS_MODE AccessMode, // type of ACE
DWORD dwInheritance // inheritance flags for new ACE
)
{
DWORD dwRes = 0;
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
if (NULL == pszObjName)
return ERROR_INVALID_PARAMETER;
//retrieve user
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
printf(username);
// Get a pointer to the existing DACL.
dwRes = GetSecurityInfo(pszObjName, ObjectType,
DACL_SECURITY_INFORMATION,
NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) {
printf( "GetSecurityInfo Error %un", dwRes );
goto Cleanup;
}
// Initialize an EXPLICIT_ACCESS structure for the new ACE.
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = AccessMode;
ea.grfInheritance= dwInheritance;
ea.Trustee.TrusteeForm = TrusteeForm;
ea.Trustee.ptstrName = pszTrustee;
// Create a new ACL that merges the new ACE
// into the existing DACL.
dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes) {
printf( "SetEntriesInAcl Error %un", dwRes );
goto Cleanup;
}
// Attach the new ACL as the object's DACL.
dwRes = SetSecurityInfo(pszObjName, ObjectType,
DACL_SECURITY_INFORMATION,
NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes) {
printf( "SetSecurityInfo Error %un", dwRes );
goto Cleanup;
}
Cleanup:
if(pSD != NULL)
LocalFree((HLOCAL) pSD);
if(pNewDACL != NULL)
LocalFree((HLOCAL) pNewDACL);
return dwRes;
}
int main(int argc, char *argv[])
{
int pid = atoi(argv[1]);
printf("[+] Ensuring we have the proper privs....n");
HANDLE self = OpenProcess(
PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE,
FALSE, (DWORD) pid);
if(self != NULL){
printf("process open !n");
AddAceToObjectsSecurityDescriptor(self, SE_KERNEL_OBJECT, (LPSTR)"S-1-5-21-BLABLALEAKBLALBLA",TRUSTEE_IS_SID, PROCESS_ALL_ACCESS, GRANT_ACCESS, 0);
}
else{
printf("error in opening of the processn");
}
}
我假设READ_CONTROL
将被拒绝,因为它在运行进程的DACL上不可用。
结果是,当你拥有一个对象时,你对它有隐式的READ_CONTROL
和WRITE_DAC
权限,即使拥有它的用户在对象上没有设置ACE。
#include <windows.h>
#include <accctrl.h>
#include <aclapi.h>
#include <winnt.h>
#include <stdio.h>
#include <lmcons.h>
DWORD AddAceToObjectsSecurityDescriptor (
HANDLE pszObjName, // name of object
SE_OBJECT_TYPE ObjectType, // type of object
LPTSTR pszTrustee, // trustee for new ACE
TRUSTEE_FORM TrusteeForm, // format of trustee structure
DWORD dwAccessRights, // access mask for new ACE
ACCESS_MODE AccessMode, // type of ACE
DWORD dwInheritance // inheritance flags for new ACE
)
{
DWORD dwRes = 0;
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
if (NULL == pszObjName)
return ERROR_INVALID_PARAMETER;
// Get a pointer to the existing DACL.
dwRes = GetSecurityInfo(pszObjName, ObjectType,
DACL_SECURITY_INFORMATION,
NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) {
printf( "GetSecurityInfo Error %un", dwRes );
goto Cleanup;
}
// Initialize an EXPLICIT_ACCESS structure for the new ACE.
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = AccessMode;
ea.grfInheritance= dwInheritance;
ea.Trustee.TrusteeForm = TrusteeForm;
ea.Trustee.ptstrName = pszTrustee;
// Create a new ACL that merges the new ACE
// into the existing DACL.
dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes) {
printf( "SetEntriesInAcl Error %un", dwRes );
goto Cleanup;
}else{
printf("SetEntriesAcl SUCCESS !n");
}
// Attach the new ACL as the object's DACL.
dwRes = SetSecurityInfo(pszObjName, ObjectType,
DACL_SECURITY_INFORMATION,
NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes) {
printf( "SetSecurityInfo Error %un", dwRes );
goto Cleanup;
}else{
printf("SetSecurityInfo SUCCESS n");
}
Cleanup:
if(pSD != NULL)
LocalFree((HLOCAL) pSD);
if(pNewDACL != NULL)
LocalFree((HLOCAL) pNewDACL);
return dwRes;
}
int main(int argc, char *argv[])
{
int pid = atoi(argv[1]);
DWORD dwRes = 0;
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
HANDLE self = OpenProcess(READ_CONTROL | WRITE_DAC, FALSE, (DWORD) pid);
if(self != NULL){
printf("process open !n");
AddAceToObjectsSecurityDescriptor(self, SE_KERNEL_OBJECT, (LPSTR)username,TRUSTEE_IS_NAME, PROCESS_ALL_ACCESS, GRANT_ACCESS, 0);
}
else{
dwRes = GetLastError();
printf("error in opening of the process. Code %u n", dwRes);
}
}