导语:对于攻击者来说,就是想方设法欺骗用户打开恶意附件或点击恶意链接。而对于安防人员来说,有一种检测攻击的办法就是所谓的“钓鱼执法”——通过向攻击者提供他们想要的服务、权限或正在寻找的信息,来让他们上钩。

几年前,我参与了几个月的企业诱捕解决方案的开发和测试项目。在此期间,我积攒了一些在活动目录中实施诱捕和钓鱼检测的经验,并意识到在活动目录中实施诱捕的关键点主要集中在honeyuser/honeytoken /honeycredentials上。像dcept等工具就是利用的这些攻击点,戴尔开源的工具称为 DCEPT(Domain Controller Enticing Password Tripwire,域控制诱导加密绊网),是一种能够用来检测尝试入侵本地Windows域和活动目录的攻击者的蜜罐服务器安全技术。如果我们想在攻击的域名枚举阶段就利用相关工具来检测出攻击,会遇到很多困难,不过这正是我本文要解决的问题。

诱捕与反诱捕的攻防游戏

对于攻击者来说,就是想方设法欺骗用户打开恶意附件或点击恶意链接。一旦进入攻击环境,攻击者就会试图截获用户的凭证,并通过其他设备来混入现有的日志和流量。

而对于安防人员来说,有一种检测攻击的办法就是所谓的“钓鱼执法”:通过向攻击者提供他们想要的服务、权限或正在寻找的信息,来让他们上钩。很多攻击者在心里上,都会天然的认为被攻击者是愚蠢的、没有防御意识的且计算机技术比较差,发现不了他们的恶意意图。通常情况下,他们认为自己也比安防人员更聪明、更有天赋。在这些心理的作用下,他们往往以为只要自己一出手,就可以迅速获得自己想要的东西,比如迅速获得Direct活动目录min权限。

所以,安防人员正是基于此向攻击者故意展示他们想看到的内容。例如,伪装成将密码设置为类似于“123…”的“弱智”用户,让他们进入到蜜罐中。

给攻击者释放的诱饵最好是以下四个:

1.攻击目标足够多,以便攻击者枚举对象;

2.易于配置;

3.攻击端不需要进行配置更改;

4.不应该触发正常的管理活动;

上面的第4点是最难实现的。如果安防人员的目标是枚举,则必须使攻击者的活动或使用的工具凸显出来,以避免误报。

部署具有诱饵属性的攻击环境

那么,我们如何通过活动目录中的内置工具实现上述攻击者所需的攻击属性呢?我们可以使用用户组策略设置ADAccess事件日志,配置攻击者感兴趣的对象并过滤掉误报信息。

活动目录访问所需的用户组策略设置过程是Windows Settings | Security Settings | Advanced Audit Policy Configuration | DS Access – Audit Directory Service Access。

1.jpg

以上设置在每次访问活动目录对象时都会导致安全事件4662,日志记录需要在对象级别进行配置。对于这种配置,我们需要修改对象的SACL并添加相关的ACE。

你可以通过查看AddAuditAccessObjectAce函数,来完整理解ACE。

2.jpg

我会在本文所讲的样本中,设置完全针对用户使用'ReadProperty''success'时的安全审计,这有助于检测针对该用户的任何枚举。

Deploy-Deception

虽然这些设置可以使用用户界面完成,但是多亏了PowerShell和ActiveDirectory模块,它才得以实现自动化。

为了自动化设置具有有趣属性和鲜为人知的属性的诱饵对象,以避免误报,我编写了Deploy-Deception。它是一个PowerShell模块,利用ActiveDirectory模块轻松高效地部署诱饵,你可以在Github上找到具体的部署过程。

下面,我会详细介绍如何在攻击的不同阶段设置不同类型的目标诱饵。

枚举:以用户对象为诱饵

用户对象是最有趣的对象,其中的一些用户属性是攻击者最感兴趣的:

1.从来没有更改过的密码或比较“弱智”的密码;

2.信任的Delegation(委托)机制, Delegation是一种实现机制:一个对象转发或者委托一个请求给另一个对象;

3.拥有SPN的用户,SPN(Service Principal name)服务器主体名称。SPN是服务在使用Kerberos身份验证的网络上的唯一标识符,它由服务类、主机名和端口用户组成;

4.被明确标记出的密码;

5.属于高权限用户组的用户;

6.对其他用户、用户组或Container(容器)对象具有ACL权限的用户;

我可以使用Deplou-UserDeception函数来创建一个含有以上诱饵因素的假用户。本文中我创建了一个名为'usermanager'的假用户,其密码从来没有更改过,如果有攻击者读取它的任何属性,就会记录在4662事件中。

PS C:\> Import-Module C:\Deploy-Deception\Deploy-Deception.psd1
PS C:\> Create-DecoyUser -UserFirstName user -UserLastName manager -Password [email protected] | Deploy-UserDeception -UserFlag PasswordNeverExpires –Verbose

4.jpg

请注意,真实的用户对象都是在域中创建的。且在实践中,上面所述的因素的触发非常频繁,因为每当有人读取用户usermanager的任何属性时,都会启用我设置的默认日志记录。这意味着即使有人简单的列出域中的所有用户,也会记录在4662。这意味着,触发以上所述诱饵的所有操作(包括正常的操作) 都会启用日志记录。比如以下操作:

1.net user /domain命令,我们在添加域用户时,有时会有用户没有添加,或者已添加的用户名拼写错误。这时,我们想查一下目前域中所有的用户,就是使用的这个命令;

2.Get-WmiObject -Class Win32_UserAccount命令,用此命令查找帐户状态($User.Status);

3.Get-ADUser -Filter * (MS ActiveDirectory module) 命令;

4.Get-NetUser (PowerView) 命令;

5.查找用户,联系人和用户组的用户界面命令;

不过,这种大范围的诱捕行为,会让我无法区分攻击者的枚举行为和正常活动行为。攻击者所使用的枚举工具有一些特别之处,就是它们喜欢尽可能多的提取攻击对象的信息(这样做是因为他们不希望重复连接到域控制器)。这意味着如果我现在要对一个不常见的属性进行触发并审计,只有通过一些枚举工具产生的枚举行为才会触发日志记录,以免存在误报。在观察了所有属性列表后,我发现有很多这样的属性,我从中选择了一个具有代表性的属性-x500uniqueIdentifier(用户界面D为 d07da11f-8a3d-42b6-b0aa-76c962be719a)

这样,我现在就可以删除之前添加的ACE了,重新添加了一个仅在x500uniqueIdentifier属性被读取时才触发日志记录的新ACE。

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 [email protected] | Deploy-UserDeception -SPN 'MSSQLSvc/dc' -GUID f3a64788-5306-11d1-a9c5-0000f80367c1 -Verbose

如果此时生成的日志记录还是让你很迷惑,那可以使用如下命令以下命令仅在读取假用户里的DACL(自由访问控制列表)诱饵属性时,才会被记录在4662事件中。

PS C:\> Create-DecoyUser -UserFirstName user -UserLastName manager-control -Password [email protected] | Deploy-UserDeception -UserFlag AllowReversiblePasswordEncryption -Right ReadControl -Verbose

枚举:以计算机对象为诱饵

我们还可以以计算机对象为诱饵,可以在域中创建假的用于诱捕的计算机对象,而不需要将真实的计算机映射到该对象中。即便如此,我还是建议使用真实的计算机或者虚拟机来部署计算机对象诱饵,以避免露馅。

攻击者感兴趣的一些计算机对象属性包括:

1.旧的操作系统;

2.有趣的SPN;

3.Delegation(委托)机制的设置;

4.具有高权限的用户组成员;

先看看如何使用Deploy-Deception模块进行的一些诱饵部署,在此期间,我可以使用Deploy-DecoyComputer函数。

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

上面的命令可以创建一个计算机对象诱饵,该对象启用了Unconstrained Delegation属性,每当有攻击者读取该对象诱饵的x500uniqueIdentifier属性或者所有相关属性时,就会被记录在4662事件中。

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

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

我还可以使用DCShadow来修改计算机对象诱饵,使其看起来像是DC(域控制器)。

枚举:以用户组对象为诱饵

我还可以以用户组对象为诱饵,攻击者感兴趣的用户组要具备以下属性:

1.有趣的名称(比如类似admins、administrators之类的名称);

2.这个用户组的成员也是高权限用户组的成员,或者具有攻击者感兴趣的用户属性;

3.具有高权限的用户组成员;

以用户组对象为诱饵是个非常有趣的诱捕方法,我可以让诱饵用户成为诱饵用户组的成员,从而创建更细致化的诱饵元素。通过这种方法,攻击者对诱饵组成员的枚举以及诱饵用户的枚举操作都会被被记录在日志里,接下来我会介绍如何使用登录限制来避免误用用户的权限,将正常的用户行为和攻击行为分开。

因此,在下面的命令中,我会创建了一个用户名为'dnsmanager'的诱饵用户组,且用户使用的密码永远有效,当攻击者读取密码时,就会被记录在相关日志中。另外,我还创建了一个名为“Forest Admins”的诱饵用户组,并假定dnsmanager用户为该组成员,将“Forest Admins”用户组加入内置的dnsadmins用户组中。一旦有人读取dnsmanager的属性,就会触发日志记录,我使用的就是Deploy-GroupDeception来完成这个过程的。

PS C:\> Create-DecoyUser -UserFirstName dns -UserLastName manager -Password [email protected] | 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

枚举和内网渗透(lateral movement):以权限用户对象为诱饵

我还可以以权限用户对象为诱饵,以监测攻击者的枚举和内网渗透)行为,具体过程就是创建具有高权限的诱饵用户,如成为域管理组的一员,具有执行DCSync的权限等。

但这种诱捕方法也存在着一定的风险,就是一旦被攻击者发现高权限用户是诱饵,则攻击者可以反过来捕获这些高权限,执行更深度的攻击。为了避免这种情况的发生,我们可以使用一些保护措施:

1.将Logon Workstation设置为一个并不是真实存在的计算机上;

2.拒绝诱饵用户的反登录;

有了上述两种保护,诱饵用户就不能使用任何类型的登陆凭证(如密码、哈希等)来登录,这意味着,攻击者无法使用诱饵用户的任何权限。

做好这些诱捕准备后,我就可以使用deploy-privilegeduserscam来创建具有高权限的用户诱饵。

PS C:\> Create-DecoyUser  -UserFirstName dec -UserLastName da -Password [email protected] | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection DenyLogon -Right ReadControl –Verbose

11.jpg

我使用上面的命令创建了一个名为“decda”的用户,并让该用户成为域管理组的一员,但该用户不能登录任何计算机。任何列出用户的DACL或列出所有属性的尝试都会导致4662日志的生成。

对于内网渗透来说,他们使用了DenyLogon保护。这意味着即使用户的密码、哈希或密钥被攻击者获取,他们也不可能重用这些凭证。为了在诱饵用户的凭证被使用期间,捕获到有意义的日志,我需要启用如下组策略:Configuration|Windows Settings|Security Settings|Advanced Audit Policy Configuration|Audit Policies|Account Logon | Audit Kerberos Authentication Service | Failure

12.jpg

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

13.jpg

虽然登陆失败,但还是会在域控制器上记录4768(故障)事件。对于像OverPass-The-Hash这样的攻击,就不会生成如此详细的错误。

另一个选项是将LogonWorkstation设置为现实中并不存在的计算机,但我们可以使用和真实主机名类似的名称。

PS C:\> Create-DecoyUser  -UserFirstName dec -UserLastName da -Password [email protected] | 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 [email protected] | Deploy-UserDeception -PasswordInDescription 'The new password is [email protected]' -Verbose
PS C:\> Deploy-PrivilegedUserDeception -DecoySamAccountName newda -Technique DomainAdminsMemebership -Protection DenyLogon -Right

上面的第一个命令负责创建一个名为“newda”的新用户,将其描述为The new password is [email protected]字符串。而第二个命令则是让“newda”成为域管理组的一员,并设置为拒绝用户登录的状态,一旦有人读取DACL或newda的所有属性,就会被记录在日志中。

由于无需使用特殊工具就可以从描述信息中获得密码,因此攻击者很容易触发这些诱饵。在讨论具有权限的用户时,还必须讨论关于ACL(访问控制列表)的问题,这个问题很重要。如果某个用户含有操控其他用户的权限,那么攻击者肯定会对这个用户感兴趣。(确保ACL的安全,包括域对象其他安全性,都是安全监控的重要一环)。

我们可以使用Deploy-SlaveDeception来设置一些诱饵用户,让其中一个用户对其他用户拥有完全控制或使用的权限。这正是攻击者感兴趣的目标,他们可以利用这些用户枚举和内网渗透。

我可以使用如下命令,捕获枚举行为。

PS C:\> Create-DecoyUser -UserFirstName master -UserLastName user -Password [email protected] | Deploy-UserDeception -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose
PS C:\> Create-DecoyUser -UserFirstName slave -UserLastName user -Password [email protected] | Deploy-UserDeception -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose
PS C:\> Deploy-SlaveDeception -SlaveSamAccountName slaveuser -DecoySamAccountName masteruser -Verbose

上面的第一个命令和第二个命令分别负责创建名为masteruser和slaveuser的用户,并且只在攻击者读取模糊属性时进行安全审核并被记录到日志中。第三个命令负责为slaveuser用户提供masteruser用户的GenericAll权限。在域中对这两个对象进行枚举或扫描感兴趣的acl的任何攻击都将触发4662事件。

为了捕获攻击者的内网渗透行为,我们可以使用masteruser的PasswordInDescription选项,或者使用其他能让攻击者容易获取诱饵用户凭证的简单方法。而我使用的是则是有点冒险的方法,就是让攻击者能截获masteruser用户的权限(请在使用前仔细考虑风险)。如果masteruser修改了slaveuser的DACL,除了在使用honeytoken/honeyuser时触发的任何其他警报外,我们还会得到一个4662日志。

PS C:\> Create-DecoyUser -UserFirstName master -UserLastName user -Password [email protected]
PS C:\> Create-DecoyUser -UserFirstName slave -UserLastName user -Password [email protected]
PS C:\> Deploy-SlaveDeception -SlaveSamAccountName slaveuser -DecoySamAccountName masteruser -Verbose
PS C:\> Deploy-UserDeception -DecoySamAccountName slaveuser -Principal masteruser -Right WriteDacl -Verbose

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

枚举:以域和域林之间的信任(ForestTrust)对象为诱饵

这个诱捕办法目前还没有实现自动化,但是有很多有趣的可能性!例如,我可以设置一个具有诱捕属性的域林之间的信任(ForestTrust) (我在本文把它称为blue forest)。攻击者可以在这个诱饵中,枚举用户、计算机和用户组,但这些对象不具有访问任何其他资源的权限。这可以通过使用选择性身份验证建立域林之间的信任来实现,我只在DC上设置了Allowed to Authenticate选项,其他主机上未设置该选项。这将允许攻击者枚举域和域林之间的信任对象,但他们不能访问其他计算机上的资源。

攻击者是否具有识破这些诱饵的能力?

那么,攻击者如何识别哪些攻击对象是真实的,哪些攻击对象是陷阱或诱饵呢?正如我在文章开头提到的,我在过去几个月里测试了多种诱捕解决方案,在这些方案中,具有许多容易被识破的诱捕对象:

1.objectSID:该对象必须转化成DomainSID-RID格式,某些企业在诱捕时,并没有这样做,往往被攻击者一眼识破。如果我们发现objectSID不包含DomainSID-RID格式,那么请仔细调查该诱饵对象。

2.lastLogon, lastlogontimestamp:用户诱饵可以通过查看这些属性来识别。如果有一个高权限的用户从未进行过登录 (lastLogon的值为31/12/1600,这比LargeInteger日期的最早时间还要早),那么它很有可能是一个诱饵。

3.logonCount:虽然不如lastLogon那么有效,但它也是一个很好的识别诱饵的方法。

4.whenCreated:它与lastLogon和logonCount对象相结合,就可以成为一个很好的识别指标。如果一个用户已经创建了很长时间,但从未登录过,那很可能就是一个诱饵。因此在真实中,企业应尽量避免使用这些僵尸或休眠用户,以防暴露自己的防御计划。

5.badPwdCount、badPasswordTime:只要是人类用户,都有大意输错密码的时候。如果某个用户从来没输错过密码(即Badpwdcount值为0,或者错误密码属性异常),那么很可能这是一个诱饵对象。

6.将很多诱饵对象的属性同时集中设置在一起:真正的攻击目标是不会有这么多攻击属性的,建议企业不要刻意对一个诱饵对象设置太多诱捕属性,这也很容易被发现。

最好的识别方法就是将怀疑是诱饵的对象与正常运行的对象进行比较,例如,如果攻击者怀疑域中所有计算机列表中的某个计算机对象是一个诱饵,那么他们就会将其与域控制器的属性或当前所使用的设备属性进行比较。真实的dc总是在logonserver环境变量中列出。真实的DC始终位于logonserver环境变量中。对于用户对象,内置DA的RID始终为500,攻击者可以将其与他们怀疑的某个用户对象进行比较。

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

攻击者如何避过诱捕进行攻击?

我开头就讲过,攻击者总是认为用户目标或安防人员都是“弱智”,只要他们一出手就没有办不成的事情,除了这种优越心里外,他们还喜欢坐享其成。殊不知,骄兵必败,因此,攻击者需要改变他们的狂妄心态,在复杂的企业网络中行动时,加着几分小心。

1.企业网络通常都非常复杂,如果轻而易举的获取自己的攻击目标,则要提高警惕;

2.避免使用自动化枚举工具,除非攻击者非常了解这些工具在后台的工作原理;

3.避免获取DA权限的诱惑,专注本身的攻击目标,因为DA权限是攻击者渴望获取的最高权限,对于此诱惑,一般人很难抗拒。

安防人员如何防止自己设置的诱饵被识别

如果使用真实的域对象,被识别出的概率就会减少。例如,没有映射到真实计算机的计算机对象,就很容易被识别出来。

如前所述,对于诱饵用户对象,至少要让其经常进行登录会话操作,避免其成为僵尸用户。

让我们看一个简单的例子,有一个著名的诱饵识别脚本叫做HoneypotBuster。现在让我会创建一个诱饵DA,并运行此脚本进行识别。

18.jpg

可以发现,我设置的诱饵DA被发现了。Deploy-PrivilegedUserDeception有一个选项'CreateLogon',此参数使用诱饵DA用户启动和停止DC上的计算器,填充用户的登录相关属性。而如果要使用此参数,必须将LogonWorkstation保护设置为执行模块的DC,这样你就可以随时更改用户的行为。

PS C:\> Create-DecoyUser -UserFirstName dec -UserLastName da -Password [email protected] | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection LogonWorkStation -LogonWorkStation revert-dc -CreateLogon –Verbose

我可以使用如上命令会创建名为decda的用户,使其成为Domain Admins组的一员,不过我会限制其登录到DC,之后,我使用该用户创建一个登录会话,这样就会在DC上创建配置文件。现在,如果运行HoneypotBuster,看看此诱饵能否被发现。

20.jpg

可以看到,FakeRank诱饵对象的怀疑度被降到了50。HoneypotBuster使用了一个排名系统来评测诱饵对象的伪造度,如果一个用户的logonCount小于6,那么肯定是诱饵。如果我将decda的logonCount设置为6,用它的凭证启动这个进程6次,那么它就不会被怀疑了。

PS C:\> Create-DecoyUser -UserFirstName dec -UserLastName da -Password [email protected] | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection LogonWorkStation -LogonWorkStation revert-dc -CreateLogon -logonCount 6 -Verbose

21.jpg

很明显,现在如果我运行HoneypotBuster, 就会发现它并没有检测到decda! 

不过这是针对HoneypotBuster工具的避免被识破的办法,未来我还将致力于使用虚拟化技术来部署诱饵,比如借助OU对象。OU(Organizational Unit,组织单位)是可以将用户、组、计算机和其它组织单位放入其中的AD容器,是可以指派组策略设置或委派管理权限的最小作用域或单元。通俗一点说,如果把AD比作一个公司的话,那么每个OU就是一个相对独立的部门。

如果想对本文的讲述有更直观的了解,请查看我在BruCON上的演讲文稿以及相关视频

源链接

Hacking more

...