Category Archives: Tools

Gatekeerper – A kernel extension to mitigate Gatekeeper bypasses

Last month Patrick Wardle presented “Exposing Gatekeeper” at VB2015 Prague.
The core of the presentation deals with Gatekeeper bypasses originating in the fact that Gatekeeper only verifies the code signatures of the main binary and not of any linked libraries/frameworks/bundles.
This means it is possible to run unsigned code using dynamic library hijacking techniques also presented by Patrick in code that should be protected by Gatekeeper. His exploit uses an Apple code signed application that is vulnerable to dylib hijacking and his modified to run unsigned code when downloaded from the Internet. In this scenario Gatekeeper enters into action and should verify if the download is code signed (assuming the default OS X scenario where it is enabled). But in this case Gatekeeper will fail to verify the linked code and effectively is bypassed.

The core of the problem is that Gatekeeper only deals with the main binary code, and never verifies any linked code. This is obviously a flaw and hopefully a fix by Apple should be out sooner or later. Meanwhile we can try to build ourselves a fix using the TrustedBSD framework. For this I created Gatekeerper, a proof of concept kernel extension for Yosemite 10.10.5 (can be easily adapted to work with El Capitan, but I don’t want to release that code).
Continue reading

Rootfool – a small tool to dynamically disable and enable SIP in El Capitan

El Capitan is finally released and System Integrity Protection aka SIP aka rootless is finally a reality we must face. Let me briefly describe SIP (technical details maybe in another post, now that El Capitan is final and out of NDAs). This post by Rich Trouton contains a very good description of its userland implementation and configuration.

What is SIP anyway?

The description that I like to use is that SIP is a giant system-wide sandbox, that controls access to what Apple considers critical files and folders. One of the reasons for this is that most of kernel side SIP implementation exists into the Sandbox.kext, the same TrustedBSD kernel extensions that implements OS X sandbox mechanism.

For example, if we try to write to /System folder we get the following result:

sh-3.2# touch /System/test
touch: /System/test: Operation not permitted

And in system logs:

12/10/15 17:27:20,650 sandboxd[120]: ([424]) touch(424) System Policy: deny file-write-create /System/test

In practice it means that even with root access we are unable to modify those critical files and folders.
Continue reading

Can I SUID: a TrustedBSD policy module to control suid binaries execution

Let me present you another TrustedBSD policy module, this time to control execution of suid enabled binaries.
The idea to create this started with nemo’s exploitation of bash’s shellshock bug and VMWare  Fusion. It was an easy local privilege escalation because there are many Fusion suid enabled binaries. This got me thinking that I want to know when this kind of binaries are executed and if possible control access to them. For the first part you don’t really need this module because the audit features available in OS X can give you this information. I’m more interested in having decision power over what is executed. Or it’s just another nice example of how TrustedBSD is so interesting and powerful and why it’s annoying that Apple is closing KPI access to it (latest SDK warnings say it was never meant to be a KPI).

There are two parts to this. The first is the kernel driver that detects execution, controls access, and notifies userland. The second is a small userland application that receives the kernel notifications, asks the user for a decision, and sends back the answer to the kernel.
The execution is blocked until a decision is made or a timeout is reached (default is 5 seconds, you probably want to increase this value).

To avoid any deadlocks all binaries before userland application is connected are authorized. When the userland finally connects it receives a list (displayed as user notifications) of all the suid binaries that executed during the boot process (from my tests this is zero in Mavericks).

Because of the changing nature of TrustedBSD started in Mavericks, this code only works with Mavericks as it is. If you want to make it work in Mountain Lion or Yosemite, you need to change the hook prototype and compile it with the correspondent SDK.

The userland application needs some work due to my crap Cocoa skills :-). The kernel extension has a few points that need a decision (what to do in error cases mostly), authentication of the userland process (it’s not hard to do), and probably more process information.

A friendly tip: The kernel control interface is used for userland/kernel communication. Because the volume of data exchanged is very low it’s ok for this. If you are thinking about using this  interface for high volumes forget about it. It has some weird bug where it starts losing data and not able to keep throughtput (error 55 is what you start to experience).

Source available at Github, https://github.com/gdbinit/can_I_suid.

Have fun,
fG!

Don’t die gdb, we love you: kgmacros ported to Mavericks.

Our lovely gdb has been declared dead with Xcode 5 release. The new king in town is lldb, and that also applies to kernel debugging. Change is good, even if we Humans don’t like it, but… there’s still no gdbinit for lldb and I just love it. Even more important (for kernel debugging), lldb still has no support (afaik) for VMware gdb stub. This means it’s not possible to do kernel debugging in Mavericks VMs other than KDP. I like the gdb stub a lot; ctrl+c and bang we got kernel control.

I needed to do some research with Mavericks so I decided to port the kgmacros script to Mavericks. It was easier than I expected, just some fixes to structures that changed. Most functions are working ok, and there are a few private helper commands I added last yet while I doing some research. Mostly improvements related to physical memory functions. The most important commands, at least for me, are fully working.

The script is available at Github repo. The kgmacros file is for Mountain Lion, and kgmacros_mavericks for Mavericks.

One small tip if you are doing two real machines debugging with lldb and thunderbolt. You will need to set the boot args parameter “kdp_match_name=en4” if you are using a thunderbolt to ethernet adapter in the target machine. KDP expects by default the network interface in en0 and the thunderbolt adapter is set as en4. Other than that everything works. It just needs the gdbinit like output and commands. Deroko started a version here. Go help him, I don’t want to learn Python (again) ;-).

Enjoy,
fG!

Updated version of Onyx The Black Cat

New version available at the github repo, compatible with Mavericks and with a Cocoa app to control its features.

Mavericks sysent table is modified so previous versions weren’t compatible with it. I updated the sysent table definitions. It’s not the best method to assure future compatibility in case Apple decides to change the structure again. A better way is to find the symbols for the syscalls and replace them directly in the sysent table. Maybe in a future update.

The GUI app is nothing special and code is not pretty for sure. My Cocoa skills still suck (feel free to improve it, I’m always open to learn). If you quit it while the driver is running and load it again, the options state will be clean and not show what was already set. This is because the driver doesn’t support querying what options are set. Maybe in a future update ;-).

Don’t forget you need to download and add diStorm to the codebase. I have to give it a try and include Capstone in the kernel driver.

Enjoy,
fG!

 

One small patch for gdb, one giant leap for reversers!

One thing that really bothered me for a long time while debugging is the need to calculate the libraries loaded addresses versus the addresses at disk if you want to follow and comment library code in IDA. While the ASLR slide can also be disabled when starting processes (or even attaching by disabling it first in the Mach-O header) sometimes I want to attach to ASLR enabled processes and once again I need to compute values without the slide to follow in IDA.

Last week I finally got fed up of this problem and decided to take action and dive into the unknown world of gdb source code. Oh boy, it’s quite an adventure but this time I managed to escape alive out of it! The result is what I think it is a very nice patch that can save time to fellow reversers (this might be the moment where someone says it already exists, he he he!). At least I like it very much since it gives me right away information that I like to have.

What the patch does it to show you the non-ASLR address value (if ASLR is set) and to which image the address belongs to. This avoids the step to use “info shared” command or vmmap util to dump the addresses and lookup where it belongs to (I think there is a gdb command for this, but it is still another extra step). The patch is not yet perfect because the gdb source is a mess with a few different conditions that do not make a lot of sense (not commented code does not help!). What I implemented seems to work for most cases so I am happy with it for now. Oh, there is also some cpu waste to search the addresses. Let’s do it game style by abusing today’s fast cpus and forgetting “optimization”. Two screenshots, one of the entrypoint for “ls” command and the other inside a library call.

gdb1 gdb2I don’t like the lack of alignment of the image name but that requires more messing with internal gdb stuff and I need a new dose of courage to get into. Submit patches if you dare :-)!

Source code located at GitHub repo – https://github.com/gdbinit/gdb-ng – also with fixes to use Darwinbuild with Xcode 5. Maybe I should buy an Apple developer certificate and start distributing signed binaries.

Have fun and say thanks to COSEINC for the patch,
fG!

P.S.: Follow this post about how to compile gdb using darwinbuild.

Update: Just added an option to print only the image name without full path. Default is disabled and variable to set is “print-full-path”. Just pull from the github repo.