Critical vulnerability in PolKit allowing root access on most Linux distributions

Qualys has identified a vulnerability (CVE-2021-4034) in the Polkit (formerly PolicyKit) system component used in distributions to allow unprivileged users to perform actions that require elevated access rights. The vulnerability allows an unprivileged local user to escalate their privileges to root and gain full control of the system. The problem was codenamed PwnKit and is notable for producing a working exploit that runs in the default configuration on most Linux distributions.

The problem is present in PolKit's pkexec utility, which comes with the SUID root flag and is designed to run commands with the privileges of another user according to the specified PolKit rules. Due to incorrect handling of command line arguments passed to pkexec, an unprivileged user could bypass authentication and run their code as root, regardless of the access rules set. For an attack, it does not matter what settings and restrictions are specified in PolKit, it is enough that the SUID root attribute is set for the executable file with the pkexec utility.

Pkexec does not check the validity of the command line argument count (argc) passed when starting a process. The developers of pkexec assumed that the first entry in the argv array always contains the name of the process (pkexec), and the second either a NULL value or the name of the command launched via pkexec. Since the argument count was not checked against the actual contents of the array and was assumed to be always greater than 1, if a process was passed an empty argv array, as the Linux execve function allows, pkexec would treat NULL as the first argument (the process name) and the next one as outside the buffer memory, like the subsequent contents of the array. |———+———+——+————|———+———+——+————| | argv[0] | argv[1] | ... | argv[argc] | envp[0] | envp[1] | ... | envp[envc] | |—-|—-+—-|—-+——+——|——|—-|—-+—-|—-+——+——|——| VVVVVV "program" "-option" NULL "value" "PATH=name" NULL

The problem is that after the argv array there is an envp array in memory containing environment variables. Thus, if the argv array is empty, pkexec extracts data about the command run with elevated privileges from the first element of the array with environment variables (argv[1] became identical to envp[0]), the contents of which can be controlled by the attacker.

Having received the value of argv[1], pkexec tries, taking into account the file paths in PATH, to determine the full path to the executable file and writes a pointer to the string with the full path back to argv[1], which leads to overwriting the value of the first environment variable, since argv[ 1] is identical to envp[0]. By manipulating the name of the first environment variable, an attacker can substitute another environment variable in pkexec, for example, substitute the “LD_PRELOAD” environment variable, which is not allowed in suid programs, and arrange for their shared library to be loaded into the process.

The working exploit involves substituting the GCONV_PATH variable, which is used to determine the path to the symbol transcoding library, dynamically loaded when calling the g_printerr() function, the code of which uses iconv_open(). By redefining the path in GCONV_PATH, an attacker can ensure that it is not the standard iconv library that is loaded, but its own library, the handlers from which will be executed when an error message is displayed at the stage when pkexec is still running with root rights and before launch permissions are checked.

It is noted that despite the fact that the problem is caused by memory corruption, it can be reliably and repeatably exploited regardless of the hardware architecture used. The prepared exploit has been successfully tested on Ubuntu, Debian, Fedora and CentOS, but can also be used on other distributions. The original exploit is not yet publicly available, indicating that it is trivial and can be easily recreated by other researchers, so it is important to install the patch update as soon as possible on multi-user systems. Polkit is also available for BSD systems and Solaris, but has not been studied for use on them. What is known is that the attack cannot be carried out on OpenBSD, since the OpenBSD kernel does not allow a null argc value to be passed when execve() is called.

The problem has been present since May 2009, since the addition of the pkexec command. The fix for the PolKit vulnerability is currently available as a patch (no patch release has been released), but since distribution developers were notified of the problem in advance, most distributions published the update simultaneously with the disclosure of information about the vulnerability. The issue is fixed in RHEL 6/7/8, Debian, Ubuntu, openSUSE, SUSE, Fedora, ALT Linux, ROSA, Gentoo, Void Linux, Arch Linux and Manjaro. As a temporary measure to block the vulnerability, you can remove the SUID root flag from the /usr/bin/pkexec program (“chmod 0755 /usr/bin/pkexec”).



Source: opennet.ru

Add a comment