加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

笔记——PowerShell注册表(五)注册表权限

(2017-01-12 21:09:08)
标签:

it

分类: 读书笔记

PowerShell注册表(五)注册表权限 

同样的机制也可以在注册表中使用,使用Get-Acl查看键的当前权限:

PS> md HKCU:\Software\Testkey

 

 

    Hive: HKEY_CURRENT_USER\Software

 

 

Name                           Property

----                           --------

Testkey

PS> Get-Acl HKCU:\Software\Testkey

 

Path                                    Owner   Access

----                                    -----   ------

Microsoft.PowerShell.Core\Registry::... mosser  mosser Allow  FullControl...

因为注册表权限管理基本和文件系统的权限管理类似,所以你可能需要在给注册表键分配权限前再看看第15,或者重温一下基础知识。注册表中所需的权限在.NET中的类和与文件系统稍微有点区别。此时需要使用的不再是FilesystemAccessRule,而是RegistryAccessRule,两者的根本区别在于可以设置不同的访问权限。在注册表访问规则(RegistryAccessRule)中,权限的枚举值并不和文件系统访问规则(FilesystemAccessRule)中的枚举值对应:

PS> [System.Enum]::GetNames([System.Security.AccessControl.RegistryRights]

QueryValues

SetValue

CreateSubKey

EnumerateSubKeys

Notify

CreateLink

Delete

ReadPermissions

WriteKey

ExecuteKey

ReadKey

ChangePermissions

TakeOwnership

FullControl

接管所有权

在尝试更改注册表的权限前,请先测试以确保你是该键的所有者。除非你是所有者,才能够撤销可能存在的错误。下面的示例会演示怎样接管一个注册表键(当然你还是得先有权限访问)的所有权。

$acl = Get-Acl HKCU:\Software\Testkey

$acl.Owner

 

mosser

$me = [System.Security.Principal.NTAccount]"$env:userdomain\$env:username"

$acl.SetOwner($me)

设置新的访问权限

下面的步骤会给这个键分配新的权限,让所有人组禁止更改此键。

1

2

3

4

5

6

7

8

9

10

$acl = Get-Acl HKCU:\Software\Testkey

$person = [System.Security.Principal.NTAccount]"Everyone"

$access = [System.Security.AccessControl.RegistryRights]"WriteKey"

$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"

$propagation = [System.Security.AccessControl.PropagationFlags]"None"

$type = [System.Security.AccessControl.AccessControlType]"Deny"

$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `

$person,$access,$inheritance,$propagation,$type)

$acl.AddAccessRule($rule)

Set-Acl HKCU:\Software\Testkey $acl

更改会立刻生效,当你尝试通过注册表编辑器或者在PowerShell中创建子键时,会得到错误信息:

1

md HKCU:\Software\Testkey\subkey

md : 不允许所请求的注册表访问权。
At line:1 char:34

+ param([string[]]$paths); New-Item <<<< -type directory -path $paths

小技巧:你可能会问,为什么连我自己都限制,我是管理员啊,我应当拥有完全的访问权啊。这是因为在访问权限中,拒绝”的优先权比允许高。哪怕你是管理员,你也是人,既然所有人都被拒绝,你自然也会被拒绝,除非你不是人。

移除一条访问规则

给所有人的访问权限完全是在浪费时间,也经不起考验。怎样删除这条规则呢?你可以使用RemoveAccessRule()方法来移除特定的权限,还可以使用RemoveAccessRuleAll()方法来移除指定用户的在某条规则中的所有权限(包括授权和拒绝),ModifyAccessRule()方法更新已存在的规则,PurgeAccessRules(),异常特定用户的所有权限。

要移除刚才创建的规则,可以这样处理:

1

2

3

4

5

6

7

8

9

10

$acl = Get-Acl HKCU:\Software\Testkey

$person = [System.Security.Principal.NTAccount]"Everyone"

$access = [System.Security.AccessControl.RegistryRights]"WriteKey"

$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"

$propagation = [System.Security.AccessControl.PropagationFlags]"None"

$type = [System.Security.AccessControl.AccessControlType]"Deny"

$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `

$person,$access,$inheritance,$propagation,$type)

$acl.RemoveAccessRule($rule)

Set-Acl HKCU:\Software\Testkey $acl -force

但是这样移除自己的访问规则后,并不是期望的结果。因为你把自己锁在了门外,因为你不在有权去更新这个键,本来是可以更改自己的安全设置的。此时如果你接管了所有权后。还是可以纠正遇到的这个问题的。此类情况发生后,你可以打开注册表编辑器,定位到这个键,右键鼠标选择权限,打开安全设置对话框,手动删除所有人组。

重要:刚才已经看到了,把自己锁在门外有多容易。所以在操作所有人这个组时,一定要格外小心。如果可以,尽量不要给这个组分配拒绝规则,因为它通常可能引入超出你预期的恶劣影响。

控制子键的访问

下面的例子,使用允许规则,而非拒绝规则,可以让世界稍微变得美好一点。在下面的测试键中,只有管理员才能更改这个键的值,而其它闲杂人等,只能读取和创建子键。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

md HKCU:\Software\Testkey2

$acl = Get-Acl HKCU:\Software\Testkey2

# 管理员无所不能:

$person = [System.Security.Principal.NTAccount]"Administrators"

$access = [System.Security.AccessControl.RegistryRights]"FullControl"

$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"

$propagation = [System.Security.AccessControl.PropagationFlags]"None"

$type = [System.Security.AccessControl.AccessControlType]"Allow"

$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `

$person,$access,$inheritance,$propagation,$type)

$acl.ResetAccessRule($rule)

# 所有人只能读取和创建子键:

$person = [System.Security.Principal.NTAccount]"Everyone"

$access = [System.Security.AccessControl.RegistryRights]"ReadKey"

$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"

$propagation = [System.Security.AccessControl.PropagationFlags]"None"

$type = [System.Security.AccessControl.AccessControlType]"Allow"

$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `

$person,$access,$inheritance,$propagation,$type)

$acl.ResetAccessRule($rule)

Set-Acl HKCU:\Software\Testkey2 $acl

稍微注意下,这种情况下没有使用AddAccessRule()而是使用ResetAccessRule()添加规则。其结果导致删除了各个用户已存在的权限。尽管如此,结果仍旧不对,因为正常的用户还是可以创建子键和写值。

md hkcu:\software\Testkey2\Subkey

Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\software\Testkey2

 

SKC   VC  Name  Property

---   --  ----  --------

    Subkey {}

 

Set-ItemProperty HKCU:\Software\Testkey2 Value1 "Here is text"

揭示继承权

查看键的当前权限,可以弄清为什么上面的设置没有如期生效:

PS> (Get-Acl HKCU:\Software\Testkey2).Access | Format-Table -wrap

 

     RegistryRights   AccessControlType IdentityReference           IsInherited    InheritanceFlags    PropagationFlags

     --------------   ----------------- -----------------           -----------    ----------------    ----------------

            ReadKey               Allow Everyone                          False                None                None

        FullControl               Allow BUILTIN\Administrat               False                None                None

                                        ors

        FullControl               Allow mosser                             True  ContainerInherit,                 None

                                                                                      ObjectInherit

        FullControl               Allow NT AUTHORITY\SYSTEM                True  ContainerInherit,                 None

                                                                                      ObjectInherit

        FullControl               Allow BUILTIN\Administrat                True  ContainerInherit,                 None

                                        ors                                           ObjectInherit

            ReadKey               Allow NT AUTHORITY\RESTRI                True  ContainerInherit,                 None

                                        CTED                                          ObjectInherit

该键包含的权限可不止我们设置的那两条规则,还有其它一些从父键中继承过来的阿猫阿狗规则。如果你想清理掉它们,可以使用SetAccessRuleProtection()方法。

1

2

3

$acl = Get-Acl HKCU:\Software\Testkey2

$acl.SetAccessRuleProtection($true, $false)

Set-Acl HKCU:\Software\Testkey2 $acl

现在再回过头来看看,该键的访问规则只有我们明确指定的两条规则,其它继承权限已不复存在。

PS> (Get-Acl HKCU:\Software\Testkey2).Access | Format-Table -wrap

 

     RegistryRights   AccessControlType IdentityReference           IsInherited    InheritanceFlags    PropagationFlags

     --------------   ----------------- -----------------           -----------    ----------------    ----------------

            ReadKey               Allow Everyone                          False                None                None

        FullControl               Allow BUILTIN\Administrat               False                None                None

                                        ors

此时再让普通用户尝试给该键添加子键或者设置值,应当会包错:Set-ItemProperty : 不允许所请求的注册表访问权。

控制你自己的继承权

继承权是一把双刃剑。你已经从父键中关闭了继承,但是你自己的继承权呢?使用管理员权限打开控制台,能让我们给上面受保护的测试键添加子键。

1

2

md HKCU:\Software\Testkey2\Subkey1

md HKCU:\Software\Testkey2\Subkey1\Subkey2

然后看看这些新创建的子键的权限:

PS> (Get-Acl HKCU:\Software\Testkey2\Subkey1\Subkey2).Access | Format-Table -wrap

 

     RegistryRights   AccessControlType IdentityReference           IsInherited    InheritanceFlags    PropagationFlags

     --------------   ----------------- -----------------           -----------    ----------------    ----------------

        FullControl               Allow NT AUTHORITY\SYSTEM               False                None                None

        FullControl               Allow BUILTIN\Administrat               False                None                None

                                        ors

CreateLink, ReadKey               Allow S-1-5-5-0-205634                  False                None                None

其结果是这些权限仍旧没有与你设置的权限对应起来。理由是:对于你的继承权你啥都没设置,如果你想把自己纯正的血统不折不扣的遗传给下一代,请更改设置:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

del HKCU:\Software\Testkey2

md HKCU:\Software\Testkey2

$acl = Get-Acl HKCU:\Software\Testkey2

# Admins may do anything:

$person = [System.Security.Principal.NTAccount]"Administrators"

$access = [System.Security.AccessControl.RegistryRights]"FullControl"

$inheritance = [System.Security.AccessControl.InheritanceFlags]`

"ObjectInherit,ContainerInherit"

$propagation = [System.Security.AccessControl.PropagationFlags]"None"

$type = [System.Security.AccessControl.AccessControlType]"Allow"

$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `

$person,$access,$inheritance,$propagation,$type)

 

$acl.ResetAccessRule($rule)

# Everyone may only read and create subkeys:

$person = [System.Security.Principal.NTAccount]"Everyone"

$access = [System.Security.AccessControl.RegistryRights]"ReadKey"

$inheritance = [System.Security.AccessControl.InheritanceFlags]`

"ObjectInherit,ContainerInherit"

$propagation = [System.Security.AccessControl.PropagationFlags]"None"

$type = [System.Security.AccessControl.AccessControlType]"Allow"

$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `

$person,$access,$inheritance,$propagation,$type)

$acl.ResetAccessRule($rule)

Set-Acl HKCU:\Software\Testkey2 $acl

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有