3 Things today — Pt. 12
1 thing: Compiling 64-bit GDB
2 : Analyzing how the heap could be brute-forced in this exploit.
3: Discovering that the address returned by malloc is consistent across runs, on different machines!! With different UTMPX file sizes!! AWESOME!! The stack doesn’t have to be brute-forced!!! I will over-write the LD linker thing to point to the UTMPX-Shellcode which is located in the heap offsetted by the recorded malloc return address entry and blam!! We are singing!! <3
3-2) in summary, if you have read access to the executable it can be copied and debugged to find the base malloc offset to aid in one-timing a heap-based overflow on a NX stack-based executable/OS. If the exe is not readable, but there is an executable stack, you're still in luck! And can execute directly into a giant NOP sled...
Even if the exe is not readable, it can always become readable by installing an identical copy of the OS in your lab.. :)
Another thing I double checked, ulab, blade72, blade60 all have the same exact copy of /usr/bin/sparcv7/w
I expect the 64-bit version to be the same as well..
Solaris 10 doesn't seem to have the 32-bit W...
Solaris 10 patch:
$NetBSD: patch-ob,v 1.1 2008/01/06 19:25:10 rillig Exp $ gcc4 complained: gdbtypes.c:2961: error: invalid lvalue in increment --- include/obstack.h.orig 2001-01-21 00:02:00.000000000 +0000 +++ include/obstack.h 2007-11-30 21:04:44.000000000 +0000 @@ -421,7 +421,7 @@ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ _obstack_newchunk (__o, sizeof (void *)); \ - *((void **)__o->next_free)++ = ((void *)datum); \ + *((*(void ***)&(__o->next_free)))++ = ((void *)datum); \ (void) 0; }) # define obstack_int_grow(OBSTACK,datum) \ @@ -429,7 +429,7 @@ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ if (__o->next_free + sizeof (int) > __o->chunk_limit) \ _obstack_newchunk (__o, sizeof (int)); \ - *((int *)__o->next_free)++ = ((int)datum); \ + *((*(int **)&(__o->next_free)))++ = ((int)datum); \ (void) 0; }) # define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
1. Let’s compile GDB 5.3 (same as 32bit present on blade72) without intl errors:
export CC=”gcc -m64″
./configure –prefix=/home/bazz/tools –with-included-gettext –disable-nls
# on my Solaris 10 box:
ln -s /opt/csw/bin/gar /opt/csw/bin/ar
3: Analysis of Heap address space in 64-bit version vs. 32 bit.. and across machines…
64:
Mapped address spaces: Start Addr End Addr Size Offset Flags 0x100000000 0x100003fff 0x4000 0 ----r-x 0x100102000 0x100103fff 0x2000 0x2000 ----rwx 0x100104000 0x10011bfff 0x18000 0 --b-rwx 0xffffffff7ef00000 0xffffffff7ef01fff 0x2000 0 ----rwx 0xffffffff7f000000 0xffffffff7f003fff 0x4000 0 ----r-x 0xffffffff7f100000 0xffffffff7f101fff 0x2000 0 ----rwx 0xffffffff7f200000 0xffffffff7f2b5fff 0xb6000 0 ----r-x 0xffffffff7f3b6000 0xffffffff7f3c3fff 0xe000 0xb6000 ----rwx 0xffffffff7f3c4000 0xffffffff7f3c5fff 0x2000 0 ----rwx 0xffffffff7f500000 0xffffffff7f501fff 0x2000 0 ----rwx 0xffffffff7f600000 0xffffffff7f62dfff 0x2e000 0 ----r-x 0xffffffff7f72e000 0xffffffff7f731fff 0x4000 0x2e000 ----rwx 0xffffffff7fffc000 0xffffffff7fffffff 0x4000 0xffffe000 -s--rw- (gdb) p/x $o0 $1 = 0x100115c00 (gdb)
$o0 is malloc return pointer in heap space..
32
(gdb) p/x $o0 $4 = 0x30770 (gdb) info proc map process 14893 flags: PR_STOPPED Process (LWP) is stopped PR_ISTOP Stopped on an event of interest PR_RLC Run-on-last-close is in effect PR_FAULTED : Incurred a traced hardware fault FLTBPT: Breakpoint trap Mapped address spaces: Start Addr End Addr Size Offset Flags 0x10000 0x13fff 0x4000 0 ----r-x 0x22000 0x23fff 0x2000 0x2000 ----rwx 0x24000 0x33fff 0x10000 0 --b-rwx 0xff280000 0xff32bfff 0xac000 0 ----r-x 0xff33c000 0xff343fff 0x8000 0xac000 ----rwx 0xff370000 0xff371fff 0x2000 0 ----rwx 0xff380000 0xff383fff 0x4000 0 ----r-x 0xff390000 0xff391fff 0x2000 0 ----rwx 0xff3b0000 0xff3dffff 0x30000 0 ----r-x 0xff3e0000 0xff3e1fff 0x2000 0x30000 ----rwx 0xff3e2000 0xff3e3fff 0x2000 0 ----rwx 0xffbee000 0xffbeffff 0x2000 0 -s--rwx (gdb)
I found that on 64 bit address, the offset returned by malloc from heap_start is 0x11C00.
Whereas on 32 bit, it was 0xC770.. No correlation there I don’t thnk..
BUT MOST IMPORTANTLY — will that offset ALWAYS be MAINTAINED???
If so, we can reliably predict where in the heap our SHELLCODE UTMPX ENTRY resides :D
I just tested on Blade72 vs. Blade71. Although they are very similar machines, they both start up the heap at the same spot!! <3 Ulab also does its heap at teh same spot.. So does blade60.. 0x30770 Of course, I am debugging these binaries without the SUID bit set.. I copied them into my home directory.. I wonder if the thing would stay the same with it set??? I also note that the Sparcv7 binary of W has it's stack space NX by default! regardless of system setting?? The 64bit malloc base address is the same on blade72 and ulab as well.. 0x100115c00 Geeze :D -- with this ability to debug the program being consistent across to the SUID execution (will be checked on LIFE).. then that means holy cow!! <3 We can have an NX heap-based execution of shellcode that is 100% reliable :D
Leave a Reply