漏洞描述
該漏洞需要在nginx.conf中進行特定配置才能觸發。具體配置如下:
location ~ [^/]\.php(/|$) { ... fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_pass php:9000; ... }
攻擊者可以使用換行符(%0a)來破壞fastcgi_split_path_info指令中的Regexp。Regexp被損壞導致PATH_INFO為空,從而觸發該漏洞。
漏洞類型:遠程代碼執行漏洞
危險等級:高危
利用條件:nginx配置了fastcgi_split_path_info
受影響系統:PHP 5.6-7.x,Nginx>=0.7.31
漏洞復現
使用某個大佬的 docker 環境進行復現:
PHP-FPM 遠程代碼執行漏洞(CVE-2019-11043)
https://github.com/vulhub/vulhub/blob/master/php/CVE-2019-11043/README.zh-cn.md
准備工作:安裝 docker、golang 環境
在kali中使用如下命令安裝docker和golang:
sudo apt-get install docker docker-compose sudo apt install golang



搭建漏洞環境
git clone https://github.com/vulhub/vulhub.git cd vulhub/php/CVE-2019-11043 && docker-compose up -d




安裝漏洞利用工具
git clone https://github.com/neex/phuip-fpizdam.git cd phuip-fpizdam go get -v && go build


漏洞利用
在phuip-fpizdam目錄下執行 go run . "http://127.0.0.1:8080/index.php"后成功顯示漏洞利用成功。
在瀏覽器進行了如下請求,成功復現,可以執行系統命令,id可以替換為其他OS命令。


漏洞分析
有漏洞信息可知漏洞是由於path_info 的地址可控導致的,我們可以看到,當path_info 被%0a截斷時,path_info 將被置為空,回到代碼中我就發現問題所在了。
如下漏洞代碼
在代碼的1134行我們發現了可控的 path_info 的指針env_path_info
其中
env_path_info 就是變量path_info 的地址,path_info 為0則plien 為0。
slen 變量來自於請求后url的長度 int ptlen = strlen(pt); int slen = len - ptlen;
由於apache_was_here這個變量在前面被設為了0,因此path_info的賦值語句實際上就是:
path_info = env_path_info ? env_path_info + pilen - slen : NULL;
env_path_info是從Fast CGI的PATH_INFO取過來的,而由於代入了%0a,在采取fastcgi_split_path_info ^(.+?\.php)(/.*)$;這樣的Nginx配置項的情況下,fastcgi_split_path_info無法正確識別現
在的url,因此會Path Info置空,所以env_path_info在進行取值時,同樣會取到空值,這也正是漏洞原因所在。
