Tag Archives: kernel

Shut up snitch! – reverse engineering and exploiting a critical Little Snitch vulnerability

Little Snitch was among the first software packages I tried to reverse and crack when I started using Macs. In the past I reported some weaknesses related to their licensing scheme but I never audited their kernel code since I am not a fan of I-O Kit reversing. The upcoming DEF CON presentation on Little Snitch re-sparked my curiosity last week and it was finally time to give the firewall a closer look.

Little Snitch version 3.6.2, released in January 2016, fixes a kernel heap overflow vulnerability despite not being mentioned in the release notes – just a “Fixed a rare issue that could cause a kernel panic”. (Hopefully Little Snitch’s developers will revise this policy and be more clear about the vulnerabilities they address, so users can better understand their threat posture.)  Are there any more interesting security issues remaining in version 3.6.3 (current at the time of research) for us to find?

You are reading this because the answer is yes!

What is Little Snitch?

Little Snitch is an application firewall able to detect applications that try to connect to the Internet or other networks, and then prompt the user to decide if they want to allow or block those connection attempts. It is a super-useful addition to OS X because you directly observe and control the network traffic on your Mac, expected and unexpected.
It is widely popular: I personally make sure it’s the first thing I install when configuring new OS X images.
Continue reading

Breaking OS X signed kernel extensions with a NOP

For some reason Apple wants to change external kernel extensions location from /System/Library/Extensions to /Library/Extensions and introduced in Mavericks a code signing requirement for all extensions and/or drivers located in that folder. Extensions will not be loaded if not signed (those located in the “old” folder and not signed will only generate a warning [check my SyScan360 slides]). The signing certificates require a special configuration and to obtain them you need to justify it. You know, there are people out there coding rootkits and other nasty stuff ;).

A couple of days ago while trolling around in IRC someone complained about this and I decided to give it a quick try (I sort of already knew it would work this way but never really tried it). Kextd is the daemon responsible for processing requests to load kernel extensions. The message you get when trying to load a unsigned kernel extension is: “ERROR: invalid signature for %@, will not load”. Load IDA, disassemble and search for this string (the alternative is to go to opensource.apple.com and download 10.9 kext_tools package – my brain defaults to IDA!). What you can see is this code for one of the two hits:

    OSStatus  sigResult = checkKextSignature(theKext, true);
    if ( sigResult != 0 ) {
        if ( isInLibraryExtensionsFolder(theKext) ||
            sigResult == CSSMERR_TP_CERT_REVOKED ) {
            /* Do not load if kext has invalid signature and comes from
             *  /Library/Extensions/
            CFStringRef         myBundleID;          // do not release
            myBundleID = OSKextGetIdentifier(theKext);
            result = kOSKextReturnNotLoadable; // see 13024670
                              kOSKextLogErrorLevel |
                              kOSKextLogLoadFlag | kOSKextLogIPCFlag,
                              CFSTR("ERROR: invalid signature for %@, will not load"),
                              myBundleID ? myBundleID : CFSTR("Unknown"));

Nothing more than a simple call to the check signature function and then a simple test to see if it was valid or not. This is pretty common in (lame) software protection schemes. One of the usual ways to bypass it is to NOP the test. Or you can just patch the checkKextSignature and return always TRUE. Many different ways to solve it.

patchmebabyNow to the interesting part. I have no idea what was Apple thinking (sometimes they do not seem to think!) by implementing the code signature checks like this. It is very hard (to impossible) to protect kextd against something running at the same privilege level (kextload or something else require root to load kernel extensions). To launch the rootkit one just simply needs a binary that runtime patches kextd (task_for_pid, mach_vm_protect, mach_vm_write) and then loads the rootkit . Game over!
Of course it is easy to argue that if attacker got root everything is possible and the game is lost. Maybe! But making things like this is just security theatre and nothing else. It creates a useless artificial barrier to load unsigned code into the kernel and a false sense of security. This kind of checks needs to be done in the kernel, at a different privilege level. True that a rootkit can just patch files at disk and bypass a kernel protection but a non persistent rootkit just needs to patch kextd, get loaded and do its work. This is just (more?) careless and sloppy work from Apple.

Have fun,

Tales from Crisis, Chapter 3: The Italian Rootkit Job

I always had some strange attraction to rootkits and was thrilled to hear that Crisis had one. This chapter is dedicated to the rootkit implementation, its tricks and how it’s controlled (and its fuckups!).

A small disclosure note about me making fun of Italians on Twitter. I love Italy and have nothing against Italians. We just share some cultural things that I really hate and that’s the reason why I was making fun of Crisis origins and some of its design/features. It’s no coincidence that the South European countries are all in economic trouble 😉

The rootkit number of features is very small: it can hide processes, files, and itself. Two versions are available for 32 and 64bits kernels (this post is about the 32bits version using Snow Leopard). Implementation is very simple and has some flaws that I will describe later.
The main feature that got me interested was hiding itself from kextstat because this needs to be done by modifying the sLoadedKexts array (the old kmod list is not enough anymore since it’s deprecated).
It doesn’t seem an easy job to find the location of this symbol and Crisis kind of cheats in doing it. What happens is that the userland backdoor module will solve the kernel symbols and pass them to the kernel module. Done this way it’s very easy to accomplish, although compatibility with future kernel releases might be in jeopardy if sLoadedKexts is modified.
Continue reading

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 😉