Dailydave mailing list archives

Re: re: PaX PoC-exploit.


From: Sinan Eren <sinan.eren () immunitysec com>
Date: Fri, 7 May 2004 16:42:57 -0400 (EDT)


Ouch, that hurt. :) It wasn't meant to be revolutionary though, just a PoC
implementation of something that has been known but ignored for years. Btw,
everyone already knows you have godlike skills, noir. You don't have to put
down us lesser beings to prove it. :)

first of all i personally did not aim to hurt your feelings or 
underestimate your skills. i truely found your PoC much pointless compared 
to what those 2 phrack articles* against PaX has to offer and say.

*http://www.phrack.org/show.php?p=59&a=9
 http://www.phrack.org/show.php?p=58&a=4

second i dont think cynicism is your best virtue.

Indeed. So I spent some time discussing it with pipacs (the PaX-developer
that replied to my PaX-PoC mail) and decided to implement it myself.

i am not quite sure whats up with this revealing the handle game is about.
i guess you're using Dave's unmask or something ....



thanks for the following! it's highly informative. bypassing no-exec can 
be a big deal if you're stuck in a no-exec chroot jail with a tmp/ 
directory and have a kernel sploit handy.


First I made a statically compiled executable that simply did "Hello
World".

Then I made another program that:

1. Read the elf header of the statically compiled executable
2. Read the program headers
3. Removed the executable-flag from the PT_LOAD-segments
4. Wrote the altered program header table to the end of the file
5. Appended a new PT_LOAD-segment with:
      p_*addr = 0xbfff0000
      p_*sz = 0xffff
      p_align = 0x1000 (runtime-linker will complain if this is less than a page)
      p_offset = file offset to filepos after this segment, rounded up to page size
6. Wrote the payload to perform a return-into-mprotect() and do:
      mprotect(0x8048000, <size-of-textsegment>, PF_R|PF_W)
   and then return into the original entry-point of the program
7. Updated the elf header with the new program header offset and number (phoff/phnum)

I got the address to mprotect() by searching the output of
"objdump -d /lib/ld-linux.so.2" for movl $0x7d,%eax followed
by an int $0x80 (0x7d = the syscall number of mprotect()).
The runtime-linker is statically compiled of course, so I
could not literally return into mprotect() in libc.

I did get it to return where I wanted it to, but it crashed
for some unknown reason. :P I returned into a piece of code
that looked like this:

    8b 54 24 10             mov    0x10(%esp,1),%edx
    8b 4c 24 0c             mov    0xc(%esp,1),%ecx
    8b 5c 24 08             mov    0x8(%esp,1),%ebx
    b8 7d 00 00 00          mov    $0x7d,%eax
    cd 80                   int    $0x80

It crashed on the first of those instructions. According to gdb the
stack pointer pointed into valid data so I actually have no idea why
it caused a crash.

However.. Since readable pages are executable on x86 (when PaX or
similar patches does not work around it) I don't really have to
mprotect() the pages. So, I modified my PoC to simply remove the
executable-flag (PF_X) from all program headers (including PT_PHDR,
why is that executable at all btw, it's just a string?).

The segments are mmap()'ed without PROT_EXEC, but since it's x86 it
doesn't matter. Nice and simple. I have verified that this technique
works in practice for bypassing noexec-mounts with at least kernel 2.4.26.

Summary. When doing this:

   /lib/ld-linux.so.2 /path/to/file/on/noexec/fs

The linux-kernel disallows the mmap() of the executable textsegment:

   mmap2(0x8048000, 16384, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = -1 EPERM (Operation not permitted)

But when trying it after doing nothing but removing the PF_X-flag from all segments:

   mmap2(0x8048000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x8048000

   (The program executes normally after this despite the missing PROT_EXEC-flag)

The best way to deal with this would probably be to patch ld.so so it enforces
the executable-bit by itself.


Hmm, can't believe I just spent that much time on bypassing noexec. :P

as i said earlier with the chroot+jail & kernel sploit analogy, bypassing 
no-exec is definately worth the time, at least worths much more than
ret2libc brute forcing ...

-sinan


_______________________________________________
Dailydave mailing list
Dailydave () lists immunitysec com
http://www.immunitysec.com/mailman/listinfo/dailydave


Current thread: