1

So even if there is some poor php written which allows a shell_exec() and that someone disabled safe mode on it, what exactly are the risks? Do admins just change the default group or are most attacks coming from other forms of web applications which run as privileged users?

Apache for example runs as user "nobody" which is assigned to either /bin/false or /usr/sbin/nologin which should prevent getting a shell anyway.

whatever489
  • 838
  • 3
  • 9
  • 21

2 Answers2

2

Using shell_exec() and its multiple variants is perfectly fine so long as the web server's user account is limited to its directory structure.

The real risk is to use unsafe scripts that run commands with user input. escapeshellcmd() and escapeshellarg() can be used to make that safer.

Note that having no login shell does not prevent from running commands through a shell.

As for PHP safe mode, it is long outdated (as shown on http://php.net/manual/en/features.safe-mode.php):

This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.

Julie Pelletier
  • 1,919
  • 10
  • 18
  • To complement: Remember that server-side languages (as php), can access pretty much the whole OS (e.g. file functions). This means that an unprotected `eval( ... )` or a unprotected path: `../../../../../../etc/passwd` could potentially access parts of the OS that it shouldn't be. The main reason websites still suffer from OS injections is because there are many custom-made sites, developed by not-so-experienced devs which are not properly revised for security vulnerabilities (in other words: cheap websites). – lepe Jul 05 '16 at 00:48
0

A shell is used (and first executed) when an interactive login happens for this user-id. Putting a value such as bin/false or /usr/sbin/nologin terminates this session and essentially logs the user out.

Many system services / daemons do not use interactive logins and are started by other processes, they are assigned a user-id and group-id though, to direct what permissions its processes are running under.

Running a shell through a processes such as shell_exec(), system() or execve() pretty much means to "run a shell under this UID/GID". There's no login process happening, thus the required shell (/bin/...) is not read.

Why does it still happen?
Because humans are lazy. Command injection It is bad practice, but often a quick and dirty way to get things done (ping a system, perform file operations, ...). Developers know how to do this using the shell, so use that knowledge to perform the same. Think about (yes, very messy PHP code, ...):

$pattern = $_GET["pattern"];
$fin =  fopen('/path/to/your/input/file.txt', 'r');
$fout = fopen('/path/to/your/output/file.txt', 'w');
while (!feof($fin)) {
  $line = fgets($fin, 4096);
  if (preg_match($pattern, $line)) { 
    fwrite($fout, $line);
  }
}
fclose($fin);
fclose($fout);

Or simply

shell_exec("cat input/file.txt | grep ".$_GET["pattern"]." > output/file.txt");

It does the same in essence, but the 2nd one is easier and quicker.

ndrix
  • 3,206
  • 13
  • 17