Can't change users within system() in php - php

My command is
echo root_password | sudo -u root -S executable_full_path arguments
The error message I get in the browser is
[sudo] password for www-data: Sorry,
try again.
From phpinfo(), safe mode is off and there are no disabled functions. Why isn't this working? The same command runs fine in the shell (bash). Escapeshellarg and escapeshellcmd don't make a difference.
EDIT: Simply being able to execute the command is not enough. The program that gets executed creates a socket in /tmp, and needs to assign it permissions. So I think I really need to be root for this, is that possible?

As Álvaro suggested, I'm putting my comment as answer. Matt, this would make it possible to run that command as root.
#Matt, don't do that /etc/sudoers (btw, you edit this file with the visudo command, never directly). That way you are making possible that any sudo whatever command run by your web application is run by root, possibiliting a lot of fun for an attacker if he founds a vulnerability in your application.
If you would like to run just ONE command as root without need for passwords, put this in /etc/sudoers (remember visudo command):
www-data ALL=(ALL) NOPASSWD: executable_full_path
Then you are only allowing to execute just this command as root. Now you should be able to do
sudo -u root executable_full_path arguments
without need to type in a password (and it will run as root). Also, this is the only command the user www-data may execute as root using sudo, so it should not be dangerous.

You're echoing the root password when you should be echoing the password for www-data.

Use this on your /ets/sudoers
Example for run gconftool-2 :
www-data ALL=NOPASSWD: /usr/bin/gconftool-2
www-data ALL=NOPASSWD: /usr/bin/sudo
www-data ALL=NOPASSWD: ALL

Related

How to run a shell as root from php (apache)

I am using ubuntu server 20.04 LTS, where I have multiple shell files, using php from apache I need to run multiple shell files from a browser but need to run as root.
I have tried the command shell_exec and added sudoers (www-data) and none works, which I can put in the code to enter as root and be able to execute the shell script.
<?php
$code = shell_exec('echo "passwd" | sudo -u root -S sh /home/user/name.sh');
echo "<pre>$code</pre>";
?>
Because your are executing this script as www-data and www-data doesn't have the required privilege to execute any sudo commands.
You can try the following steps.
Modify www-data in /etc/sudoers to be able to execute a script as the superuser. This is a sensitive file and you have to use visudo as the editor to make the changes.
$ sudo visudo -f /etc/sudoers
www-data ALL=(ALL) NOPASSWD: /home/user/name.sh
This will allow www-data to execute the script as the superuser without a password.
In your PHP code change the command in your shell_exec() as follows:
$code = shell_exec(sudo sh /home/user/name.sh');
Make sure your name.sh is set up with proper file modes to protect yourself.

xvfb-run works in shell but not when running from php exec() command

I'm trying to get nightmarejs to work on my centos server and was able to do so by running xvfb-run however I need to call this command via a php exec() function.
when I do I'm just getting an empty result as though it doesn't work?
When I run it via command line (i.e. xvfb-run node my-script.js) everything works great. Any idea why it doesn't seem to work or be available to my php script?
Although Cono's answer does work, it is less secure as it gives YOUR_USER access to wheel, making YOUR_USER an administrator.
Instead, create a file in /etc/sudoers.d (RHEL/CentOS) with contents like: (presuming YOUR_USER is apache)
# Allow apache to run xvfb-run
Defaults:apache !requiretty
Defaults:apache visiblepw
apache ALL = NOPASSWD: /usr/bin/xvfb-run
This way, if the apache user is compromised they can only run the xvfb-run command.
(Answer thanks to ThirdNode)
Ok i figured it out. Basically, sudo access has to be granted for xvfb-run in order to call it via an executable script in php. To do so, log into terminal and do the following:
# sudo visudo
Make sure the wheel group is uncommented
%wheel ALL=(ALL) ALL
This means that users added to the wheel group will have access to call sudo commands
At the bottom of the file, grant your user access to the script
YOUR_USER ALL = NOPASSWD: /usr/bin/xvfb-run
Save your file and add your user to the wheel group
usermod -aG wheel YOUR_USER
finally, from your php script you can now call xvfb-run via sudo
<?php exec('sudo xvfb-run node my-script.js'); ?>

Mounting a drive in debian from php code

I've been at this for two days now and haven't been able to find any way (good or bad) of doing that to work.
I have to be able of dynamically mounting drives over network from my website's pages (that part is inevitable).
I have no problems doing it directly on the console with the following command
mount -t cifs //IP-REMOTE-MACHINE/Folder -o username=username,password=password /mnt/share
Obviously trying to just do a shell_exec() of this command wouldn't work with no root rights.
I tried to shell_exec() a script in which I would switch to root user (via su or sudo mycommand) but both of them wouldn't work (never been able to succeed in doing a script who would automatically switch my user to root even with the root pwd hard coded (even if that feels an extremely bad idea I could have accepted that atm).
After that I tried to use pmountbut never found a way to access to a remote shared file (don't think it's even possible but I may have missed something here?)
All that is running on a Debian machine with apache2.
I have a wild idea...
You could set a cron to run as root that checks for mount commands from your script. The script would simply set a mount command to be processed, and when the cron gets to it, runs the mount, marks the command as processed, and writes to a log file which you could then display.
It's not safe to run sudo commands with www-data (the user for web servers in Debian).
But if you want to run sudo [command] in a php script, you must add the user www-data in sudoers: http://www.pendrivelinux.com/how-to-add-a-user-to-the-sudoers-list/
And then you can exec: sudo mount ...
EDIT: It's safer to add in visudo:
www-data ALL= NOPASSWD: /bin/mount
To allow www-data to use only sudo /bin/mount

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

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?
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)
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

PHP shell_exec() and sudo: must be setuid root

I have a shell_exec() command that accesses a directory above my document root so I need to use sudo "as root" to make it happen. (I understand the security issues and am putitng in measures to address it).
The issue is when I run the shell_exec() I get a "sudo: must be setuid root" error in my apache error_log file.
I thought the solution was to chmod 4750 the bash script that is called by my sheel_exec() but that does not do the job.
What exactly is "sudo: must be setuid root" trying to tell me and how might I resolve it?
Is the sudo executable itself setuid root? You may need to
chown root: /usr/bin/sudo
chmod u+s /usr/bin/sudo
Alternatively, skip sudo altogether. If your script is owned by root and has its own setuid bit set, then you don't need to use sudo to get root privileges. In fact, it can be more secure that way; you guarantee that your web user can only use that script, without having to edit sudoers. To do so, remove sudo from your shell_exec() line:
<?php
shell_exec('/path/to/your/command');
?>
Did you check the permissions for your script?
Who is owning the script?
Does the web user has the rights to sudo?
To fix this problem you need to chown and chmod sudo file as root as below.
chown root:root /usr/bin/sudo
chmod 4111 /usr/bin/sudo
chmod 0440 /etc/sudoers

Categories