8 ms·
Pwnkit: Local Privilege Escalation in polkit's pkexec
- detaro 5y agohttps://news.ycombinator.com/item?id=30077271 https://news.ycombinator.com/item?id=30077271
- loeg 5y agoAnd https://news.ycombinator.com/item?id=30075993 https://news.ycombinator.com/item?id=30075993
- Klasiaster 5y agoSetuid programs like pkexec or sudo are hard to get right… Here an example of using systemd-run (not setuid, and the wrapper script neither) for something similar like sudo (but it uses a systemd unit instead of a direct child process in the same process group): https://gist.github.com/pothos/73dd4f7694acc3b6bbed614438f6e2b1 https://gist.github.com/pothos/73dd4f7694acc3b6bbed614438f6e... Since polkit is used (but not the setuid pkexec, this was the point of this exercise) there is still one setuid binary invoked for the PAM check, though.
- remram 5y agoDoesn't --scope run the process as a child? Is this done without setuid?
- Klasiaster 5y agoIt won't be a child process because PID 1 will actually start this unit. Yes, without setuid because PID 1 takes the request from the unprivileged systemd-run client.
- remram 5y agoI said with --scope: > If a command is run as transient scope unit, it will be executed by systemd-run itself as parent process and will thus inherit the execution environment of the caller. (...) This mode is enabled via the --scope switch
- throwawayboise 5y agoSudo got so complex that OpenBSD replaced it with their own much simpler "doas." But even doas has grown some additional features since it was first released.
- nerdponx 5y agoWhat's the origin of this complexity? Too many configurations and settings? The project being really old and lacking a strong culture around software architecture? Something else?
- throwawayboise 5y agoI believe it's mostly years of "creeping featuritis" but I don't really know the history in detail. Just read the sudoers(5) manpage and let the sense of hopelessness slowly overtake you.
- foxfluff 5y agoThere's irony in the man page telling you not to despair. There's an xkcd about it: https://xkcd.com/1343/ https://xkcd.com/1343/ By comparison, the manual to doas.conf is pretty short: https://man.openbsd.org/doas.conf.5 https://man.openbsd.org/doas.conf.5 It seems like OpenBSD was also stuck on an older version of sudo when it was removed. It's possible they just weren't having all the churn of such a large tool? But then they also missed a bunch of important fixes: https://marc.info/?l=openbsd-bugs&m=142270265216628&w=2 https://marc.info/?l=openbsd-bugs&m=142270265216628&w=2 More: https://marc.info/?l=openbsd-ports&m=143465998814989&w=2 https://marc.info/?l=openbsd-ports&m=143465998814989&w=2
- mjb 5y agoThis is a great write-up, and also a great illustration of something that's fundamentally broken in the way Linux and Unix think about security. `suid` binaries exist for a good reason: they allow users to escalate their privilege in limited ways under control of the system. Good, but obviously risky if the user can subvert that control. The offered solution to that risk is where the problem comes in. Developers of suid binaries are just asked to write them really, really carefully. There are some documents to describe how to do it carefully, but they pretty much assume that code can be developed without bugs, as long as we're careful enough. At least initially, there was no help, no tooling, no verification, no testing, nothing. Just real, real careful. Unfortunately, instead of seeing the absurdity of that situation, many people have gone all "no true Scotsman" on it. "If you were a real Unix Developer then you wouldn't make mistakes like that." We don't need no stinking tools, we're Real Programmers. The situation has been improving, but the underlying mechanism is still super popular and here to stay. It's either time to stop pretending that local `root` means anything, or start taking stuff like this much much more seriously. Some people sure are, but it hasn't pervaded the culture yet.
- jonathanstrange 5y agoI don't really understand your point. The kernel, cryptographic primitives, and device drivers also need to be developed really, really carefully. Some things require more care than others. What would be the alternative?
- mjb 5y agoIt seems like a good first goal would be to dramatically reduce the size of the code base you need to trust (especially complex code with high privilege), and focus on verifying the correctness of that code base. Then, have fine-grained encapsulation mechanisms for things that do need some level of privilege, and especially avoid conflating "can administer the system" and "can access all user data" levels of privilege. As an example, although one that practically seems to have turned out harder to do than the authors expected, take a look at HiStar: http://www.scs.stanford.edu/histar/ http://www.scs.stanford.edu/histar/
- 5y ago
- jandrusk 5y agoThere is already POC code published: https://github.com/mebeim/CVE-2021-4034 https://github.com/mebeim/CVE-2021-4034
- petergottesman 5y agoWorth noting that this and the other exploit that was posted on twitter last night do not work (at least) on Fedora 34, and some versions of OpenSUSE. Generally they will not work on versions of polkit which disable GVFS. My POC [0] handles this by just setting the relevant env variable explicitly. [0] https://github.com/PeterGottesman/pwnkit-exploit https://github.com/PeterGottesman/pwnkit-exploit
- mwarkentin 5y agoThe piece of polkit that this exploits was blogged about in 2013: https://ryiron.wordpress.com/2013/12/16/argv-silliness/ https://ryiron.wordpress.com/2013/12/16/argv-silliness/
- tyingq 5y agoGreat find...so they gave up at "However, because we can’t pass any option arguments, the executing user will default to root, which presumably we don’t have the password for." It seems possible the current exploit authors read this and picked up from there..."what else could we do given that we can't pass options?"
- noobermin 5y agoIf this was known in 2013 why wasn't it fixed? This is literally a simple error in parsing program arguments.
- dc-programmer 5y agoThis is the dark side of risk based security which often manifests. The code gets audited over a day or two and items get ranked by severity. The “minor” bugs are fixed much later if never and it’s ok because they are low severity. But if you pull on the threads of minor issues there are usually deeper issues at play. Further bugs might be minor if considered independently, but can be chained together to perform severe exploits. Given the resources, I think the best approach is to just aggressively eliminate all known undefined behavior in a application
- karmakaze 5y agoFrom Wikipedia for Polkit > It is also possible to use polkit to execute commands with elevated privileges using the command pkexec followed by the command intended to be executed (with root permission).[7] However, it may be preferable to use sudo, as this command provides more flexibility and security, in addition to being easier to configure.[8] > A memory corruption vulnerability PwnKit (CVE-2021-4034[10]) discovered in the pkexec command (installed on all major Linux distributions) was announced on January 25, 2022.[11][12] The vulnerability dates back to the original distribution from 2009. The vulnerability received a CVSS score of 7.8 ("High severity") reflecting serious factors involved in a possible exploit: unprivileged users can obtain full root privileges, independent of the underlying machine architecture, regardless of whether the polkit daemon is running or not. Does a lot of software depend on pkexec? How could it be secured to be recommended over sudo?
- foxfluff 5y agoOn my desktop, only pipewire and intel video drivers depend on polkit. I don't know if they actually use pkexec though.
- rascul 5y ago> Does a lot of software depend on pkexec? If I try to remove polkit here, it would result in the loss of various parts of KDE and Gnome, PCManFM, and virt-manager. I'm not sure if it's a hard dependency, a dependency of a dependency, or what. I'm also not sure if they use pkexec specifically.
- josephcsible 5y agoHere's a shorter summary of the vulnerability: for (n = 1; n < (guint) argc; n++) Usually, after that loop, n equals argc (or could be less than argc if the loop breaks or something). But if argc is 0, then n will equal 1 after. Later on, the program writes to argv[n]. If argc is 0, then argv[n] is argv[1], which is out-of-bounds, but happens to refer to the same place as envp[0] (at least on Linux). This lets the attacker set an arbitrary environment variable, after ld.so(8) already sanitized the environment. In particular, setting the GCONV_PATH environment variable (which is one that would have been removed during sanitization) will cause pkexec to load and execute code from a .so file in an attacker-controlled directory.
- tptacek 5y agoIt is a truly excellent vulnerability that hits a weird POSIX corner case, coupled with a fairly subtle coding error.
- likpok 5y agoHow does this exploit avoid environment sanitization? Is that because most environment sanitization (e.g. clearenv) adjusts the pointer rather than the memory, and argv[argc + 1] is the original environment location?
- lilyball 5y agoIt's because this environment manipulation occurs after ld.so sanitized the environment, and there are opportunities to then trigger behavior based on the environment before pkexec re-sanitizes it. The GCONV_PATH variable in particular makes it load shared code when attempting to log an error.
- josephcsible 5y agoBecause the code that gets exploited to set the environment variable runs after sanitization has already finished, and no further sanitization happens between then and when it gets read.
- notyourday 5y agoThere's zero reason for policykit to be installed on multiuser systems or servers. This is just a part of bizarre obsession with "new tools" bullshit coming from RedHat and the inept software developers it accumulates. The following should be the output of "find / -type f -perm -4000 -o -perm -2000" on a VM. If it is a container, you might need an "su" and/or "sudo" and maybe, if for some reason you are using a cron internal to the container (but why?!), crontab. /usr/bin/chfn /usr/bin/chage /usr/bin/chsh /usr/bin/sudo /usr/bin/crontab /usr/bin/su /usr/bin/ssh-agent /usr/bin/newgrp /usr/bin/passwd
- offmycloud 5y agoIf polkit is "sudo for GUIs", are there any use cases for polkit on a non-GUI Linux server?