Link Search Menu Expand Document

Arbitrary file upload is surprisingly common among web applications, which can be abused to upload malicious files and then compromise the server. Usually, the attacker will select a payload based on whatever server-side programming language is supported. So if the vulnerable app is in PHP, then clearly PHP is supported, therefore an easy choice would be using a PHP payload such as Metasploit’s PHP meterpreter. However, the PHP meterpreter does not share the same performance as, say, a Windows meterpreter. So in reality, what happens is you will probably want to upgrade to a better shell, which involves extra manual work during the process. So why limit your payload options? For this type of scenario, you should use the PhpEXE mixin. It serves as a payload stager in PHP that will write the final malicious executable onto the remote file system, and then clear itself after use, so it leaves no traces.


To use the PhpEXE mixin, some typical exploitable requirements should be met:

  • You must find a writeable location on the web server.
  • The same writeable location should also be readable with a HTTP request.

Note: For an arbitrary file upload bug, there is usually a directory that contains uploaded files, and is readable. If the bug is due to a directory traversal, then a temp folder (either from the OS or the web app) would be your typical choice.


First include the mixin under the scope of your MetasploitModule class like the following:

include Msf::Exploit::PhpEXE

Generate the payload (with the PHP stager) with get_write_exec_payload

p = get_write_exec_payload

If you’re working on a Linux target, then you can set unlink_self to true, which will automatically clear the executable:

p = get_write_exec_payload(:unlink_self=>true)

On Windows, you probably cannot clear the executable because it will probably still be in use. If it’s not possible to automatically clean up malicious files, you should always warn the user about where they are, so they can do it manually later during the penetration test.

At this point you can upload the payload generated by get_write_exec_payload, and then call it by using a GET request. If you do not know how to send a GET request, please refer to the following article: How to Send an HTTP Request Using HttpClient