PHP let www-data run a command as if it were a dif

2019-08-23 03:54发布

问题:

So I want to execute the following command in my php script:

exec("/path/to/command");

Because it is the www-data user who runs php scripts, i currently can not run this command. I have read something about suexec being able to run a command as if it was a different user. I find it rather difficult to understand how this works.

I have already installed suexec and edited the /etc/apache2/suexec/www-data file and added:

/home/user_to_run_command/script.php

I have also edited /etc/apache2/sites-enabled/000-default and added:

SuexecUserGroup user_to_run_command user_to_run_command

Am I missing anything?

回答1:

suEXEC will work only when PHP is executed in CGI mode but not if PHP is running as an apache2 module. I guess you are running it as a module.


An alternative might be to transfer the ownership to the desired user and then set the suid bit:

chown desired_user your.program
chmod u+s your.program

Now when executing your.program it has permissions as if it where executed by it's owner. Follow the wiki article that I've linked for more information.

Side note: This will work with binaries only (not with shell scripts as they where executed by the shell binary which has no suid bit set)



回答2:

I had the same problem and finally found a solution which as far a I can see is both safe and simple. A disadvantage of this method is that you have to take care of security updates when they are published.

What we are gonna do is make our own special shell which we chown and SUID to the user which we want the task to perform. To remain safe this user should be just an ordinary user without extensive system rights and place the script somewhere others are not allowed. Now we let php execute a script which uses this special shell and all command within this script will be executed as the chosen user.

In practice:

sudo mkdir /usr/lib/specialshell
sudo chown user_who_may_run_command:root /usr/lib/specialshell
sudo chmod 700 /usr/lib/specialshell
sudo cp /bin/perl specialperl
sudo chown user_to_run_command:usergroup_to_run_command specialperl
sudo u+s specialperl
sudo mv specialperl /usr/lib/specialshell

Now we make a script named command.script containing:

#!/usr/lib/specialshell/specialperl
$ENV{"PATH"} = "/usr/bin";
system("/path/to/command");

and from php code we use:

exec("/path/to/command.script");

et voila, no code change, just the name of command in php.

edit: works only with perl as shell, so changed bash to perl and put the shell somewhere safe