File Upload

Once authenticated, try to upload a text file, if only zips are allowed, upload a zip with a txt inside.

If the zip is accepted but the contetns are also scanned and we receive an error, then should look at the code:

grep -ir "Error message displayed" /var/www/html/app --color

Then we sould check the inspector in the browser to see which file handles the file upload, and then find references to the error in that file.

If we see something like this: $example_xml = @file_get_contents($import_path.'example.xml');

Then the file must contain a specific name (creating a valid and properly formatted XML file, which is able to pass the parser checks)

Now we must verify that the file is created:

sudo find / -name "poc.txt"

If it is deleted, then we should check other parts of the code and see how to abuse them.

If in the XML validation code chunk we see that a failed attempt to parse the contents of the file forces the PHP script to die with an error message, we can assume that no other PHP code is executed after this point and then we should be able to permanently write a file of our choice to the target file system by including an improperly formed xml file.

Then if we receive a response that the XML file is not well-formed, we may have been successful uploaded the file and we could check it again.

To gain RCE, maybe we need to scape the jail and try to upload the file in other directory than the default one:

z.writestr('../../../../../tmp/poc/poc.txt', 'hola')

If we run the following command and the file is under the desired directoty, then we have scaped the jail:

sudo find / -name "poc.txt"

Since we are using a white box approach, we know the web root directory and we can simply search for writable directories within the web root on the command line.

find /var/www/html/ -type d -perm -o+w

Once we have a target, we can check witht he previous script if it writes the file successfully.

- Bypass File Extension Filter

If we include any file with the .php extension in our ZIP file, the entire import will fail.

To see how the file extension filtering is implemented, search for $IllegalExtentions.

Once we have the list of ilegal extensions, we must pick one that executes our code and is not blacklisted, for example .phtml.

def _build_zip():
    f = StringIO()
    z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
    z.writestr('../../../../../var/www/html/app/poc.phtml', '<?php\nphpinfo(); ?>')
    z.writestr('example.xml', 'invalid xml!')
    z.close()
 
zip = open('poc.zip', 'wb')
zip.write(f.getvalue())
zip.close()
 
_build_zip()

If the poc opens the php info page, the we can leverage this to code execution.

If we can upload php files but execution is set to off, if we can upload .htaccess files, we can set it on by uploading that file with the following content:

php_flag engine on
RewriteEngine on
If we can upload php6 files:
RewriteRule shell.php shell.php6

Last updated