Execute command with sudo via PHP - php

I have scripts in /etc/init.d/ that I use to control game servers and I would like to build a simple web interface to call those scripts. My sudoers file contains something like
www-data ALL=(ALL) NOPASSWD: /etc/init.d/starbound start stop
When I execute sudo /etc/init.d/starbound start within PHP, nothing happens. Am I missing something? Trying to access paths my PHP user is not allowed to usually gives me the appropriate warnings at least.

Using sudo requires that you input your password when you run a command. By running sudo with exec() you aren't providing the password to sudo and cannot run the command with root level privileges.
Ubuntu.SE provides a way to pass the password to sudo in a single command, but the result is a little messy when implemented with PHP because the Password: prompt will be sent to STDOUT when the call is made, but that can be silenced by sending the output to /dev/null. The result of the command can still be stored in a variable as you might expect.
<?php
//Kill a sudo session if one exists.
exec('sudo -k');
//Run sudo without authenticating
$output = exec('sudo echo "foo"');
var_dump($output); //string(0) ""
//Provide the password and pipe it into sudo.
$output = exec('echo "password" | sudo -S echo "foo" 2> /dev/null');
var_dump($output); //string(3) "foo"
?>

Seems the problem lies in the sudoers file. If I remove the start stop, it works.
So a correct sudoers could look like this:
Cmnd_Alias GAMES = /etc/init.d/ark_thecenter start, \
/etc/init.d/ark_thecenter stop, \
/etc/init.d/ark_theisland start, \
/etc/init.d/ark_theisland stop, \
/etc/init.d/starbound start, \
/etc/init.d/starbound stop
www-data ALL=(ALL) NOPASSWD: GAMES

Related

shell_exec() not executing shell script

I've a shell_test.php file in /var/www/html folder with this code:
<?php
shell_exec('/var/www/html/config.sh');
?>
config.sh in the same folder has this code:
#!/bin/sh
sudo -u root kill -SIGHUP $(cat /var/www/html/mosquitto/mosquitto.pid)
When I run ./config.sh from folder, it runs.
When I run command in config.sh file directly in terminal, it
works too.
I've added this into sudoers file so that there is no need of password:
www-data ALL=(ALL) NOPASSWD: /var/www/html/config.sh
The thing is it's working fine when run using terminal in both the mentioned ways. Why is not executing when run in PHP?
Your problem is probably, that it is apache, www-data or some other user that is running your script and you try to run it as root.
Try without sudo -u root and change the group of the file to www-data with:
chown root:www-data your-script
As you say "It isn't outputting anything but my mosquitto broker is resetting every time it runs which lets me know"
I think you should replace
shell_exec('/var/www/html/config.sh');
with
$output = shell_exec('/var/www/html/config.sh');
echo $output;
According to php docs "shell_exec — Execute command via shell and return the complete output as a string"
shell_exec doesn't print by default; you have to store the string output and then use it
I made few changes in codes and it worked.
In shell_test.php, I changed code like this:
<?php
shell_exec('sudo -S ./config.sh');
?>
In config.sh, I changed like this:
#!/bin/sh
sudo kill -SIGHUP $(cat /var/www/html/mosquitto/mosquitto.pid)

Can't run PHP exec() on command line

Hoping someone can help me out here. Trying to run any command using exec() returns 126 and displays the same error message. I've narrowed it down to this pretty minimal test case.
root#test:~ $ sudo -u asterisk php -r 'exec("ls /", $out, $result); var_dump($result);'
sh: /bin/ls: Permission denied
int(126)
root#test:~ $ sudo -u asterisk ls /
bin boot dev etc home lib lib64 lost+found media mnt opt proc root sbin selinux srv sys tmp usr var
root#test:~ $ su -lc 'php -r '\''exec("ls /", $out, $result); var_dump($result);'\' asterisk
This account is currently not available.
SELinux and PHP safe mode are not enabled
permissions are fine on /, /bin/, and /bin/ls
asterisk is a system user created with this command: adduser -d /var/lib/asterisk -M -r -s /sbin/nologin asterisk
it works fine via Apache, which runs as this user
Every attempt to run any command returns permission denied and 126 as $?. The PHP config is pretty much as it shipped (Scientific Linux 6.7, PHP 5.4 via Remi package.)
Would appreciate some assistance (preferably the kind that would require some arcane knowledge, not the kind that means I missed something blindingly obvious!)
Edit: I can get it to work using su if I give the user a login shell:
root#test:~ $ usermod -s /bin/bash asterisk
root#test:~ $ su -c 'php -r '\''exec("ls /", $out, $result); var_dump($result);'\' asterisk
int(0)
However, this isn't my code so changing all the use of sudo to su is not likely to happen. Also, there shouldn't be anything stopping PHP from running this without a login shell.
You probably have enabled sudo option NOEXEC.
When this option is active, you can run command with high privilege, but cannot spawn other commands. This is (AFAIK) required to avoid an exploiter to gain a shell. Since you are using the asterisk user, this also makes much sense.
In your case, PHP command is granted the execution as asterisk user, but when it tries to spawn with exec, the command cannot be executed and it returns 126.
EDIT (as in comment below)
Adding this line to sudoers will solve this issue:
root ALL = (ALL) EXEC: ALL
Your account doesn't have permission to run bash commands.
As you know int(126) return the status of the executed command. From the bash man page:
If a command is found but is not executable, the return status is 126.
Try running ls directly from your asterisk user to see if it works.
If it doesn't work then check the permissions on your asterisk user and see if you have the necessary permissions. If you don't have the permissions, just use chmod to give your asterisk user permission. You should also try and create a new user and see if this command works with that user.
Edit: Since your asterisk account does not have a shell, you cannot execute shell commands from it.
Coming back to provide another answer to my own question a couple of years later. As the accepted answer supposed, I had set this in my file:
Defaults noexec
And I fixed this by overriding it for the root user.
But a better solution would be to apply the defaults only to the targeted user:
Defaults:admin noexec
This way the setting would not have affected the asterisk user I was having problems with in my question!

Run SUDO through PHP exec? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to call shell script from php that requires SUDO?
I have a Python file that needs SU rights to run (on Ubuntu server).
Can't figure out how to do it.
Running it from PHP like so:
$command = "python /path/to/my/file.py params";
$temp = exec($command, $output);
var_dump($output);
Not working. (Xvfb fails to start for non-root)
Tried:
$command = "echo 'root_pwd' | sudo -S python /program.py params"
...
didn't work.
Tried: edit /etc/sudoers:
Cmnd_Alias BUNDLE = /path/to/myprog.py
nobody ALL=(ALL) NOPASSWD:BUNDLE
and then:
$command = "sudo -u nobody python myprog.py params";
...
didn't work.
When I say "didn't work" - I mean that var_dump($output) returns empty array, no successful result on server (myprog.py should generate a file on the server) or the page simply loads for a couple mins until it times out.
Basic .py files (that don't require special rights) work.
Pls help.
PS:
.Py file is making screenshot of URL, so is using webkitgtk, Xvfb and couple other things.
Your command is wong:
$command = "sudo -u nobody python myprog.py params";
Here you're calling the python interpreter directly, but in your sudores file you only allowed /path/to/myprog.py.
If you want to do it this way, then add a shebang to your python program and make it executable, then change your command to
$command = "sudo -u nobody /path/to/myprog.py params";
But for this to work, the user you specify in your sudoers file must be the user executing the command, which probably isn't nobody but the web server process (www-data?):
Cmnd_Alias BUNDLE = /path/to/myprog.py
www-data ALL=(ALL) NOPASSWD:BUNDLE
The other way you tried
$command = "echo 'root_pwd' | sudo -S python /program.py"
probably failed because of two reasons:
the current user (probably the webserver process) isn't allowed to sudo
sudo doesn't take the root password, but the current users password
And you don't really want to pass passwords like this anyway...

what is the best way to run shell script (with root privilege) via php?

I've made a simple bash script for server admininstration and I cannot figure how can I run it in safely inside a php page: I'd like to create a php admininstration page but I obviously don't want to hard-code root password anyware. Let's make an example (this is a foo script, of course)
#!/bin/bash
touch /$1
this simple/stupid script will not work if the user who run it as no writing permission on /.
Actually the script add apache virtualhosts, ftp users and so on...
any ideas?
thanks
Use
sudo /path/to/executable/file
and set up sudo so it can execute the following command for the current user as a root.
http://www.sudo.ws/sudo/sudoers.man.html - here is the sudoers manual, the configuration file, that you have to modify.
zerkms ALL = (ALL) NOPASSWD: /sbin/iptables -L FORWARD -n -v -x
This is example from my /etc/sudoers. Here I allowed to run command /sbin/iptables -L FORWARD -n -v -x as root without asking a password for user zerkms.

sudo in php exec()

I don't know what the deal is here…
So I want to run an applescript: sudo osascript myscript.scpt
This works fine in the terminal, but not when I execute it via PHP's exec(); nothing happens. The console says
no tty present and no askpass program specified ; TTY=unknown ; …
I did my research, and it seems I'm missing the password for the sudo command. I tried a couple different ways to get around this, including:
writing %admin ALL=(ALL) ALL in /etc/sudoers
and proc_open() instead of exec()
none of which seem to be working, consequently driving me CrAzY!
So basically, is there a clear-cut way to get PHP to execute a simple terminal command?
EDIT: to clarify, myscript.scpt is a simple appleScript that changes the onscreen UI (for a larger project). In theory, simply osascript myscript.scpt should be enough, however the sudo is for some reason necessary to invoke some response from the system. If the sudo could be somehow eliminated, I don't think I would be having this permissions problem.
It sounds like you need to set up passwordless sudo. Try:
%admin ALL=(ALL) NOPASSWD: osascript myscript.scpt
Also comment out the following line (in /etc/sudoers via visudo), if it is there:
Defaults requiretty
I think you can bring specific access to user and command with visudo something like this:
nobody ALL = NOPASSWD: /path/to/osascript myscript.scpt
and with php:
#exec("sudo /path/to/osascript myscript.scpt ");
supposing nobody user is running apache.
php: the bash console is created, and it executes 1st script, which call sudo to the second one, see below:
$dev = $_GET['device'];
$cmd = '/bin/bash /home/www/start.bash '.$dev;
echo $cmd;
shell_exec($cmd);
/home/www/start.bash
#!/bin/bash
/usr/bin/sudo /home/www/myMount.bash $1
myMount.bash:
#!/bin/bash
function error_exit
{
echo "Wrong parameter" 1>&2
exit 1
}
..........
oc, you want to run script from root level without root privileges, to do that create and modify the /etc/sudoers.d/mount file:
www-data ALL=(ALL:ALL) NOPASSWD:/home/www/myMount.bash
dont forget to chmod:
sudo chmod 0440 /etc/sudoers.d/mount
I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
The shell has a pty (pseudo terminal device, same as you would have in i.e. a ssh session), and you can get the shell as root if desired. Not sure you need root to execute your script, but given you mention sudo it is likely.
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('/path/to/osascript myscript.scpt');
Run sudo visudo command then set -%sudo ALL=(ALL:ALL) to %sudo ALL=(ALL:ALL) NOPASSWD: ALL it will work.
I had a similar situation trying to exec() a backend command and also getting no tty present and no askpass program specified in the web server error log. Original (bad) code:
$output = array();
$return_var = 0;
exec('sudo my_command', $output, $return_var);
A bash wrapper solved this issue, such as:
$output = array();
$return_var = 0;
exec('sudo bash -c "my_command"', $output, $return_var);
Not sure if this will work in every case. Also, be sure to apply the appropriate quoting/escaping rules on my_command portion.
The best secure method is to use the crontab. ie Save all your commands in a database say, mysql table and create a cronjob to read these mysql entreis and execute via exec() or shell_exec(). Please read this link for more detailed information.
killProcess.php
I think directly calling a sudo command might be difficult because you are setting up the whole server to work without a password.
Perhaps as an alternative you could setup a CRONjob as root and monitor a flag file. Once the flag file exists it will run the osascript myscript.scpt and then delete the flag file.
This way you will keep SUDO secure from a config point of view and the server safer. To run the script you just need to touch the flag file from PHP.
It would of course introduce a delay of however many minutes you running the CRON job. It would also mean that you would have to redirect the output to a file and have a async monitor of the output, but it will depend on your application if this is a problem or not.
But it is an alternative that might protect the server.

Categories