Hello,
Thanks a lot for this writing! That'll surely be an interesting read for whoever wants to look a bit at the details of how the Hurd works. And of course thanks for finding and fixing the vulnerabilities :)
Samuel
Hello!
As promised [0], here are the details of the Hurd vulnerabilities I have found >earlier this year [1] [2].
[0]: https://lists.gnu.org/archive/html/bug-hurd/2021-10/msg00006.html
[1]: https://lists.gnu.org/archive/html/bug-hurd/2021-05/msg00079.html
[2]: https://lists.gnu.org/archive/html/bug-hurd/2021-08/msg00008.html
(You'll notice that I'm formatting this just like a patch series. I'll even try
to send it out with git send-email; if you're reading this, it has worked!)
These texts are partly based on the mails and write-ups I sent to Samuel at the
time, but most of the text is new, rewritten to incorporate the better >understanding that I now have as the result of exploring the issues and working
with Samuel on fixing them.
I've grouped the information by the four "major" vulnerabilities -- ones that I
have actually written an exploit for. Other related vulnerabilities are briefly
mentioned in the notes sections.
Each text contains a short and a detailed description of the relevant issue, >source code of the exploit I have written for the issue, commentary on how the >exploit works, and a description of how we fixed the issue. While this should >hopefully be an interesting read for everyone, understanding some of the details
requires some familiarity with the Mach and Hurd mechanisms involved. I've tried
to briefly describe the necessary bits (as I understand them myself) in the >"Background" sections throughout the texts -- hopefully this will make it easier
to understand. Please don't hesitate to ask me questions (while I can still >answer them)!
I also hope that all this info should be enough to finally allocate official >CVEs for these vulnerabilities, if anyone is willing to go forward with that in
my absence.
While all of the vulnerabilities described have been fixed, most of the fixes >are not yet in the main Hurd tree for legal reasons: namely, my FSF copyright >assignment process is still unfinished. All the out-of-tree patches with the >fixes can be found in the Debian repo [3].
[3]: https://salsa.debian.org/hurd-team/hurd/-/tree/master/debian/patches
Our work on fixing these vulnerabilities required some large changes and touches
most of the major Hurd components (now I can actually name them: glibc, GNU >Mach, libports, libpager, libfshelp, libshouldbeinlibc, lib*fs, proc server, >exec server, *fs, ...) -- and this was even more true of the previous designs >that we have considered (the final design ended up being the most compact one).
Still, it's kind of amazing _how little_ has changed: we managed to keep most >things working just as they were (with the notable exception of mremap ()). The
Hurd still looks and behaves like the Hurd, despite all the changes.
Finally, I should note that there still are unfixed vulnerabilities in the Hurd.
There's another "major" vulnerability that I have already written an exploit >for, but I can't publish the details since it's still unfixed. I won't be there
to see it fixed (assuming it will take less than a year to fix it -- which I >hope it will), but Samuel should have all the details.
Let me know what you think!
Sergey
Hello!
As promised [0], here are the details of the Hurd vulnerabilities I have found
earlier this year [1] [2].
[0]: https://lists.gnu.org/archive/html/bug-hurd/2021-10/msg00006.html
[1]: https://lists.gnu.org/archive/html/bug-hurd/2021-05/msg00079.html
[2]: https://lists.gnu.org/archive/html/bug-hurd/2021-08/msg00008.html
(You'll notice that I'm formatting this just like a patch series. I'll even try
to send it out with git send-email; if you're reading this, it has worked!)
These texts are partly based on the mails and write-ups I sent to Samuel at the
time, but most of the text is new, rewritten to incorporate the better understanding that I now have as the result of exploring the issues and working
with Samuel on fixing them.
I've grouped the information by the four "major" vulnerabilities -- ones that I
have actually written an exploit for. Other related vulnerabilities are briefly
mentioned in the notes sections.
Each text contains a short and a detailed description of the relevant issue, source code of the exploit I have written for the issue, commentary on how the
exploit works, and a description of how we fixed the issue. While this should hopefully be an interesting read for everyone, understanding some of the details
requires some familiarity with the Mach and Hurd mechanisms involved. I've tried
to briefly describe the necessary bits (as I understand them myself) in the "Background" sections throughout the texts -- hopefully this will make it easier
to understand. Please don't hesitate to ask me questions (while I can still answer them)!
I also hope that all this info should be enough to finally allocate official CVEs for these vulnerabilities, if anyone is willing to go forward with that in
my absence.
While all of the vulnerabilities described have been fixed, most of the fixes are not yet in the main Hurd tree for legal reasons: namely, my FSF copyright assignment process is still unfinished. All the out-of-tree patches with the fixes can be found in the Debian repo [3].
[3]: https://salsa.debian.org/hurd-team/hurd/-/tree/master/debian/patches
Our work on fixing these vulnerabilities required some large changes and touches
most of the major Hurd components (now I can actually name them: glibc, GNU Mach, libports, libpager, libfshelp, libshouldbeinlibc, lib*fs, proc server, exec server, *fs, ...) -- and this was even more true of the previous designs that we have considered (the final design ended up being the most compact one).
Still, it's kind of amazing _how little_ has changed: we managed to keep most things working just as they were (with the notable exception of mremap ()). The
Hurd still looks and behaves like the Hurd, despite all the changes.
Finally, I should note that there still are unfixed vulnerabilities in the Hurd.
There's another "major" vulnerability that I have already written an exploit for, but I can't publish the details since it's still unfixed. I won't be there
to see it fixed (assuming it will take less than a year to fix it -- which I hope it will), but Samuel should have all the details.
Let me know what you think!
Sergey
I've been meaning to ask: Why does the hurd attempt to re-authenticate open file descriptors during exec?
William ML Leslie, le ven. 05 nov. 2021 21:18:50 +1100, a ecrit:
which makes the root filesystem reauthenticate all of the
processes file descriptors.
It seems to eliminate a rather convenient method of delegation; a
process opening a descriptor, forking and executing a child, and
dropping privileges, while retaining access to that one resource.
reauthenticating doesn't mean closing. File permissions for open are
checked at the open step, not later on. But then there are other things
than just opening a file, such as starting a translator, which we don't necessarily want to let the unprivileged-with-one-opened-file do.
Samuel
To get someone privileged to authenticate to me, I went with the same exec(/bin/su) trick, which makes the root filesystem reauthenticate all of the
processes file descriptors. If we place our own port among the file descriptors,
we'll get a io_reauthenticate () call from the root filesystem on it, which we'll forward to the proc server, pretending to reauthenticate our process.
<div class="gmail_default" style="font-family:arial,sans-serif">This is fantastic research Sergey, this vuln especially so.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 3 Nov 2021 at 03:49, Sergey Bugaev <<a href="mailto:bugaevc@gmail.com">bugaevc@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
</div></div></div></div>
which makes the root filesystem reauthenticate all of the
processes file descriptors.
It seems to eliminate a rather convenient method of delegation; a
process opening a descriptor, forking and executing a child, and
dropping privileges, while retaining access to that one resource.
William ML Leslie, le ven. 05 nov. 2021 21:18:50 +1100, a ecrit:
which makes the root filesystem reauthenticate all of the
processes file descriptors.
It seems to eliminate a rather convenient method of delegation; a
process opening a descriptor, forking and executing a child, and
dropping privileges, while retaining access to that one resource.
reauthenticating doesn't mean closing. File permissions for open are
checked at the open step, not later on. But then there are other things
than just opening a file, such as starting a translator, which we don't necessarily want to let the unprivileged-with-one-opened-file do.
On Fri, Nov 5, 2021 at 1:41 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
William ML Leslie, le ven. 05 nov. 2021 21:18:50 +1100, a ecrit:
which makes the root filesystem reauthenticate all of the
processes file descriptors.
It seems to eliminate a rather convenient method of delegation; a
process opening a descriptor, forking and executing a child, and
dropping privileges, while retaining access to that one resource.
reauthenticating doesn't mean closing. File permissions for open are checked at the open step, not later on. But then there are other things than just opening a file, such as starting a translator, which we don't necessarily want to let the unprivileged-with-one-opened-file do.
If I may add to what Samuel has said...
The Hurd is a capability system, but not a *pure* capability system:
it implements Unix semantics on top of Mach/capabilities. File
descriptors, exec, setuid, etc. are all Unix concepts.
And in a Unix
system, you definitely expect that a change in a process' authority
applies to things like which files it is allowed to open through a
file descriptor that refers to a directory, which is why all the file descriptors have to be reauthenticated when the auth changes. The file descriptor table is really meant to hold I/O objects, not arbitrary
ports; and I/O objects are expected to behave in a predictable way
when reauthenticated: you keep access to the object, but the object reconsiders what further things you can do to it / access through it, according to your new authority.
As another example, you can open a
device while you have root access, then drop privileges; you'll still
be able to read or write the file descriptor, but you won't be able to fchown/file_chown it.
If you ignore the Unix personality of the system, you can indeed pass
any ports to an otherwise unprivileged task, but you better do it
outside of the file descriptors table. The Mach mechanisms for that
are the bootstrap port and mach_ports_register ().
On Fri, 5 Nov 2021 at 22:17, Sergey Bugaev <bugaevc@gmail.com> wrote:
The Hurd is a capability system, but not a *pure* capability system:
it implements Unix semantics on top of Mach/capabilities. File
descriptors, exec, setuid, etc. are all Unix concepts.
Indeed, and the reason I ask is because I'd like to enable more capability patterns, even though Mach and The HURD don't protect ports like they are capabilities (c.f. hurd/utils/msgport.c for some really cool and impressive "look at how much power youhave!" moments).
One wonderful property of capabilities is that delegating them works. You should be able to weaken them deliberately, but having them weakened for you is a bit weird. The stranger thing is having them become more powerful without an explicit action.Implicitly gaining more power on what is supposed to be a capability sounds like a new way to introduce a confused deputy vulnerability.
Or alternatively, ignore glibc exec() and talk to the exec and proc servers directly.
Short description
=================
The use of authentication protocol in the proc server is vulnerable to man-in-the-middle attacks, which can be exploited for local privilege escalation
to get full root access to the system.
Short description
=================
libports accepts fake notification messages from any client on any port, which
can lead to port use-after-free, which can be exploited for local privilege escalation to get full root access to the system.
Thanks a lot for this writing! That'll surely be an interesting read for whoever wants to look a bit at the details of how the Hurd works. And of course thanks for finding and fixing the vulnerabilities :)
Am I right that the fixes have not been applied yet in the upstream repository?
Ludovic Courtès, le mar. 09 nov. 2021 18:19:03 +0100, a ecrit:
Am I right that the fixes have not been applied yet in the upstream
repository?
That's right. That's still waiting for the copyright assignment.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 286 |
Nodes: | 16 (2 / 14) |
Uptime: | 83:50:23 |
Calls: | 6,495 |
Calls today: | 6 |
Files: | 12,096 |
Messages: | 5,276,885 |