如何以SYSTEM账户身份程序化恢复注册表项(含子项)的完全控制权
如何以SYSTEM账户身份程序化恢复注册表项(含子项)的完全控制权
嘿,我之前也碰到过注册表权限被篡改的棘手问题,刚好整理了几个能以SYSTEM身份执行的程序化解决方案,涵盖你提到的PowerShell、命令行、VBScript和Python,给你参考:
一、PowerShell 方案
这是最直观的方式,能递归处理所有子项,先获取所有权再设置完全控制权限:
# 定义目标注册表路径(替换成你的实际路径) $regPath = "HKLM:\SOFTWARE\Your\Target\Key" # 1. 递归将注册表项所有权转移给SYSTEM Get-Item -Path $regPath -Recurse -Force | ForEach-Object { $acl = Get-Acl -Path $_.PSPath $systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY\SYSTEM") $acl.SetOwner($systemAccount) Set-Acl -Path $_.PSPath -AclObject $acl } # 2. 递归给SYSTEM添加完全控制权限 $fullControlRule = New-Object System.Security.AccessControl.RegistryAccessRule( "NT AUTHORITY\SYSTEM", [System.Security.AccessControl.RegistryRights]::FullControl, [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow ) Get-Item -Path $regPath -Recurse -Force | ForEach-Object { $acl = Get-Acl -Path $_.PSPath $acl.AddAccessRule($fullControlRule) Set-Acl -Path $_.PSPath -AclObject $acl }
说明:脚本会先把目标项(包括所有子项)的所有权转到SYSTEM名下,再给SYSTEM添加递归的完全控制权限,确保后续操作不受权限限制。
二、命令行方案(CMD)
用系统自带的takeown.exe和icacls.exe工具,轻量且支持递归:
:: 替换为你的目标注册表路径 set REG_PATH=HKLM\SOFTWARE\Your\Target\Key :: 1. 递归获取所有权,自动确认所有提示 takeown /f "%REG_PATH%" /r /d y :: 2. 递归给SYSTEM分配完全控制权限 icacls "%REG_PATH%" /grant "NT AUTHORITY\SYSTEM":F /t
说明:/r和/t参数分别表示递归处理子项,/d y是默认确认所有权转移的提示,无需手动交互。
三、VBScript 方案
适合兼容老Windows系统的场景,通过WMI的StdRegProv类操作:
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv") ' 定义注册表根键(HKLM对应&H80000002)和目标路径 Const HKLM = &H80000002 strRegPath = "SOFTWARE\Your\Target\Key" ' 递归处理目标项及所有子项 SetPermissionsRecursive HKLM, strRegPath Sub SetPermissionsRecursive(hRootKey, strSubPath) ' 先处理当前项的权限 SetAclForKey hRootKey, strSubPath ' 获取子项列表,递归处理 objReg.EnumKey hRootKey, strSubPath, arrSubKeys If IsArray(arrSubKeys) Then For Each strSubKey In arrSubKeys SetPermissionsRecursive hRootKey, strSubPath & "\" & strSubKey Next End If End Sub Sub SetAclForKey(hRootKey, strKeyPath) ' 获取当前安全描述符 objReg.GetSecurityDescriptor hRootKey, strKeyPath, objSD ' 设置所有者为SYSTEM Set objOwner = objSD.Owner objOwner.Domain = "NT AUTHORITY" objOwner.Name = "SYSTEM" objSD.Owner = objOwner ' 添加完全控制权限规则 Set objAce = CreateObject("WbemScripting.SWbemObject") objAce.SecurityDescriptor = objSD objAce.AccessMask = &H1F003F ' 对应注册表完全控制权限 objAce.AceType = 0 ' 允许访问 objAce.AceFlags = 3 ' 权限继承给子容器和子对象 objAce.Trustee.Domain = "NT AUTHORITY" objAce.Trustee.Name = "SYSTEM" objSD.DACL.Add objAce ' 应用修改后的权限 objReg.SetSecurityDescriptor hRootKey, strKeyPath, objSD End Sub
说明:需要以SYSTEM身份运行cscript.exe来执行该脚本,比如cscript.exe fix_reg_perms.vbs。
四、Python 方案
借助pywin32库调用Windows安全API,实现递归权限修复:
import win32api import win32security import win32con def set_reg_permissions_recursive(root_key, sub_path): # 尝试打开当前注册表项 try: hkey = win32api.RegOpenKeyEx(root_key, sub_path, 0, win32con.KEY_ALL_ACCESS) except Exception as e: print(f"无法打开项 {sub_path}: {str(e)}") return # 获取当前安全描述符 sd = win32security.GetNamedSecurityInfo( hkey, win32security.SE_REGISTRY_KEY, win32security.DACL_SECURITY_INFORMATION | win32security.OWNER_SECURITY_INFORMATION ) # 设置所有者为SYSTEM system_sid = win32security.CreateWellKnownSid(win32security.WinLocalSystemSid, None) sd.SetSecurityDescriptorOwner(system_sid, False) # 添加SYSTEM的完全控制权限规则 access_rule = win32security.AccessControlEntry( system_sid, win32con.KEY_ALL_ACCESS, win32security.ACCESS_ALLOWED_ACE_TYPE, win32security.CONTAINER_INHERIT_ACE | win32security.OBJECT_INHERIT_ACE ) dacl = sd.GetSecurityDescriptorDacl() dacl.AddAccessAllowedAce(win32security.ACL_REVISION, access_rule) sd.SetSecurityDescriptorDacl(True, dacl, False) # 应用修改后的权限 win32security.SetNamedSecurityInfo( hkey, win32security.SE_REGISTRY_KEY, win32security.DACL_SECURITY_INFORMATION | win32security.OWNER_SECURITY_INFORMATION, None, None, dacl, None ) # 递归处理子项 try: subkey_count, _, _ = win32api.RegQueryInfoKey(hkey) for i in range(subkey_count): subkey_name = win32api.RegEnumKey(hkey, i) new_sub_path = f"{sub_path}\\{subkey_name}" if sub_path else subkey_name set_reg_permissions_recursive(root_key, new_sub_path) except Exception as e: print(f"遍历子项失败 {sub_path}: {str(e)}") win32api.RegCloseKey(hkey) # 示例:处理HKLM下的目标项 if __name__ == "__main__": target_root = win32con.HKEY_LOCAL_MACHINE target_path = "SOFTWARE\\Your\\Target\\Key" set_reg_permissions_recursive(target_root, target_path)
说明:需要先安装pywin32库(执行pip install pywin32),脚本会自动遍历所有子项完成权限修复。
备注:内容来源于stack exchange,提问作者Me Myself
相关产品推荐
相关产品推荐

