
OS X 10.10.5 kernel local privilege escalation - tyilo
https://github.com/kpwn/tpwn
======
benwilber0
$ git clone
[https://github.com/kpwn/tpwn.git](https://github.com/kpwn/tpwn.git)

Cloning into 'tpwn'...

remote: Counting objects: 16, done.

remote: Compressing objects: 100% (11/11), done.

remote: Total 16 (delta 3), reused 16 (delta 3), pack-reused 0

Unpacking objects: 100% (16/16), done.

Checking connectivity... done.

$ cd tpwn

$ make

gcc *.m -o tpwn -framework IOKit -framework Foundation -m32
-Wl,-pagezero_size,0 -O3

strip tpwn

$ ./tpwn

leaked kaslr slide, @ 0x0000000008e00000

sh-3.2# whoami

root

sh-3.2#

Shit's real.

Edit: for those of you wondering, no, I didn't just run this willy-nilly. I
read the code thoroughly and determined there were no side-effects aside from
just the PoC dropping to a root shell.

~~~
fit2rule
Phew, didn't work for me out of the box:

$ make gcc *.m -o tpwn -framework IOKit -framework Foundation -m32
-Wl,-pagezero_size,0 -O3 In file included from
/usr/include/dispatch/dispatch.h:51:0, from
/System/Library/Frameworks/IOKit.framework/Headers/IOKitLib.h:56, from
import.h:13, from lsym.h:5, from lsym.m:1:
/usr/include/dispatch/object.h:143:15: error: expected identifier or '('
before '^' token typedef void (^dispatch_block_t)(void);

~~~
klapinat0r
Just to clearify: that's just means you couldn't compile it. It doesn't imply
your system is/isn't vulnerable.

~~~
fit2rule
Sure, but its somehow satisfying to know that its broken for those who don't
make the effort to fix it. ;) (It happened to me because I'm using a different
compiler than the exploit needs..)

~~~
MagerValp
Malware comes precompiled and ready to run, it doesn't depend on you having a
compiler installed.

~~~
fit2rule
True that! I'm looking at you, homebrew ..

~~~
D4AHNGM
Not sure why you're looking at Homebrew.

If you're feeling jumpy about binary packages, just set
`HOMEBREW_BUILD_FROM_SOURCE="1"` in your shell profile.

Nobody's forcing binaries onto you.

~~~
fit2rule
True, but I don't have all the time in the world to read the sources, either
..

~~~
qwertyoruiop
Then you should not install them on a machine with confidential data at all,
source or binary. It's that simple!

------
lisper
Anyone who is worried about privilege escalation on OSX should be aware that
Apple ships sudo with requiretty disabled. This means that sudo authentication
is not bound to the TTY in which the authentication occurred, and so using
sudo for anything is tantamount to giving root to _all_ of your processes.

UPDATE:
[https://news.ycombinator.com/item?id=10069706](https://news.ycombinator.com/item?id=10069706)

------
Mojah
So we currently have 2 local privilege escalation exploits [1] available for
Mac OSX. Apple appears to be in no rush to fix the first one, I wouldn't bet
my money on this vulnerability getting a fix any time soon, either ...

[1] [http://bit.ly/1MrsdID](http://bit.ly/1MrsdID)

~~~
MagerValp
The DYLD_PRINT_TO_FILE exploit was fixed in 10.10.5.

~~~
pacquiao882
It was not fixed. There are currently no plans to fix it in 10.10.

[https://blog.malwarebytes.org/mac/2015/08/dyld_print_to_file...](https://blog.malwarebytes.org/mac/2015/08/dyld_print_to_file-
exploit-found-in-the-wild/)

~~~
MagerValp
That article is two weeks old. 10.10.5 was released 3 days ago, and the fix is
mentioned in the release notes (under dyld): [https://support.apple.com/en-
us/HT205031](https://support.apple.com/en-us/HT205031)

------
abhv
Just curious when you disclosed this to apple? I'm impressed by your skill in
finding this, but not sure it is a good idea to make it so easy for people to
weaponize like this.

~~~
koenigdavidmj
Apple traditionally has a poor record of responding to delayed disclosures.
They burned that bridge a long time ago.

~~~
Jerry2
No they did not. Provide some evidence please. They've responded to hundreds
of security issues and have credited people in security updates. About the
only incident that I can recall is the Google one when Google automatically
disclosed vuln's after Apple asked them for more time since it affected a very
deep kernel issue.

~~~
scintill76
My vague recollections of past vulns (and admitted dislike for Apple) leads me
to believe the parent comment, so I did some Googling. "A prominent security
researcher warned Apple about this dangerous vulnerability in mid-2008, _yet
the company waited more than 1,200 days to fix the flaw_."[1] But hey, they
_did_ credit him in the release notes!

Granted, it's been several years now, but the parent did say "has a poor
record", and a 3 year patch delay fits that description.

More recently, there was the 4-day gap[2] between patching "goto fail" on iOS
vs. OS X. While not really the same point as the parent comment, it reflects
poorly on their commitment to rapidly fixing things.

[1] [http://krebsonsecurity.com/2011/11/apple-took-3-years-to-
fix...](http://krebsonsecurity.com/2011/11/apple-took-3-years-to-fix-
finfisher-trojan-hole/) [2] [http://www.cnet.com/news/apple-finally-fixes-
gotofail-os-x-s...](http://www.cnet.com/news/apple-finally-fixes-gotofail-os-
x-security-hole/)

~~~
MagerValp
Apple fixes hundreds of vulnerabilities every year, and while they do drop the
ball on one or two, those are exceptions, not typical. Reports to product-
security@apple.com are responded to by a human within a few hours, and issues
are typically patched in the next point release or the next after.

I can see why you'd drop a 0-day if you were somehow ignored or they were
stalling for years, but dropping it without even trying is just irresponsible.
There's a lot of room for improvement in Apple's handling of vulnerabilities,
especially with regards to response time and proactive work, but I don't see
how deliberately waiting until 10.10.5 and then releasing a 0-day is helping
anyone.

~~~
scintill76
I'm not sure if I would ever fully support this kind of disclosure, but maybe
we should consider that both this person and Stefan Esser (DYLD_PRINT_TO_FILE)
concurrently released fixes/mitigations, meaning vigilant users are secure
faster than they would be if it was kept secret until Apple patched it.

~~~
MagerValp
Are you talking about his comment about -no_shared_cr3, which causes a
noticable performance degradation, and how he will be releasing a kext soon -
neither of which is mentioned in the github readme, but buried in HN comments?
A small portion of users might be considered vigilant, but they're not
psychic.

The largest target for local privesc are the people who get hit by different
kinds of malware, usually as a payload in sleazy spyware installers. The
malware authors now have a few profitable weeks before Apple patches it
(here's hoping they're quick!) and only the elite few who know how to deploy
an unsigned kext (that still isn't available) will be able to protect
themselves.

Still not seeing the upside to this.

~~~
scintill76
I'm counting on the press and community to distribute the information about
the no_shared_cr3 workaround and any kext that comes out, just as Apple's fix
is most effective when everyone's being told they should be sure it gets
applied.

There are people in this thread more secure today than they were yesterday,
and they owe it to this "irresponsible disclosure." Do they have less of a
right to security than the "unelite"? We don't know whether this is already
being exploited by someone else, and as you said, it could be weeks before an
official patch. This release both lights a fire under Apple and helps a few
people patch early or at least be extra-careful about what they execute.
That's an "upside"... I guess it's down to one's own values and possibly
omniscience to conclusively determine whether the downsides outweigh that.

A more responsible version of this might be to release the source of a kext
that patches the issue concurrently with confirmation from Apple. Apple got a
few hours' head-start, some people can patch early, malware authors will have
to spend some time reverse-engineering a complete exploit.

~~~
gress
This argument is a general argument for is irresponsible disclosure of 0-days.

You don't need omnicience to determine whether the downsides outweigh the
potential benefits to a tiny number of jumpy elite who would have to be
constantly following and applying patches.

Notably those patches couldn't be applied blindly - so all of those 'elite' in
parallel would have to fully understand the exploit and patches lest these
become just another attack vector.

There is clearly no justification for this. This isn't just irresponsible.
It's a straight up attack on users.

~~~
mikeash
Malware that uses this exploit to cause damage is a straight up attack on
users. Merely revealing a vulnerability isn't an attack. The vulnerability was
there all along, and there's no guarantee that this person is the only one who
could find it, or even the first.

I'm all for responsible disclosure. But I think we need to clarify good and
bad here. Responsible disclosure is _better_ than just announcing findings to
the world, but telling people about what you've discovered is not _bad_.

~~~
MagerValp
There's writing a nicely worded letter, and sending it in a rose scented
envelope. And then there's scribbling a note, tying it to a rock, and throwing
it through the window.

Telling the world via a fully working exploit causes a ton of collateral
damage, and the author made no effort at all to reduce the impact. Waiting for
10.10.5 and releasing it on a Saturday afternoon makes it seem like the point
was to cause as big a mess as possible.

~~~
mikeash
Maybe Saturday afternoon just happened to be when he finished.

And no, it's not like throwing a rock through somebody's window. The
information may be used by other people to cause damage, but the mere act of
releasing it is not by itself damaging. Let's put blame where it belongs: on
the people actually using exploits for bad purposes. If you want to encourage
responsible disclosure, don't lead with bad analogies about what happens when
you announce a vulnerability to the world, because it just reduces your
credibility.

~~~
qwertyoruiop
for the record: i had no idea yesterday was saturday at the time I dropped the
code.

~~~
mikeash
Nothing says "hardcore hacker at work" quite like forgetting what day of the
week it is.

~~~
gress
Nothing says 'irresponsible' like not thinking at all about the impact of
releasing information you know people will use for harm. Publishing to github
comes after the hacking.

If qwertyoruiop had instead come up with plans for making a suitcase nuke from
household ingredients, or for breeding an Ebola analog using a home beer
making kit, your argument would imply that you think that posting them on the
Internet would not be bad.

I disagree.

~~~
mikeash
And again with the ridiculous analogies.

It's really difficult to have a serious discussion about computer security
vulnerabilities when people keep comparing it to throwing rocks through
windows or weapons of mass destruction.

And yes, it's relevant, because the severity of a problem can and does
influence how problematic various approaches are.

This is a local root exploit. Those are common and not generally problematic.
The barrier to escalating from a normal user to root is at best the absolute
last line of defense, and often completely irrelevant. It's a problem that
should be fixed, don't get me wrong, but the severity is about 2 out of 10.

The fact that I think it's not a bad thing to release information like this
has no bearing on what I would think about releasing information on building a
suitcase nuke from household ingredients.

Could we try to keep the conversation grounded, here?

~~~
gress
If you had been saying before now that this wasn't a severe bug and so we
shouldn't be too concerned about disclosure, then you wouldn't have been
presented with these strong counterarguments.

But that isn't what you've been saying - rather, you've been making the
general argument that releasing information is not damaging or bad, and that
we should only hold the people who exploit vulnerabilities responsible - not
those who disclose them. Multiple people have argued against you on this.

Now you have switched your position to 'It's not bad to disclose
vulnerabilities unless they are severe'. This seems much more reasonable, and
came as the consequence of you being presented with what you are calling
'ridiculous' analogies.

To me this seems like a serious discussion done right.

------
gregwtmtno
Any way to protect a machine until apple publishes an update?

~~~
qwertyoruiop
add -no_shared_cr3 to your boot-args.

it will have an hefty performance penalty, but if you value security over
performance, it'll also protect you against a lot of (even 0day!) exploits.

~~~
clebio
Could you provide some context for that? What does that flag do? How do you
even set boot args for OSX? I have little context to OSX boot process, and
would like to understand this better.

~~~
qwertyoruiop
'sudo nvram boot-args=-no_shared_cr3' will do the trick.

The flag essentially prevents kernel from accessing userland memory unless
special routines are used. Since the bug is a NULL pointer deference (which
requires a read to userland memory in order to be exploited), exploitation
becomes impossible. Due to this flag, however, your kernel will have to
context switch every time a system call is done, which does have a noticeable
performance impact. I will be releasing a KEXT to fix the bug soon.

~~~
clebio
Well, I was more looking for an explanation of what "no shared CR3" means.
What is CR3, how do I know to go to that option as a way to disable this
exploit.

And, coming from a Grub/ubuntu perspective, when you say "boot args", I think
of the boot loader, which for Grub is configured with config files (text
files) or else at boot-time, via the Grub menu. I know OSX has a single-user
mode, but don't know of a way to edit boot args prior to completing the boot
sequence.

Please don't take this wrong. I'm glad to see the original fix you gave, so
much so that I want to know more about it. What provides the capability, how
to know the specific options that mitigate such a vulnerability.

~~~
glitch
CR3:
[https://en.wikipedia.org/wiki/Control_register#CR3](https://en.wikipedia.org/wiki/Control_register#CR3)

Some relevant excerpts from _Mac OS X and iOS Internals: To the Apple 's Core_
by Jonathan Levi:

From page 133: _In 64-bit mode, there is such a huge amount of memory
available anyway that it makes sense to follow the model used in other
operating systems, namely to map the kernel’s address space into each and
every process. This is a departure from the traditional OS X model, which had
the kernel in its own address space, but it makes for much faster user /kernel
transition (by sharing CR3, the control register containing the page tables)._

From page 266: _Still, unlike Windows or Linux, OS X applications in 32-bit
(Intel) used to enjoy a largely unfettered address space with virtually no
kernel reservation — that is, the kernel had its own address space. Apple has
conformed, however, and in 64-bit mode OS X behaves more like its monolithic
peers: the kernel /user address spaces are shared, unless otherwise stated (by
setting the -no-shared-cr3 boot argument on Intel architectures). The same
holds true in iOS, wherein XNU currently reserves the top 2 GB of the 4 GB
address space (prior to iOS version 4 the separation was 3 GB user/1 GB
kernel)._

------
abhv
(1) Can I also ask how you found this? Were you fuzzing Iokit?

(2) I'm trying to work through your ROP. Can you explain a bit more? Thanks.

~~~
qwertyoruiop
1) I cannot really discuss specifics, but this particular bug would have been
hard to find via a traditional IOKit fuzz, since it requires an invalid 'task'
port passed over to IOServiceOpen. Most fuzzers use mach_task_self for that,
and fuzz method calls/traps/properties/etc.

2) When IOServiceRelease is called, vtable+0x20 is called. the vtable pointer
is controlled, at +0x20 I place a stack pivot, which sets RSP = RAX and pops 3
times. At 0x20 I place a POP RAX;RET gadget to let the chain begin after 0x28.
Payload then locates the credentials structure, sets UID to 0 by bzero()ing,
cleans up the memory corruption, decreases the task count for current user and
increases task count for root. It then unlocks locks held by IOAudioEngine to
prevent your audio from freezing up, and then returns to the userland context.

~~~
qwertyoruiop
for the record: "At 0x20 I place a POP RAX;RET gadget" should be "At 0x18 I
place a POP RAX;RET gadget".

------
thrownaway2424
Interesting. This prompted me to look at my Mac and it's running 10.10.3, I
never got a prompt to update to 10.10.4 or 10.10.5, but when I open App Store
it tells me there's an upgrade to 10.10.5. I guess Apple managed to break the
automatic update mechanism in 10.10.3.

I wonder if this is related to the behavior where my iMac wakes up every
minute starting every morning at 2AM. This is so obnoxious that I now turn my
iMac off at night instead of putting it to sleep.

~~~
joao
Do happen to have Adobe software installed? Perhaps something from Creative
Cloud. It usually checks for updates at 2am, might be what its turning on your
Mac from sleep.

You will have to disabling automatic updates for that not to occur.

------
pit
I'm running 10.10.4, and it just crashed my Mac -- the "A problem has
occurred" screen -- followed by a forced restart.

~~~
readme
Yep, same result here on 10.10.4 heh.

~~~
qwertyoruiop
Interesting. I am on 10.10.4 myself, and that's the OS I tested it on.

tpwn has been tested from 10.9 to 10.10.5, but of course, your mileage may
vary. the KASLR leak part is not 100% reliable, unlike the actual code
execution which is. I'd be interested in panic logs to sort the issue out, if
you could share.

~~~
devy
10.10.5 kernel panic too.
[https://gist.github.com/anonymous/6a76b0793607c890c3ea](https://gist.github.com/anonymous/6a76b0793607c890c3ea)

~~~
qwertyoruiop
You are not vulnerable since you have SMAP!

~~~
m1keil
what's SMAP? can't find info anywhere. edit: ok, found, cpu security feature.
so it's possible this issue is mitigated on newer CPUs?

~~~
qwertyoruiop
well, this bug is a null pointer deference. smap is like -no_shared_cr3, but
without the performance loss.

------
facetube
Does anyone know if 10.9.5 is vulnerable?

~~~
qwertyoruiop
Yes, it is.

~~~
facetube
Thanks.

------
x0
Okay, this is really weird... after rooting, and pressing ^D or typing exit, I
stay root

    
    
        ~/code/tpwn % id -u
        503
        
        ~/code/tpwn % ./tpwn
        leaked kaslr slide, @ 0x0000000005600000
        sh-3.2# exit
        exit
        
        ~/code/tpwn # id -u
        0
    

Edit: and it crashes iTerm2 after the last `id -u`. Managed to get a
screenshot of what I'm talking about:
[http://i.imgur.com/foWgTBN.png](http://i.imgur.com/foWgTBN.png)

~~~
jake223
This does not happen for me.

    
    
      bash-3.2$ ./tpwn
      leaked kaslr slide, @ 0x000000000f800000
      sh-3.2# exit
      bash-3.2$ id -u
      501

------
chatmasta
And here I was pressing "update later tonight." Thanks for the heads up!

~~~
gargarplex
Unless you manually update to 10.11 you are still vulnerable

------
thought_alarm
Does it work on 10.11 with "rootless" mode disabled?

~~~
kibibyte
I just tested on 10.11 with rootless being disabled, and it prints out "not
vulnerable".

I assume that if it doesn't work on 10.11, then rootless being enabled or
disabled shouldn't make a difference. You still have a root user either way,
it's just that if rootless is enabled, then the root user wouldn't be able to
modify certain system directories, which could mitigate the consequences of
such an attack if it did work.

~~~
mbilker
In the README it states the vulnerability is not present in 10.11.

------
mbilker
At least 10.11 isn't vulnerable

~~~
landr0id
For what it's worth I believe he also has a 0day for bypassing rootless. Check
his Twitter.

~~~
rsy96
What is his twitter account?

~~~
josso
[https://twitter.com/qwertyoruiop](https://twitter.com/qwertyoruiop)

~~~
_delirium
The author also has an interesting and relevant series of blog posts:
[http://blog.qwertyoruiop.com/?p=38](http://blog.qwertyoruiop.com/?p=38)

------
edude03
So for anyone who hasn't tried it but is wondering about it - it works on
10.10.4 and 10.10.5, running the tpwn binary does drop you to a root shell.
Looks like a weakness in the address randomization in OS X

~~~
gizmo686
I haven't look into this vulnerability, but how could it be a weakness in
address randomization? Isn't address randomization supposed to be a
mitigation, to make it more difficult to exploit other vulnerabilities.

~~~
qwertyoruiop
There is no weakness in address randomization I relied on for exploitation.

It relies on two distinct bugs, an info-leak to obtain a pointer to an
allocation in the kalloc.1024 zone and a memory corruption primitive (deriving
from a NULL pointer dfr. in IOKit) allowing me to OR 0x10 anywhere in kernel
memory.

To break kASLR I corrupt the size of a vm_map_copy struct, which allows me to
read the adjacent allocation to the struct, which is a C++ object. First 8
bytes of said C++ object is a pointer to the vtable, which resides in __TEXT
of some kernel extension. Since I can calculate the unslid address from
userland without any issue, by subtracting what gets leaked with what gets
calculated you get to know the kASLR slide.

Just to clarify: The code execution part has 100% reliability rate. The kASLR
leaking part does have some chance in it, however empirical evidence indicates
that the failure rate is extremely low.

~~~
XMPPwocky
So you can bail out cleanly and go around for another run if the infoleak
fails, yeah? Or do bad things happen up in kernelspace?

~~~
qwertyoruiop
If the heap info leak fails, I bail out cleanly. If the kASLR leak fails, it
is usually because instead of hitting a vm_map_copy (the intended structure I
need to corrupt), something completely unrelated is hit instead. If it happens
to hit something different than expected, that's undefined behaviour usually
ending up in a panic.

~~~
bro-stick
Mad props.

If osx were s/xnu/minix 3-style, full microkernel/, sploiting Iokit as a least
priv'd process, only it would get pwned and be limited to iokit's acls. Still
bad, but it likely wouldnt have rights to exec a root shell.

XNU kexts have way too much authority, and all the syscalls they each tack on
compounds the attack surface to the total codebases of all Apple and third-
party kexts. Because once you've found and symbolicated the not-really-hidden
call table, you're pretty much able to do whatever. And with a mutating mem
kext bug ...

~~~
qwertyoruiop
while I agree with you on the security benefits of a full microkernel, to be
entirely honest, if you had access to just IOKit you could easily use a
network card or an hard drive controller to get a physical memory write-what-
where, which in turn would allow you to gain access to anything, plus the
microkernel performance issues of e.g. having to context switch on interrupts.

~~~
bro-stick
That things may be broken is no argument against defense-in-depth and least
privilege. By having smaller codebases and smaller system components, the
attack surface is far, far smaller than say Linux. IOKit is shit as is, and a
full microkernel would break it up into processes based on areas of
responsibility. Also, that shows the hardware needs better bus- and command-
level security to prevent such attacks. (Don't even get me started on closed
firmware blobs or unverifiability of commercial cores.)

Expecting a finished product of a new project would be unreasonable. Minix 3
is early on and not the only full microkernel out there. They will probably
find an approach to reduce context switches if it's a mature optimization to
make. An Android-like mobile/embedded platform would make a sensible research
-> real use-case, minus Java.

