2014-06-23 43 views
1

閱讀 this questionthis blog post 後,我想出了這些命令設置的ACL:請求的註冊表訪問不允許

Set-Location HKLM:\Software\Classes\cmdfile\ShellEx\PropertySheetHandlers 
$am = New-Object Security.Principal.NTAccount 'BUILTIN', 'Administrators' 
$ke = Get-Acl 'ShimLayer Property Page' 
$ke.SetOwner($am) 
Set-Acl -AclObject $ke -Path 'ShimLayer Property Page' 

然而,當我運行他們,我得到這個消息

Set-Acl : Requested registry access is not allowed. 

如何更改此密鑰的所有者?

回答

2

的訪問控制看完另一種方式,這些

Changing owner of key to Administrator

Set controls on files owned by TrustedInstaller

我想出了這個工作解決方案。

Function Enable-Privilege { 
    param($Privilege) 
    $Definition = @' 
using System; 
using System.Runtime.InteropServices; 
public class AdjPriv { 
    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 
    internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, 
    ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr rele); 
    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 
    internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); 
    [DllImport("advapi32.dll", SetLastError = true)] 
    internal static extern bool LookupPrivilegeValue(string host, string name, 
    ref long pluid); 
    [StructLayout(LayoutKind.Sequential, Pack = 1)] 
    internal struct TokPriv1Luid { 
    public int Count; 
    public long Luid; 
    public int Attr; 
    } 
    internal const int SE_PRIVILEGE_ENABLED = 0x00000002; 
    internal const int TOKEN_QUERY = 0x00000008; 
    internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; 
    public static bool EnablePrivilege(long processHandle, string privilege) { 
    bool retVal; 
    TokPriv1Luid tp; 
    IntPtr hproc = new IntPtr(processHandle); 
    IntPtr htok = IntPtr.Zero; 
    retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
     ref htok); 
    tp.Count = 1; 
    tp.Luid = 0; 
    tp.Attr = SE_PRIVILEGE_ENABLED; 
    retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); 
    retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, 
     IntPtr.Zero); 
    return retVal; 
    } 
} 
'@ 
    $ProcessHandle = (Get-Process -id $pid).Handle 
    $type = Add-Type $definition -PassThru 
    $type[0]::EnablePrivilege($processHandle, $Privilege) 
} 

do {} until (Enable-Privilege SeTakeOwnershipPrivilege) 
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
    'Software\Classes\cmdfile\ShellEx\PropertySheetHandlers\ShimLayer Property Page', 
    'ReadWriteSubTree', 'TakeOwnership') 
$owner = [Security.Principal.NTAccount]'Administrators' 
$acl = $key.GetAccessControl() 
$acl.SetOwner($owner) 
$key.SetAccessControl($acl) 
1

如果管理員組已從ACL中刪除,則最終會出現此錯誤。但是您可以使用OpenSubKey()方法來檢索指定的子密鑰以進行讀取或讀取/寫入訪問,請求指定的訪問權限。

$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("Software\Classes\cmdfile\ShellEx\PropertySheetHandlers",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions) 

一旦你擁有了它,那麼你可以使用GetAccessControl()SetAccessControl()方法來獲得許可回

$acl = $key.GetAccessControl() 
$key.SetAccessControl($acl) 

更多信息請參見this post

編輯:

設置註冊表

$ke = Get-Acl 'HKLM:\Software\Classes\cmdfile\ShellEx\PropertySheetHandlers\ShimLayer Property Page' 

$rule = New-Object System.Security.AccessControl.RegistryAccessRule ("mydomain\myusername","FullControl","Allow") 

$ke.SetAccessRule($rule) 

$ke |Set-Acl -Path 'HKLM:\Software\Classes\cmdfile\ShellEx\PropertySheetHandlers\ShimLayer Property Page' 
+0

@StevenPenny,它的註冊表否則我會發布的答案曾經使用過相關的,但它應該每工作文檔。編輯答案並刪除了「HKLM:\」。試一試。 – Rahul

+0

感謝編輯,但你仍然有錯誤的關鍵,它應該是問題中所示的ShimLayer屬性頁面。當用這個鍵使用你的命令時,我會得到'帶有「3」參數的異常調用「OpenSubKey」:「請求註冊表 訪問不被允許。」' –

1

試試看:

# group BULTIN\Users takes full control of key and all subkeys 
Take-Permissions("HKLM", "SOFTWARE\test") 

# group Everyone takes full control of key and all subkeys 
Take-Permissions("HKLM", "SOFTWARE\test", "S-1-1-0") 

# group Everyone takes full control of key WITHOUT subkeys 
Take-Permissions("HKLM", "SOFTWARE\test", "S-1-1-0", $false) 

只要定義這個功能:

function Take-Permissions { 
    # Developed for PowerShell v4.0 
    # Required Admin privileges 
    # Links: 
    # http://shrekpoint.blogspot.ru/2012/08/taking-ownership-of-dcom-registry.html 
    # http://www.remkoweijnen.nl/blog/2012/01/16/take-ownership-of-a-registry-key-in-powershell/ 
    # https://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/ 

    param($rootKey, $key, [System.Security.Principal.SecurityIdentifier]$sid = 'S-1-5-32-545', $recurse = $true) 

    switch -regex ($rootKey) { 
     'HKCU|HKEY_CURRENT_USER' { $rootKey = 'CurrentUser' } 
     'HKLM|HKEY_LOCAL_MACHINE' { $rootKey = 'LocalMachine' } 
     'HKCR|HKEY_CLASSES_ROOT' { $rootKey = 'ClassesRoot' } 
     'HKCC|HKEY_CURRENT_CONFIG' { $rootKey = 'CurrentConfig' } 
     'HKU|HKEY_USERS'   { $rootKey = 'Users' } 
    } 

    ### Step 1 - escalate current process's privilege 
    # get SeTakeOwnership, SeBackup and SeRestore privileges before executes next lines, script needs Admin privilege 
    $import = '[DllImport("ntdll.dll")] public static extern int RtlAdjustPrivilege(ulong a, bool b, bool c, ref bool d);' 
    $ntdll = Add-Type -Member $import -Name NtDll -PassThru 
    $privileges = @{ SeTakeOwnership = 9; SeBackup = 17; SeRestore = 18 } 
    foreach ($i in $privileges.Values) { 
     $null = $ntdll::RtlAdjustPrivilege($i, 1, 0, [ref]0) 
    } 

    function Take-KeyPermissions { 
     param($rootKey, $key, $sid, $recurse, $recurseLevel = 0) 

     ### Step 2 - get ownerships of key - it works only for current key 
     $regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, 'ReadWriteSubTree', 'TakeOwnership') 
     $acl = New-Object System.Security.AccessControl.RegistrySecurity 
     $acl.SetOwner($sid) 
     $regKey.SetAccessControl($acl) 

     ### Step 3 - enable inheritance of permissions (not ownership) for current key from parent 
     $acl.SetAccessRuleProtection($false, $false) 
     $regKey.SetAccessControl($acl) 

     ### Step 4 - only for top-level key, change permissions for current key and propagate it for subkeys 
     # to enable propagations for subkeys, it needs to execute Steps 2-3 for each subkey (Step 5) 
     if ($recurseLevel -eq 0) { 
      $regKey = $regKey.OpenSubKey('', 'ReadWriteSubTree', 'ChangePermissions') 
      $rule = New-Object System.Security.AccessControl.RegistryAccessRule($sid, 'FullControl', 'ContainerInherit', 'None', 'Allow') 
      $acl.ResetAccessRule($rule) 
      $regKey.SetAccessControl($acl) 
     } 

     ### Step 5 - recursively repeat steps 2-5 for subkeys 
     if ($recurse) { 
      foreach($subKey in $regKey.OpenSubKey('').GetSubKeyNames()) { 
       Take-KeyPermissions $rootKey ($key+'\'+$subKey) $sid $recurse ($recurseLevel+1) 
      } 
     } 
    } 

    Take-KeyPermissions $rootKey $key $sid $recurse 
} 
相關問題