Using PHP’s data:// stream and File Inclusion to execute code
This is a reasonably old remote code execution trick that I was actually unaware of until recently, illness when I stumbled across it by accident. I have been heavily researching various ways to go from a file inclusion bug to a remote code execution bug, and this one really got me interested.
As we previously mentioned in the I expect:// a shell post, medical you can use certain PHP streams to execute code via a file inclusion vulnerability. This one does not require any PHP extensions to be installed, unlike the expect:// trick, and relies solely on allow_url_include to be enabled, which sadly is becoming a rarity these days.
How this works is simple. PHP has a data:// stream, which can decode and accept data. If you insert some PHP code into this stream and include() it, the code will be executed. Rather simple, and rather effective too. I will cover php://input in a follow up post, and then post my findings on abusing FindFirstFile.
Essentially, instead of including /etc/passwd or a remote file, you simply include the following. data://text/plain;base64,PAYLOAD_GOES_HERE
Where the payload is base64 encoded PHP code to be executed. I choose to base64 encode the payload to avoid some problems I ran into with whitespace and longer payloads.
Where the payload is base64 encoded PHP code to be executed. I choose to base64 encode the payload to avoid some problems I ran into with whitespace and longer payloads.
Now, obviously this would be no fun without a simple proof of concept tool to demonstrate the vulnerability. The following tool is under serious redevelopment at the moment, so it only spawns a bind shell at the moment. Next version will offer several payloads (I am working on a generic payload library for this kind of thing).
You can download the current version of the tool here: PHP data include exploit
I will update that code later, might do a video once there is something worth watching.
*****************************************
new-host:data xxxx$ ./p.py
Traceback (most recent call last):
File “./p.py”, line 9, in
import requests
ImportError: No module named requests
If you have “pip” or “Easy_install” just run “pip install requests” or “easy_install requests”