Great people share their wisdom without asking for anything in return…

Menu

I had a meeting yesterday evening with some organisation and these people offered me $50,000 – in a bag – to take over computers running Mavericks, Yosemite and El Capitan. All legally of course. Right. Man that is insane! Do I look like a drug dealer or something?

Update: For clarity. I won’t help this unnamed organisation, but not that it matters because I was informed earlier today that somebody else (some company) in the hack scene stepped in. Good for them. Not that I case, because I don’t have time for this kind of stuff anymore.

I have found a very simple way to bypass Apple’s kext signing in El Capitan, like I did before in Yosemite and Mavericks before that. This time I did it differently, and this blog post is a short and simple POC (proof of concept) to show you that bypassing Apple’s rather strict kext signing restrictions still works. Even in El Capitan DP5. This means that I run my hack with maximum System Integrity Protection (SIP) activated (no rootless=0 boot argument/runtime/NVRAM variables to bypass the code signing restrictions) with the following unsigned kexts:

I use /Extra/Extensions for unsigned kexts, so that the /Library/Extensions and /System/Library/Extensions directories can be kept vanilla/untouched. This way unsigned kexts won’t show up in System Information/Software/Extensions, which in my view makes it somewhat harder to detect. Sure. Running kextstat does shows all loaded kexts, so it’s not that hidden, but cleaner anyway. We could add another hack to hide kexts in kextstat, and that makes it even worse.

A Little Background Info
OS X won’t load/execute unsigned kexts, unless you use kext-dev-mode=1 in Mavericks and Yosemite for /Library/Extensions, but this setting is obsolete in El Capitan so you either have to use rootless=0 (now also obsolete in El Capitan) or all unsigned kexts will fail to load. Another option is to use the Security Configurator utility to toggle a checkbox, or run csrutil [enable/disable] from the Recovery OS.

Apple already said that rootless=0 will be absolute, in due time, and then we have to use the Security Configurator… or use a boot loader that sets boot flag CSR_ALLOW_UNTRUSTED_KEXTS to allow unsigned kexts ;)

This is also what I use for the third Developer Preview of El Capitan in RevoBoot and the Enoch branch of Chameleon. Slice, the Clover project owner and main developer, also recently implemented a Clover option to set the NVRAM key csr-active-config (see nvram -xp).

Kext Injection
Some boot loaders can inject kexts, like FakeSMC.kext, but RevoBoot is not one of them. That will certainly change now that I have seen the use of it. Anyway. Clover kext injection used to work, but works differently than what I envision, and now also fails in DP4. This was why I looked into it, to see if I could find a workaround, so that the Clover developers can solve this issue. A group of Clover users even offered me to pay a 1800 Euro bounty (2000 Dollar), but I declined their offer.

Prelinkedkernel
The prelinkedkernel is located in /System/Library/prelinkedkernels and is loaded by boot.efi, or in case of a legacy boot loader.. the boot loader. Not that it really matters for this POC but anyway. The prelinkedkernel replaces the old /System/Library/Caches/com.apple.kext.caches/Startup/kernelcache and is compressed with LZSS. The former with LZVN – I blogged about changing the compression type and the new, at that time, LZVN compression here OS X 10.10 Yosemite DP1 kernel(cache).

Tools
I use a self written command line tool called LZVN to unpack and repack the prelinkedkernel, but the current version needs a few small changes to automate the process of unpacking, repacking, calculating the adler32, fixing the offset and size of the (un)compressed file.

Bootloader
I use RevoBoot as my primary boot loader of choice for my Hack, but it can’t inject kexts. Not yet that it, but adding support for it would have been a lot of work, and that is why I chose to modify the prelinkedkernel instead. For this to work I added a “Kernel Cache” property in /Library/Preferences/com.apple.Boot.plist with a string value pointing to the modified prelinkedkernel. This way RevoBoot loads that instead of the normal prelinkedkernel. And it does that just like any other booter would do, including boot.efi

Sure. What you want is a boot loader that can inject the required kext for you. Something that Clover and Chameleon can do for quite some time already, so please keep using the boot loader of your choice. I don’t care. Really. I only shared my view on this matter, and used RevoBoot because that makes things easier for me. Thing is. Since this works with a modified copy of a prelinkedkernel, then it will work with my type of kext injection. Someone just need to write/patch the code for it.

Kext Injection
Like I said earlier; RevoBoot cannot inject kext and the main reason for this is twofold.1) I had no need for it.2) I like to write my own code.

Nope. Nobody learns anything from a simple copy/paste action, and thus that won’t happen. I also want to do things differently. The reason for this is simple. I found out – the hard way for the macosxbootloader project – that boot.efi was changed in Yosemite, and it is likely going to be changed in the near future as well, so we need to do things a bit differently, so please note that we are not going to create a prelinkedkernel from scratch. I can, but it takes too much time to explain/write it all up!

Ok. Let’s get cracking (still a work-in-progress) but only start doing this when you know what you are doing. Be aware that mistakes can render your Mac/Hack unbootable!

The red value 01 19 15 09 is the file size minus 28/0x1c. The purple value D1 E2 8A C2 is the checksum (adler32). The brown value 02 EF 40 00 is the size of the uncompressed file. The blue value 01 19 13 89 is the size of the compressed file. Nothing new, and the required values can be found in the output of LZVN. I myself kept the length the same (added a couple of zero’s).

Note: Please wait for me to update my LZVN repository if you don’t want to mess with this.

7) Fix the coloured values and insert the 412/0x19c bytes at the top of [path]prelinkedkernel_el_capitan_repacked

8) Save the file and copy it to: /Extra/Prelinkedkernels/Prelinked_El_Capitan_Patched, or use any other location that allows you to write the file to.

Edit: Oops. I changed the path from /System/Library/Prelinkedkernels to /Extra/Prelinkedkernels because that is what I use.

9) Open /Library/Preferences/SystemC*/com.apple.Boot.plist with nano (example) and add a “Kernel Cache” key property. Below that you add a string property with the value pointing to your copy of the prelinkedkernel. In my case: /Extra/Prelinkedkernels/Prelinked_El_Capitan_Patched

Edit: Path to El_Capitan_Patched added.

10) Reboot and run cat /var/log/system.log | grep kext to see if everything is OK.

Why patch a prelinkedkernel?
Well. For starters. The idea was to simply demonstrate a weakness in Apple’s kext signing protection in El Capitan. I also want it to work on my Mac as well. Yes. I could have added code to the macosxbootloader project, and compiled a new version of boot.efi to inject the (unsigned) kexts into the prelinkedkernel, but like I said earlier… that would have taken too much time. Not to mention that this is only a simple POC.

And sure. OS X recreates prelinkedkernel files automatically, so normally there is no need to do this manually, but this route opens the door of loading unsigned kexts on a system with SIP in place. And with El Capitan being the first version of OS X full SIP in place, which should make it way more restrictive than all previous versions of OS X… this hack is definitely new(s) – though Apple may close the door before the El Capitan GM is released.

The fact that you can set kext-dev-mode=1 in Mavericks and Yosemite, and let it update the kernel cache and prelinkedkernel with unsigned kexts, and then remove the setting afterwards, not only makes me wonder why nobody implemented proper kext injection – as in injecting kexts in the prelinkedkernel – in Clover and/or Chameleon. To me this shows us that this weakness wasn’t so well known as some people want you to believe. I mean saying something like that after a POC is published for El Capitan, is dead easy, but also a bit unfair. Why else is kext injection still broken? Nobody told slice this, or any of the other Clover developers? Really? Not to mention that I do all this with SIP fully enabled in El Capitan, without the need of kext-dev-mode, rootless=0 or any of the CSR flags… and that makes it a totally different.

Note: RevoBoot was the first boot loader to add the following CSR boot flags:

This was picked up a little later by the Enoch branch of Chameleon, with my help, and now Clover can also configure the CSR settings (runtime variable). And adding CSR_ALLOW_UNTRUSTED_KEXTS is similar to kext-dev-mode and thus enables you to add unsigned kexts to the prelinkedkernel in El Capitan. Just like using kext-dev-mode in Mavericks and Yosemite, but my POC is about injection kexts in the prelinkedkernel with SIP already fully enabled. A different kind of story.

“A new security policy that applies to every running process, including privileged code and code that runs out of the sandbox. The policy extends additional protections to components on disk and at run-time, only allowing system binaries to be modified by the system installer and software updates. Code injection and runtime attachments to system binaries are no longer permitted.”

But I can still inject code in the prelinkedkernel. That is not OK. I don’t like that. Another thing is that /Library/Preferences/com.apple.Boot.plist is (still) unprotected, and thus anyone who likes to use a patched prelinkedkernel with unsigned kext in it… can do that. Easily. You just need to know how.

A more serious problem is that Apple allows unsigned kext to execute from anywhere. In this POC we load them from /Extra/Extensions but other locations can be used as well. Plus. If you hide the directory including the unsigned kexts, then the average joe user won’t even notice it, since it won’t show up the finder. Plus that it will be undetectable in System Information/Software/Extensions so you won’t even know what kext is loaded from where. To me this is due to some lazy coding.

A possible oversight on Apple’s side, and that is why I expect this to change in a next Developer Preview. Well. So I hope, otherwise the first security exploit can take over your Mac/Hack. Like Hackinteam et all. Shrug.

Kext Whitelisting
If all you need is kext whitelisting, with SIP in place, then you can change/add one or more entries under OSKextSigExceptionHashList (see AppleKextExcludeList.kext/Content/Info.plist) in the prelinkedkernel, like we have been doing in Mavericks and Yosemite.

Update: Woohoo. I found another more serious way to bypass Apple’s kext signing restrictions, but this time I go for the bounty money (have a meeting tomorrow evening).

Note: Hang in tight folks. Sure. I am still very busy with my – non hack related – work, and I still suffer pain from my accident, but I will do my utmost best to finish this work. Promised!

First. I believe that Hacking Team (currently offline ROFL) was hacked in late 2014 already, by the Dream Team, and that using rootless=0 as NVRAM/boot-arg is utterly stupid. I mean. Nobody should open ‘a backdoor in OS X’ and rootless=0 helps to protect your filesystem – among others – and so please do not use it with installations that are connected to the Internet. That is all I can say here.

Yes. I can replace your boot.efi with a modified copy of mine and give myself access to all of your files. Trust me. I would never do this, and that is why I urge you to listen to me: Please do NOT boot with rootless=0 Period!!!

Okay. Your hack won’t boot without rootless=0 but hang on. I hear you. This is why I am/will be working with boot loaders developers so that they can fix this. To let your modified kexts load without the need of rootless=0. Without the need of opening a back door. Promised.

Note: You don’t need to replace boot.efi with a legacy boot loader – think Chameleon, Chimera and RevoBoot – to be vulnerable, because boot.efi isn’t used by legacy boot loaders. Not that it really matters, because all* legacy boot loaders are still vulnerable.

Update: RevoBoot and the Enoch branch of Chameleon are no longer vulnerable and can now boot El Capitan without rootless=0 (the ‘all or nothing’ setting.. going away in a next DP).

Update-2: I have not yet been contacted by Clover developers, but then again they might not care about (your) security/privacy.

Update-3: Clover is recently changed and now sets csr-active-config by default similar to rootless=0. Which is, again, utterly stupid.

I received e-mails, and posts that I blocked, from people asking for help with the installation of El Capitan. Ok. So they can’t get it to run with either Chameleon, Chimera or RevoBoot. Something had changed, and we needed to figure out what it was.

The good news is that a couple new guests arrived, former co-workers loving to hack so I am there also, and they just couldn’t sleep after their flight. Well. I have more good news for you because now, two hours later… and a lot of beer for my friends; We are pleased to announce that we got the OS X installer downloaded from the Apple Store, fired it up with a modified copy of RevoBoot and the new El Capitan kernel (15.0.0) and extensions are loaded and executed.

One thing that we had to fix is that the Installer app failed to install El Capitan on the new SSD, but that was only due to a previously (broken) installation on the drive. We solved this the next day by installing Yosemite before El Capitan. Everything works now. I was just too tired to push the update to my RevoBoot Github repository the first day, but that is now also completed.

A few notes. I did not use a USB memory stick to install El Capitan on the SSD, but launched the Install OS X 10.11 Developer Beta.app from the /Application folder. This copied files to the new ElCapitanSSD and then reboots afterwards. Not that I let it boot from ElCapitanSSD, because we first had to add extensions to /System/Library/Extensions/ and the kernel to /System/Library/Kernels. Files that we extracted from the packages with help of Pacifist. The next step was to add a couple of boot arguments to .IABootFiles/com.apple.Boot.plist Here is what we added:

A bit overkill, but it worked with the modified version of RevoBoot. By the way. We only changed this setting in: RevoBoot/i386/config/SETTINGS/Macmini71.h (the used configuration for my hack)

#define INSTALL_ESD_SUPPORT 1

This setting is set to 0 by default, but since we want to load the installer from ElCapitanSSD… By the way. This file was created for us after running: make MODEL=Macmini71 The next step was to copy boot0, boot1h and boot to ElCapitanSSD followed by a reboot. Please note that without the proper modifications to the boot loader, you end up seeing a zone_init panic before it reboots.

Anyway. The installer ran and installed El Capitan on ElCapitanSSD, but it failed to remove files like /.IABootFiles so we had to do that ourselfs. The next boot took a little longer, time used to recreate the prelinkedkernel and (old) kernel cache, and the Apple logo seems a little wider, but at least the desktop showed up. All without a single error/problem. Ok. Audio failed, but hey that is easily fixed.

Update: The slightly wider Apple logo was caused by an error on my side. This simple change in RevoBoot/i386/config/SETTINGS/Macmini71,h solved it:

Edit: I changed the value (0x40000000) right after the installation of El Capitan to 0xc0000000 and then 0x3f9cba000 but the legacy sane_size is still 0x400000000. In other words; legacy installers appear to be limited to 1 GB and the installer failed with values greater than 0x40000000. . Nope. I was wrong. I now changed the RevoBoot source code to let it use the detected amount of physical memory (see in function SetupSMBIOS) and that works just fine. Much better now.

Also. After the installation I removed all Kernel Flags, including rootless=0 and kext-dev-mode=1 and everything is A OK.

Edit: I added some text, and added new text, to clarify how I did it. This should help other people to get El Capitan booting with Chameleon/Chimera/RevoBoot ;)

p.s. Sorry. I forgot to mention that I also added a couple of files in /Extra on the ElCapitanSSD:

My wife and I have been thinking about a change of life, for months already, and we want to start a very very exclusive bed and breakfast / Hotel accommodation in Spain. Exclusive as in jetset expensive and thus I’m afraid that it won’t be affordable for everyone. Our target guests are looking for quality, glamour and exclusivity with the right amount of privacy in a relaxed environment, with a pool for every guest staying with us (four pools in total). The minimum stay is a weekend and starts at 1000 euro for two people (minimum). This includes our exclusive airport shuttle service with premium class cars (round trips). Breakfast is included for Bed and Breakfast stays. Lunch is also included for hotel guests, but dinner is served by professionals with hotel/restaurant style and quality, and is not included. Your stay will also be very very comfortable because for this we traveled a lot (several countries) for stuff like this designer coffee table.
Or these sun beds that my wife loves to pieces.
We also have several lounge beds with really beautiful sea- and mountain views for you to sit/relax on. Like this one for example.
Or this one.
And every so often you will be joined by honourable guests like my father and his girlfriend who just like to sit down here and enjoy our views.
Who is always willing to sail away with a couple of guests to places like Ibiza and Mallorca where you can continue your trip in one of the two exclusive holiday homes he owns there.

This all also means that I will have quit my job at Google, eventually, and that I will stop working on hackintosh related stuff, effectively immediately. Looking forward to our new future. A bright future, with eighty three former coworkers joining us this summer to testdrive our new Bed and Breakfast / Hotel which by the way was estimated at a value of 3.4 Million euro (co-owned by my father).

Edit

I got a couple of questions (per e-mail) and like to answer a few of them here.

Q: Is this B&B / Hotel located at your home?

A: No. The B&B / Hotel is not located at home. We live in a finca surrounded by a couple of acres of olive tries.

Q: Will you be there?

A: Sometimes. However. Management of our Bed and Breakfast / Hotel is under control of my wife Angélica – with help of my father as a mentor/advisor. I myself run the vineyard that we inherited from my late father in law.

Q: Where is this Bed and Breakfast located?

A: North of Marbella.

Q: You asked for donations, and I donated, and now this. What’s up with that?

A: My father bought the villa and had it finished for this purpose six months ago. I guess that he wanted to do something good with his hard earned money, part of his retirement plan, and then I fell off our roof and suffered a permanent handicap – damaged nerves – so I am sure that you get the picture.

Q: Is Internet available in your Bed and Breakfast / Hotel?

A: Yes. We have a 200 Mbit/s connection with 802.11 AC (WiFi). Guests can also use one of our iPads and/or MacBooks.

Q: What TV channels do you offer?

A: Several, including the most important Dutch/UK channels. There is also an Apple TV with Netflix in every room and the lounge / meeting area inside (downstairs) is also equipped with a 75 inch Ultra HD TV for special events like Formula one races and Football (soccer).

Q: Can I rent a car there?

A: Yes you can. Please note that the airport shuttle service is free, but you can opt to rent a car at the airport. Or one of the two new Tesla’s that should arrive in two weeks from now.

Q: Do people smoke there?

A: No, but we have a smoking area located at a few steps down the mountain.

Q: Is your dad still working for Apple?

A: No.

p.s. Thank you to all people who were so nice to me. I surely won’t forget you and your hard work. Please keep on going, while I float in one of our pools… looking back and remembering the great times we had. Thank you!

David, also known as toleda in our community, asked me for help last year (October), but you know me… I am always busy. Or pretending to be too busy, and thus I forgot about his request for help. Then. A few days ago I received another e-mail about it and I thought… Oops I did it again. Sorry David. I complete forgot. Anyway. I have some good news, because we solved the last piece of the SSDT puzzle.

Let’s first go back in time. Look at the WiKi of my late sister Samantha. There you will find three really amazing Tiny SSDT examples. Her work in 2011 enabled us to keep the DSDT and/or SSDT tables and still be able to disable/hide and/or rename Devices. Which was a great step forward for running OS X on our hacks. Oh yeah. I almost forgot. She also found a way to decompress/compress the ZLIB files.

David, and many people with him, used her TinySSDT examples and came up with great solutions to make things even easier. Audio among others. But one thing was still impossible, and that was that we couldn’t simply rename Device (B0D3) to Device (HDAU) but I have good news because now we can. You can find my TinySSDT example, for a GA-Z87MX-D3H with F6 BIOS right here.

In short. We found a new way to disable individual devices, including LNKx, PS2n and ThermalZones. Something that was not possible before. David already confirmed that it is working for him, so let’s go have some more fun with it. Have a look at the code (the new TinySSDT example) it and please remember this; In case you asked for my help, and I forgot you, then feel free to remind me about it ;)

Edit

The last piece of the audio puzzle is to find a way to load patched copies of the XML files. A puzzle I tried to solve last year, but David was unable to reproduce my success, so I am still using my dummy AudioHDA.kext trick. Which is neat, but it is time for some improvements.

Too bad that I lost the code, because now I have to do it all over again, but I can’t help it that my main SSD decided that it had enough of me and all my read/write attempts. Well. If only I had made backups, or pushed it to some repository, but I didn’t. Stupid but anyway. You know me. I may be slow, from time to time, but I think that I can pull it off again. Let me see what I can come up with ;)