本文原創(chuàng)作者:?p0wd3r
來源:SecWiki
0x00 漏洞概述
1.漏洞簡介
WordPress是一個(gè)以PHP和MySQL為平臺的自由開源的博客軟件和內(nèi)容管理系統(tǒng),近日在github (https://gist.github.com/anonymous/908a087b95035d9fc9ca46cef4984e97)上爆出這樣一個(gè)漏洞,在其<=4.6.1版本中,如果網(wǎng)站使用攻擊者提前構(gòu)造好的語言文件來對網(wǎng)站、主題、插件等等來進(jìn)行翻譯的話,就可以執(zhí)行任意代碼。
2.漏洞影響
任意代碼執(zhí)行,但有以下兩個(gè)前提:
- 攻擊者可以上傳自己構(gòu)造的語言文件,或者含有該語言文件的主題、插件等文件夾
- 網(wǎng)站使用攻擊者構(gòu)造好的語言文件來對網(wǎng)站、主題、插件等進(jìn)行翻譯
這里舉一個(gè)真實(shí)場景中的例子:攻擊者更改了某個(gè)插件中的語言文件,并更改了插件代碼使插件初始化時(shí)使用惡意語言文件對插件進(jìn)行翻譯,然后攻擊者通過誘導(dǎo)管理員安裝此插件來觸發(fā)漏洞。
3.影響版本
<= 4.6.1
0x01 漏洞復(fù)現(xiàn)
1. 環(huán)境搭建
docker pull wordpress:4.6.1
docker pull mysql
docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=hellowp -e MYSQL_DATABASE=wp -d mysql
docker run --name wp --link wp-mysql:mysql -d wordpress
2.漏洞分析
首先我們來看這樣一個(gè)場景:
在調(diào)用create_function
時(shí),我們通過}
將原函數(shù)閉合,添加我們想要執(zhí)行的內(nèi)容后再使用/*
將后面不必要的部分注釋掉,最后即使我們沒有調(diào)用創(chuàng)建好的函數(shù),我們添加的新內(nèi)容也依然被執(zhí)行了。之所以如此,是因?yàn)?code>create_function內(nèi)部使用了eval
來執(zhí)行代碼,我們看PHP手冊上的說明:
所以由于這個(gè)特性,如果我們可以控制create_function
的$code
參數(shù),那就有了任意代碼執(zhí)行的可能。這里要說一下,create_function
這個(gè)漏洞最早由80sec在08年提出,這里提供幾個(gè)鏈接作為參考:
- https://www.exploit-db.com/exploits/32416/
- https://bugs.php.net/bug.php?id=48231
- http://www.2cto.com/Article/201212/177146.html
接下來我們看Wordpress中一處用到create_function
的地方,在wp-includes/pomo/translations.php
第203-209行:
/**
* Makes a function, which will return the right translation index, according to the
* plural forms header
* @param int $nplurals
* @param string $expression
*/
function make_plural_form_function($nplurals, $expression) {
$expression = str_replace('n', '$n', $expression);
$func_body = "
\$index = (int)($expression);
return (\$index < $nplurals)? \$index : $nplurals - 1;";
return create_function('$n', $func_body);
}
根據(jù)注釋可以看到該函數(shù)的作用是根據(jù)字體文件中的plural forms
這個(gè)header來創(chuàng)建函數(shù)并返回,其中$expression
用于組成$func_body
,而$func_body
作為$code
參數(shù)傳入了create_function
,所以關(guān)鍵是控制$expresstion
的值。
我們看一下正常的字體文件zh_CN.mo
,其中有這么一段:
Plural-Froms
這個(gè)header就是上面的函數(shù)所需要處理的,其中nplurals
的值即為$nplurals
的值,而plural
的值正是我們需要的$expression
的值。所以我們將字體文件進(jìn)行如下改動:
然后我們在后臺重新加載這個(gè)字體文件,同時(shí)進(jìn)行動態(tài)調(diào)試,可以看到如下情景:
我們payload中的)
首先閉合了前面的(
,然后;
結(jié)束前面的語句,接著是我們的一句話木馬,然后用/*
將后面不必要的部分注釋掉,通過這樣,我們就將payload完整的傳入了create_function
,在其創(chuàng)建函數(shù)時(shí)我們的payload就會被執(zhí)行,由于訪問每個(gè)文件時(shí)都要用這個(gè)對字體文件解析的結(jié)果對文件進(jìn)行翻譯,所以我們訪問任何文件都可以觸發(fā)這個(gè)payload:
其中訪問index.php?c=phpinfo();
的函數(shù)調(diào)用棧如下:
3.補(bǔ)丁分析
目前官方還沒有發(fā)布補(bǔ)丁,最新版仍存在該漏洞。
0x02 修復(fù)方案
在官方發(fā)布補(bǔ)丁前建議管理員增強(qiáng)安全意識,不要使用來路不明的字體文件、插件、主題等等。
對于開發(fā)者來說,建議對$expression
中的特殊符號進(jìn)行過濾,例如:
$not_allowed = array(";", ")", "}");
$experssion = str_replace($not_allowed, "", $expression);
0x03 參考
https://www.seebug.org/vuldb/ssvid-92459
https://gist.github.com/anonymous/908a087b95035d9fc9ca46cef4984e97
http://php.net/manual/zh/function.create-function.php
https://www.exploit-db.com/exploits/32416/
https://bugs.php.net/bug.php?id=48231
http://www.2cto.com/Article/201212/177146.html
https://codex.wordpress.org/InstallingWordPressinYourLanguage
原文地址:http://paper.seebug.org/63/