php system() command files due to '&' in password - php

I'm running the following command:
$cmd = escapeshellcmd( "echo '$password' | sudo -S mv \"$old\" \"$new\" " );
system( $cmd, $out );
This works when $password doesn't contain & but fails if it does.
How do I get this to allow & and any other special characters in the password ?
Thanks

Don't use escapeshellcmd() on the whole command, use escapeshellarg() on individual arguments.
$password_esc = escapeshellarg($password);
$cmd = "echo $password_esc | sudo -S mv '$old' '$new'";
system($cmd, $out);
You don't need quotes around $password_esc because escapeshellarg() adds them.

Related

PHP shell_exec() doesn't allow less-than "<" character or "<()" command to be used?

I need to run this exact shell command from PHP shell_exec():
/usr/bin/paste -d'|' <(echo $(id)) <(echo $(pwd))
From a VPS shell (Debian) it works perfectly. However, from shell_exec() it doesn't work:
$command = "/usr/bin/paste -d'|' <(echo $(id)) <(echo $(pwd)) 2>&1";
$output = shell_exec($command);
print_r($output);
It doesn't output anything, the output is just blank/empty.
I am using PHP 7.3 with safe_mode = On and open_basedir, shell_exec() is enabled.
How can I run that command with shell_exec()?
I think the less-than "<" char or "<()" create problems?
perhaps escapeshellcmd would help ?
$command = "/usr/bin/paste -d'|' <(echo $(id)) <(echo $(pwd)) 2>&1";
$escaped_command = escapeshellcmd($command);
$output = shell_exec($escaped_command);
print_r($output);
good luck.

Binary file not executed for web user

I have a php script that creates a shell script file that finally executes as the www-data user, all of the commands are executed except for the last one which implies a binary file. If I run the command as root, it runs ok...
This is the last part of the script:
&& echo "Tokenizing the file........" >> Logs/table_of_contents.php \
&& perl ../common/Scripts/xmltokenize.pl --filename=xmlfiles/table_of_contents.xml >> Logs/table_of_contents.php \
&& perl ../common/Scripts/xmlrenumber.pl --filename=xmlfiles/table_of_contents.xml >> Logs/table_of_contents.php \
&& echo "Tagging the file........" >> Logs/table_of_contents.php \
# I have added this line to check if it helps but id doesn't
&& export HOME="/tmp/" \
# And this is the command that calls the binary file
&& perl tagfile.pl xmlfiles/table_of_contents.xml \
Here you have the content of the tagfile.pl
use File::Find;
$\ = "\n";
$fn = shift;
if ( $fn =~ /([^\/\.]+)\.xml/ ) { $fileid = $1; } else { exit;};
print $fileid;
$cmd = "perl tagfl2/makevrt.pl 'xmlfiles/$fileid.xml' > 'tagtmp/$fileid.vrt'";
print $cmd;
print `$cmd`;
#ALL OF THE PREVIOUS WORKS
#THIS IS THE ONE THAT GIVES PERMISSION ERRORS
# OF COURSE: "www-data:www-data tagtmp/" and "www-data:www-data $fileid.vrt = table_of_contents.vrt"
$cmd = "cut -f 1 tagtmp/'$fileid.vrt' | tagfl2/treetagger/bin/tree-tagger -no-unknown -token -lemma tagfl2/treetagger/lib/english.par > 'tagtmp/$fileid.tagged'";
print $cmd;
`$cmd`;
$cmd = "perl tagfl2/mrg.pl 'tagtmp/$fileid.vrt' 'tagtmp/$fileid.tagged' > 'tagtmp/$fileid.mrg'";
print $cmd;
`$cmd`;
$cmd = "perl tagfl2/tagxml.pl 'tagtmp/$fileid.mrg' 'xmlfiles/$fileid.xml'";
print $cmd;
`$cmd`;
Here is the error:
sh: 1: tagfl2/treetagger/bin/tree-tagger: Permission denied
Also, just in case:
chown -R www-data:www-data tagfl2/
chmod -R g+rwx tagfl2/
Try to define a full path to the script
$cmd = "perl /[full_path]/makevrt.pl 'xmlfiles/$fileid.xml' > 'tagtmp/$fileid.vrt'";
Why did you update user ownership?
Changing the group ownership should have been enough:
chgrp -R www-data tagfl2/
chmod -R g+rwX tagfl2/
And change the lowercase x by a greater one, to give access/execution permission, only if it is already the case for the user owner (no need to give otherwise).
You may then check the permission like this:
su -m -c 'ls -R tagfl2/' www-data
And see if you reproduce access issue; and then update permission accordingly.
Ok, all solved, one thing was giving the file system, actually the mounted unit, the exec attribution.
The second thing was moving treetagger directory to /usr/local/
Then, at /usr/local/bin/ I have created a soft link this way:
ln -s ../treetagger/bin/tree-tagger
Making the binary file globally executable. Actually, this last step was the ultimate solution.
Then at the tagfile.pl perl script, the line containing the tree-tagger command, I have changed it this way:
cut -f 1 'tagtmp/$fileid.vrt' | /usr/local/bin/tree-tagger -no-unknown -token -lemma tagfl2/treetagger/lib/english.par > 'tagtmp/$fileid.tagged'

php with sudo works on command line but not in browser

Hello I am writing a little php/html page and trying to pass user & password to run, although it works on command line, it does not work in the browser.. Any advise?
$user = "echo password!";
$row = exec('$user | sudo -u user_id -S /usr/bin/VBoxManage list vms',$output,$error);
echo "\n";
while(list(,$row) = each($output)){
echo sprintf($row) . "<BR>\n";
}
if($error){
echo "Error : $error<BR>\n"; exit;
}
One possible cause is that the sudo binary requires a full path too.
However, your syntax is incorrect - single quotes prevent $user from being expanded.
Even then, it is possible that exec will not honor the pipe request and you will instead need to authorize the user running Apache to issue VBoxManage commands without password, using visudo. Or you may want to look into proc_* functions.
This should work:
$output = shell_exec("/bin/sh -c '{$user} | sudo -u ...'");

Underscore in php shell_exec

i try to execute a grep command inside a php shell_exec. And it works fine besides it fails when i have a underscore in the search word. I can not seem to figure out why this fails because of a underscore since, a grep command with a underscore in search word works in shell code below:
$output = shell_exec("grep -l -r '$search_word'");
The content in search_word variable is dynamic from database but the word that gives me trouble is base_64
Try like this:
$output = shell_exec("grep -l -r '$search_word' ./*");
Before PHP spawns a subprocess your command will be $search_word evaluated:
grep -l -r '....'
# So in $search_word is set to `john doe` it will become:
grep -l -r 'john doe'
How PHP behaves I'm not sure, it might be stalling waiting for the process to finish, it might have been closing stdin already.
Your above command will expect input from stdin because no file name is specified, breakdown:
grep [option]... [pattern] [file]...
-l will only print file name of the matched file
-r recursive search.
TLDR: You properly want to specify a file / directory to search in:
$output = shell_exec("grep -l -r '$search_word' .");
// Or maybe
$output = shell_exec("grep -l -r '${search}_word' ."); # will use $search variable as an input from PHP while _word is a string now.

Background upload in PHP

I am working with a form that allows me to upload files via a local folder and FTP.
So I want to move files over ftp (which already works)
Because of performance reasons I chose this process to run in the background so I use nfcftpput (linux)
In CLI the following command works perfectly:
ncftpput-b-u name -p password -P 1980 127.0.0.1 /upload/ /home/Downloads/upload.zip
(Knowing that the b-parameter triggers background process)
But if I run it via PHP it does not work (without the-b parameter it does)
PHP code:
$cmd = "ncftpput -b -u name -p password -P 1980 127.0.0.1 /upload/ /home/Downloads/upload.zip";
$return = exec($cmd);
Try one of the following:
1) Use the command $cmd = "ncftpput -b -u name -p password -P 1980 127.0.0.1 /upload/ /home/Downloads/upload.zip &";
(Notice the &)
2) Try php's proc_open function http://php.net/manual/en/function.proc-open.php
Try adding '&' at the end of command, this will fork it on linux level. Also try shell_exec(), if previous won't work.
Take a look at pcntl_fork. This user note has information how to correctly spawn a background process. Note that the extension that provides this function might not be activated in your PHP installation.
The best working solution for me is the following code:
function executeBackgroundProces($command) {
$command = $command . ' > /dev/null 2>&1 & echo $!';
exec ( $command, $op );
$pid = ( int ) $op [0];
if ($pid != "")
return $pid;
return false;
}
The command I run is: "ls bashfile"
The bash file contains commands like the upload and deletion of the original files separated by ;
This works fine by me

Categories