CVE-2012-0809 Investigation

7erry

sudo 1.8.0 到 1.8.3p1 的 sudo_debug 函数存在格式化字符串漏洞,攻击者拿到靶机的本地用户权限后可借此漏洞进行提权

影响范围

sudo 1.8.0, 1.8.1, 1.8.1p1, 1.8.1p2, 1.8.2, 1.8.3, 1.8.3p1

漏洞分析

sudo 程序是开源的,我们可以通过漏洞公告前后的源码比对定位到漏洞的位置,下以 1.8.3p1 与 1.8.3p2 的源码为例

1.8.3p1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* Simple debugging/logging.
*/
void
sudo_debug(int level, const char *fmt, ...)
{
va_list ap;
char *fmt2;

if (level > debug_level)
return;

/* Backet fmt with program name and a newline to make it a single write */
easprintf(&fmt2, "%s: %s\n", getprogname(), fmt); //! vul
va_start(ap, fmt);
vfprintf(stderr, fmt2, ap);
va_end(ap);
efree(fmt2);
}

1.8.3p2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* Simple debugging/logging.
*/
void
sudo_debug(int level, const char *fmt, ...)
{
va_list ap;
char *buf;

if (level > debug_level)
return;

/* Bracket fmt with program name and a newline to make it a single write */
va_start(ap, fmt);
evasprintf(&buf, fmt, ap);
va_end(ap);
fprintf(stderr, "%s: %s\n", getprogname(), buf);
efree(buf);
}

注意到低版本中地这两行

1
2
easprintf(&fmt2, "%s: %s\n", getprogname(), fmt); //! vul
vfprintf(stderr, fmt2, ap);

结合函数名可推断 getprogname 函数的返回值是用户可控的,它将被 easprintf 函数写入到 fmt2 变量中,并在 vfprintf 中作为格式化控制字符串输出到 stderr。若程序名包含了格式化控制字符串的相关关键字,就会导致格式化字符串漏洞

这样的漏洞成因和利用方式实在是让了解 SQL 注入等代码注入技术的人倍感亲切啊

漏洞利用

编译安装 sudo 1.8.2 后执行

1
2
ln -s /usr/local/bin/sudo %n
./%n -D9

出现

1
Segmentation fault

漏洞验证成功,再通过构造格式化控制字符串控制偏移量即可实现任意读任意写进而提权,详见国外安全研究院撰写的 Exploiting Sudo format string vunerability : VNSECURITY / CLGT TEAM

漏洞修复

在漏洞分析的源码比对中能看到修复后的版本直接使用了 %s: %s\n 进行格式化控制,避免了本漏洞的产生

Reference

NVD - CVE-2012-0809
CVE - CVE-2012-0809
Sudo - Sudo format string vulnerability
漏洞战争

  • Title: CVE-2012-0809 Investigation
  • Author: 7erry
  • Created at : 2025-01-01 18:53:57
  • Updated at : 2025-01-01 18:53:57
  • Link: https://7erryx.github.io/2025/01/01/Vulnerability Investigation/CVE-2012-0809-Investigation/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
CVE-2012-0809 Investigation