Page 1 of 1

Get Registry key permissions [Win_Func]

Posted: Tue Aug 16, 2016 6:48 pm
by Thunder93

Code: Select all

#SDDL_REVISION_1 = 1
#DACL_SECURITY_INFORMATION = $00000004

Prototype ConvertSecurityDescriptorToStringSecurityDescriptor(SecurityDescriptor, requestedStringSDRevision.l, SecurityInformation, StringSecurityDescriptor, StringSecurityDescriptorLen.l)

Procedure Advapi32_Init()
  Shared Lib_Advapi32, cExt.s
  Protected Retr.b
  
  CompilerIf #PB_Compiler_Unicode : cExt = "W" : CompilerElse : cExt = "A" : CompilerEndIf  
  
  Lib_Advapi32 = OpenLibrary(#PB_Any,"Advapi32.dll")
  If Lib_Advapi32
    Global ConvertSecurityDescriptorToStringSecurityDescriptor.ConvertSecurityDescriptorToStringSecurityDescriptor = GetFunction(Lib_Advapi32,"ConvertSecurityDescriptorToStringSecurityDescriptor"+cExt)
    Retr = 1    
  EndIf
  
  ProcedureReturn Retr
EndProcedure

Procedure Advapi32_End()
  Shared Lib_Advapi32
  CloseLibrary(Lib_Advapi32)
EndProcedure


Procedure.q TopHiveKey(HiveKeyConvert$)
  Protected HiveKeyx.q
  
  If Right(HiveKeyConvert$, 1) = "\"
    HiveKeyConvert$ = RemoveString(HiveKeyConvert$, "\", #PB_String_NoCase, Len(HiveKeyConvert$) - 1, 1)
  Else
    HiveKeyConvert$ = HiveKeyConvert$
  EndIf
  
  HiveKeya$=StringField(HiveKeyConvert$,1,"\")
  HiveKeyTop$=UCase(HiveKeya$)
  Select HiveKeyTop$
    Case "HKEY_CLASSES_ROOT"
      HiveKeyx = #HKEY_CLASSES_ROOT
    Case "HKEY_CURRENT_USER"
      HiveKeyx = #HKEY_CURRENT_USER
    Case "HKEY_LOCAL_MACHINE"
      HiveKeyx = #HKEY_LOCAL_MACHINE
    Case "HKEY_USERS"
      HiveKeyx = #HKEY_USERS
    Case "HKEY_CURRENT_CONFIG"
      HiveKeyx = #HKEY_CURRENT_CONFIG
    Default
      HiveKeyx = #Null
  EndSelect
  ProcedureReturn HiveKeyx
  
EndProcedure

Procedure.s KeyConvert(KeyToConvert$)
  
  If Right(KeyToConvert$, 1) = "\"
    KeyToConvert$ = RemoveString(KeyToConvert$, "\", #PB_String_NoCase, Len(KeyToConvert$) - 1, 1)
  Else
    KeyToConvert$ = KeyToConvert$
  EndIf
  
  GetBackSlash=FindString(KeyToConvert$,"\",1)
  KeyNameX$=Right(KeyToConvert$,(Len(KeyToConvert$)-GetBackSlash))
  If Left(KeyNameX$, 1) = "\"
    KeyNameX$ = Right(KeyNameX$, Len(KeyNameX$) - 1)
  EndIf
  ProcedureReturn KeyNameX$
EndProcedure

Procedure.s Reg_GetKeySecurity(Key.s, secInfo.l)
  Protected hKey, HiveKey.i, KeyName$, SIDString.s, cbLength.l, seclen.l
  Protected *secDescPtr.SECURITY_DESCRIPTOR
  
  HiveKey = TopHiveKey(Key)
  KeyName$ = KeyConvert(Key)
  
  If RegOpenKeyEx_(HiveKey, KeyName$, 0,  #KEY_ALL_ACCESS, @hKey) = #ERROR_SUCCESS
    If RegGetKeySecurity_(hKey, secInfo, 0, @cbLength) = #ERROR_INSUFFICIENT_BUFFER
      *secDescPtr = AllocateMemory(cbLength)
      If RegGetKeySecurity_(hKey, secInfo, *secDescPtr, @cbLength) <> #ERROR_SUCCESS
        Debug "RegGetKeySecurity API: failed. "+GetLastError_()
        ProcedureReturn "0"
      EndIf
      RegCloseKey_(hKey)
    EndIf
  EndIf

  If ConvertSecurityDescriptorToStringSecurityDescriptor(*secDescPtr, #SDDL_REVISION_1, secInfo, @*pSID, @seclen) = 0
    Debug "ConvertSecurityDescriptorToStringSecurityDescriptor API failed. "+GetLastError_()
  EndIf
  
  If *secDescPtr : FreeMemory(*secDescPtr) : EndIf
  
  SIDString = PeekS(*pSID, seclen)  
    
  If SIDString :
    ProcedureReturn SIDString
  EndIf
  
  ProcedureReturn "0" 
EndProcedure

If Advapi32_Init()
  Debug Reg_GetKeySecurity("HKEY_CURRENT_USER\Control Panel", #DACL_SECURITY_INFORMATION)
  Advapi32_End()
EndIf

Re: Get Registry key permissions

Posted: Tue Aug 16, 2016 7:27 pm
by Thunder93
All that is needed is a SDDL Parser to a more easier comprehensible format. :wink:

Re: Get Registry key permissions [Win_Func]

Posted: Tue Aug 23, 2016 7:18 pm
by Thunder93
Here's another approach, with human comprehensible format. I've had something several days ago, that I've posted here. However, I've made several changes.

Get Registry Key Permissions; v0.001 [2016-08-23 Rev: #0]

Code: Select all

Enumeration ;ACL_INFORMATION_CLASS
  #AclRevisionInformation = 1
  #AclSizeInformation
EndEnumeration

#OWNER_SECURITY_INFORMATION   = $1
#DACL_SECURITY_INFORMATION    = $4

Procedure TopHiveKey(TopHiveKey$)
  Protected HiveKey, HiveKeyTop$
  
  HiveKeyTop$ = UCase(TopHiveKey$)
  
  Select HiveKeyTop$
    Case "HKEY_CLASSES_ROOT"
      HiveKey = #HKEY_CLASSES_ROOT
    Case "HKEY_CURRENT_USER"
      HiveKey = #HKEY_CURRENT_USER
    Case "HKEY_LOCAL_MACHINE"
      HiveKey = #HKEY_LOCAL_MACHINE
    Case "HKEY_USERS"
      HiveKey = #HKEY_USERS
    Case "HKEY_CURRENT_CONFIG"
      HiveKey = #HKEY_CURRENT_CONFIG
    Default
      HiveKey = #Null
  EndSelect
  
  ProcedureReturn HiveKey
EndProcedure

Procedure.b Reg_EnumAccountKeyAccessPermission(Key.s)
  Protected *pSecDesc.SECURITY_DESCRIPTOR, *pDacl.ACL, *pAce.ACCESS_ALLOWED_ACE, aclSize.ACL_SIZE_INFORMATION
  Protected.i hTKey, hKey, retfunc, bRtnBool, acl_ACECount, dwAccountNameSize, dwDomainNameSize, SID_NAME_USE
  Protected.s TopHiveKey, KeyName, szAccountName, szDomainName, szAccountName1
  
  TopHiveKey = StringField(Key, 1, "\")
  KeyName = Mid(Key, Len(TopHiveKey)+2)
  
  hTKey = TopHiveKey(TopHiveKey)
  
  retfunc = RegOpenKeyEx_(hTKey, @KeyName, 0, #KEY_ALL_ACCESS, @hKey)
  
  If retfunc = #ERROR_SUCCESS
    
    retfunc = RegGetKeySecurity_(hKey, #DACL_SECURITY_INFORMATION|#OWNER_SECURITY_INFORMATION, #Null, @nLengthNeeded.l)
    If retfunc = #ERROR_INSUFFICIENT_BUFFER
      *pSecDesc = AllocateMemory(nLengthNeeded)
      If Not *pSecDesc : Debug "*pSecDesc memory allocation failed." : ProcedureReturn 0 : EndIf
      retfunc = RegGetKeySecurity_(hKey, #DACL_SECURITY_INFORMATION|#OWNER_SECURITY_INFORMATION, *pSecDesc, @nLengthNeeded)
    EndIf
    
    If retfunc = #ERROR_SUCCESS
      
      Debug "Key: "+Key
      If RegQueryInfoKey_(hKey, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @lpftLastWriteTime.FILETIME) = #ERROR_SUCCESS
        If FileTimeToSystemTime_(@lpftLastWriteTime, @SystemTime.SYSTEMTIME)
          Debug "   Last Modified Date: "+FormatDate("%dd/%mm/%yyyy %hh:%ii:%ss", Date(SystemTime\wYear, SystemTime\wMonth, SystemTime\wDay, SystemTime\wHour, SystemTime\wMinute, SystemTime\wSecond))
        EndIf
      EndIf
      
      Protected pOwner.i, lpbOwnerDef.l
      
      bRetFunc = GetSecurityDescriptorOwner_(*pSecDesc, @pOwner, @lpbOwnerDef)
      
      If bRetFunc
        bRtnBool = LookupAccountSid_(#Null, pOwner, 0, @dwAccountNameSize, 0, @dwDomainNameSize, @SID_NAME_USE)
        
        szAccountName = Space(dwAccountNameSize)
        szDomainName = Space(dwDomainNameSize)
        If LookupAccountSid_(#Null, pOwner, @szAccountName, @dwAccountNameSize, @szDomainName, @dwDomainNameSize, @SID_NAME_USE)
          Debug ""
          Debug "Object Ownership:"
          Debug "   Account = " + szAccountName + ", Domain = " + szDomainName
          Debug ""
        EndIf
        
        dwDomainNameSize = 0
      EndIf
      
      If *pSecDesc
        GetSecurityDescriptorDacl_(*pSecDesc, @bDaclPresent.l, @*pDacl, @bDaclDefault.l)
        
        If bDaclPresent = 0
          RegCloseKey_(hKey)
          Debug "No DACL"
          ProcedureReturn 0
        Else
          
          GetAclInformation_(*pDacl, @aclSize, SizeOf(aclSize), #AclSizeInformation)
          
          acl_ACECount = aclSize\AceCount - 1          
          
          Repeat
            GetAce_(*pDacl, acl_ACECount, @*pAce)              
            
            bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, 0, @dwAccountNameSize, 0, @dwDomainNameSize, @snu)
            szAccountName = Space(dwAccountNameSize)
            szDomainName = Space(dwDomainNameSize)
            bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, @szAccountName, @dwAccountNameSize, @szDomainName, @dwDomainNameSize, @snu)

            
            ;Standard Access Rights
            If *pAce\Mask & #STANDARD_RIGHTS_REQUIRED = #STANDARD_RIGHTS_REQUIRED
              StandardAccess$ + "( Full Access ) | "
            EndIf  
            If *pAce\Mask & #READ_CONTROL
              StandardAccess$ + "READ_CONTROL - "
            EndIf 
            If *pAce\Mask & #WRITE_DAC
              StandardAccess$ + "WRITE_DAC - "
            EndIf
            If *pAce\Mask & #WRITE_OWNER
              StandardAccess$ + "WRITE_OWNER - "
            EndIf
            If *pAce\Mask & #DELETE
              StandardAccess$ + "DELETE - "
            EndIf
            
            StandardAccess$ = RemoveString(StandardAccess$, " - ", #PB_String_NoCase, Len(StandardAccess$) - 3, 1)

            
            If *pAce\Mask & #KEY_ALL_ACCESS = #KEY_ALL_ACCESS
              SpecificAcess$ + "(Full Access) - "
            EndIf
            
            If *pAce\Mask & #KEY_READ = #KEY_READ
              SpecificAcess$ + "KEY_READ / KEY_EXECUTE - " ; Equivalent to KEY_EXECUTE (0x20019)
            EndIf
            If *pAce\Mask & #KEY_WRITE
              SpecificAcess$ + "KEY_WRITE - "
            EndIf
            
            If *pAce\Mask & #KEY_QUERY_VALUE
              SpecificAcess$ + "KEY_QUERY_VALUE - "
            EndIf            
            If *pAce\Mask & #KEY_SET_VALUE
              SpecificAcess$ + "KEY_SET_VALUE - "
            EndIf
            If *pAce\Mask & #KEY_CREATE_SUB_KEY
              SpecificAcess$ + "KEY_CREATE_SUB_KEY - "
            EndIf
            If *pAce\Mask & #KEY_ENUMERATE_SUB_KEYS
              SpecificAcess$ + "KEY_ENUMERATE_SUB_KEYS - "
            EndIf
            If *pAce\Mask & #KEY_NOTIFY = #KEY_NOTIFY
              SpecificAcess$ + "KEY_NOTIFY - "
            EndIf
            If *pAce\Mask & #KEY_CREATE_LINK = #KEY_CREATE_LINK
              SpecificAcess$ + "KEY_CREATE_LINK - "
            EndIf
            
            SpecificAcess$ = RemoveString(SpecificAcess$, " - ", #PB_String_NoCase, Len(SpecificAcess$) - 3, 1) ; goes away later with string formatting
            
            
            Select *pAce\Header\AceType
              Case #ACCESS_ALLOWED_ACE_TYPE
                AceType$ = "ACCESS_ALLOWED_ACE_TYPE"
                ;Break
              Case #ACCESS_DENIED_ACE_TYPE
                AceType$ = "ACCESS_DENIED_ACE_TYPE"
                ;Break
              Case #SYSTEM_AUDIT_ACE_TYPE
                AceType$ = "SYSTEM_AUDIT_ACE_TYPE"
                ;Break
              Default
                AceType$ = "Unknown ACE type"
                ;Break
            EndSelect
            
            Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Specific Access Rights = " + SpecificAcess$
            Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Standard Access Rights = " + StandardAccess$
            Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", ACE Type = " + AceType$
            Debug ""
            
            szAccountName1 = szAccountName
            dwDomainNameSize = 0
            StandardAccess$=""
            SpecificAcess$=""
            
            acl_ACECount - 1
          Until acl_ACECount < 0          
          
        EndIf
        FreeMemory(*pSecDesc)
      EndIf
      RegCloseKey_(hKey)
      ProcedureReturn 1
    EndIf
  EndIf  
EndProcedure

Debug Reg_EnumAccountKeyAccessPermission("HKEY_CURRENT_USER\Control Panel")

When compiled;

Code: Select all

Key: HKEY_CURRENT_USER\Control Panel
   Last Modified Date: 04/08/2016 02:25:09

Object Ownership:
   Account = SYSTEM, Domain = NT AUTHORITY

Account = ALL APPLICATION PACKAGES, Domain = APPLICATION PACKAGE AUTHORITY, Specific Access Rights = KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY
Account = ALL APPLICATION PACKAGES, Domain = APPLICATION PACKAGE AUTHORITY, Standard Access Rights = READ_CONTROL
Account = ALL APPLICATION PACKAGES, Domain = APPLICATION PACKAGE AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE

Account = RESTRICTED, Domain = NT AUTHORITY, Specific Access Rights = KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY
Account = RESTRICTED, Domain = NT AUTHORITY, Standard Access Rights = READ_CONTROL
Account = RESTRICTED, Domain = NT AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE

Account = Administrators, Domain = BUILTIN, Specific Access Rights = (Full Access) - KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_SET_VALUE - KEY_CREATE_SUB_KEY - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY - KEY_CREATE_LINK
Account = Administrators, Domain = BUILTIN, Standard Access Rights = ( Full Access ) | READ_CONTROL - WRITE_DAC - WRITE_OWNER - DELETE
Account = Administrators, Domain = BUILTIN, ACE Type = ACCESS_ALLOWED_ACE_TYPE

Account = SYSTEM, Domain = NT AUTHORITY, Specific Access Rights = (Full Access) - KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_SET_VALUE - KEY_CREATE_SUB_KEY - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY - KEY_CREATE_LINK
Account = SYSTEM, Domain = NT AUTHORITY, Standard Access Rights = ( Full Access ) | READ_CONTROL - WRITE_DAC - WRITE_OWNER - DELETE
Account = SYSTEM, Domain = NT AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE

Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Specific Access Rights = (Full Access) - KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_SET_VALUE - KEY_CREATE_SUB_KEY - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY - KEY_CREATE_LINK
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Standard Access Rights = ( Full Access ) | READ_CONTROL - WRITE_DAC - WRITE_OWNER - DELETE
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, ACE Type = ACCESS_ALLOWED_ACE_TYPE

1