无法使用我的代码修改我拥有的 Process DACL,但 Process Hacker 可以
Cannot modify Process DACL that I own with my code but Process Hacker can
我有一个进程(我们称之为 ProcessX),默认情况下 运行s 只有 Terminate
、Synchronize
和 Query Limited Information
权限。
当我在 Process Hacker 中查看 ProcessX 时,我可以看到权限(ACE、所有者等)。我可以看到我是 ProcessX 的所有者,我可以看到与之关联的 3 个有限权限(Terminate
、Synchronize
和 Query Limited Information
),我什至可以编辑权限(例如,在上面设置 Full Control
)。
但是,当我 运行 下面的代码检查 ProcessX 的 DACL 时,与拥有 ProcessX[=51= 的同一用户], 我在 GetSecurityInfo()
函数上收到错误代码 5(拒绝访问)。
在 ProcessX 上使用 AccessChk 和 Process Explorer 的结果相同。
但是,Process Hacker 完全能够读取 ProcessX 的 DACL 并对其进行修改。
我不明白。这怎么可能?为什么我的代码无法读取 ProcessX 的 DACL?
我在 MS 文档中读到要读取 DACL,我必须使用 OpenProcess()
和 READ_CONTROL
。
但是 READ_CONTROL
不是我的用户的流程中可用的 ACE。所以,我无法用它打开进程(如果我尝试 OpenProcess()
错误,这是合乎逻辑的)。
所以,我是进程的所有者,但我不能修改 ACE,但 Process Hacker 可以。
谁能帮我理解一下?
#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 %u\n", 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 %u\n", 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 %u\n", 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 process\n");
}
}
问题已解决!
我假设 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 %u\n", 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 %u\n", 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 %u\n", 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);
}
}
我有一个进程(我们称之为 ProcessX),默认情况下 运行s 只有 Terminate
、Synchronize
和 Query Limited Information
权限。
当我在 Process Hacker 中查看 ProcessX 时,我可以看到权限(ACE、所有者等)。我可以看到我是 ProcessX 的所有者,我可以看到与之关联的 3 个有限权限(Terminate
、Synchronize
和 Query Limited Information
),我什至可以编辑权限(例如,在上面设置 Full Control
)。
但是,当我 运行 下面的代码检查 ProcessX 的 DACL 时,与拥有 ProcessX[=51= 的同一用户], 我在 GetSecurityInfo()
函数上收到错误代码 5(拒绝访问)。
在 ProcessX 上使用 AccessChk 和 Process Explorer 的结果相同。
但是,Process Hacker 完全能够读取 ProcessX 的 DACL 并对其进行修改。
我不明白。这怎么可能?为什么我的代码无法读取 ProcessX 的 DACL?
我在 MS 文档中读到要读取 DACL,我必须使用 OpenProcess()
和 READ_CONTROL
。
但是 READ_CONTROL
不是我的用户的流程中可用的 ACE。所以,我无法用它打开进程(如果我尝试 OpenProcess()
错误,这是合乎逻辑的)。
所以,我是进程的所有者,但我不能修改 ACE,但 Process Hacker 可以。
谁能帮我理解一下?
#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 %u\n", 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 %u\n", 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 %u\n", 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 process\n");
}
}
问题已解决!
我假设 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 %u\n", 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 %u\n", 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 %u\n", 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);
}
}