Ejecutar comandos raíz a través de PHP

Tengo un CentOS 5.7 servidor linux y usar php5.3.x.

En un pfSense sistema, usted puede reiniciar los servicios-que requiere permisos de root usando php de la página web.

Estoy tratando de hacer algo similar, he escrito algo de código php para ejecutar comandos de shell. Por ejemplo, para reiniciar el servicio sshd:

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

y traté de ejecutar ese comando a través de la función exec, pero necesita root permiso, pero tenemos un usuario de apache autoridad.

Me he encontrado un par de soluciones:

  1. «ejecutar apache con usuario root»
    realmente inseguro. Yo no quiero hacer eso.
  2. «apache ALL=NOPASSWD:/sbin/service a /etc/sudoers»
    Lo intenté, pero y todavía tiene un problema.

Cualquier otras soluciones?
Gracias por las respuestas.


ahora.. es muy interesante. traté de @refp post y funcionó mi local de ubuntu server. Pero cuando traté mismo en mis cenOS servidor vps. No es de trabajo.y que es apache registro de error de «rm: no se puede quitar `/var/lock/subsys/vsftpd»: Permiso denegado»

  • Y, ¿intenta el sudoers solución? ¿Qué problema tenía? ¿Agregar sudo en el exec() comando? O algo que valga la pena en la error.log, syslog, o /var/log/auth.log para que la materia?
  • tail /var/log/httpd/error.registro de «sudo: lo siento, debe tener un tty para ejecutar sudo»
  • posibles duplicados de Ejecutar un sistema linux comando como superusuario, utilizando una secuencia de comandos de python (Véase la última respuesta)
  • Gracias por responder a mario, pero todavía tiene un problema. <nombre de usuario> «ALL = NOPASSWD: /etc/init.d/postfix» yo ya la prueba de que el método como «apache ALL=NOPASSWD: /sbin/service» . . . yo no entiendo por qué fichero sudoers no dan permiso a usuario de apache con esa línea.
  • Usted puede restringir sudo ejecución (¿por qué ALL como una serie de especificaciones? localhost debería ser suficiente!). También, si su sudoers tiene, quitar Defaults require_tty, ya que Apache no se ejecutan con un teléfono conectado a la misma.
  • vemos que la línea de error en httpd registros de error porque cuando php intentar ejecutar comandos con exec(), no tienen totalmente sesión de terminal. Es lo mismo como la inversa de conectar con el servidor…
  • he cambiado el archivo sudoers configuración; cerrado línea tty. y el usuario de apache cambiar TODOS los LOCALES. y aquí está la nueva httpd registro de error de «sudo: no se puede stat /var/run/sudo: Permiso denegado sudo: no tty presente y no askpass programa especificado «
  • Se las arregló para ejecutar en Cent OS, desde que estoy teniendo el mismo problema.

InformationsquelleAutor Mehmet INCE | 2011-12-16

5 Kommentare

  1. 91

    Leer todo este post, antes de probarlo, hay que elegir.


    Solución utilizando un binario de contenedor (con el bit suid)

    1) Crear una secuencia de comandos (preferiblemente .sh) que contiene lo que queremos ser ejecutado como root.

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

    2) Este archivo debe ser propiedad de root, y ya será más adelante se ejecute con permisos de root, asegúrese de que sólo root tiene permiso para escribir en el archivo.

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

    3) Para ejecutar el script como root no importa lo que el usuario que lo ejecuta, vamos a necesitar un binario de contenedor. Crear uno que se va a ejecutar nuestro 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) Compilar y establecer los permisos adecuados, incluyendo el bit suid (diciendo que se debe ejecutar con privilegios de root):

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

    php_root va a ejecutar con permisos de root, y ejecuta los comandos especificados en php_shell.sh.


    Si usted no necesita la opción de cambiar fácilmente los comandos que serán ejecutados yo te recomiendo escribir los comandos directamente en wrapper.c en el paso 4. Entonces usted no necesita tener un binario de la ejecución de un script externo de la ejecución de los comandos en cuestión.

    En wrapper.c, uso system ("your shell command here"); para especificar los comandos que desea ejecutar.

    • Que el código de test.php. para ejecutar un script de bash. <?php exec(‘./php_root.sh’); ?> y aquí php_root.sh los códigos #!/bin/bash /sbin/service vsftpd stop y yo te chmod y chow comandos. y todavía no funciona. aquí está el error.registro de salida «rm: no se puede quitar `/var/lock/subsys/vsftpd»: Permiso denegado»
    • echa un vistazo a la edición de mi post.
    • y problema RESUELTO con refp respuestas. me olvidé de agregar /sbin ruta de acceso al comando en php_shell.sh.. gracias a todos mucho!!
    • Problema RESUELTO con «refp» como respuesta. gracias chicos!
    • yo flaged tu post «aceptar», supongo. gracias por su interés y ayuda. ¿cómo puedo dar rep para usted ?
    • He hecho todos los 4 pasos mencionados anteriormente y sigue recibiendo de error de permiso denegado en CentOS 6. Alguien ha caras de un mismo problema ?
    • Gracias por el código. Se está trabajando para mí.
    • hola.. estoy tratando de conseguir que esto funcione, pero no puedo 🙁 si puedo ejecutar desde ssh php test.php me puede llegar a poner a trabajar, pero si puedo ejecutar el archivo a través del navegador http://www.domain.com/teste.php no puedo ejecutar el comando!!:( alguna ayuda? gracias
    • ¿Php_root tienen que ser reemplazados con mi usuario de apache?
    • Estoy tratando de utilizar este método para ejecutar python script cgi, como la raíz de un http formulario (<form action=»/cgi-bin/php_root» method=»POST»>). Sin embargo, las variables POST siempre son Ninguno en la secuencia de comandos de Python. Estoy suponiendo que el POST las variables se pasan en el código de C y que debo extraer de ellos y enviarlos a la secuencia de comandos de python como argumentos? Podrías decirme cómo puedo hacer eso?
    • Es posible que una pregunta estúpida: ¿Pero por qué hemos de crear una secuencia de comandos cuando se puede hacer todo en el ejecutable escrito en C? Primero debemos crear una aplicación en C que decir que para ejecutar una secuencia de comandos de shell. ¿Por qué no hacer todo en C?
    • He tratado de llamar la secuencia de comandos con <?php $mensaje=shell_exec(‘./php_root 2>&1’); print_r($mensaje);?> pero volviendo error sh: ./php_root: Permiso denegado El archivo php es propia de apache:apache
    • esta línea no está trabajando para mí? setuid (0); he corrido el gcc y ahora es el error de Permiso denegado /var/www/html/x/php_shell.sh
    • Porque si usted necesita más de un par de líneas de código bash, o de la necesidad de bucles o condiciones, sólo puede hacerse a partir de un archivo de secuencia de comandos.
    • Oh, Está Bien. No sabía eso, gracias! 🙂
    • Esto es como la creación de un rootkit lugar en su propio sistema y esperando a alguien para ver el código fuente de php y activar los comandos para acceder directamente a su sistema linux.

  2. 23

    Yo no habría PHP ejecutar sudo comandos. Para mí eso suena como pidiendo problemas. En lugar de eso me gustaría crear dos sistemas separados.

    El primer sistema en PHP (el nivel web), se encargan de manejar las solicitudes del usuario. Cuando se realiza una petición que necesita un comando sudo me gustaría realizar esta solicitud en alguna cola. Esto podría ser una base de datos de algún tipo o middle-ware como ZeroMQ.

    El segundo sistema (el nivel de negocios) iba a leer o recibir los mensajes de la cola y tendría la capacidad de ejecutar comandos sudo, pero no será en el ámbito de su web-servidor de proceso.

    Sé que esto es un poco vago y puede ser resuelto de diferentes maneras con diferentes tecnologías, pero creo que esta es la mejor y más segura manera de ir.

  3. 8

    Permitir la www-data usuario a ejecutar para ejecutar programa1 y programa2 sin contraseña:

    sudo visudo

    Añadir el contenido del archivo sudoers:

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

    Guardar.

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

    • Yo prefiero esto a través de la compilación de un archivo ejecutable para hacer las cosas. Para asegurarse de que el mejor método sería SuExec si usted tiene el tiempo para configurarlo.
    • Cabe aclarar aquí que usted necesita para agregar sudo al principio de su comando cuando se utiliza este método.
  4. 3

    Solución utilizando un binario de contenedor (con el bit suid)
    Algunos de modificación de Filip Roséen – refp post.

    Para ejecutar cualquiera de los comandos de modificación de contenedor.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 y establecer los permisos adecuados;

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

    Ahora llamada desde PHP. Ejecutar cualquier comando.

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

    Recientemente he publicado un proyecto que permite a PHP para obtener e interactuar con un shell de Bash, es fácil dar una shell ha iniciado la sesión como root. A continuación, puede simplemente ejecutar el individuo comandos en bash, en lugar de agrupación, a continuación, en una secuencia de comandos. De esa manera usted también puede gestionar la devolución. Consíguelo aquí: https://github.com/merlinthemagic/MTS

    Después de la descarga, simplemente utilice el siguiente 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  ]
    • Un montón de errores tratando de ejecutar esto en mi centos 6.7 servidor. Corregido un par de ellos, a continuación, decidió renunciar.
    • Pásate a github y abrir un nuevo tema documentar el error que tienes.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea