Reconnaissance
Target
The target web application is an online book store by Projectworlds.in.
A quick Google search with the terms “projectworlds vulnerability, projectworlds cve” lead me to CVE-2020-19110 with a link to a Github issue reported by Github user liao10086. I’ve been able to replicate the issue.
But not much help with our goal to pop a shell for RCE. Looking for some more known vulnerabilities, 47887 seems to be promising and scary! Unauthenticated Remote Code Execution!
Vulnerability
The POC attached to the vulnerability can be found here. Credits to Tib3rius for providing the POC.
Let’s try and make sense on what vulnerability is and how the script exploits this.
The script leverages the file upload vulnerability found in admin_add.php. This page handles the data entry of new book records.
Here, it requires that the POST body includes the add
parameter.
A few lines more, an image can be uploaded within the POST files and that this file is saved to bootstrap/img
directory. This is the same directory as the image assets found in the site. This information is enough to compose the payload.
The key components to make to exploit this vulnerability are:
- Arbitrary file upload
- Access to the uploaded file, with possibility for remote code execution.
For the script, here is how the payload is created and uploaded.
Without restrictions and validation on the file types to accept, the attacker can simply upload a PHP file despite the intention to upload an image file.
Notice that the payload accepts command line instruction via GET parameters. So when the attacker views the uploaded file, the command line instructions will be executed and the output is returned as plain text.
The above snippet verifies that the file has been uploaded successfully, and the file can be accessed.
/bootstrap/img/ur7XGsG8Tq.php?cmd=whoami
The attacker can then just repeatedly request the file and carefully craft instructions in the URL request parameters.
Exploit
Mitigation
Assets and media files
In my experience as a developer, assets (css/img/js) that are essential for the user-facing interface can be separated from the media files which commonly includes attachments and uploads from users. Depending on the size of the project, a single server may only expose public access on the assets directory, and the uploaded media files only accessible to its rightful users with permission policies in place. It is also common to spin up an entirely different server for storage of media files (the same principle for S3 buckets) where finer access controls can be imposed.
File validation
- Specify file type criteria
- Do not rely on the given file name/file type for the file type extension
The PHP manual on file upload has this to say,
You could use the $_FILES[‘userfile’][’type’] variable to throw away any files that didn’t match a certain type criteria, but use this only as first of a series of checks, because this value is completely under the control of the client and not checked on the PHP side.
Require authorization/permission checks on restricted pages
Put the “admin” on the “admin_*.php” to work!
Disable specific PHP functions
Consider a black list of PHP functions when it is not necessary for your web application and when the web server allows this feature.
More from OWASP guide
- Uploaded directory should not have any “execute” permission and all the script handlers should be removed from these directories.
- Never accept a filename and its extension directly without having an allow list filter.
- Write permission should be removed from files and folders other than the upload folders. The upload folders should not serve any
- Ensure that files with double extensions (e.g. “file.php.txt”) cannot be executed especially in Apache.
This list is not intended to be exhaustive. For more recommendations, please see OWASP Unrestricted File Upload from the references section.