简体   繁体   English

通过 PHP 执行 root 命令

[英]Execute root commands via PHP

I have a CentOS 5.7 linux server and use php5.3.x.我有一个 CentOS 5.7 linux 服务器并使用 php5.3.x。

On a pfSense system, you can restart services-that required root permissions using a php web page.在 pfSense 系统上,您可以使用 php 网页重新启动需要 root 权限的服务。

I'm trying to do something similar, I have written some php code to execute shell commands.我正在尝试做类似的事情,我编写了一些 php 代码来执行 shell 命令。 For example, to restart the sshd service:例如,要重新启动 sshd 服务:

<?php
exec('/sbin/service sshd restart');
?>

and I tried to execute that command via exec function, but it needs root permission, but we have a apache user authority.我试图通过 exec 函数执行该命令,但它需要 root 权限,但我们有 apache 用户权限。

I have come across a few solutions:我遇到了一些解决方案:

  1. "run apache with root user" really unsafe. “用root用户运行apache”真的不安全。 I do not want to do that.我不想那样做。
  2. "apache ALL=NOPASSWD:/sbin/service to /etc/sudoers" I tried but and still have a problem. “apache ALL=NOPASSWD:/sbin/service to /etc/sudoers”我试过了,但仍然有问题。

Any other solutions?还有其他解决方案吗? Thanks for answers.感谢您的回答。


now.. it's interesting.现在..很有趣。 i tried @refp post and it worked my local ubuntu server.我试过@refp 帖子,它在我的本地 ubuntu 服务器上工作。 But when i tried same at my cenOS vps server.但是当我在我的 cenOS vps 服务器上尝试相同时。 It's not working.and that is apache's error log "rm: cannot remove `/var/lock/subsys/vsftpd': Permission denied"它不起作用。那是 apache 的错误日志“rm:无法删除`/var/lock/subsys/vsftpd':权限被拒绝”

Read this whole post before trying it out, there are choices to be made.在尝试之前阅读整篇文章,有很多选择。


Solution using a binary wrapper (with suid bit)使用二进制包装器的解决方案(带有 suid 位)

1) Create a script (preferrably .sh ) that contains what you want to be ran as root. 1)创建一个脚本(最好是.sh ),其中包含您希望以 root 身份运行的内容。

# cat > php_shell.sh <<CONTENT
  #!/bin/sh
  /sbin/service sshd restart
CONTENT

2) This file should be owned by root, and since it will later run with root permissions make sure that only root has permission to write to the file. 2)这个文件应该归 root 所有,因为它以后会以 root 权限运行,所以确保只有 root 才有写入文件的权限。

# chown root php_shell.sh
# chmod u=rwx,go=xr php_shell.sh

3) To run the script as root no matter what user that executes it, we will need a binary wrapper. 3)无论执行脚本的用户是谁,都要以 root 身份运行脚本,我们需要一个二进制包装器。 Create one that will execute our php_shell.sh .创建一个将执行我们的php_shell.sh

# cat > wrapper.c <<CONTENT
  #include <stdlib.h>
  #include <sys/types.h>
  #include <unistd.h>

  int
  main (int argc, char *argv[])
  {
     setuid (0);

     /* WARNING: Only use an absolute path to the script to execute,
      *          a malicious user might fool the binary and execute
      *          arbitary commands if not.
      * */

     system ("/bin/sh /path/to/php_shell.sh");

     return 0;
   }
CONTENT

4) Compile and set proper permissions, including the suid bit (saying that it should run with root privileges): 4)编译并设置适当的权限,包括suid位(说它应该以root权限运行):

# gcc wrapper.c -o php_root
# chown root php_root
# chmod u=rwx,go=xr,+s php_root

php_root will now run with root permissions, and execute the commands specified in php_shell.sh . php_root现在将以 root 权限运行,并执行php_shell.sh指定的命令。


If you don't need to the option to easily change what commands that will be executed I'd recommend you to write the commands directly in wrapper.c under step 4 .如果您不需要选项来轻松更改将要执行的命令,我建议您直接在wrapper.c step 4下编写命令。 Then you don't need to have a binary executing a external script executing the commands in question.然后,您不需要让二进制文件执行执行相关命令的外部脚本。

In wrapper.c , use system ("your shell command here");wrapper.c ,使用system ("your shell command here"); to specify what commands you'd like to execute.指定您要执行的命令。

I would not have PHP execute any sudo commands.我不会让 PHP 执行任何 sudo 命令。 To me that sounds like asking for trouble.对我来说,这听起来像是自找麻烦。 Instead I would create two separate systems.相反,我会创建两个独立的系统。

The first system, in PHP (the web tier), would handle user requests.第一个系统,在 PHP(Web 层)中,将处理用户请求。 When a request is made that needs a sudo command I would place this request in some queue.当发出需要 sudo 命令的请求时,我会将这个请求放在某个队列中。 This could be a database of some sort or middle-ware such as ZeroMQ.这可能是某种数据库或中间件,例如 ZeroMQ。

The second system (the business tier) would read or receive messages from this queue and would have the ability to execute sudo commands but won't be in the scope of your web-server process.第二个系统(业务层)将从该队列读取或接收消息,并且能够执行 sudo 命令,但不会在您的 Web 服务器进程的范围内。

I know this is a bit vague and it can be solved in different ways with various technologies but I think this is the best and safest way to go.我知道这有点含糊,可以使用各种技术以不同方式解决,但我认为这是最好和最安全的方法。

Allow the www-data user to run to run program1 and program2 with no password:允许www-data用户运行无需密码即可运行program1和program2:

sudo visudo

Add to the contents of the sudoers file:添加到 sudoers 文件的内容:

User_Alias WWW_USER = www-data
Cmnd_Alias WWW_COMMANDS = /sbin/program1, /sbin/program2
WWW_USER ALL = (ALL) NOPASSWD: WWW_COMMANDS

Save.节省。

from https://askubuntu.com/questions/76920/call-a-shell-script-from-php-run-as-root来自https://askubuntu.com/questions/76920/call-a-shell-script-from-php-run-as-root

Solution using a binary wrapper (with suid bit) Some modification of Filip Roséen - refp post.使用二进制包装器(带有 suid 位)的解决方案Filip Roséen 的一些修改- refp帖子。

To execute any command modified wrapper.c执行任何命令修改wrapper.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int main (int argc, char  **argv)
{
 setuid (0);
 char cmd[100] = "";
 int i;
 char *p;
 for(i=0; i < argc; i++) {
    if(i != 0){
   strcat(cmd, *(argv+i));
   strcat(cmd, " ");
    }
 }

 system (cmd);

 return 0;
 }

Compile and set proper permissions;编译并设置适当的权限;

  gcc wrapper.c -o php_root     # php_root can be any name.
  chown root php_root
  chmod u=rwx,go=xr,+s php_root

Now call from PHP.现在从 PHP 调用。 Execute any command.执行任何命令。

 shell_exec('./php_root '.$cmd);//execute from wrapper

I recently published a project that allows PHP to obtain and interact with a real Bash shell, it will easily give you a shell logged in as root.我最近发布了一个项目,它允许 PHP 获取真正的 Bash shell 并与之交互,它可以轻松地为您提供一个以 root 身份登录的 shell。 Then you can just execute the individual bash commands rather than bundling then in a script.然后你可以只执行单独的 bash 命令,而不是捆绑在脚本中。 That way you can also handle the return.这样你也可以处理退货。 Get it here: https://github.com/merlinthemagic/MTS在这里获取: https : //github.com/merlinthemagic/MTS

After downloading you would simply use the following code:下载后,您只需使用以下代码:

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd('service sshd restart');

echo $return1;

//On CentOS 7 output would be like: 
//Redirecting to /bin/systemctl restart  sshd.service

//On CentOS 6 and lower output would be like:
//Stopping sshd:                                             [  OK  ]
//Starting sshd:                                             [  OK  ]
setenforce 0

Write this command in the terminal this command will disable SELinux.在终端中写入此命令此命令将禁用 SELinux。 this isn't a good practice .这不是一个好习惯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM