Recently, I have been searching around Apple's Github and discovered PowerManagement's swd was open source. At the time I was looking at random projects that might have an arbitrary root file write, and took a look at its usage of the /tmp directory for it. I discovered from the source that it seems to write a file named /tmp/sw_stackshot
and appends the time stamp to the file name.
swd stands for Sleep Wake Daemon. Whenever it detects a sleep wake failure in EFI, it generates a panic log of swd to create a report. One thing I noticed is that the open() call seems to lack the O_NOFOLLOW flag, meaning it will follow symlinks. This means that if you can somehow manage to guess what the timestamp and make it take a snapshot, then you can make the file it will write to a symlink under user mode, and have the root binary write to that file to write to an arbitrary file restricted to root only. Alright, well if you can do this, why am I talking about it here instead of reporting it to Apple, and why don't I consider it a 0day?
The Problem
Let me be real here: There is no realistic scenario in which an attacker can exploit this. To trigger this someone would need to have the device sleep wake failure, and realistically no process is going to know when a sleep wake failure will happen, or guess the timestamp that it will happen, and even if it does get it, what use is there in writing a panic log to an arbitrary root file? It's not like you get to write your own data to it, you don't really control the data.
Sure, it may be useful if a user doesn't have root privileges, so they have a program write a bunch of timestamps to cover a minute and purposely cause a swd panic in that minute to write to the file they want, but even then as stated previously it's not like they can write custom data. Also, at that point, if a user is willing to purposely cause a swd panic, they deserve root access. Anyone can just take the hard drive out of a Mac and write to root owned files, so is this really an issue? (I forgot about FileVault, but I still don't consider this really an issue)
I think this brings up an interesting point of conversation: If something is realistically unexploitable, but it theoretically is exploitable, is it still a 0day? This is, in my opinion, still a cool bug even if non-functional; I don't really think it is intended behavior to have it write to other directories and it theoretically can be triggered, but there is no realistic scenario in which an attacker can exploit it.
Another Example
Let's take a look at another very similar example. I noticed this line in auditd: fopen("/var/run/auditd.pid","a")
. auditd writes its pid to a file named /var/run/auditd.pid
. It is true that this file has its write access reserved for root, but /var/run
is not! This means that a non-root owned programs can rename /var/run to something else and make a clone of it so that it has write access to everything in the directory, and have auditd.pid be a symlink to something it doesn't have access to but root has, which would make auditd append its pid to the root file. Sure, auditd only writes the pid to the file so you can't write custom data either, but at least a programming not running as root can trigger it, so maybe this has a better chance of being a 0day, right?
Well, notice how I've been neglecting something? I have been specifically saying "non-root" instead of user owned. This is because /var/run is not owned by root or user, but instead, uid 1 (daemon). Now, sure, if you want to be technical, this is a uid 1 program writing to uid 0 files so it technically is privilege escalation in regards to our file write, but lets be real here: uid 1 is already insanely privileged, and you likely aren't going to be able to run as uid 1 specifically instead of uid 0. For this reason, while closer, I still don't really consider this a 0day, or something even worthy of reporting. There is no realistic scenario which this would benefit an attacker, so I don't consider it useful.
What Really Makes a 0day?
Not every bug is exploitable or the end of the world. Just because a bug could theoretically be used to escalate privileges doesn't automatically make it a 0day. Context matters. Exploitability matters. And most importantly, impact matters.
The swd
and auditd
behaviors I noticed are definitely not intended. In a world where an attacker would realistically be able to exploit them, I would report it to Apple in a heartbeat. However, they just really aren't. Both of them already require scenarios so specific that it makes me pretty sure that if I did, Apple would not only deny bounty but deny the report itself.
That being said, I do think that looking at bugs like this are good reminders of what can be real 0days. If /var/run
was owned by user, then even if you still can't control the data auditd appends to the file, this would make it much more realistic for grounds for an attacker to realistically exploit. Are these 0days? Not really, but they're fun.