Re: [Vuln-Dev Challenge] - VulnDev1.c Summary

From: Joel Eriksson (je-vulndev_at_bitnux.com)
Date: 05/21/03

  • Next message: Jeremy Junginger: "CORRECTION: vulndev1.c solution (WARNING! QUESTIONS!)"
    Date: Wed, 21 May 2003 11:25:45 +0200
    To: Aaron Adams <aadams@securityfocus.com>
    
    
    

    On Tue, May 20, 2003 at 05:19:16PM -0600, Aaron Adams wrote:
    > I have not been able to figure out why 0x4 and 0x5 will trigger a segfault
    > during the second free() as I would expect their behavior to mimic those
    > values above. Especially since they also only consume the 3 least
    > significant bits of buf2 [SIZE]. Any takers?

    Well, here is what's happening during the second free() in glibc-2.3.1 anyway:

    (gdb) n
    3333 ar_ptr = arena_for_chunk(p);
    (gdb) x/4i$pc
    0x40092c64 <__libc_free+84>: and $0x4,%edx
    0x40092c67 <__libc_free+87>: je 0x40092cb2 <__libc_free+162>
    0x40092c69 <__libc_free+89>: and $0xfff00000,%eax
    0x40092c6e <__libc_free+94>: mov (%eax),%edi
    (gdb) i r edx eax
    edx 0x104 260
    eax 0x8049bd0 134519760
    (gdb)

    Relevant snippets of code:

    arena.c:

      #define heap_for_ptr(ptr) \
       ((heap_info *)((unsigned long)(ptr) & ~(HEAP_MAX_SIZE-1)))
      #define arena_for_chunk(ptr) \
       (chunk_non_main_arena(ptr) ? heap_for_ptr(ptr)->ar_ptr : &main_arena)

    malloc.c:

      #define NON_MAIN_ARENA 0x4
      /* check for chunk from non-main arena */
      #define chunk_non_main_arena(p) ((p)->size & NON_MAIN_ARENA)

    0x4 and 0x5 both have the NON_MAIN_ARENA-bit set in the chunk size,
    which is stored in register %edx in the asm-dump from gdb shown above.
    As you probably have figured out, the pointer p is stored in %eax and
    is a pointer to the start of the chunk, e.g. the pointer returned by
    malloc(), minus 8.

    Thus, if the NON_MAIN_ARENA-bit is set (size & 4), chunk_non_main_arena(ptr)
    evaluates to a non-zero value (namely, 4) and arena_for_chunk(p) is evaluated
    to heap_for_ptr(ptr)->ar_ptr.

    As you can see in the definition of heap_for_ptr() it will locate the heap_info
    struct by doing bitwise-anding ptr with ~(HEAP_MAX_SIZE-1). HEAP_MAX_SIZE is
    defined to 1024*1024 = 1048576. With a little bash-magic we'll find out this:

    [je@vudo ~]$ printf "%08x\n" $[~(1024*1024-1)&0xffffffff]
    fff00000

    Which explains this:

    0x40092c69 <__libc_free+89>: and $0xfff00000,%eax

    And since %eax = p = 0x8049bd0 bitwise-anded with 0xfff00000 is 0x08000000
    we get a segmentation fault when trying to move a word of data from that,
    unmapped, address. That is, when the following is executed:

    0x40092c6e <__libc_free+94>: mov (%eax),%edi

    Btw, was I excluded from the summary because of my sarcastic comments towards
    the majority of the readers, that thought the idea of the challenge was to find
    the rather obvious faulty for-loop or because you overlooked my exploit when
    summarizing the thread?

    Anyway, here's a helper for my exploit for the dummies out there:

       #!/bin/bash
       [ $# -ge 1 ] && VULN=$1 || VULN=./vulndev-1; shift
       [ $# -ge 1 ] && EXPL=$1 || EXPL=./expldev-1; shift
       ADDR=`printf "0x%08X" $[0x$(objdump -R $VULN | awk '$3 == "free" { print $1 }') - 8]`
       exec $EXPL $VULN $ADDR

    For the actual exploit, look in the archives.

    > Aaron Adams

    -- 
    Joel Eriksson <je@mensa.se>
    -------------------------------------------------
    Cellphone: +46-70-288 64 16 Home: +46-26-10 23 37
    Security Research & Systems Development at Bitnux
    PGP Key Server pgp.mit.edu, PGP Key ID 0x529FDBD1
    A615 A1E1 3CA2 D7C2 CFEA 47B4 7EF7 E6B2 529F DBD1
    -------------------------------------------------
    
    



  • Next message: Jeremy Junginger: "CORRECTION: vulndev1.c solution (WARNING! QUESTIONS!)"

    Relevant Pages

    • Panic on CURRENT
      ... GNU gdb 6.1.1 ... page fault while in kernel mode ... instruction pointer = 0x20:0xc0716dd2 ... frame pointer = 0x28:0xf8d80bc4 ...
      (freebsd-current)
    • Re: Shellcode itself segfaults
      ... a pointer to the string '/bin/sh' in the ... ebx register, a pointer to a pointer to char, however this ... You have an option to go with a managed service or an enterprise software. ...
      (Pen-Test)
    • Re: kernel problem
      ... > i have done a kgdb on the dumps it gave out here is the output ... > Unread portion of the kernel message buffer: ... GNU gdb 6.1.1 ... instruction pointer = 0x20:0xc08badd7 ...
      (freebsd-stable)
    • Re: Format of Pointers in Unix
      ... >>All unixes I've seen use a flat memory model for user space applications. ... Pointer Test Code. ... GDB is free software, covered by the GNU General Public License, and you are ... FreeBSD does use a segmented memory model of some sort. ...
      (comp.lang.c)
    • Re: Format of Pointers in Unix
      ... >>All unixes I've seen use a flat memory model for user space applications. ... Pointer Test Code. ... GDB is free software, covered by the GNU General Public License, and you are ... FreeBSD does use a segmented memory model of some sort. ...
      (comp.unix.programmer)