Bugtraq mailing list archives

Traceroute exploit details


From: pedward () WEBCOM COM
Date: Mon, 2 Oct 2000 22:18:33 -0700

Today I read up on the Solar post on heap overflows with free and looked at
traceroute again.  I decided to take the bent that it COULD be overflowed.
I found the addresses of __malloc_hook (0x40074ff8) on RH6.0 and the location
that our string gets allocated (0x804cd7a).

So, I got the SRPM for glibc and looked over the code for free.  It looked
kinda promising, excerpt:

        if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
        {
                sz += nextsz;

                if (!islr && next->fd == last_remainder(ar_ptr))
                                                      /* re-insert last_remainder */
                {
                        islr = 1;
                        link_last_remainder(ar_ptr, p);
                }
                else
                        unlink(next, bck, fwd);

                next = chunk_at_offset(p, sz);
        }

The macro 'unlink':

        /* take a chunk off a list */

        #define unlink(P, BK, FD)                                                     \
        {                                                                             \
          BK = P->bk;                                                                 \
          FD = P->fd;                                                                 \
          FD->bk = BK;                                                                \
          BK->fd = FD;                                                                \
        }                                                                             \

To make this exercise work, we would need 2 rogue malloc_chunks: rogue1 and rogue2.

The fd and bk pointers in malloc_chunk could be used for the overflow:

        struct malloc_chunk
        {
          INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
          INTERNAL_SIZE_T size;      /* Size in bytes, including overhead. */
          struct malloc_chunk* fd;   /* double links -- used only if free. */
          struct malloc_chunk* bk;
        };

In rogue 1, it would have the following values:

prev_size = "CCCC"
size      = "CCCC"
fd        = __malloc_hook - 12
bk        = 0x804cd7a + 0x20 (our rogue code)

In rogue 2, it would have the following values:

prev_size = "CCCC"      (dead value)
size      = 0xFFFFFF01  (0xFFFFFF00 & 0x01 (PREV_INUSE)
fd        = "CCCC"      (dead unused value)
bk        = "CCCC"      (dead unused value)

The first '-g' argument would look like this:

offset  value
0x00    "CCCC"
0x04    "CCCC"
0x08    __malloc_hook - 12
0x0C    0x804cd7a + 0x0F
0x10    jmp +0x0F
 |
 |      garbage
 |
0x1F
0x20
 |
 |      code to execute
 |
0xF0    "CCCC"
0xF4    0xFFFFFF01
0xF8    "CCCC"
0xFC    "CCCC"

The theory about how it works:

When the second '-g' is encountered, free() reads ptr - 0x0F for the malloc_chunk.
Our rogue2 malloc_chunk is the last bit of data, which points to the one with our
pointers, free sees that PREV_INUSE on the second chunk is 0x0, so it tries to
consolidate the chunks.  We get at the address of our rogue1 chunk by rolling over
the address space - 0xFF (for our data).  The 0x01 is to prevent backlinking of
our chunk, and it handy to get a NULL too (it gets XORed with 0x01 when the size
is calculated).

During the consolidation phase the unlink macro dorks with the chunk of memory directly
after rogue1, so you have to put a relative jump to get over it.

The rogue code appears at offset 0x20 in parameter of the first '-g' and is 208 bytes long.

I think I got all the numbers right, but I may have been off a little here or there.

I didn't actually write the code, just thought it through, but it looks like it's
exploitable to me.

I got the pointer values from an RH6.0 version, RH6.2 has the same bug, possibly the same
offsets.

Further discussion would be enlightening.

--Perry

--
Perry Harrington                 Director of                   zelur xuniL  ()
perry () webcom com             System Architecture               Think Blue.  /\


Current thread: