TUCoPS :: Linux :: Apps N-Z :: bt1429.txt

traceroute local root


This is a multi-part message in MIME format.

------=_NextPart_000_013A_01C39ED0.7B389DC0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit


----- Original Message -----
From: "assasa sasasaaa" <bazrar@hotmail.com>
To: <bugtraq@securityfocus.com>
Sent: Thursday, June 19, 2003 10:09 PM
Subject: BAZARR FAREWELL


> local root advisory. bye
>
> _________________________________________________________________
> MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*.
> http://join.msn.com/?page=features/virus
>


/* traceroute local root advisory     */
/* by: bazarr       */
/* bazrar@hotmail.com      */
/* bazarr episode #*       */

------------------
PREFACE

its me bazarr. i dont use ziplip anymore. resend any emails sent to
bazarr@ziplip
to bazrar@hotmail.com if i dident respond to them. this is a local root
vulnerability
in the traceroute shipped with alot of distros and operating systems.
and ya its really the real bazarr.

lets take a look at the vendor info:

/*
* traceroute host  - trace the route ip packets follow going to "host".
*
* Attempt to trace the route an ip packet would follow to some
* internet host.  We find out intermediate hops by launching probe
* packets with a small ttl (time to live) then listening for an
* icmp "time exceeded" reply from a gateway.  We start our probes
* with a ttl of one and increase by one until we get an icmp "port
* unreachable" (which means we got to "host") or hit a max (which
* defaults to 30 hops & can be changed with the -m flag).  Three
* probes (change with -q flag) are sent at each ttl setting and a
* line is printed showing the ttl, address of the gateway and
* round trip time of each probe.  If the probe answers come from
* different gateways, the address of each responding system will
* be printed.  If there is no response within a 5 sec. timeout
* interval (changed with the -w flag), a "*" is printed for that
* probe.
*/

around the time of the get_origin() bug found by Carl Livitt, debian
released a patch for that bug
and a few other little problems in traceroute which noone really bothered to
talk about i guess.
but uh lets take a look at the source code for a second. this is after
applying the patch by debian
to secure traceroute from buffer overflows.

#define SPRAYMAX 256            /* We'll only do up to 256 TTLs at once */
struct {
        u_long  dport;          /* check for matching dport */
        u_char  ttl;            /* ttl we sent it to */
        u_char  type;           /* icmp response type */
        struct  timeval out;    /* time packet left */
        struct  timeval rtn;    /* time packet arrived */
        struct  sockaddr_in from; /* whom from */
} spray[SPRAYMAX];
int *spray_rtn[SPRAYMAX];       /* See which TTLs have responded */

...

                        case 'S':
                                argc--, AbortIfNull((++av)[0]);
                                min_ttl = atoi(av[0]);
                                if ((min_ttl < 0) || (min_ttl > max_ttl)) {
                                        Fprintf(stderr, "min ttl must be
 >=%d%s and >0",max_ttl,terminator);
                                        exit(1);
                                }
                                goto nextarg;
                        case 'm':
                                argc--, AbortIfNull((++av)[0]);
                                max_ttl = atoi(av[0]);
                                if (max_ttl < min_ttl) {
                                        Fprintf(stderr, "max ttl must be
 >%d%s",min_ttl,terminator);
                                        exit(1);
                                }
                                goto nextarg;

...

                        case 'P':
                                spray_mode = 1;
                                break;
                        case 'f':
                                argc--, AbortIfNull((++av)[0]);
                                sport = atoi(av[0]);
                                goto nextarg;
                        case 'q':
                                argc--, AbortIfNull((++av)[0]);
                                nprobes = atoi(av[0]);
                                if (nprobes < 1) {
                                        Fprintf(stderr, "nprobes must be
 >0%s",terminator);
                                        exit(1);
                                }
                                goto nextarg;
...


        /* Prevent overflow of spray[] array */
        if (spray_mode && (nprobes*max_ttl > SPRAYMAX)) {
                Fprintf(stderr, "too many spray packets\n");
                exit(1);
        }

now what is the first thing we see here. we can control 'nprobes' ,
'min_ttl' and 'max_ttl'
with any values we want. now debian added this code at the end here with
their patch trying to
prevent overflow of the spray[] array i guess. well lets take a look

bazarr:traceroute-nanog-6.1.1$ ./traceroute -P -q 256 -m 2147483648
google.com
traceroute to google.com (216.239.33.100), 2147483647 hops max, 40 byte
packets
Segmentation fault
bazarr:traceroute-nanog-6.1.1$

since we can control max_ttl and nprobes all we have to do is make sure that
the equation

"nprobes * max_ttl"

will result in an int wrap around and become < SPRAYMAX (256)
which is really easy since its not checking that the value is not < 0 it can
just be negative.

now lets take a look at some of our options after we bypass its little check
we go back to the land of source code once again:


   if (!spray_mode) {
      /* For all TTL do */

...


} else {

/*
* Enter Spray mode
*/
   spray_target = spray_max = spray_total = 0;
   spray_min = SPRAYMAX+1;

   /* For all TTL do */
   for (ttl = min_ttl; ttl <= max_ttl; ++ttl) {
      spray_rtn[ttl] = (int *)malloc(sizeof(int)*nprobes + 1);
      for (probe = 0; probe < nprobes; ++probe) {
             spray_rtn[ttl][probe]=0;
         send_probe(++seq, ttl);
      }
   }

what we can see here is multiple possibliltys.

spray_rtn[ttl] = (int *)malloc(sizeof(int)*nprobes + 1);

since we can control 'ttl' this tells us we can write a 4 byte ptr anywhere
we want.
only thing is that it will be to a 4 byte aligned address so modifying parts
of a ret address is out of the question.
and we cannot control the data at the ptr we are able to write so putting
shellcode their is out of the question.

so this line tells us we can write a 4 byte ptr returned by malloc anywhere
we want , but we can also
force the malloc call to fail and write a 4 byte NULL anywhere we want
easily since we can control nprobes
we can make it a pretty big number , bigger then the system can alloc so
malloc will fail and return NULL.

this line also tells us since we can control nprobes we can force malloc to
alloc too low by supplying a big
value to nprobes , this isnt that great of an option though.

also if we write a NULL then

spray_rtn[ttl][probe] = 0;

is bound to fail with an access violation.

so with that line we can either write a really big number or a really small
number anywhere we want on a 4 byte align.
since we cant control the data at the addr we can write its kind of useless.
but what about
writing a big number somewhere which would cause another bug? or a small
number?

lets take a look at the send_probe() function for a sec:

send_probe(seq, ttl)
int ttl;
int seq;
{
        struct opacket *op = outpacket;
        struct ip *ip = &op->ip;
        struct udphdr *up = &op->udp;
        int i;

      retry:
        if (mtudisc) {
          ip->ip_off = (short) IP_DF;
        }
        else {
          ip->ip_off = 0;
        }

        ip->ip_p = IPPROTO_UDP;
#ifndef BYTESWAP_IP_LEN
        ip->ip_len = ((u_short)datalen-_optlen);   /*  The OS inserts
options  */
#else /* BYTESWAP_IP_LEN */
        ip->ip_len = htons((u_short)datalen-_optlen);   /*  The OS inserts
options  */
#endif /* BYTESWAP_IP_LEN */
        ip->ip_ttl = ttl;
        ip->ip_v = IP_VERSION;
        ip->ip_hl = sizeof(*ip) >> 2;

        up->uh_sport = htons(ident);
        up->uh_dport = htons(port+seq);
        up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip) -
_optlen));
        up->uh_sum = 0;

        op->seq = seq;
        op->ttl = ttl;
#ifndef __linux__
        (void) gettimeofday(&op->tv, NULL);
#else /* __linux__ */
        (void) gettimeofday(&op->tv, &tz);
#endif /* __linux__ */

#ifdef SPRAY
        if (spray_mode) {
           spray[seq].dport = up->uh_dport;
           spray[seq].ttl   = ttl;
           bcopy(&op->tv, &spray[seq].out, sizeof(struct timeval));
        }

....

now we can write past spray[] essentially because 'seq' will be bigger then
its sposed to be cuz we can control the value of 'nrpobes'.
but we cant write all that much data we want to or even where we want to
really. so we can write our 4 byte ptr from above to 'outpacket'
which will point outpacket to a spot in the heap and then we can make
'nprobes' a low number like 4 forcing it to malloc pretty low.
then it will be writing a shit load of data on the heap in spots its not
sposed to.

if your gunna try and xploit this bug you probly know your options anyways
and i probly missed alot. but
as you can see there are alot of possibilitys to xploiting this bug. if you
do manage to xploit this bug it probly
will be a combination of things inside traceroute to lead to code exec.

------------------
PATCH

:`(

------------------
XPLOIT

:`(

------------------
ADVANCE WARNING

nothing is comming for you anymore.

------------------
GREETS

sad cow - hi sad cow.
dethy - hehe :)
#!FHAB - im all by myself in there on ircs somtimes
puppy of the rain forest - why dont you return my friendly email ? :(
dave aitel - for sending 2 nice emails to me :)
archim - hi
morgan - for telling me he dont really care about anything i do , and
refusing to be a big brother twards me , why morgan why JUST GIMMIE A
REASON!
spender - for nice conversation with lonely young boy.
bighawk - for taking out cryptome.org

i sent alot of emails to various people saying 'hi' and noone responded
accept 2 people. thank you hendy. thank you anonymous p59_9 author.

------------------
BYE

what in the fuck was i thinking doing somthing like this.
i cant even belive i actually went through with all this.

you aint gunna be seeing bazarr around for long time.
sorry for disruptence. no hard feelings.

farewell.

-bazarr



------=_NextPart_000_013A_01C39ED0.7B389DC0
Content-Type: text/plain;
	name="bazarr.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="bazarr.txt"

/* traceroute local root advisory	 			*/
/* by: bazarr							*/
/* bazrar@hotmail.com						*/
/* bazarr episode #*	 					*/

------------------
PREFACE

its me bazarr. i dont use ziplip anymore. resend any emails sent to=20
bazarr@ziplip
to bazrar@hotmail.com if i dident respond to them. this is a local root=20
vulnerability
in the traceroute shipped with alot of distros and operating systems.
and ya its really the real bazarr.

lets take a look at the vendor info:

/*
* traceroute host  - trace the route ip packets follow going to "host".
*
* Attempt to trace the route an ip packet would follow to some
* internet host.  We find out intermediate hops by launching probe
* packets with a small ttl (time to live) then listening for an
* icmp "time exceeded" reply from a gateway.  We start our probes
* with a ttl of one and increase by one until we get an icmp "port
* unreachable" (which means we got to "host") or hit a max (which
* defaults to 30 hops & can be changed with the -m flag).  Three
* probes (change with -q flag) are sent at each ttl setting and a
* line is printed showing the ttl, address of the gateway and
* round trip time of each probe.  If the probe answers come from
* different gateways, the address of each responding system will
* be printed.  If there is no response within a 5 sec. timeout
* interval (changed with the -w flag), a "*" is printed for that
* probe.
*/

around the time of the get_origin() bug found by Carl Livitt, debian=20
released a patch for that bug
and a few other little problems in traceroute which noone really =
bothered to=20
talk about i guess.
but uh lets take a look at the source code for a second. this is after=20
applying the patch by debian
to secure traceroute from buffer overflows.

#define SPRAYMAX 256            /* We'll only do up to 256 TTLs at once =
*/
struct {
        u_long  dport;          /* check for matching dport */
        u_char  ttl;            /* ttl we sent it to */
        u_char  type;           /* icmp response type */
        struct  timeval out;    /* time packet left */
        struct  timeval rtn;    /* time packet arrived */
        struct  sockaddr_in from; /* whom from */
} spray[SPRAYMAX];
int *spray_rtn[SPRAYMAX];       /* See which TTLs have responded */

...

                        case 'S':
                                argc--, AbortIfNull((++av)[0]);
                                min_ttl =3D atoi(av[0]);
                                if ((min_ttl < 0) || (min_ttl > =
max_ttl)) {
                                        Fprintf(stderr, "min ttl must be =

 >=3D%d%s and >0",max_ttl,terminator);
                                        exit(1);
                                }
                                goto nextarg;
                        case 'm':
                                argc--, AbortIfNull((++av)[0]);
                                max_ttl =3D atoi(av[0]);
                                if (max_ttl < min_ttl) {
                                        Fprintf(stderr, "max ttl must be =

 >%d%s",min_ttl,terminator);
                                        exit(1);
                                }
                                goto nextarg;

...

                        case 'P':
                                spray_mode =3D 1;
                                break;
                        case 'f':
                                argc--, AbortIfNull((++av)[0]);
                                sport =3D atoi(av[0]);
                                goto nextarg;
                        case 'q':
                                argc--, AbortIfNull((++av)[0]);
                                nprobes =3D atoi(av[0]);
                                if (nprobes < 1) {
                                        Fprintf(stderr, "nprobes must be =

 >0%s",terminator);
                                        exit(1);
                                }
                                goto nextarg;
...


        /* Prevent overflow of spray[] array */
        if (spray_mode && (nprobes*max_ttl > SPRAYMAX)) {
                Fprintf(stderr, "too many spray packets\n");
                exit(1);
        }

now what is the first thing we see here. we can control 'nprobes' ,=20
'min_ttl' and 'max_ttl'
with any values we want. now debian added this code at the end here with =

their patch trying to
prevent overflow of the spray[] array i guess. well lets take a look

bazarr:traceroute-nanog-6.1.1$ ./traceroute -P -q 256 -m 2147483648=20
google.com
traceroute to google.com (216.239.33.100), 2147483647 hops max, 40 byte=20
packets
Segmentation fault
bazarr:traceroute-nanog-6.1.1$

since we can control max_ttl and nprobes all we have to do is make sure =
that=20
the equation

"nprobes * max_ttl"

will result in an int wrap around and become < SPRAYMAX (256)
which is really easy since its not checking that the value is not < 0 it =
can=20
just be negative.

now lets take a look at some of our options after we bypass its little =
check
we go back to the land of source code once again:


   if (!spray_mode) {
      /* For all TTL do */

...


} else {

/*
* Enter Spray mode
*/
   spray_target =3D spray_max =3D spray_total =3D 0;
   spray_min =3D SPRAYMAX+1;

   /* For all TTL do */
   for (ttl =3D min_ttl; ttl <=3D max_ttl; ++ttl) {
      spray_rtn[ttl] =3D (int *)malloc(sizeof(int)*nprobes + 1);
      for (probe =3D 0; probe < nprobes; ++probe) {
             spray_rtn[ttl][probe]=3D0;
         send_probe(++seq, ttl);
      }
   }

what we can see here is multiple possibliltys.

spray_rtn[ttl] =3D (int *)malloc(sizeof(int)*nprobes + 1);

since we can control 'ttl' this tells us we can write a 4 byte ptr =
anywhere=20
we want.
only thing is that it will be to a 4 byte aligned address so modifying =
parts=20
of a ret address is out of the question.
and we cannot control the data at the ptr we are able to write so =
putting=20
shellcode their is out of the question.

so this line tells us we can write a 4 byte ptr returned by malloc =
anywhere=20
we want , but we can also
force the malloc call to fail and write a 4 byte NULL anywhere we want=20
easily since we can control nprobes
we can make it a pretty big number , bigger then the system can alloc so =

malloc will fail and return NULL.

this line also tells us since we can control nprobes we can force malloc =
to=20
alloc too low by supplying a big
value to nprobes , this isnt that great of an option though.

also if we write a NULL then

spray_rtn[ttl][probe] =3D 0;

is bound to fail with an access violation.

so with that line we can either write a really big number or a really =
small=20
number anywhere we want on a 4 byte align.
since we cant control the data at the addr we can write its kind of =
useless.=20
but what about
writing a big number somewhere which would cause another bug? or a small =

number?

lets take a look at the send_probe() function for a sec:

send_probe(seq, ttl)
int ttl;
int seq;
{
        struct opacket *op =3D outpacket;
        struct ip *ip =3D &op->ip;
        struct udphdr *up =3D &op->udp;
        int i;

      retry:
        if (mtudisc) {
          ip->ip_off =3D (short) IP_DF;
        }
        else {
          ip->ip_off =3D 0;
        }

        ip->ip_p =3D IPPROTO_UDP;
#ifndef BYTESWAP_IP_LEN
        ip->ip_len =3D ((u_short)datalen-_optlen);   /*  The OS inserts=20
options  */
#else /* BYTESWAP_IP_LEN */
        ip->ip_len =3D htons((u_short)datalen-_optlen);   /*  The OS =
inserts=20
options  */
#endif /* BYTESWAP_IP_LEN */
        ip->ip_ttl =3D ttl;
        ip->ip_v =3D IP_VERSION;
        ip->ip_hl =3D sizeof(*ip) >> 2;

        up->uh_sport =3D htons(ident);
        up->uh_dport =3D htons(port+seq);
        up->uh_ulen =3D htons((u_short)(datalen - sizeof(struct ip) -=20
_optlen));
        up->uh_sum =3D 0;

        op->seq =3D seq;
        op->ttl =3D ttl;
#ifndef __linux__
        (void) gettimeofday(&op->tv, NULL);
#else /* __linux__ */
        (void) gettimeofday(&op->tv, &tz);
#endif /* __linux__ */

#ifdef SPRAY
        if (spray_mode) {
           spray[seq].dport =3D up->uh_dport;
           spray[seq].ttl   =3D ttl;
           bcopy(&op->tv, &spray[seq].out, sizeof(struct timeval));
        }

....

now we can write past spray[] essentially because 'seq' will be bigger =
then=20
its sposed to be cuz we can control the value of 'nrpobes'.
but we cant write all that much data we want to or even where we want to =

really. so we can write our 4 byte ptr from above to 'outpacket'
which will point outpacket to a spot in the heap and then we can make=20
'nprobes' a low number like 4 forcing it to malloc pretty low.
then it will be writing a shit load of data on the heap in spots its not =

sposed to.

if your gunna try and xploit this bug you probly know your options =
anyways=20
and i probly missed alot. but
as you can see there are alot of possibilitys to xploiting this bug. if =
you=20
do manage to xploit this bug it probly
will be a combination of things inside traceroute to lead to code exec.

------------------
PATCH

:`(

------------------
XPLOIT

:`(

------------------
ADVANCE WARNING

nothing is comming for you anymore.

------------------
GREETS

sad cow - hi sad cow.
dethy - hehe :)
#!FHAB - im all by myself in there on ircs somtimes
puppy of the rain forest - why dont you return my friendly email ? :(
dave aitel - for sending 2 nice emails to me :)
archim - hi
morgan - for telling me he dont really care about anything i do , and=20
refusing to be a big brother twards me , why morgan why JUST GIMMIE A=20
REASON!
spender - for nice conversation with lonely young boy.
bighawk - for taking out cryptome.org

i sent alot of emails to various people saying 'hi' and noone responded=20
accept 2 people. thank you hendy. thank you anonymous p59_9 author.

------------------
BYE

what in the fuck was i thinking doing somthing like this.
i cant even belive i actually went through with all this.

you aint gunna be seeing bazarr around for long time.
sorry for disruptence. no hard feelings.

farewell.

-bazarr


------=_NextPart_000_013A_01C39ED0.7B389DC0--

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH