Old exploit in polkit

this issue is more for admins who have users logging in.
Uhm, so, why do you typically use unprivileged service accounts for network services? 😏

I'd say everyone should care about a hole like that, even if it's just the second step in a possible attack scenario ;)
 
As far as being exploitable on FreeBSD, it would depend on if you have polkit installed. Looking at the commit messages, polkit has been patched for this CVE today (Jan 26). Beyond that, like it has been said before; they need to have access to the system already to use the exploit. I haven't checked on if the polkit by default is SUID on FreeBSD or not, if it wasn't then you had it mitigated.
 
I haven't checked on if the polkit by default is SUID on FreeBSD or not, if it wasn't then you had it mitigated.
Uhm, the affected polkit executable would be pretty pointless without the suid bit, it's the one used to execute things "privileged". Removing the suid bit is mentioned somewhere as a temporary mitigation, but of course this will break some polkit functionality.

From the sources I've seen so far, I only found OpenBSD isn't affected because it doesn't allow execve() without argv[0]. No idea whether the same would hold for FreeBSD. Best just test it, now that some exploit code is available?

What's really worrying me is: Assuming that argc is always at least 1 is really a beginner's error :eek:
 
I have polkit installed (not patched) and tried the above suggested exploit tests: both failed.

In fact, pkexec doesn't seem to work on my system. If I try to pkexec whatever program I get
Error checking for authorization org.freedesktop.policykit.exec: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: get_kinfo_proc() failed for pid 77999: No such process

This may be related to the security hardening options I have in /etc/sysctl.conf:
Code:
security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.see_jail_proc=0
security.bsd.unprivileged_read_msgbuf=0
security.bsd.unprivileged_proc_debug=0
kern.randompid=1

Does it work on your systems?
 
There is some movement ;-) Now we are checking for the number of arguments



It has something to do with this exploit, isn't it? ;-)
 
[FONT=monospace]_martin[/FONT] had this on his profile post last night:
I wrote the exploit yesterday after qualys shared the info on CVE-2021-4034. Due to the nature of the bug argc has to be 0, i.e we need to execute execve(cmd, NULL, env). FreeBSD doesn't allow this -- execve returned error rendering this exploit unusable.

I'm not sure why the patch would be needed but I didn't follow up on the FreeBSD kernel src on that.
 
Probably. But that's just a patch for people who can't read the C standard. Still makes sense of course, there's too much broken crappy software out there.
 
You can test this yourself. Here I'm on 13.0-RELEASE-p6:
Code:
#include <stdio.h>
#include <unistd.h>

int main() {
    char* args[] = { "/bin/ls", "-la", NULL };
    execve(*args, NULL, NULL);

    perror("oops");
    return 42;
}
Test it with $ cc -o test test.c && ./test. Trace shows
Code:
execve("/bin/ls",0x0,0x0)             ERR#14 'Bad address'

So there's already something in the kernel checking this. Other check would be redundant and useless. But let's see what happens to that commit.
 
  • Thanks
Reactions: drr
So there's already something in the kernel checking this. Other check would be redundant and useless.
Well, that's nice. Still doesn't change anything about the fact that relying on argc >= 1 is a severe bug. But it seems it's a somewhat common one, so trying to prevent it makes sense.
 
Are we discussing polkit issue now or how FreeBSD handles it ? There's no question about the bug in polkit. Current implementation on FreeBSD prevents this bug to be triggered.

Glancing at the patch above it seems to be about passing an empty array as args, i.e. execve(*args, fake, NULL) where fake is defined as char* fake[] = { NULL };. Passing args like this doesn't trigger the polkit bug (edit: the code is buggy, but the exploit is not usable) but opened a discussion about sanitizing that too.
That's my assumption at least from what I quickly checked. Not going down the sources to check that for the sake of argument.
 
So why are you trying to execute a C source file?

The readme over there even literally lists the commands to use (just make to build...)
 
It looks like the message is comming from make, so nit his doing.
 
I believe I did it exactly as the GitHub page instructed:

If the exploit is working you'll get a root shell immediately:


Code:
vagrant@ubuntu-impish:~/CVE-2021-4034$ make
cc -Wall --shared -fPIC -o pwnkit.so pwnkit.c
cc -Wall    cve-2021-4034.c   -o cve-2021-4034
echo "module UTF-8// PWNKIT// pwnkit 1" > gconv-modules
mkdir -p GCONV_PATH=.
cp /usr/bin/true GCONV_PATH=./pwnkit.so:.
vagrant@ubuntu-impish:~/CVE-2021-4034$ ./cve-2021-4034
# whoami
root
# exit

If your Cut&Paste skills are superior to mine, why wouldn't they be?

So Sorry..
*sob*
So Very Very Sorry...
*crying*
 
The bug affects systems only which are using GNU libc. It is true that the attack vector is polkit, but the underlying problem is the ccs (coded character set) parameter on fopen() in GNU libc, which allows to load other charsets into iconv during runtime.

Further readings: https://hugeh0ge.github.io/2019/11/04/Getting-Arbitrary-Code-Execution-from-fopen-s-2nd-Argument/

FreeBSD's libc is not GNU, and FreeBSD's libc has no ccs parameter on fopen(). Therefore this exploit doesn't work on vanilla FreeBSD installations.

 
  • Like
Reactions: drr
Careful with that.

Even if the current exploit needs glibc, the underlying bug is assuming argc >= 1 and therefore invalid (stack) accesses. It's perfectly possible a different exploit could be found using this same bug.

OTOH, if FreeBSD indeed prevents starting a process without argv[0], then you can say it's for sure not affected, cause that's preventing this bug in polkit from happening.
 
  • Like
Reactions: drr
The bug affects systems only which are using GNU libc.
Bug requires GLib, not glibc. As said in qualys report.

The POC you shared is demonstrating the issue with gconv-modules and triggers it by fopen() (Linux way).

Also as said in qualys report LD_PRELOAD and friends were not usable as clerenv() is being called very early in the code. But there was an option to trigger it the way described.
Note also due to the bug we are modifying environment (on Linux that is) which was already sanitized by ld.so (and this a building block of the exploit).

FreeBSD survived this because argv can't be NULL (which is needed due to the nature of the bug). It can still do execve(cmd, fake, NULL) where fake[] = { NULL }. Also FreeBSD's ld.so has some extra env sanitation in place that makes this a problem.

We are talking about execve syscall which has nothing to do with libc.
 
Failed for me also in Linux Compatibility Layer.

1643547986310.png
 

Attachments

  • 1643547751309.png
    1643547751309.png
    22.9 KB · Views: 52
jammied That's actually not a bad idea to test. FreeBSD implemented sys_execve differently to linux one, similar to its native one. Small program to test:
Code:
.section .text
_start:
        xorl %edx, %edx
        xorl %esi, %esi
        leaq shstr, %rdi
        movl $59, %eax
        syscall

        movl %eax, %edi
        movl $60, %eax
        syscall

shstr:  .asciz "/bin/sh"
Compile with (using GNU's as from gcc): as -o test.o test.s && ld -o test test.o && brandelf -t Linux ./test

Code:
# truss ./test
linux_execve("/bin/sh",0x0,0x0)                  ERR#-14 'Bad address'
linux_exit(0xfffffff2)
process exit, rval = 4294967282
#
So you can't use the exploit under ABI either.
 
Back
Top