Fix upload filter bypass leading to RCE #49
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
It is possible to bypass the media asset upload restrictions that are in place to prevent arbitrary PHP being executed on the server by abusing a combination of two issues.
The first is the support for uploading animated GIFs. By submitting a GIF that contains the following content we can place a GIF file that contains [currently unexecutable] PHP code in a GIF file on the server (in this case
test.gif):After uploading this, the file can now be clicked and the move function can be used to move this into another directory within the application directory with a PHP extension (in this case, it is moved to
tmp/media_thumb/shell.php):As can be seen in the below screenshot, this is now stored on the server with a valid extension:
At this point, the PHP file cannot be executed as the htaccess file found in
tmp/.htaccesscontains the following configuration:This prevents any PHP files under
tmp/being accessed. However, the same upload vulnerability can be abused to overwrite the htaccess file. To do this, one uploads a GIF file again but with the content:This creates a GIF file on the server, that starts with a valid comment character, which prevents the server running into an error when parsing it during subsequent requests. The same rename bug can then be used to move this file to
tmp/.htaccess:After doing this, the PHP file can be accessed from the web browser, and remote code execution is gained as can be seen in the below screenshot in which
cat /etc/passwdis executed:This pull request implements a rather simplistic means of patching this for now, by checking the extension of the specified destination path and blocking it if it is either
phporhtaccess. Ideally, a more robust solution should be put in place in the long term by creating a valid white list of safe extensions, but for now, this should mitigate the immediate threat.