The /proc permissions in Illumos were optional. I’m not sure how long this has been an issue but looking at the history of the files associated with the permission check I could not find where the problem was introduced. I checked if this was also an issue in Solaris but this had been fixed in Solaris. However, I could not find the CVE associated with this fix. My suspicion is that this has been an issue prior to the Illumos fork and was found by Solaris engineers and fixed in Solaris but not fixed in Illumos.
I found this vulnerability when I was looking for a RBAC bypass. RBAC in Solaris lets you have different named privileges associated with each process. It is possible for a process with a lot of privileges to drop most of them and keep only the ones that it needs. I thought it might be possible for a low privilege process to use /proc to debug a process owned by the same user that had higher privileges. This was because I thought the filesystem permissions would be the only permission check that would be performed. But if I would have checked the man page I would have seen:
EPERM
An attempt was made to control a process of which the E, P, and I privilege sets were not a subset of the effective set of the controlling process or the limit set of the controlling process is not a superset of limit set of the controlled process.
But I didn’t check the man page and just tried to write to a /proc file of a higher privileged process using bash.
1
|
|
Which instead of giving a permission error gave back an I/O error.
This issue can be demonstrated via the following commands:
First we drop the sys_mount permission which will prevent us from opening proc on our parent bash process because we have a subset of permissions.
1 2 3 4 5 6 7 8 |
|
Next, we try and open the parent process lwpctl and it correctly fails.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Next, we open the file with O_CREAT and it incorrectly succeeds.
1 2 |
|
In Illumos there is the concept of a VNode which is contains a bunch of pointers to methods that are used by the kernel to interact with the filesystem. When a file is opened the kernel will call a #access
method on the VNode first and then will call the open method on the VNode if it the #access
succeeds. However, in the case when O_CREAT is passed the kernel will only call the #create method and it will assume the #create
method will also call the #access
method. In the case of the /proc file system this was not happening so anybody could pass in O_CREAT and no permission check would occur so the open would always succeed. Since there is no other checks not only does this work as an RBAC bypass it always works as a privilege escalation from non-root to root. It is important to note that Zone’s contain this issue and it doesn’t seem possible to use this as a way of escalating your privileges outside of a Zone.
If you look at the patch you can see a call to #praccess
was added and some other checks as well that I don’t understand.
I notified Joyent about this on the 14th of Decemeber and they had a fix commited by the 17th. The advisory from Joyent is available here. The Joyent people are probably quietly cheering on the demise of Solaris because as you can see from this vulnerability security issues might be fixed in Solaris while still being vulnerable in Illumos. One way of looking at this is that Oracle is selling a zero day exploit feed for Joyent’s public cloud. Though, it is probably not that bad because the code bases have diverged a bit.
Exploit
I have an exploit for this that will use the lwp_agent to create a file /tmp/elevator
that is suid root. It also uses the lwp_agent
to write a program to this file that contains:
1 2 3 |
|
It can be compiled via:
1 2 |
|
Example output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|