it-swarm-pt.tech

Execute comandos raiz via PHP

Eu tenho um servidor Linux CentOS 5.7 e uso php5.3.x.

Em um sistema pfSense, você pode reiniciar os serviços - as permissões de root necessárias usando uma página da web php.

Estou tentando fazer algo semelhante, eu escrevi algum código php para executar comandos do shell. Por exemplo, para reiniciar o serviço sshd:

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

e tentei executar esse comando via função exec, mas ele precisa de permissão root, mas temos uma autoridade de usuário do Apache.

Encontrei algumas soluções:

  1. "execute Apache com usuário root" realmente inseguro. Eu não quero fazer isso.
  2. "Apache ALL = NOPASSWD:/sbin/service para/etc/sudoers" Tentei, mas ainda tenho um problema.

Alguma outra solução? Obrigado pelas respostas.


agora .. é interessante. Eu tentei @refp post e funcionou meu servidor ubuntu local. Mas quando eu tentei o mesmo no meu servidor cenOS vps. Não está funcionando. E esse é o log de erros do Apache "rm: não é possível remover`/var/lock/subsys/vsftpd ': permissão negada "

50
Mehmet INCE

Leia este post inteiro antes de testá-lo, há opções a serem feitas.


Solução usando um invólucro binário (com bit suid)

1) Crie um script (preferencialmente .sh) que contenha o que você deseja que seja executado como root.

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

2) Este arquivo deve pertencer ao root e, como será executado posteriormente com permissões de root, verifique se apenas o root tem permissão para gravar no arquivo.

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

) Para executar o script como root, não importa qual usuário o execute, precisaremos de um wrapper binário. Crie um que execute nosso 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 e defina permissões apropriadas, incluindo o suid bit (dizendo que ele deve ser executado com privilégios de root):

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

php_root agora será executado com permissões de root e executará os comandos especificados em php_Shell.sh.


Se você não precisa alterar facilmente quais comandos serão executados, recomendo que você escreva os comandos diretamente em wrapper.c na etapa 4. Então você não precisa ter um binário executando um script externo executando os comandos em questão.

Em wrapper.c, use system ("your Shell command here"); para especificar quais comandos você gostaria de executar.

88
Filip Roséen - refp

Eu não teria PHP executado nenhum comando Sudo. Para mim, isso parece pedir problemas. Em vez disso, eu criaria dois sistemas separados.

O primeiro sistema, em PHP (a camada da web), trataria das solicitações do usuário. Quando é feito um pedido que precisa de um comando Sudo, eu colocaria esse pedido em alguma fila. Pode ser um banco de dados de algum tipo ou middleware, como o ZeroMQ.

O segundo sistema (a camada de negócios) leria ou receberia mensagens dessa fila e teria a capacidade de executar comandos Sudo, mas não estará no escopo do processo do servidor da web.

Sei que isso é um pouco vago e pode ser resolvido de maneiras diferentes com várias tecnologias, mas acho que esse é o melhor e mais seguro caminho a percorrer.

22
Luke

Permita que o usuário www-data execute para executar o programa1 e o programa2 sem senha:

Sudo visudo

Adicione ao conteúdo do arquivo sudoers:

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

Salve .

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

8
harrrrrrry

Solução usando um invólucro binário (com suid bit) Alguma modificação de Filip Roséen - refp post.

Para executar qualquer comando modificado 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;
 }

Compilar e definir permissões apropriadas;

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

Agora ligue do PHP. Execute qualquer comando.

 Shell_exec('./php_root '.$cmd);//execute from wrapper
2
sharif143

Publiquei recentemente um projeto que permite ao PHP obter e interagir com um Bash Shell real; ele fornecerá facilmente um Shell conectado como root. Em seguida, você pode simplesmente executar os comandos bash individuais em vez de agrupar em um script. Dessa forma, você também pode lidar com o retorno. Obtenha aqui: https://github.com/merlinthemagic/MTS

Após o download, você simplesmente usaria o seguinte código:

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