這個預計許多同學看了不屑,認為是爛大街的對象了:
.htaccess文件組成的PHP后門
那么我來個新的吧:.user.ini。它比.htaccess用的更廣,不管是nginx/apache/IIS,只要是以fastcgi運行的php都可以用這個要領。我的nginx處事器全部是fpm/fastcgi,我的IIS php5.3以上的全部用的fastcgi/cgi,我win下的apache上也用的fcgi,可謂很廣,不像.htaccess有范圍性。
0x01 .user.ini那么什么是.user.ini?
這得從php.ini說起了。php.ini是php默認的設置文件,個中包羅了許多php的設置,這些設置中,又分為幾種:PHP_INI_SYSTEM、PHP_INI_PERDIR、PHP_INI_ALL、PHP_INI_USER。 在此可以查察:http://php.net/manual/zh/ini.list.php 這幾種模式有什么區別?看看官方的表明:
個中就提到了,模式為PHP_INI_USER的設置項,可以在ini_set()函數中配置、注冊表中配置,再就是.user.ini中配置。 這里就提到了.user.ini,那么這是個什么設置文件?那么官方文檔在這里又表明白:
除了主 php.ini 之外,PHP 還會在每個目次下掃描 INI 文件,從被執行的 PHP 文件地址目次開始一直上升到 web 根目次($_SERVER['DOCUMENT_ROOT'] 所指定的)。假如被執行的 PHP 文件在 web 根目次之外,則只掃描該目次。
在 .user.ini 氣勢氣魄的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 配置可被識別。
這里就很清楚了,.user.ini實際上就是一個可以由用戶“自界說”的php.ini,我們可以或許自界說的配置是模式為“PHP_INI_PERDIR 、 PHP_INI_USER”的配置。(上面表格中沒有提到的PHP_INI_PERDIR也可以在.user.ini中配置)
實際上,除了PHP_INI_SYSTEM以外的模式(包羅PHP_INI_ALL)都是可以通過.user.ini來配置的。
并且,和php.ini差異的是,.user.ini是一個能被動態加載的ini文件。也就是說我修改了.user.ini后,不需要重啟處事器中間件,只需要期待user_ini.cache_ttl所配置的時間(默認為300秒),即可被從頭加載。
然后我們看到php.ini中的設置項,惋惜我沮喪地發明,只要稍微敏感的設置項,都是PHP_INI_SYSTEM模式的(甚至是php.ini only的),包羅disable_functions、extension_dir、enable_dl等。 不外,,我們可以很容易地借助.user.ini文件來結構一個“后門”。
Php設置項中有兩個較量有意思的項(下圖第一、四個):
auto_append_file、auto_prepend_file,點開看看什么意思:
指定一個文件,自動包括在要執行的文件前,雷同于在文件前挪用了require()函數。而auto_append_file雷同,只是在文件后頭包括。 利用要領很簡樸,直接寫在.user.ini中:
auto_prepend_file=01.gif
01.gif是要包括的文件。
所以,我們可以借助.user.ini輕松讓所有php文件都“自動”包括某個文件,而這個文件可以是一個正常php文件,也可以是一個包括一句話的webshell。
測試一下,我別離在IIS6.0+Fastcgi+PHP5.3和nginx+fpm+php5.3上測試。 目次下有.user.ini,和包括webshell的01.gif,和正常php文件echo.php:
會見echo.php即可看到后門:
Nginx下同樣:
那么,我們可以猥瑣地想一下,在哪些環境下可以用到這個姿勢? 好比,某網站限制不答允上傳.php文件,你便可以上傳一個.user.ini,再上傳一個圖片馬,包括起來舉辦getshell。不外前提是含有.user.ini的文件夾下需要有正常的php文件,不然也不能包括了。 再好比,你只是想埋沒個后門,這個方法是最利便的。