nginx+php(fpm-php fastcgi)open_basedir安全設定
0x00 實驗目的
根據文章”PHP繞過open_basedir列目錄的研究”通過測試不同的配置驗證本文的繞過basedir的方法是否有效,從而安全配置php open_basedir的目的.
文中後面幾個方法都是windwos下采用列舉的方式列出目錄,linux下需要做暴力猜解的方式才可以,所以不做測試.
測試”DirectoryIterator + Glob”方式是否可以繞過open_basedir
測試webshell工具”菜刀”是否可以繞過open_basedir
0x01 實驗環境
nginx + PHP 5.6.7 fastcgi模式, centos7 linux
目前配置open_basedir有三處地方php-fpm.conf,nginx fastcgi_param,php.ini
下面逐一測試
0x02 測試詳細
只在php-fpm.conf中配置
1 | php_admin_value[open_basedir]=/home/wwwroot/:/proc/:/tmp/ |
結果
open_basedir的目錄以外不能讀,不能寫,不過DirectoryIterator + Glob 可以成功列出全盤檔案
1234567891011121314151617181920212223242526 | 當前open_basediropen_basedir:/home/wwwroot/:/proc/:/tmp/--DirectoryIterator+Glob--....autorelabelbinbootdevetchomeliblib64mediamnt |
菜刀不可跨出basedir
只在nginx的fastcgi_param配置
12 | # set php open_basedirfastcgi_param PHP_ADMIN_VALUE"open_basedir=$document_root/:/tmp/:/proc/"; |
這裡的”$document_root”是nginx中的變數,為nginx的每個server裡的root目錄
比如server www.iamle.com配置的root目錄為/home/wwwroot/www.iamle.com
認真讀php手冊有下面這段話
PHP配置值通過 php_value 或者 php_flag 設定,並且會覆蓋以前的值。
請注意 disable_functions 或者 disable_classes 在 php.ini 之中定義的值不會被覆蓋掉,但是會將新的設定附加在原有值的後面。
使用 php_admin_value 或者 php_admin_flag 定義的值,不能被 PHP
程式碼中的 ini_set() 覆蓋。自 5.3.3 起,也可以通過 web 伺服器設定
PHP 的設定。也就是nignx中fastcgi_param配置php的配置
php_flag用來專門設定布林值,如on, off, 1, 0, true, false, yes, no,
而php_value用來設定所有型別的值
結果和上面一樣
open_basedir的目錄以外不能讀,不能寫,不過DirectoryIterator + Glob 可以成功列出全盤檔案
菜刀不可跨出basedir
只在php.ini配置
1234 | [HOST=www.iamle.com]open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/[PATH=/home/wwwroot/www.iamle.com/]open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/ |
意思是當HOST=www.iamle.com設定open_basedir,當PATH=/home/wwwroot/www.iamle.com/
設定open_basedir,我測試的時候2個任意設定一個都是有效的
結果和上面一樣
open_basedir的目錄以外不能讀,不能寫,不過DirectoryIterator + Glob 可以成功列出全盤檔案
菜刀不可跨出basedir
0x03 個人結論
DirectoryIterator + Glob的方式可以列出php伺服器上所有檔案,看似沒什麼危害,實際上對於長期的APT絕對有幫助.
open_basedir不是想象的那麼安全,說不定別人手上有甚至有能讀寫open_basedir的0day
0x04 個人推薦的nginx + php(fastcgi fpm-php)(lnmp) open_basedir的配置
先設定fpm-php中pool池中的總open_basedir這叫頂層設計,有個總限制,比如統一限制到/home/wwwroot/這樣的web目錄下
再對nginx中單個server 通過 fastcgi_param PHP_ADMIN_VALUE 設定
再對php.ini設定 [HOST=XXX] [PATH=XXX]
三管齊下媽媽再也不用擔心我的php open_basedir了(希望吧)
雖然很囉嗦,但是這樣豈不是更放心
總而言之就是下面的結果,我就是下面這種囉嗦的配置
12345678910111213 | #在php-fpm.conf對應的pool池中行尾配置php_admin_value[open_basedir]=/home/wwwroot/:/proc/:/tmp/#在nginx fastcgi fastcgi_param配置#這裡用$document_root是一種取巧的方法,也可以設定絕對路徑# set php open_basedirfastcgi_param PHP_ADMIN_VALUE"open_basedir=$document_root/:/tmp/:/proc/";#在php.ini行尾配置[HOST=www.iamle.com]open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/[PATH=/home/wwwroot/www.iamle.com/]open_basedir=/home/wwwroot/www.iamle.com/:/proc/:/tmp/ |
測試中還發現這三個地方配置的優先順序如下
“php.ini” > “nginx fastcgi fastcgi_param” > “php-fpm.conf”
如果有錯誤歡迎大家留言斧正,感謝!