I'm working on creating my own little Website to manage a Minecraft server as fun project. Now what I would need to accomplish is being able to send commands to the screen in which the server is running.
My approach to this was the following:
<?php
if (isset($_POST['startbutton']))
{
exec('sudo screen -S 23971 -X stuff "say hello^M"');
}
?>
<form method="post">
<button type="submit" name="startbutton">Test</button>
</form>
Now that command line works just fine when i execute it in the terminal itself, but as soon as i try to run it over the Website nothing happens.
If i just try to execute
if (isset($_POST['startbutton']))
{
echo exec('whoami');
}
?>
it works just fine as well. I don't know what I am doing wrong.
i'm really not sure about it, but try:
<?php
if (isset($_POST['startbutton']))
{
exec('sudo screen -S 23971 -X stuff "say hello^M"');
exec('YOUR SUDO PSW');
}
?>
<form method="post" action="YOUR PHP PAGE LIKE server.php">
<button type="submit" name="startbutton">Test</button>
</form>
let me know if it works
Seems like you are trying to execute a command that needs superuser permissions. In most setups PHP runs under the webserver user and it does not have those permissions. Also you should keep in mind that giving superuser permissions to PHP is a security risk.
My suggestion would be to have a dedicated service, responsible for executing those shell commands. You could then call that service from your PHP script without needing sudo.
Check these for details:
https://serverfault.com/questions/622271/securely-executing-system-commands-as-sudo-from-php/622277
sudo in php exec()
First of all: Thank you all for your support.
I was doing a bit of further research and found a solution for my problem:
I created a new user which I then gave the ownership of /var/www.
I then changed the apache2 user from www-data to the new user.
Now i just needed to start the screen with the minecraft server as the new user so i can access this screen out of php and I was able to get it to work without having to give any user full root privileges or anything.
After opening and reading every result on Google, I figured it's time to make my own thread somewhere. I am sorry that I need to ask a question that's already been asked before, I cannot stress this enough, but I have no other option as no other question asked has helped me achieve what my goal is.
I'm trying to setup a means of rebooting/doing other system functions through a web interface powered by HTML (for the buttons/text) and PHP (for the execution of the aforementioned functions).
I'm unable to get this to work. I've read that I need to add the web user to the sudoers file, and I've tried. I'm running Nginx on my server, how do I add the user to the sudoers in my case?
Also, I'm aware of the security risks.
The following is what I have so far:
HTML (index.html):
<body>
<h3>Restart</h3>
<p>
<form action="restart.php" method="get">
<input type="submit" value="Press me.">
</form>
</p>
</body>
PHP (restart.php):
<?php
echo "This is a test";
echo "<br>";
echo "<br>";
echo shell_exec('ifconfig');
echo "<br>";
echo "<br>";
echo "Restarting server...";
exec ('/usr/bin/sudo /etc/init.d/portmap restart');
shell_exec("/sbin/reboot");
exec("/sbin/reboot");
system("/sbin/reboot");
?>
Mind you that here, I only have so many things attempting to execute, so that I make sure I hit the target when one of them works, if that makes sense. The IFConfig is just a test to make sure that it's actually able to execute.
Sudoers:
# User privilege specification
root ALL=(ALL:ALL) ALL
www-data reboot = NOPASSWD: /sbin/reboot
This is all on Ubuntu 14.04 LEMP.
You can do this either by editing your sudoers file :
Sudoers:
www-data ALL=(root) NOPASSWD: /sbin/reboot
The first ALL is for the hostname if you're hostname is not 'reboot' I advise you to keep ALL as it will work in any hostname. That's why it doesn't seem to work on your server
restart.php
exec('sudo /sbin/reboot');
Or without editing your sudoers file.
First create a file where you're gonna store you're root password
~/password :
myrootpassword
Second run any command you want while being root from php file (don't forget to specify the file which store your password)
phpfile.php :
exec('sudo -u root -S /sbin/reboot < ~/password');
www-data reboot = NOPASSWD: /sbin/reboot
this means you dont need a password when running sudo, not that the command runs as sudo when ever run by that user.
The answer is to use sudo /sbin/reboot as the command
You can use puty. I think using php is not a good plan.
I want to restart mysql service on click of the button using php.
I have developed application using php till now I tried below things and facing the problem
<?php
if ($_GET['run']) {
# This code will run if ?run=true is set.
var_dump(exec("sh rst.sh"));
exit;
}
?>
<!-- This link will add ?run=true to your URL, myfilename.php?run=true -->
Click Me!
What I am getting is:
string(55) "Restarting mysql (via systemctl): mysql.service failed!"
rest.sh:
#!/bin/bash
/etc/init.d/mysql restart
while executing above file from the commnad line it asks for the password.
any help will be appreciated.
Thanks
Granting the user that runs PHP/web server permissions to restart any service is generally a bed idea from security perspective not even taking about permission to manage all system daemons or full sudo.
Once you have been warned, you have to make sure the user that is running the PHP script has the permission to run the restart command. As already stated, the issue has likely little to do with PHP. There are several ways from you to proceed here:
You can grant the PHP user the sudo permission to run the desired command and nothing else (how to do that is covered elsewhere) and invoke the command directly from PHP: sudo systemctl restart mysql.
Keep the rst.sh file, get it owned by root, writeable by noone else but root and set SUID bit on that file. This way you can invoke the script without sudo but the script will be run as root thanks to the SUID bit.
#1 feels safer and simpler.
You could also try with system():
<?php
if ($_GET['run']) {
# This code will run if ?run=true is set.
var_dump(system("sh rst.sh"));
exit;
}
?>
<!-- This link will add ?run=true to your URL, myfilename.php?run=true -->
Click Me!
Though your problem is coming from the script you are running (rst.sh). Check the commands in script, you probably need to a systemctl call with sudo.
In php try using this command
exec("/etc/init.d/mysql restart");
or push this command to rst.sh
be ensure have chmod +x on file rst.sh
i am using arch linux. i want to execute the php file which changes the ip of the system. i did
ifconfig eth0 192.168.163.137
in the terminal and it works fine. the same i tried doing with
shell_exec('ifconfig eth0 192.168.163.137');
in a php file and tried opening the page from a remotely located web browser from another pc connected via router. teh page displays nothing and the code also doesnt execute. i guess its the problem with the user executing it.apache is executing it. so i want it to be run by the root.can anyone please guide me to the execution of my code. i even installed sudo and just put
shell_exec('sudo ifconfig......');
it too doesnt execute...please help...thanku..:)
Sudo normally requires an interactive shell to enter your password. That's obviously not going to happen in a PHP script. If you're sure you know what you're doing and you've got your security issues covered, try allowing the Apache user to run sudo without a password, but only for certain commands.
For example, adding the following line in your sudoers file will allow Apache to run sudo without a password, only for the ifconfig command.
apache ALL=NOPASSWD: /sbin/ifconfig
Adjust the path and add any arguments to suit your needs.
Caution:
There might still be complications due to the way PHP calls shell commands.
Remember that it's very risky to allow the web server to run commands as root!
Probably a better alternative:
Write a shell script with the suid bit to make it run as root no matter who calls it.
shell_exec
This function is disabled when PHP is running in safe mode.
Documentation : http://php.net/manual/en/function.shell-exec.php
So, maybe try tweaking your php.ini file?
Write the commands to a queue and have cron pick them up, validate them (only allow known good requests), and run them, then mark that queue complete with the date and result.
Your end-user can then click/wait for update using ajax.
I need to detect if php is running as nobody. How do I do this?
Are there any other names for "nobody"? "apache"? Any others?
<?php echo exec('whoami'); ?>
If available you can probe the current user account with posix_geteuid and then get the user name with posix_getpwuid.
$username = posix_getpwuid(posix_geteuid())['name'];
If you are running in safe mode however (which is often the case when exec is disabled), then it's unlikely that your PHP process is running under anything but the default www-data or apache account.
Kind of backward way, but without exec/system:
file_put_contents("testFile", "test");
$user = fileowner("testFile");
unlink("testFile");
If you create a file, the owner will be the PHP user.
This could also likely be run with any of the temporary file functions such as tempnam(), which creates a random file in the temporary directory and returns the name of that file. If there are issues due to something like the permissions, open_basedir or safe mode that prevent writing a file, typically, the temp directory will still be allowed.
More details would be useful, but assuming it's a linux system, and assuming php is running under apache, it will run as what ever user apache runs as.
An easy way to check ( again, assuming some unix like environment ) is to create a php file with:
<?php
print shell_exec( 'whoami' );
?>
which will give you the user.
For my AWS instance, I am getting apache as output when I run this script.
You can try using backticks like this:
echo `whoami`;
I would use:
lsof -i
lsof -i | less
lsof -i | grep :http
You can type any of these in your ssh command line and you will see which user is listening to each service.
You can also check this file:
more /etc/apache2/envvars
and look for these lines:
export APACHE_RUN_USER=user-name
export APACHE_RUN_GROUP=group-name
To filter out envvars file data, you can use grep:
more /etc/apache2/envvars | grep APACHE_RUN_
Straight from the shell you can run:
php -r "echo exec('whoami');"
exec('whoami') will do this
<?php
echo exec('whoami');
?>
In my setup I want to check if the current process has permission to create folders, subfolders and files before I begin a process and suggest a solution if it looks like I can't. I wanted to run stat(<file>) on various things to ensure the permissions match those of the running process (I'm using php-fpm so it varies depending on the pool).
The posix based solution Mario gave above, seems perfect, however it seems the posix extension is --disabled so I couldn't do the above and as I want to compare the results with the response from running stat() running whoami in a separate shell isn't helpful either (I need the uid and gid not the username).
However I found a useful hint, I could stat(/proc/self) and stat(/proc/self/attr) and see the uid and gid of the file.
Hope that helps someone else
Proposal
A tad late, but even though the following is a work-around, it solves the requirement as this works just fine:
<?
function get_sys_usr()
{
$unique_name = uniqid(); // not-so-unique id
$native_path = "./temp/$unique_name.php";
$public_path = "http://example.com/temp/$unique_name.php";
$php_content = "<? echo get_current_user(); ?>";
$process_usr = "apache"; // fall-back
if (is_readable("./temp") && is_writable("./temp"))
{
file_put_contents($native_path,$php_content);
$process_usr = trim(file_get_contents($public_path));
unlink($native_path);
}
return $process_usr;
}
echo get_sys_usr(); // www-data
?>
Description
The code-highlighting above is not accurate, please copy & paste in your favorite editor and view as PHP code, or save and test it yourself.
As you probably know, get_current_user() returns the owner of the "current running script" - so if you did not "chown" a script on the server to the web-server-user it will most probably be "nobody", or if the developer-user exists on the same OS, it will rather display that username.
To work around this, we create a file with the current running process. If you just require() this into the current running script, it will return the same as the parent-script as mentioned; so, we need to run it as a separate request to take effect.
Process-flow
In order to make this effective, consider running a design pattern that incorporates "runtime-mode", so when the server is in "development-mode or test-mode" then only it could run this function and save its output somewhere in an include, -or just plain text or database, or whichever.
Of course you can change some particulars of the code above as you wish to make it more dynamic, but the logic is as follows:
define a unique reference to limit interference with other users
define a local file-path for writing a temporary file
define a public url/path to run this file in its own process
write the temporary php file that outputs the script owner name
get the output of this script by making a request to it
delete the file as it is no longer needed - or leave it if you want
return the output of the request as return-value of the function
add the file info.php to the following directory - your default http/apache directory - normally /var/www/html
with the following contents
<?php
phpinfo();
?>
Then httpd/apache restart
the go to your default html directory
http://enter.server.here/info.php
would deliver the whole php pedigree!
You can use these commands :
<? system('whoami');?>
or
<? passthru('whoami');?>
or
<? print exec('whoami');?>
or
<? print shell_exec('whoami');?>
Be aware, the get_current_user() returns the name of the owner of the current PHP script !
I usually use
<?php echo get_current_user(); ?>
I will be glad if it helped you
$_SERVER["USER"]
$_SERVER["USERNAME"]
<?php phpinfo(); ?>
save as info.php and
open info.php in your browser
ctrl+f then type any of these:
APACHE_RUN_USER
APACHE_RUN_GROUP
user/group
you can see the user and the group apache is running as.
$user = $_SERVER['REMOTE_USER'];
http://php.net/manual/en/reserved.variables.server.php
Authenticated user