如何为服务帐户授予远程windows服务控制权限

roejwanj  于 2023-10-22  发布在  Windows
关注(0)|答案(1)|浏览(107)

我正在设置一个由服务帐户运行的定期任务,该任务需要在不同时间停止/启动远程计算机上的服务。服务帐户不需要管理员权限,只需访问所需的服务。使用subinacl赠款服务特定的权限,但似乎没有授予远程管理它所需的所有权限。
我使用subinacl.exe通过subinacl.exe /service \\machine\myservice /GRANT=Domain\SVCAccount=TOP授予帐户停止/启动权限,并将该帐户添加到远程计算机的远程管理用户组,以便它可以通过命令行命令访问它。
当我运行

Invoke-Command -Credential $SVCcredential -ComputerName server -ScriptBlock {Restart-Service service}

我得到错误找不到任何服务名称为'name'的服务。我对此进行了一些研究,发现人们正在讨论SC_ENUMERATE_SERVICE权限,但我无法找到一种方法来将该权限授予非交互式用户。我确信服务的名称是正确的,因为从invoke-command中删除了帐户凭据,并以自己的方式运行它。
我也试过使用net stop/start作为服务帐户,它不会返回错误,但也不会重新启动服务。它似乎什么都不做。
我错过了一些简单的subinacl.exe,将解决这个问题?

pgvzfuti

pgvzfuti1#

微软service-security-and-access-rights
当通过CreateService函数安装服务时,SCM将创建服务对象的安全描述符。服务对象的默认安全描述符赠款以下访问权限。

远程认证用户:默认情况下不授予。

  • Windows Server 2003 SP1:SERVICE_USER_DEFINED_CONTROL
  • Windows Server 2003和Windows XP:经过身份验证的远程用户的访问权限与经过身份验证的本地用户相同。

当使用Invoke-Command时,它可能就像是一个“远程身份验证用户”,因此除非您的服务帐户是本地组(如“administrators”)的成员,否则您不太可能被授予重新启动服务的权限。
不过,这应该可以使用您的服务帐户与任务调度程序,因为服务帐户应被视为“本地身份验证用户”。默认情况下,“本地身份验证用户”在服务上具有READ_CONTROL权限(除非服务上的安全性描述符已更改)。
本地身份验证用户(包括LocalService和NetworkService)
READ_CONTROL
服务_枚举_依赖
服务_询问
服务_查询_配置
服务_查询_状态
SERVICE_USER_DEFINED_CONTROL
您需要检查您的服务帐户是否被授予以下权限:

  • “作为批处理作业登录”安全权限(使用本地策略或组策略)。

要进行测试,我建议您使用Get-Service,同时在远程计算机上交互式登录或使用任务调度程序启动测试PowerShell脚本。如果非交互式连接(使用任务调度程序),您也可以使用Start-Transcript来获取一些输出。
如果要检查服务的安全描述符,您可以使用:用途:

sc sdshow wuauserv

然后,您可以在PowerShell中转换SDDL表单:可能有备用代码/方法可用,甚至有一个我不知道的专用库。

$sd = [System.Security.AccessControl.RawSecurityDescriptor]::new("D:(A;;RPWPDT;;;WD)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)")

我不想去安全描述符。但它就像文件和文件夹上的安全描述符。但面具(或权利)有其他含义。每个服务都有一个安全描述符,用于授予对特定操作的访问权限。

$sd.DiscretionaryAcl | Select-Object AceType, AccessMask, @{l='Identity'; e={[System.Security.Principal.SecurityIdentifier]::new($_.SecurityIdentifier).Translate([System.Security.Principal.NTAccount])}}

通过示例,结果如下:

AceType AccessMask Identity                
------- ---------- --------                
AccessAllowed        112 Everyone                
AccessAllowed     131469 NT AUTHORITY\INTERACTIVE
AccessAllowed     131469 NT AUTHORITY\SERVICE    
AccessAllowed     131581 NT AUTHORITY\SYSTEM     
AccessAllowed     983551 BUILTIN\Administrators

如果我们进一步挖掘,将这个掩码转换成一个更可读的形式:

$rights = @{
    SERVICE_ALL_ACCESS = 0xF01FF 
    SERVICE_CHANGE_CONFIG = 0x0002 
    SERVICE_ENUMERATE_DEPENDENTS = 0x0008 
    SERVICE_INTERROGATE = 0x0080 
    SERVICE_PAUSE_CONTINUE = 0x0040 
    SERVICE_QUERY_CONFIG = 0x0001 
    SERVICE_QUERY_STATUS = 0x0004 
    SERVICE_START = 0x0010 
    SERVICE_STOP = 0x0020 
    SERVICE_USER_DEFINED_CONTROL= 0x0100 
    DELETE = 0x10000 
    READ_CONTROL = 0x20000 
    WRITE_DAC = 0x40000 
    WRITE_OWNER = 0x80000 
    GENERIC_READ = 0x0001 + 0x0004 + 0x0080 + 0x0008 
        <#
         STANDARD_RIGHTS_READ
        SERVICE_QUERY_CONFIG
        SERVICE_QUERY_STATUS
        SERVICE_INTERROGATE
        SERVICE_ENUMERATE_DEPENDENTS
         #>
    GENERIC_WRITE = 0x0002
        <#
        STANDARD_RIGHTS_WRITE
        SERVICE_CHANGE_CONFIG
        #>
    GENERIC_EXECUTE = 0x0010 + 0x0020 + 0x0040 + 0x0100
        <#
        STANDARD_RIGHTS_EXECUTE
        SERVICE_START
        SERVICE_STOP
        SERVICE_PAUSE_CONTINUE
        SERVICE_USER_DEFINED_CONTROL
        #>
}

$sd.DiscretionaryAcl | Select-Object AceType, `
    @{l='Rights'; e={
        foreach($key in $rights.Keys) {
            if (($_.AccessMask -band $rights[$key]) -eq $rights[$key]) {
                $key
            }
        }
     }}, `
     @{l='Identity'; e={[System.Security.Principal.SecurityIdentifier]::new($_.SecurityIdentifier).Translate([System.Security.Principal.NTAccount])}}

结果如下:

AceType Rights                                                                                                     Identity                
      ------- ------                                                                                                     --------                
AccessAllowed {SERVICE_PAUSE_CONTINUE, SERVICE_STOP, SERVICE_START}                                                      Everyone                
AccessAllowed {SERVICE_USER_DEFINED_CONTROL, SERVICE_QUERY_STATUS, SERVICE_INTERROGATE, SERVICE_ENUMERATE_DEPENDENTS...} NT AUTHORITY\INTERACTIVE
AccessAllowed {SERVICE_USER_DEFINED_CONTROL, SERVICE_QUERY_STATUS, SERVICE_INTERROGATE, SERVICE_ENUMERATE_DEPENDENTS...} NT AUTHORITY\SERVICE    
AccessAllowed {SERVICE_USER_DEFINED_CONTROL, SERVICE_PAUSE_CONTINUE, SERVICE_QUERY_STATUS, SERVICE_INTERROGATE...}       NT AUTHORITY\SYSTEM     
AccessAllowed {GENERIC_WRITE, SERVICE_USER_DEFINED_CONTROL, SERVICE_PAUSE_CONTINUE, SERVICE_QUERY_STATUS...}             BUILTIN\Administrators

有了这些知识,你就可以检查你的服务是否有默认的安全描述符。这里存在“Everyone”特殊组,通常也适用于“远程身份验证用户”。如果“Everyone”组不适用于“远程身份验证用户”,我会有点困惑。因此,对于这个特定的服务“wuauserv”(Windows更新服务),任何经过身份验证的用户都应该被授予重新启动它的权利。
另一个技巧是使用命令whoami /all检查您的服务帐户属于哪个组,如果:

  • 使用Invoke-Command
  • 运行任务

最后,您最终可以修改“服务”安全描述符,以显式地授予您的服务帐户停止和启动服务的权利。我不会深入讨论细节,你必须更新安全描述符的SDDL格式并使用sc sdset命令。

相关问题