Page 1 of 1

Security: PHP and Shells

Posted: Thu Dec 18, 2003 1:53 pm
by shans
Hi *,

I have a question concerning arguments of shell_exec:

what signs can finish arguments and make the following becoming a command?

e.g.
$_POST['search_pattern'] = "; cat afile";
$out = shell_exec("ls ".$_POST['search_pattern']);
does it

"&&" as well and "||" maybe could

any ideas?

tia and greetings from munich

stefan

Posted: Thu Dec 18, 2003 2:00 pm
by Weirdan
[php_man]escapeshellcmd[/php_man]

Posted: Thu Dec 18, 2003 2:30 pm
by Stoker
also, escapeshellarg - if you hardcode the command but use user-data in the arguments you can create shell safe arguments with escapeshellarg, it will add quotes if needed..

Code: Select all

<?php
 $cmd = '/bin/echo' . escapeshellarg($_POST['sensitivedata']);
 $cmd .= ' | ';
 $cmd .= '/usr/bin/gpg -ea --homedir=/path/to/keyring -r '.escapeshellarg($_POST['to_user']);
 $cmd .= ' --always-trust --no-secmem-warning';
?>

quick answer :-)

Posted: Thu Dec 18, 2003 2:31 pm
by shans
Hi Weirdan,

thx for your answer.

But I need * and ? as part of the search pattern.

neither <bash> ls \*.xml does work nor the php-script does

tia stefan

btw: what is the difference between escapeshellarg and escapeshellcmd?

Posted: Thu Dec 18, 2003 5:03 pm
by Stoker
escapeshell arg is for creating a valid argument, escapeshellcmd is to create a command, read the phpmanual!

escaping * or ? creates literal characters, a * is by the shell intepreted as any file it can find matching your pattern so if a folder contains multiple files matching they will be turned in to multiple arguments..
Use of * and ? from a post sounds unusual, cant you hardcode that in?

Otherwise I would suggest that instead of not using escapeshellarg, use that and then explicit remove any escapes in front of * and ? that only has one slash.. something like

Code: Select all

<?php
function shellargwithwildcard ($argtext)
{
  return preg_replace_all (
    '/(^|[^\\])\\(*|?)/',
    '\\1\\2',
    escapeshellarg($argtext)
  );
}
?>
untested...

Posted: Thu Dec 18, 2003 5:10 pm
by Stoker
oops, forgot some escapes there for the wildcards..

Code: Select all

<?php
function shellargwithwildcard ($argtext)
{
  return preg_replace_all (
    '/(^|[^\\\\])\\\\(\\*|\\?)/',
    '\\1\\2',
    escapeshellarg($argtext)
  );
}
?>

thx

Posted: Thu Dec 18, 2003 9:35 pm
by shans
early morning resp. midnight greetings from old europe,

in this case php is a middleware to get fs info to the client application
normally via https but to have good security if not:

Code: Select all

<?php
if((substr_count($_POST['search_pattern'], ";") == 0 && substr_count($_POST['search_pattern'], "&") == 0 && substr_count($_POST['search_pattern'], "|") == 0)
   &&
   (substr_count($_POST['sort_mtime'], ";") == 0 && substr_count($_POST['sort_mtime'], "&") == 0 && substr_count($_POST['sort_mtime'], "|") == 0))
{
	$out = shell_exec("cd ../data; ls -c".$_POST['sort_mtime']."gGH --author --time-style long-iso ".$_POST['search_pattern']." | egrep -v '^total' | awk '{ print $1,$3,$4,$5,$6,$7 }'");
...
i will add the backtick as well
...
sort out files not owned by phpuser, wraps it to xml and send it back
...
}
else
{
...
puts the man-in-the-middle IP onto a rdbms ect.
...
}php?>
maybe you see now that my first question was quite accurate

normally i do not post in forums but my knowledge of hacking is not too good so i posted

and - compliment - your answers were competent and kind :-)

if i post i post on about 4-5 forums worldwide and in this case no answers except one unfriendly "RTM answer"

sorry, but "escapeshell arg is for creating a valid argument, escapeshellcmd is to create a command" is a "null sentence" for me and guess how many time i rtfm :-)

thx again and greetings to the big apple

stefan

Posted: Fri Dec 19, 2003 12:41 am
by Stoker
an argument is a parameter to a shell command... escapeshellarg()
makes it safe...

command arg1 arg2 arg3 'arg number 4' arg5 'arg no''s here 6'

--

$arg = 'Hello; mail -s secret bob@msn.com < /etc/passwd';

Unsafe:
exec( '/bin/echo ' . $arg , $result);

Safe:
exex('/bin echo ' . escapeshellarg($arg), $result);

escapeshellcmd is for the command, not an argument..