這篇文章主要講解了“怎么利用PHP-FPM實現繞過open_basedir”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么利用PHP-FPM實現繞過open_basedir”吧!
0X00 安裝模式
成都創新互聯公司從2013年創立,是專業互聯網技術服務公司,擁有項目成都網站設計、網站制作網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元浙江做網站,已為上家服務,為浙江各地企業和個人服務,聯系電話:13518219792
在PHP中有以下幾種常見的安裝模式:1. CGI模式
CGI是通用網關接口,HTTP使用這樣的接口程序來調用外部程序,外部程序可以使用任何計算機語言來編寫,例如C,C++,Perl,Visual Basic,Shell等等,歷史上用來編寫CGI程序使用最廣泛的是Perl語言。
服務器在認為這是一個CGI請求時,會調用相關CGI程序,并通過環境變量和標準輸出將數據傳送給CGI程序,CGI程序處理完數據,生成html,然后再通過標準輸出將內容返回給服務器,服務器再將內容交給用戶瀏覽器,CGI進程退出。
CGI的出現讓WEB從靜態變為為動態,隨著Web的越來越普及,很多的網站的都需要有動態的頁面,以便與瀏覽者互交。CGI方式的缺點也越來越突出。因為HTTP要生成一個動態頁面,系統就必須啟動一個新的進程以運行CGI程序,CGI采用fork and execution方式,每次請求都需要新建立CGI程序來進行處理,不斷地fork是一項很消耗時間和資源的工作,導致性能的低下。這就出現了FastCGI。2. FastCGI模式
FastCGI是從CGI發展改進而來的。傳統CGI接口方式的主要缺點是性能很差,因為每次HTTP服務器遇到動態程序時都需要重新啟動腳本解析器來執行解析,然后結果被返回給HTTP服務器。這在處理高并發訪問時,幾乎是不可用的。另外傳統的CGI接口方式安全性也很差,現在已經很少被使用。FASTCGI快速通用網關接口是常駐內存的CGI,實際上是對CGI程序的進程管理,FastCGI接口方式采用C/S結構,可以將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啟動一個或者多個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,可以將其直接交付給FastCGI進程來執行,然后將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務器專一地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。
相關的Fastcgi學習可到合天網安實驗室操作實驗——Fastcgi安全:實驗:Fastcgi安全(合天網安實驗室)本實驗介紹了fastcgi安全,是以nginx+php+fastcgi為環境,在多臺fastcgi服務器做的情況下,容易出現的錯誤。3. Module模式
Module模式就是把php作為apache的一個子模塊來運行,使用LoadModule來加載php模塊,比如在apache的配置文件中
//httpd.confLoadModule php7_module "${INSTALL_DIR}/bin/php/php7.2.13/php7apache2_4.dll"
當web訪問php文件時,apache會調用php模塊來解析,phpmodule通過sapi來把數據傳遞給php解析器進行解析。4. PHP-FPM模式
最后是本篇文章的主角PHP-FPM,FPM是一個FastCGI協議解析器,Nginx等服務器中間件將用戶請求按照FastCGI的規則打包好發送給PHP-FPM,再由PHP-FPM來將打包的數據進行解析并與FastCGI進行通信,PHP-FPM就是為了實現和管理FastCGI協議的進程(fastcgi進程管理器),管理一個進程池,處理來自于web服務器的請求。其中,Ngnix與PHP-FPM有兩種通信方式,分別是TCP與Unix domain sockets模式。在windows系統中只能使用tcp socket的通信方式。
TCP模式
TCP模式是PHP-FPM進程監聽本機上端口(默認為9000),Ngnix將用戶請求按照fastcgi的規則打包好發送給php-fpm,由PHP-FPM調用cgi進行解析。TCP通信模式允許通過網絡進程之間的通信,也可以通過loopback進行本地進程之間通信。
Unix domain sockets模式
Unix socket 又叫 IPC (inter-process communication 進程間通信) socket,用于實現同一主機上的進程間通信,這種方式需要在 Ngnix配置文件中填寫 PHP-FPM 的 socket 文件位置。
在P神的Fastcgi協議分析 && PHP-FPM未授權訪問漏洞 && Exp編寫這篇文章中對其中的原理已經做了比較詳細的解釋:
假如用戶訪問
http://127.0.0.1/index.php?a=1&b=2
如果web 目錄為 /var/www/html,Nginx將請求變成鍵值對
{ 'GATEWAY_INTERFACE': 'FastCGI/1.0', 'REQUEST_METHOD': 'GET', 'SCRIPT_FILENAME': '/var/www/html/index.php', 'SCRIPT_NAME': '/index.php', 'QUERY_STRING': '?a=1&b=2', 'REQUEST_URI': '/index.php?a=1&b=2', 'DOCUMENT_ROOT': '/var/www/html', 'SERVER_SOFTWARE': 'php/fcgiclient', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '12345', 'SERVER_ADDR': '127.0.0.1', 'SERVER_PORT': '80', 'SERVER_NAME': "localhost", 'SERVER_PROTOCOL': 'HTTP/1.1'}
這個數組其實就是PHP中$_SERVER數組的一部分,也就是PHP里的環境變量。其作用不僅是填充$_SERVER數組,也是在告訴FPM要執行哪個PHP文件。當PHP-FPM拿到了數據包在之后,進行解析,得到了環境變量,然后執行SCRIPT_FILENAME的值指向的PHP文件,即/var/www/html/index.php。0X01 如何利用
PHP-FPM默認監聽9000端口,如果這個端口暴露在公網,則我們可以自己構造FastCGI協議,和FPM進行通信。這時候可以利用SCRIPT_FILENAME來指定執行php文件,如果文件不存在則返回404。在Nginx中存在一個配置限定了只有帶某些后綴的文件才允許被PHP-FPM執行,默認為.php,security.limit_extensions
; Limits the extensions of the main script FPM will allow to parse. This can; prevent configuration mistakes on the web server side. You should only limit; FPM to .php extensions to prevent malicious users to use other extensions to; exectute php code.; Note: set an empty value to allow all extensions.; Default Value: .php;security.limit_extensions = .php .php3 .php4 .php5 .php7
為了避免404,首先需要找到已存在的PHP文件,如果不知道web的絕對路徑或者web目錄下的php文件名,可以使用全局搜索得到環境中默認的php文件。
find / -name "*.php"
在我們獲得一個webshell的時候,怎么能突破限制執行任意PHP代碼呢?
首先我們能控制SCRIPT_FILENAME,讓fpm執行的任意文件,但是也只是執行目標服務器上的文件,并不能執行我們需要其執行的文件,但是在PHP中有很多有趣的技巧,比如在php.ini中有兩個配置項
auto_prepend_file //在執行目標文件之前,先包含auto_prepend_file中指定的文件auto_append_file //在執行完成目標文件后,包含auto_append_file指向的文件
如果設置auto_prepend_file為php://input,則相當于執行任何php文件之前會包含$_POST中的內容,使用php://input需要開啟遠程文件包含(allow_url_include)。
在PHP-FPM中還會解析兩個環境變量
PHP_VALUE //用于設置PHP的配置項,除 disable_function 以外的大部分 php 配置PHP_ADMIN_VALUE
設置auto_prepend_file = php://input且allow_url_include = On,然后將我們需要執行的代碼放在Body中,即可執行任意代碼。
{ 'GATEWAY_INTERFACE': 'FastCGI/1.0', 'REQUEST_METHOD': 'GET', 'SCRIPT_FILENAME': '/var/www/html/index.php', 'SCRIPT_NAME': '/index.php', 'QUERY_STRING': '?a=1&b=2', 'REQUEST_URI': '/index.php?a=1&b=2', 'DOCUMENT_ROOT': '/var/www/html', 'SERVER_SOFTWARE': 'php/fcgiclient', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '12345', 'SERVER_ADDR': '127.0.0.1', 'SERVER_PORT': '80', 'SERVER_NAME': "localhost", 'SERVER_PROTOCOL': 'HTTP/1.1' 'PHP_VALUE': 'auto_prepend_file = php://input', 'PHP_ADMIN_VALUE': 'allow_url_include = On'}
以上介紹的只是對PHP-FPM進行攻擊的正常流程,假如環境中增加了disable_functions的限制,如果使用包含PHP_VALUE==disable_function=的惡意FastCgi攻擊FPM時,只能修改展示phpinfo信息的EG(ini_directives),也就是表面修改,對于已經禁用的函數無效的。0X02 實例解析
以SUCTF2019中的一道題為例easyphp,在獲得webshell以后,發現有disable_functions的限制,這里可以通過與php-fpm進行通信來繞過open_basedir。
這里想要獲得flag需要利用php_value對open_basedir的值進行重設
'PHP_VALUE': 'auto_prepend_file = php://input'+chr(0x0A)+'open_basedir = /',
官方給的環境很有問題,少了upload目錄,需要自行加上,進去以后直接用官方給的exp復現也沒成功,進去docker發現php-fpm根本沒有起,emmmm醉了
直接在ubuntu16.04起一個phpfpm
sudo apt updatesudo apt install -y nginxsudo apt install -y software-properties-commonsudo add-apt-repository -y ppa:ondrej/phpsudo apt updatesudo apt install -y php7.3-fpm
修改nginx站點文件
sudo vim /etc/nginx/sites-enabled/default
啟用unix socket模式
sudo vim /etc/php/7.3/fpm/pool.d/www.conf
配置php-fpm監聽,將listen參數修改為127.0.0.1:9000
重啟php-fpm和nginx
/etc/init.d/php7.3-fpm restartservice nginx restart
修改相應的open_basedir
利用php-fpm通信來修改basedir,用p神的腳本修改一下
最后繞過open_basedir成功
網站名稱:怎么利用PHP-FPM實現繞過open_basedir
網頁URL:http://m.newbst.com/article0/epcsio.html
成都網站建設公司_創新互聯,為您提供網頁設計公司、網站制作、網站設計公司、微信公眾號、外貿建站、品牌網站設計
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯