通过PHP执行root命令

时间:2011-12-16 09:43:16

标签: php apache permissions root

我有一个CentOS 5.7 linux服务器并使用php5.3.x。

在pfSense系统上,您可以使用php网页重新启动需要root权限的服务。

我正在尝试做类似的事情,我已经写了一些PHP代码来执行shell命令。例如,要重新启动sshd服务:

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

我尝试通过exec函数执行该命令,但它需要root权限,但我们有一个apache用户权限。

我遇到了一些解决方案:

  1. “用root用户运行apache” 真的不安全。我不想这样做。
  2. “apache ALL = NOPASSWD:/ sbin / service to / etc / sudoers” 我试过但仍然有问题。
  3. 还有其他解决方案吗? 谢谢你的回答。


    现在..这很有趣。我试过@refp post,它工作了我的本地ubuntu服务器。但是当我在我的cenOS vps服务器上尝试相同时。它不起作用。这是apache的错误日志“rm:无法删除`/ var / lock / subsys / vsftpd':权限被拒绝”

6 个答案:

答案 0 :(得分:89)

在尝试之前阅读整篇文章,可以做出选择。


使用二进制包装器(带有suid位)的解决方案

1)创建一个脚本(最好.sh),其中包含您希望以root用户身份运行的内容。

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

2)此文件应由root拥有,并且由于它稍后将以root权限运行,因此请确保只有root用户才有权写入该文件。

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

3)要以root身份运行脚本,无论执行它的用户是什么,我们都需要一个二进制包装器。创建一个将执行我们的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)编译并设置适当的权限,包括suid位(说它应该以root权限运行):

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

php_root现在将以root权限运行,并执行php_shell.sh中指定的命令。


如果您不需要选项来轻松更改将要执行的命令,我建议您直接在步骤 4 wrapper.c中编写命令。然后,您不需要二进制文件执行执行相关命令的外部脚本。

wrapper.c中,使用system ("your shell command here");指定您要执行的命令。

答案 1 :(得分:22)

我不会让PHP执行任何sudo命令。对我而言,这听起来像是在寻找麻烦。相反,我会创建两个独立的系统。

PHP(Web层)中的第一个系统将处理用户请求。当发出需要sudo命令的请求时,我会将此请求放在某个队列中。这可能是某种类型的数据库或中间件,如ZeroMQ。

第二个系统(业务层)将从此队列读取或接收消息,并且能够执行sudo命令,但不在您的Web服务器进程范围内。

我知道这有点模糊,可以通过各种技术以不同的方式解决,但我认为这是最好和最安全的方式。

答案 2 :(得分:8)

允许www-data用户运行以运行无密码的program1和program2:

sudo visudo

添加到sudoers文件的内容:

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

保存。

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

答案 3 :(得分:2)

我最近发布了一个允许PHP获取真实Bash shell并与之交互的项目,它将很容易为您提供以root身份登录的shell。然后你可以只执行单独的bash命令,而不是在脚本中捆绑。这样你也可以处理回报。在此处获取:https://github.com/merlinthemagic/MTS

下载后,您只需使用以下代码:

$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  ]

答案 4 :(得分:2)

使用二进制包装器(带有suid位)的解决方案Filip Roséen - refp帖子进行了一些修改。

执行任何命令修改后的wrapper.c

hadoop dfadmin -safemode get

编译并设置适当的权限;

#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;
 }

现在从PHP调用。执行任何命令。

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

答案 5 :(得分:0)

setenforce 0

在终端中写入此命令将禁用SELinux。 这不是一个好习惯