简体   繁体   中英

Cannot modify Process DACL that I own with my code but Process Hacker can

I have a process (let's call it ProcessX ) that runs by default with only Terminate , Synchronize , and Query Limited Information permissions.

When I look at ProcessX in Process Hacker, I can see the permission (ACE, Owner, etc). I can see that I'm the owner of ProcessX , I can see the 3 limited permissions associated with it ( Terminate , Synchronize , and Query Limited Information ), and I can even edit the permissions (for instance, set Full Control on it).

However, when I run the code below to check the DACL of ProcessX , with the same user that owns ProcessX , I'm getting an error code 5 (Access Denied) on the GetSecurityInfo() function.

Same results with AccessChk and Process Explorer on ProcessX .

However, Process Hacker is perfectly able to read the DACL of ProcessX and modify it.

I don't understand. How is that possible? Why is my code unable to read the DACL for ProcessX ?

I've read in MS documents that to read the DACL, I must use OpenProcess() with READ_CONTROL .

But READ_CONTROL is not an available ACE on the process for my user. So, I can't open the process with it ( OpenProcess() errors if I try, which is logical).

So, I'm the owner of the process, but I can't modify the ACE, but Process Hacker can.

Can anybody help me understand?

#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");
  }
}

Problem solved. I've assumed that READ_CONTROL will be refused because it wasn't available on the DACL of the running process.

But it works. I also use now TRUSTEE_IS_NAME with the username.

#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);
    printf("\n");
    // 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]);
  char c;
  DWORD dwRes = 0;
  c = getchar();
  printf("[+] Ensuring we have the proper privs....\n");
  HANDLE self = OpenProcess(
  PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE | READ_CONTROL | WRITE_DAC,
  FALSE, (DWORD) pid);
  if(self != NULL){
    printf("process open !\n"); 
    AddAceToObjectsSecurityDescriptor(self, SE_KERNEL_OBJECT, (LPSTR)"MYAWESOMELOGIN",TRUSTEE_IS_NAME, PROCESS_ALL_ACCESS, GRANT_ACCESS, 0);
  }
  else{
      dwRes = GetLastError();
      printf("error in opening of the process. Code %u \n", dwRes);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM