- 資訊首頁(yè) > 網(wǎng)絡(luò )安全 >
- 怎么利用PHP-FPM實(shí)現繞過(guò)open_basedir
這篇文章主要講解了“怎么利用PHP-FPM實(shí)現繞過(guò)open_basedir”,文中的講解內容簡(jiǎn)單清晰,易于學(xué)習與理解,下面請大家跟著(zhù)小編的思路慢慢深入,一起來(lái)研究和學(xué)習“怎么利用PHP-FPM實(shí)現繞過(guò)open_basedir”吧!
在PHP中有以下幾種常見(jiàn)的安裝模式:
CGI是通用網(wǎng)關(guān)接口,HTTP使用這樣的接口程序來(lái)調用外部程序,外部程序可以使用任何計算機語(yǔ)言來(lái)編寫(xiě),例如C,C++,Perl,Visual Basic,Shell等等,歷史上用來(lái)編寫(xiě)CGI程序使用最廣泛的是Perl語(yǔ)言。
服務(wù)器在認為這是一個(gè)CGI請求時(shí),會(huì )調用相關(guān)CGI程序,并通過(guò)環(huán)境變量和標準輸出將數據傳送給CGI程序,CGI程序處理完數據,生成html,然后再通過(guò)標準輸出將內容返回給服務(wù)器,服務(wù)器再將內容交給用戶(hù)瀏覽器,CGI進(jìn)程退出。
CGI的出現讓W(xué)EB從靜態(tài)變?yōu)闉閯?dòng)態(tài),隨著(zhù)Web的越來(lái)越普及,很多的網(wǎng)站的都需要有動(dòng)態(tài)的頁(yè)面,以便與瀏覽者互交。CGI方式的缺點(diǎn)也越來(lái)越突出。因為HTTP要生成一個(gè)動(dòng)態(tài)頁(yè)面,系統就必須啟動(dòng)一個(gè)新的進(jìn)程以運行CGI程序,CGI采用fork and execution方式,每次請求都需要新建立CGI程序來(lái)進(jìn)行處理,不斷地fork是一項很消耗時(shí)間和資源的工作,導致性能的低下。這就出現了FastCGI。
FastCGI是從CGI發(fā)展改進(jìn)而來(lái)的。傳統CGI接口方式的主要缺點(diǎn)是性能很差,因為每次HTTP服務(wù)器遇到動(dòng)態(tài)程序時(shí)都需要重新啟動(dòng)腳本解析器來(lái)執行解析,然后結果被返回給HTTP服務(wù)器。這在處理高并發(fā)訪(fǎng)問(wèn)時(shí),幾乎是不可用的。另外傳統的CGI接口方式安全性也很差,現在已經(jīng)很少被使用。FASTCGI快速通用網(wǎng)關(guān)接口是常駐內存的CGI,實(shí)際上是對CGI程序的進(jìn)程管理,FastCGI接口方式采用C/S結構,可以將HTTP服務(wù)器和腳本解析服務(wù)器分開(kāi),同時(shí)在腳本解析服務(wù)器上啟動(dòng)一個(gè)或者多個(gè)腳本解析守護進(jìn)程。當HTTP服務(wù)器每次遇到動(dòng)態(tài)程序時(shí),可以將其直接交付給FastCGI進(jìn)程來(lái)執行,然后將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務(wù)器專(zhuān)一地處理靜態(tài)請求或者將動(dòng)態(tài)腳本服務(wù)器的結果返回給客戶(hù)端,這在很大程度上提高了整個(gè)應用系統的性能。
相關(guān)的Fastcgi學(xué)習可到合天網(wǎng)安實(shí)驗室操作實(shí)驗——Fastcgi安全:實(shí)驗:Fastcgi安全(合天網(wǎng)安實(shí)驗室)本實(shí)驗介紹了fastcgi安全,是以nginx+php+fastcgi為環(huán)境,在多臺fastcgi服務(wù)器做的情況下,容易出現的錯誤。
Module模式就是把php作為apache的一個(gè)子模塊來(lái)運行,使用LoadModule來(lái)加載php模塊,比如在apache的配置文件中
//httpd.conf LoadModule php7_module "${INSTALL_DIR}/bin/php/php7.2.13/php7apache2_4.dll"
當web訪(fǎng)問(wèn)php文件時(shí),apache會(huì )調用php模塊來(lái)解析,phpmodule通過(guò)sapi來(lái)把數據傳遞給php解析器進(jìn)行解析。
最后是本篇文章的主角PHP-FPM,FPM是一個(gè)FastCGI協(xié)議解析器,Nginx等服務(wù)器中間件將用戶(hù)請求按照FastCGI的規則打包好發(fā)送給PHP-FPM,再由PHP-FPM來(lái)將打包的數據進(jìn)行解析并與FastCGI進(jìn)行通信,PHP-FPM就是為了實(shí)現和管理FastCGI協(xié)議的進(jìn)程(fastcgi進(jìn)程管理器),管理一個(gè)進(jìn)程池,處理來(lái)自于web服務(wù)器的請求。其中,Ngnix與PHP-FPM有兩種通信方式,分別是TCP與Unix domain sockets模式。在windows系統中只能使用tcp socket的通信方式。
TCP模式
TCP模式是PHP-FPM進(jìn)程監聽(tīng)本機上端口(默認為9000),Ngnix將用戶(hù)請求按照f(shuō)astcgi的規則打包好發(fā)送給php-fpm,由PHP-FPM調用cgi進(jìn)行解析。TCP通信模式允許通過(guò)網(wǎng)絡(luò )進(jìn)程之間的通信,也可以通過(guò)loopback進(jìn)行本地進(jìn)程之間通信。
Unix domain sockets模式
Unix socket 又叫 IPC (inter-process communication 進(jìn)程間通信) socket,用于實(shí)現同一主機上的進(jìn)程間通信,這種方式需要在 Ngnix配置文件中填寫(xiě) PHP-FPM 的 socket 文件位置。
在P神的Fastcgi協(xié)議分析 && PHP-FPM未授權訪(fǎng)問(wèn)漏洞 && Exp編寫(xiě)這篇文章中對其中的原理已經(jīng)做了比較詳細的解釋?zhuān)?/p>
假如用戶(hù)訪(fǎng)問(wèn)
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' }
這個(gè)數組其實(shí)就是PHP中$_SERVER數組的一部分,也就是PHP里的環(huán)境變量。其作用不僅是填充$_SERVER數組,也是在告訴FPM要執行哪個(gè)PHP文件。當PHP-FPM拿到了數據包在之后,進(jìn)行解析,得到了環(huán)境變量,然后執行SCRIPT_FILENAME的值指向的PHP文件,即/var/www/html/index.php。
PHP-FPM默認監聽(tīng)9000端口,如果這個(gè)端口暴露在公網(wǎng),則我們可以自己構造FastCGI協(xié)議,和FPM進(jìn)行通信。這時(shí)候可以利用SCRIPT_FILENAME來(lái)指定執行php文件,如果文件不存在則返回404。在Nginx中存在一個(gè)配置限定了只有帶某些后綴的文件才允許被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文件名,可以使用全局搜索得到環(huán)境中默認的php文件。
find / -name "*.php"
在我們獲得一個(gè)webshell的時(shí)候,怎么能突破限制執行任意PHP代碼呢?
首先我們能控制SCRIPT_FILENAME,讓fpm執行的任意文件,但是也只是執行目標服務(wù)器上的文件,并不能執行我們需要其執行的文件,但是在PHP中有很多有趣的技巧,比如在php.ini中有兩個(gè)配置項
auto_prepend_file //在執行目標文件之前,先包含auto_prepend_file中指定的文件 auto_append_file //在執行完成目標文件后,包含auto_append_file指向的文件
如果設置auto_prepend_file為php://input,則相當于執行任何php文件之前會(huì )包含$_POST中的內容,使用php://input需要開(kāi)啟遠程文件包含(allow_url_include)。
在PHP-FPM中還會(huì )解析兩個(gè)環(huán)境變量
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進(jìn)行攻擊的正常流程,假如環(huán)境中增加了disable_functions的限制,如果使用包含PHP_VALUE==disable_function=的惡意FastCgi攻擊FPM時(shí),只能修改展示phpinfo信息的EG(ini_directives),也就是表面修改,對于已經(jīng)禁用的函數無(wú)效的。
以SUCTF2019中的一道題為例easyphp,在獲得webshell以后,發(fā)現有disable_functions的限制,這里可以通過(guò)與php-fpm進(jìn)行通信來(lái)繞過(guò)open_basedir。
這里想要獲得flag需要利用php_value對open_basedir的值進(jìn)行重設
'PHP_VALUE': 'auto_prepend_file = php://input'+chr(0x0A)+'open_basedir = /',
官方給的環(huán)境很有問(wèn)題,少了upload目錄,需要自行加上,進(jìn)去以后直接用官方給的exp復現也沒(méi)成功,進(jìn)去docker發(fā)現php-fpm根本沒(méi)有起,emmmm醉了
直接在ubuntu16.04起一個(gè)phpfpm
sudo apt update sudo apt install -y nginx sudo apt install -y software-properties-common sudo add-apt-repository -y ppa:ondrej/php sudo apt update sudo apt install -y php7.3-fpm
修改nginx站點(diǎn)文件
sudo vim /etc/nginx/sites-enabled/default
啟用unix socket模式
sudo vim /etc/php/7.3/fpm/pool.d/www.conf
配置php-fpm監聽(tīng),將listen參數修改為127.0.0.1:9000
重啟php-fpm和nginx
/etc/init.d/php7.3-fpm restart service nginx restart
修改相應的open_basedir
利用php-fpm通信來(lái)修改basedir,用p神的腳本修改一下
最后繞過(guò)open_basedir成功
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站