Include from the stream "php: // memory"

I am writing a system for a browser application that will store some specific php scripts in a database and then pull them out and execute them if necessary. At first I tried using exec () and piping to php the output of a script that received scripts from the database and printed them. This worked in one case, but not in all, and fragility is felt anyway, so I'm looking for the best way.

Now I am trying to accomplish this using a stream of PHP files in memory. For instance:

$thing = <<<'TEST' <?php $thing = array(); print "Testing code in here."; var_dump($thing); ?> TEST; $filename = "php://memory"; $fp = fopen($filename, "w+b"); fwrite($fp, $thing); //rewind($fp); fclose($fp); include "php://memory"; 

However, when the script is executed, nothing is printed. Is this possible with this tool, and if not, is there another way to do this? I try to avoid writing temporary files and reading from them, since I am sure that access to the file system will slow down. Is there a URL that I can provide for include to read the memory stream as if it were a file?

I do not think that eval() will do this, because if I remember correctly, it is limited to one line.

Also, please do not answer "eval = include = hell". Users who are not administrators do not have access to write scripts stored in the database, I know that this requires special treatment during the life cycle of my application.

+6
source share
3 answers

You need to use stream_get_contents to read from php://memory stream . You cannot enable it directly.

+5
source

eval() and include are actually the same. Therefore, eval() works with multiple lines - just FYI. However, I would prefer to include here, I always think it is faster. Maybe I'm wrong, no idea.

However, I think you should debug your code, I see no reason why it should not work. You may need a rewind pointer (you commented on this), but what you need to check first hand is that your PHP configuration allows URLs to be included . I know that this parameter prohibits the use of the data:// URI, so you can enable this.

You can also always try if PHP can open memory using file_get_contents and unloading. That should give you the code. If not, you have already made a mistake (for example, rewinding or something similar).

Edit: I didn't go that far ( demo ):

 <?php /** * Include from "php://memory" stream * @link https://stackoverflow.com/q/9944867/367456 */ $thing = <<<TEST <?php \$thing = array(); print "Testing code in here."; var_dump(\$thing); TEST; $filename = "php://memory"; $fp = fopen($filename, "w+b"); fwrite($fp, $thing); rewind($fp); var_dump(stream_get_contents($fp)); 

Here is what I learned:

  • You must not close the "file". php://memory - a stream that will disappear after closing it.
  • You need to access the stream $fp as, which is impossible for include from the AFAIK window.
  • Then you need to create a stream wrapper that maps the stream resource to the file name.
  • When you do this, you can enable the memory stream.
  • PHP settings that need to be checked anyway. There are more than one, see the PHP manual.

It may be easier to use a data URI ( demo ):

 <?php /** * Include from "php://memory" stream * @link https://stackoverflow.com/q/9944867/367456 */ $thing = <<<TEST <?php \$thing = array(); print "Testing code in here."; var_dump(\$thing); TEST; include 'data://text/plain;,'. urlencode($thing); 

See also: Include code from a PHP stream

+4
source

If there is a way to include php: // from memory, then this is a serious vulnerability. Although it has many uses, eval is used quite often with code obfuscation methods to hide malicious code.

(Each tool is a weapon if you keep it in order.)

With that being said there (fortunately) does not seem to be the obvious way to include from php: // memory

0
source

Source: https://habr.com/ru/post/912052/


All Articles