攻防对抗:活动目录中的欺骗技术

阅读量    36720 | 评论 2   稿费 200

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

一、前言

我对欺骗技术一直非常感兴趣,作为军事历史专业的学生,我一直对战争中的欺骗技巧非常着迷,认为欺骗是非常有效且成本较低的一个策略。

几年前,我参与了一系列企业欺骗方案的开发和测试(从红队视角出发),大概持续几个月时间。2018年年初,在一次活动目录(Active Directory,AD)课程中,有个学生向我咨询,希望我能测试他们正在评估的3种欺骗产品。

在这些经验的帮助下,我发现AD中的欺骗技巧主要集中在蜜罐用户(honeyuser)、蜜罐令牌(honeytokens)以及蜜罐凭据(honeycredentials)上,类似dcept之类的工具较好地实现了这些场景,非常受人们欢迎。然而如果我们想利用欺骗技巧,在域枚举攻击阶段成功检测攻击者,那么相关资料就有所匮乏。这正是本文即将解决的一个问题。

另外,为了吸引人们的兴趣以及社区的参与,几周前(2018年10月)我在BruCON上发表了主题为“Forging Trusts for Deception in Active Directory”的一次演讲,相关演示文档及视频会在文末给出。

 

二、欺骗技术

欺骗是一种心理学游戏。红队以及攻击者长期以来一直使用这种方法来诱导毫无戒心的用户打开恶意附件或者点击恶意链接。在AD环境中,攻击者会尝试使用其他用户的凭据,利用其他主机来混淆已有的日志和流量。

蓝队会为攻击者提供他们感兴趣的服务、权限或者信息来利用欺骗技巧。据我看来,不管从心理学和技术控制层面来讲,蓝队在欺骗方面会占据上风。

 

三、攻击者心理

有一种心理状态为“错觉优势”,这种心理状态适用于大多数攻击者和红队,他们认为自己比蓝队更加聪明、更有才华。随之而来的结果是,他们会倾向于摘取“触手可及的果实”,迫切想获取DA(域管)权限,这也使得他们容易成为欺骗技术的手下败将。

因此,有个想法应运而生,防御方可以为攻击者展示他们想要看到的东西。比如,密码永不过期的用户或者运行Server 2003的某台主机。

 

四、诱饵的吸引力

根据我的演讲文稿,我认为诱饵的吸引力属性应该具备如下几个特点:

1、应该具有足够的吸引力,使得攻击者会去枚举该对象;

2、应该很容易配置;

3、端点不需要更改任何配置;

4、不会被正常的管理员活动触发。

第4点最难实现。如果我们的目标是攻击者的枚举行为,那么必须使攻击者的活动或使用的工具脱颖而出,避免出现误报。

 

五、部署欺骗环境

那么我们如何通过AD中的内置工具实现如上所需的属性?我们可以使用组策略来设置AD访问日志记录功能,配置“有趣的”对象并且过滤掉误报信息。

设置AD访问所需的组策略具体路径位于:Windows Settings | Security Settings | Advanced Audit Policy Configuration | DS Access – Audit Directory Service Access。

经过上述配置后,当AD对象被访问时就会生成Security日志中的4662事件。我们需要在对象级别上配置日志记录选项,具体而言,我们需要修改对象的SACL属性并添加相关的ACE属性。

我们来看一下AddAuditAccessObjectAce函数,以便理解ACE:

因此,我们可以为某个用户设置审计规则,在everyone使用ReadProperty“成功”访问该用户时,检测到针对该用户的任何枚举操作。

 

六、Deploy-Deception

我们可以通过GUI完成这些设置,由于PowerShell和ActiveDirectory模块的强大功能,以上操作可以自动化完成。

为了自动设置具有有趣属性和其他不常用属性的诱饵对象,避免误报,我开发了一个PowerShell模块:Deploy-Deception,该模块利用ActiveDirectory模块来轻松且高效地部署诱饵,大家可以通过Github下载该工具。

接下来看一下如何在不同的攻击阶段设置不同类型的诱饵对象。

枚举用户对象诱饵

用户(User)对象是最为有趣的对象,攻击者比较感兴趣某些用户属性:

1、密码永不过期;

2、可信委派

3、拥有SPN的用户

4、描述中包含密码

5、属于高权限组的用户

6、对其他用户、组或者容器具有ACL权限的用户

我们可以使用Deplou-UserDeception函数来创建诱饵用户。比如,我们创建一个usermanager诱饵用户,其密码永不过期,当任何人读取该用户属性时就会生成4662事件。

PS C:\> Import-Module C:\Deploy-Deception\Deploy-Deception.psd1
PS C:\> Create-DecoyUser -UserFirstName user -UserLastName manager -Password Pass@123 | Deploy-UserDeception -UserFlag PasswordNeverExpires -Verbose

注意此时域中的确会创建一个实际用户。由于我们启用了默认日志功能,当任何人读取usermanager用户的任何属性时都会触发告警。这意味着即使有人只是简单罗列域的所有用户,也会生成4662事件。也就是说,许多行为(包括正常或者其他行为)都会触发该诱饵,比如如下行为:

net user /domain
Get-WmiObject -Class Win32_UserAccount
Get-ADUser -Filter * (MS ActiveDirectory module)
Get-NetUser (PowerView)
GUI界面查找Users、Contacts以及Groups信息

这并非我们想要的结果,因此我们需要找到方法将攻击者的枚举行为与正常活动区分开来。攻击者所使用的枚举工具有一些非常有趣的特征,他们喜欢尽可能多地提取对象的信息(这是因为他们不想重复连接到域控制器)。现在这一点意味着如果我们审计某个不常见的属性,那么很有可能(可能还存在误报)只有动作较大的枚举操作才会触发日志记录。有许多属性满足条件,观察所有属性列表后,我选定了这样一个属性:x500uniqueIdentifier(GUID为d07da11f-8a3d-42b6-b0aa-76c962be719a)。

因此,现在我们可以移除前面添加的ACE,添加一个新的规则,只有当x500uniqueIdentifier属性被读取时才触发日志记录:

PS C:\> Deploy-UserDeception -DecoySamAccountName usermanager -RemoveAuditing $true -Verbose
PS C:\> Deploy-UserDeception -DecoySamAccountName usermanager -UserFlag PasswordNeverExpires -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose

只有类似PowerView之类的工具(或者类似ADExplorer之类的其他工具)才会触发审核规则,这些工具会获取对象的所有属性。虽然现在仍不完美,但我们已经取得了巨大的进步。

如果我们有足够的信心,确定我们的监控或者管理工具不会读取用户对象的所有属性,那么我们也可以设置类似SPN之类的属性,只有当读取SPN(或者所有属性)时才会触发日志记录。

PS C:\> Create-DecoyUser -UserFirstName user -UserLastName manager-spn -Password Pass@123 | Deploy-UserDeception -SPN 'MSSQLSvc/dc' -GUID f3a64788-5306-11d1-a9c5-0000f80367c1 -Verbose

如果生成的日志还是较多,我们可以使用如下命令,只有当诱饵用户对象的DACL(或者所有属性)被读取时才会记录4662事件:

PS C:\> Create-DecoyUser -UserFirstName user -UserLastName manager-control -Password Pass@123 | Deploy-UserDeception -UserFlag AllowReversiblePasswordEncryption -Right ReadControl -Verbose

枚举计算机对象诱饵

我们也可以设置计算机(Computer)对象诱饵。我们可以在域中创建计算机对象,无需将一台实际的计算机映射到该对象。即便如此,我还是建议使用真实的计算机或者虚拟机来部署计算机对象诱饵,避免被攻击者识别真相。

攻击者对计算机对象的某些属性比较感兴趣:

1、老版本的操作系统

2、有趣的SPN

3、委派设置

4、高权限组成员

我们可以使用如下Deploy-DecoyComputer函数来部署诱饵对象:

PS C:\> Create-DecoyComputer -ComputerName revert-web -Verbose | Deploy-ComputerDeception -PropertyFlag TrustedForDelegation -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a  -Verbose

如上命令可以创建一个诱饵计算机,该对象启用了Unconstrained Delegation属性,每当读取该计算机的x500uniqueIdentifier属性或者所有属性时就会记录日志。

PS C:\> Deploy-ComputerDeception -DecoyComputerName comp1 -PropertyFlag TrustedForDelegation -Right ReadControl -Verbose

如上命令使用的是现有的计算机对象,设置Unconstrained Delegation属性。每当读取计算机的DACL或者所有属性时就会记录日志。

我们也可以使用DCShadow来修改某个计算机对象,使其看起来像是DC(域控制器)。我在这篇文章中简要介绍了相关内容,改天会详细讨论这个话题。

枚举组对象诱饵

我们也可以部署组(Group)对象诱饵。攻击者比较感兴趣的属性包括:

1、有趣的组名(包含类似admins、administrators之类的名字)

2、该组成员也是高权限组的成员或者具备“有趣的”用户属性

3、高权限组成员

组为我们提供了有趣的机会。我们可以在诱饵组中包含诱饵用户,创建“层次化”诱饵。通过这种方法,我们可以记录下攻击者对诱饵组成员的枚举以及诱饵用户的枚举操作。接下来我们可以看到如何使用登录(Logon)限制来避免对用户权限的错误使用。

在如下命令中,我们创建了一个诱饵用户dnsmanager,其密码永不过期,当读取隐藏属性时会记录相关日志。我们也创建了名为Forest Admins的一个组,dnsmanager用户为该组成员,将Forest Admins组加入内置的dnsadmins组中。当该组的成员被读取时就会触发日志记录。我们可以使用Deploy-GroupDeception来完成这个任务:

PS C:\> Create-DecoyUser -UserFirstName dns -UserLastName manager -Password Pass@123 | Deploy-UserDeception -UserFlag PasswordNeverExpires -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose 

PS C:\> Create-DecoyGroup -GroupName 'Forest Admins' -Verbose | Deploy-GroupDeception -AddMembers dnsmanager -AddToGroup dnsadmins -GUID bc0ac240-79a9-11d0-9020-00c04fc2d4cf -Verbose

枚举特权用户对象诱饵及横向渗透

我们也可以部署高权限用户诱饵来针对枚举及横向渗透行为。我们可以创建具备高权限的一个诱饵用户,比如属于与管理员组,可以执行DCSync等等。

使用高权限的的诱饵用户有些风险,如果这类用户被攻击者突破,那么其权限可能被滥用。为了避免出现这种情况,我们可以使用几种保护措施:

1、将其Logon Workstation属性设置为不存在的一台主机;

2、拒绝该用户登录。

在以上两种情况下,由于诱饵用户不能使用任何类型的凭据(如密码、哈希等)来登录,因此攻击者无法使用该用户的权限。

了解这些知识后,现在我们可以使用Deploy-PrivilegedUserDeception来创建高权限诱饵用户:

PS C:\> Create-DecoyUser  -UserFirstName dec -UserLastName da -Password Pass@123 | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection DenyLogon -Right ReadControl -Verbose

如上命令创建了名为decda的用户,该用户属于Domain Admins组,但无法登录到任何主机。一旦有人尝试列出用户的DACL或者列出所有属性,就会生成4662事件。

在横向渗透方面,我们使用了DenyLogon防护方案。这意味着即便用户的密码或哈希或者密钥被攻击者获取,他们还是无法复用这些凭据。为了在该用户的凭据被使用时获得有意义的日志,我们需要启用如下组策略:

Configuration|Windows Settings|Security Settings|Advanced Audit Policy Configuration|Audit Policies|Account Logon | Audit Kerberos Authentication Service | Failure

登录失败的界面如下图所示:

并且域控上会记录下4768错误事件。如果是类似OverPass-The-Hash之类的攻击行为,就不会生成如此详细的错误。

另一个选项是将LogonWorkstation设置为不存在的一台主机。我们可以采用与实际主机名类似的一个名字。

PS C:\> Create-DecoyUser  -UserFirstName dec -UserLastName da -Password Pass@123 | Deploy-PrivilegedUserDeception-Technique DCSyncRights -Protection LogonWorkStation revert-webserver1 -Right ReadControl -Verbose

如上命令会创建名为decda的一个诱饵用户,该用户具备DCSync权限,其LogonWorkStation设置为不存咋的某台主机。如果攻击者获取并复用了用户凭据,就会出现与DenyLogon类似的错误并生成4768事件。

我们也可以对非域管账户使用这两种保护措施。从我的观点来看,在内存中留下错误的密码或者哈希可能更好(这是大家已知的一种技术)。

这种技术可以与其他技术相结合。比如,当我们的目标是横向渗透行为时,更简单的一种方法就是在Deploy-UserDeception中使用-PasswordInDescription选项,让攻击者能够“获取”诱饵用户的凭据。然后,我们可以让该用户成为特权用户,使用前面讨论的几种保护措施:

PS C:\> Create-DecoyUser  -UserFirstName new -UserLastName da -Password Pass@123 | Deploy-UserDeception -PasswordInDescription 'The new password is Pass@123' -Verbose

PS C:\> Deploy-PrivilegedUserDeception -DecoySamAccountName newda -Technique DomainAdminsMemebership -Protection DenyLogon -Right ReadControl -Verbose

如上第一条命令会创建名为newda的用户,其描述为The new password is Pass@123字符串。第二条命令会让newda用户成为域管组的一员,拒绝该用户登录,并且一旦newda用户的DACL或者所有属性被读取就会触发告警。

攻击者无需使用特殊工具就可以从描述信息中获得密码!这也是攻击者倾向于摘取“触手可及的果实”的一种表现。

在讨论具备权限的用户时,还有另一个方面我们要关注,即ACL方面的内容。如果某个用户具备操控其他用户的有趣权限,那么攻击者肯定会对这类用户感兴趣(备注:我们要确保对ACL的审核也是安全方法的一部分内容,不管是域对象还是其他安全性)。

我们可以使用Deploy-SlaveDeception来部署一些诱饵用户,其中某个用户具备其他用户的FullControl/GenericAll权限。攻击者会对此感兴趣,我们可以利用该环境来捕获枚举操作以及横向渗透行为。

为了捕获枚举操作,我们可以使用如下命令:

PS C:\> Create-DecoyUser -UserFirstName master -UserLastName user -Password Pass@123 | Deploy-UserDeception -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose

PS C:\> Create-DecoyUser -UserFirstName slave -UserLastName user -Password Pass@123 | Deploy-UserDeception -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose

PS C:\> Deploy-SlaveDeception -SlaveSamAccountName slaveuser -DecoySamAccountName masteruser -Verbose

上面第一条以及第二条命令会分别创建masteruser以及slaveuser用户,仅在读取某个属性时会触发审计规则。第三条命令会为masteruser提供slaveuserGenericAll权限。一旦攻击者枚举或者扫描域中这两个用户的ACL时就会触发4662事件。

在横向渗透方面,我们可以为masteruser使用PasswordInDescription选项,或者使用其他常用的方法让攻击者容易获取该用户凭据。我们已经准备好让攻击者获取和使用masteruser的凭据(在此之前请仔细考虑风险)。如果masteruser修改slaveuser的DACL,除了用户或令牌被使用的警告以外,我们还会得到4662事件:

PS C:\> Create-DecoyUser -UserFirstName slave -UserLastName user -Password Pass@123

PS C:\> Deploy-SlaveDeception -SlaveSamAccountName slaveuser -DecoySamAccountName masteruser -Verbose

PS C:\> Deploy-UserDeception -DecoySamAccountName slaveuser -Principal masteruser -Right WriteDacl -Verbose

在如上命令中,一旦masteruser修改slaveuser的DACL,就会生成4662事件。

枚举域及森林信任对象

这部分内容尚未实现自动化,但依然有很多有趣的可能性。比如,我们可以构造一个信任森林(forest)诱饵(这里我们称之为蓝色森林),其中我们允许对用户、计算机以及组的枚举,但拒绝对其他资源的访问。我们可以使用选择性认证来设置森林信任关系,其中在DC上设置了Allowed to Authenticate选项,其他主机上未设置该选项。这样攻击者就可以枚举对象,但无法访问其他计算机上的资源。

 

七、红队的复仇

识别欺骗环境

那么红队如何识别那些对象是真实的,哪些对象是陷阱或者诱饵?我们在文章开头提到过,我在过去几个月内测试了多种欺骗方案。有许多企业解决方案所使用的对象可以通过对象的属性进行识别,其中部分属性包括:

1、objectSID:该对象必须具有DomainSID-RID格式。某些企业解决方案并没有满足该格式。如果我们发现某个对象的SID并不包含域SID,那么请仔细调查该对象。

2、lastLogonlastlogontimestamp:我们可以查看这些属性来识别诱饵用户。如果某个高权限用户从来没登录过(lastLogon的值为31/12/1600,这比LargeInter日期的最早时间还要早),那么很有可能这是一个诱饵用户。

3、logonCount:虽然不如lastLogon好使,logonCount还是一个不错的指标。

4、whenCreated:与lastLogonlogonCount结合起来就会成为一个很好的指标。如果某个用户创建时间非常早,但从来没登录过,那很有可能是个诱饵。我们可能会注意到该用户可能是一个休眠用户,因此请务必查看其他属性。

5、badPwdCountbadPasswordTime:大家应该都输错过密码。如果某个用户从来没输错过密码(Badpwdcount值为0,或者其他字段值异常),那么这也是很好的一个指标。

6、过多的属性:某些企业解决方案会为某个对象填满所有属性,或者填充过多属性。我们很容易发现这一点。

最好的方法是将某个对象将已知的某个“良民”对象进行匹配。比如,如果我们怀疑所有计算机列表中的某个计算机对象是一个诱饵,那么可以将其与域控制器或者我们当前所使用的节点进行比较。实际的DC始终位于logonserver环境变量中。对于用户对象,内置DA的RID始终为500,我们可以将其属性与我们怀疑的某个用户对象进行对比。

如果某些解决方案不会在域中创建真实的对象,那么我们可以使用WMIC来获取域信息,显示正确的对象,排除伪造的对象。

避免被欺骗

红队需要改变他们的方法和虚幻的优越心理,以避免上当受骗:

1、停止摘取“触手可及的果实”。企业网络非常复杂,但如果事情看起来过于简单,那么请保持警惕。

2、避免使用自动化枚举工具,除非我们完全知道这些工具在后台的工作流程。

3、我一直在演讲和培训中强调一点:抑制获取DA权限的冲动,专注于我们的行动目标。

 

八、蓝队应避免被识别

如果使用真实的域对象,那么被识别的概率就会减少。比如,如果某个计算机对象没有映射到某台真实的计算机,那么就有较高的概率被攻击者识别。

对于用户诱饵,前面我们讨论过,这些用户至少应该具有一个登录会话,这样可以减少被识别的几率。下面我们来试一下。

我们来看一下一个简单的例子。大家都知道有个简单识别欺骗环境的脚本:HoneypotBuster。现在我们创建一个DA诱饵,运行该脚本:

脚本会检测到我们的DA诱饵用户。Deploy-PrivilegedUserDeception中有一个选项CreateLogon,这个参数可以使用DA诱饵用户在DC上启动和停止计算器程序,以便填充用户登录相关属性。要使用该参数,我们必须将LogonWorkstation属性设置为待操作的DC。后面我们可以随时修改该用户的行为。

PS C:\> Create-DecoyUser -UserFirstName dec -UserLastName da -Password Pass@123 | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection LogonWorkStation -LogonWorkStation revert-dc -CreateLogon -Verbose

如上命令会创建decda用户,使其成为Domain Admins组的一员,限制其登录到DC,创建一个登录会话(这样也会在DC上创建配置文件)。现在,如果我们运行HoneypotBuster

非常好,该工具的FakeRank指数已经下降到50。HoneypotBuster使用了一个排名系统来评测对象,如果用户的logonCount小于6,那么就有可能是一个伪造用户。如果我们使用decda的凭据启动某个进程6次,那么其logonCount就会变成6,不会出现在该工具的输出结果中。

PS C:\> Create-DecoyUser -UserFirstName dec -UserLastName da -Password Pass@123 | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection LogonWorkStation -LogonWorkStation revert-dc -CreateLogon -logonCount 6 -Verbose

现在如果我们运行HoneypotBuster,就会发现它并没有检测到decda。但这种方法针对的是这款特定工具,因此我们不会过多讨论这种“绕过”细节。

 

九、下一步工作

如果你愿意在域环境中部署诱饵并与我分享结果,那将是非常棒的一件事。通过这种方法,即便你无法在代码方面做出贡献,也能极大地帮助该项目。

不久的将来,我会在这款工具中纳入OU对象。我也正在研究如何自动化部署域和信任森林诱饵,我雄心勃勃,想使用虚拟化技术来实时部署诱饵森林以及计算机。

主要内容就是这些。感谢大家阅读本文,如果需要可以获取我在BruCON上的演讲文稿以及视频

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多