如果服务具有对特定文件夹的读取权限,如何在 PowerShell 中进行检查?
How do I check in PowerShell if a service has read access to a certain folder?
到目前为止,我知道要执行以下操作:
- 确定服务登录账号-
(Get-WmiObject -Query "SELECT StartName FROM win32_service where name = 'mssqlserver'").StartName
- 获取对文件夹具有读取权限的帐户 -
accesschk -q -d $env:TEMP
但这让我无处可去:
PS C:\> (Get-WmiObject -Query "SELECT StartName FROM win32_service where name = 'mssqlserver'").StartName
LocalSystem
PS C:\> accesschk -q -d $env:TEMP
c:\Users\MKHARI~1\AppData\Local\Temp
RW NT AUTHORITY\SYSTEM
RW BUILTIN\Administrators
RW DAYFORCE\mkharitonov
PS C:\> accesschk LocalSystem -q -d $env:TEMP
Accesschk v5.2 - Reports effective permissions for securable objects
Copyright (C) 2006-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
Error looking up account: LocalSystem:
The operation completed successfully.
PS C:\> accesschk "DAYFORCE\mkharitonov" -q -d $env:TEMP
RW c:\Users\MKHARI~1\AppData\Local\Temp
PS C:\>
AccessChk 似乎无法识别 LocalSystem
。另外,如果我 运行 它使用属于 BUILTIN\Administrators
的帐户,它似乎不承认访问。
这是否意味着 AccessChk 不适合这个或者我使用它有误?有没有办法在根本不尝试访问相关帐户下的文件夹的情况下做到这一点?
当 PowerShell 运行不是管理员时:
PS C:\> $service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "MSSQLSERVER"}
PS C:\> '{0:x}' -f $service.GetSecurityDescriptor().ReturnValue
80070522
PS C:\>
这对应于客户端没有所需的权限。当 PowerShell 运行 以管理员身份运行时,该命令工作正常。理想情况下,我想要一个不需要提升的解决方案。
$account = 'whatever you like'
$acl = Get-Acl 'folder'
$acl.access | where { $_.IdentityReference -like "*$account*"}).FileSystemRights
我不确定这是否适用于 PowerShell v.2,但它适用于 PowerShell v.3 及更高版本。
本地系统使用 nt authority\System 的令牌,因此此命令行可以工作(您需要在代码中将本地系统映射到系统):
accesschk.exe system -q -d $env:temp
我创建了一个片段来获取正确的名称并将其传递给 accesschk(在 PowerShell v5 中测试并需要提升访问权限):
$service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "wlidsvc"}
$desc = (($service.GetSecurityDescriptor()).Descriptor).owner
$desc.Domain + "\"+$desc.name | %{.\accesschk.exe $_ -q -d $env:temp}
$desc.Domain + "\"+$desc.name 将 return NT AUTHORITY\SYSTEM 而不是 localsystem
PS: 脚本可以优化
到目前为止,我知道要执行以下操作:
- 确定服务登录账号-
(Get-WmiObject -Query "SELECT StartName FROM win32_service where name = 'mssqlserver'").StartName
- 获取对文件夹具有读取权限的帐户 -
accesschk -q -d $env:TEMP
但这让我无处可去:
PS C:\> (Get-WmiObject -Query "SELECT StartName FROM win32_service where name = 'mssqlserver'").StartName
LocalSystem
PS C:\> accesschk -q -d $env:TEMP
c:\Users\MKHARI~1\AppData\Local\Temp
RW NT AUTHORITY\SYSTEM
RW BUILTIN\Administrators
RW DAYFORCE\mkharitonov
PS C:\> accesschk LocalSystem -q -d $env:TEMP
Accesschk v5.2 - Reports effective permissions for securable objects
Copyright (C) 2006-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
Error looking up account: LocalSystem:
The operation completed successfully.
PS C:\> accesschk "DAYFORCE\mkharitonov" -q -d $env:TEMP
RW c:\Users\MKHARI~1\AppData\Local\Temp
PS C:\>
AccessChk 似乎无法识别 LocalSystem
。另外,如果我 运行 它使用属于 BUILTIN\Administrators
的帐户,它似乎不承认访问。
这是否意味着 AccessChk 不适合这个或者我使用它有误?有没有办法在根本不尝试访问相关帐户下的文件夹的情况下做到这一点?
当 PowerShell 运行不是管理员时:
PS C:\> $service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "MSSQLSERVER"}
PS C:\> '{0:x}' -f $service.GetSecurityDescriptor().ReturnValue
80070522
PS C:\>
这对应于客户端没有所需的权限。当 PowerShell 运行 以管理员身份运行时,该命令工作正常。理想情况下,我想要一个不需要提升的解决方案。
$account = 'whatever you like'
$acl = Get-Acl 'folder'
$acl.access | where { $_.IdentityReference -like "*$account*"}).FileSystemRights
我不确定这是否适用于 PowerShell v.2,但它适用于 PowerShell v.3 及更高版本。
本地系统使用 nt authority\System 的令牌,因此此命令行可以工作(您需要在代码中将本地系统映射到系统):
accesschk.exe system -q -d $env:temp
我创建了一个片段来获取正确的名称并将其传递给 accesschk(在 PowerShell v5 中测试并需要提升访问权限):
$service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "wlidsvc"}
$desc = (($service.GetSecurityDescriptor()).Descriptor).owner
$desc.Domain + "\"+$desc.name | %{.\accesschk.exe $_ -q -d $env:temp}
$desc.Domain + "\"+$desc.name 将 return NT AUTHORITY\SYSTEM 而不是 localsystem
PS: 脚本可以优化