如何实现sudo提权漏洞cve - 2021 - 3156的利用及分析

  

如何实现sudo提权漏洞CVE-2021-3156的利用及分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

0x01 漏洞背景

sudo程序存在一个高危安全漏洞,漏洞编号为CVE-2021-3156,非root用户可通过执行“sudoedit -s”和以单个'\'结尾的命令行参数利用漏洞,获取root权限。

该漏洞NVD的打分为 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H,最终得分为7.8分。

漏洞影响范围为:

sudo 1.8.2-1.8.31p2

sudo 1.9.0-1.9.5p1

0x02 漏洞成因及利用说明

sudo sudoers.c源文件中的set_cmnd()函数在拷贝参数时,由于错误处理'\',造成堆写越界的问题,攻击者可通过控制参数和环境变量向特定堆地址之后的内存中写入任意长度的数据,其中包括'\0'。

该漏洞存在多种利用方式,常见利用方式包括:

1、通过堆溢出覆盖process_hooks_getenvsudo_hook_entry结构体的函数指针,进而通过execve()`函数执行代码得到root权限。

2、通过堆溢出覆盖glibcnss_load_library()函数ni结构体,进而通过__libc_dlopen()加载恶意动态库,执行代码得到root权限。

由于不同版本的环境上执行时,堆内存分布不同,发生溢出的缓冲区大小、溢出长度、环境变量等参数需要模糊测试或暴力破解等方式得到,本文分析的是第二种利用方式。

0x03 漏洞调试分析

使用execve()函数执行系统中的/usr/bin/sudoedit,并将payload通过参数变量char *sudo_argv[]和环境变量char *sudo_envp[]进行传递。(这里使用execve()的目的是为了便于控制执行时的env环境变量。)

execve("/usr/bin/sudoedit", sudoargv, sudoenvp);

char *sudo_argv[]char *sudo_envp[]值分别如下。

如何实现sudo提权漏洞CVE-2021-3156的利用及分析

如何实现sudo提权漏洞CVE-2021-3156的利用及分析

sudo.cmain()函数先调用paese_args()解析运行状态并转义特殊字符,然后调用set_cmnd()函数。set_cmnd()函数存在堆溢出漏洞,可向堆中写入任意长的数据。

main()函数首先调用parse_args.c中的parse_args()函数。

main(int argc, char *argv[], char *envp[])
  {
  ,,,int  nargc,,好的,,status =, 0;
  ,,,char  * * nargv,, * * env_add;
  ,,,sudo_mode =, parse_args(命令行参数个数,argv,,, nargc,,, nargv,,,设置,,,env_add);
  …
  }

该函数处理如下。

1,根据用户执行命令及相关参数对<代码>模式及<代码>标记标志位进行赋值。

2,根据<代码>模式及<代码>标记标志位的值,判断是否需要对<代码> & # 39;\ & # 39;等特殊字符进行转义。

3,对参数数量变量<代码> int nargc> char * * nargv 进行赋值。

4,将<代码>模式|旗帜> sudo_mode>

攻击者执行<强> sudoedit (- s shell)文件强命令时,<代码> parse_args() 函数会判断用户命令行输入的执行文件名<代码> char * progname> 字符串,如果是则将<代码> int模式> MODE_EDIT * *(该宏为<强> 0 x02 ),然后使用<代码>开关()语句判断参数是否包含* * & # 39;s # 39; <>强,如果是则将<代码> int旗帜> MODE_SHELL * *(该宏为<强> 0 x20000 )。

 # define  default_valid_flags (MODE_BACKGROUND | MODE_PRESERVE_ENV | MODE_RESET_HOME | MODE_LOGIN_SHELL | MODE_NONINTERACTIVE | MODE_SHELL)
  
  int
  命令行参数个数,parse_args (int  char  * * argv,, int  * nargc,, char  * * * nargv,
  ,,,struct  sudo_settings  * * settingsp, char  * * * env_addp)
  {
  ,,,struct  environment  extra_env;
  ,,,int  mode =, 0;
  ,,,int  flags =, 0;
  ,,,int  valid_flags =, DEFAULT_VALID_FLAGS;
  …
  ,,,if  (4, proglen 的在,,,,,比较字符串(时间+ progname  proglen 作用;4,“edit"),==, 0), {
  时间=progname “sudoedit";
  时间=mode  MODE_EDIT;
  sudo_settings [ARG_SUDOEDIT] .value =,“true";
  ,,,}
  …
  ,,,if  ((=ch  getopt_long (argv,命令行参数个数,还以为,short_opts, long_opts,, NULL)), !=, 1), {
  ,,,switch  (ch), {
  ,,,,case  & # 39; & # 39;:
  ,,,sudo_settings [ARG_USER_SHELL] .value =,“true";
  ,,,集(旗帜,MODE_SHELL);
  ,,,休息;
  ,,,}
  …
  }

如何实现sudo提权漏洞cve - 2021 - 3156的利用及分析