Tag Archives: aslr

Kextstat_ASLR util or how to start hiding your kernel rootkit in Mountain Lion

Welcome back!

This is a small post about a quick util that I created yesterday’s night while working on a side project. Mountain Lion introduced kernel ASLR and the kextstat util output doesn’t support (yet?) this feature. The addresses are not the real ones and this is quite annoying (kgmacros from kernel debugging also seem to fail at this!).

What this util does is to read the kernel extensions information via the /dev/kmem device (hence this util is probably not useful for a large audience) and display it like kextstat does with the correct address for each kext (just the most important information, the linked against info might be added in the future).

Besides useful for anyone wanting to read the kexts information, it’s also useful for rootkits because it implements the trick that Crisis uses to retrieve this information for 64bits kernels (my posts were against the 32bits version). The only piece left is how to find the sLoadedKexts symbol. Here it’s hardcoded for version 10.8.2. I do have a nice trick to find it but it’s not ready for public consumption. First I want to see if it’s possible to implement my new idea 🙂

Due to some whacky reason I was convinced that each kernel extension had individual ASLR slide values, which after I got this util working was demonstrated false. The slide is the same as the kernel. I probably had some mistake while searching manually for the kexts. Practice makes perfection and part of this code was needed for my new project so it’s not wasted time!

The code is located at https://github.com/gdbinit/kextstat_aslr.
One feature to be added is to “bruteforce” the whole sLoadedKexts array. The reason is that rootkits usually decrease the count but the information remains there. Since the class has a capacity instance variable, we can move beyond the count and check if there’s anything suspicious there. Just a fun detail 🙂

The last detail is that this is susceptible to changes to OSArray and OSKext classes since it’s using offsets into the instance variables. The best way would be to get this ported to C++ but I still have to read a book or two on C++. Need to verify how stable are these classes since Snow Leopard.

Phew, too many written words for such small util!
Have fun,

fG!

Update:
There is a privileged syscall called kas_info() that allows to retrieve kernel ASLR value. I’ve updated the code to use this feature.

How gdb disables ASLR in Mac OS X Lion

This isn’t a rocket science post but more like some notes for future reference 🙂
Lion finally introduces full ASLR and gdb has the possibility to disable that feature when analyzing target binaries. A new gdb setting was added, “disable-aslr”, which allows to enable or disable this feature.

By default this feature appears to be enabled (I am just looking at gdb source code) and it’s set by the variable “disable_aslr_flag” configured at gdb/macosx/macosx-tdep.c source file. But this isn’t the place where the magic happens. That is located in gdb/fork-child.c file (well there’s a second version at macosx/macosx-nat-inferior.c).
A very rough draft of gdb workflow is something like this:

  1. Fork
  2. If we are the child process, drop privileges
  3. If we are the child process, use ptrace to “stop” the new process
  4. Exec the target
  5. Use again ptrace to resume the child
  6. Wait for breakpoint events

Step 4 in Apple’s gdb version tries to use posix_spawn instead of exec (or any of its variants) to launch the target. This allows to set some special attributes in the new process. One of the new attributes in Lion is “_POSIX_SPAWN_DISABLE_ASLR”. The name should be explicit about its purpose 🙂

The piece of code that sets it in gdb/fork-child.c is:

(...)
            if (disable_aslr_flag)
              ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
            retval = posix_spawnattr_setflags(&attr, ps_flags);
(...)

If posix_spawn fails gdb will then try to execvp the target. At the kernel side, this is dealt with in “posix_spawn()” at “bsd/kern/kern_exec.c”:

(...)
                /*
                 * Disable ASLR for the spawned process.
                 */
                if (px_sa.psa_flags & _POSIX_SPAWN_DISABLE_ASLR)
                        OSBitOrAtomic(P_DISABLE_ASLR, &p->p_flag);
                /*
                 * Forcibly disallow execution from data pages for the spawned process
                 * even if it would otherwise be permitted by the architecture default.
                 */
                if (px_sa.psa_flags & _POSIX_SPAWN_ALLOW_DATA_EXEC)
                        imgp->ip_flags |= IMGPF_ALLOW_DATA_EXEC;
        }
 
        /*
         * Disable ASLR during image activation.  This occurs either if the
         * _POSIX_SPAWN_DISABLE_ASLR attribute was found above or if
         * P_DISABLE_ASLR was inherited from the parent process.
         */
        if (p->p_flag & P_DISABLE_ASLR)
                imgp->ip_flags |= IMGPF_DISABLE_ASLR;

And that’s it! A new flag added, processes spawned with that flag active and bye bye ASLR 😉
Enjoy,
fG!