it-swarm.com.de

Führen Sie root-Befehle über PHP aus

Ich habe einen CentOS 5.7 Linux Server und benutze php5.3.x.

Auf einem pfSense-System können Sie Dienste, für die Root-Berechtigungen erforderlich sind, über eine PHP-Webseite neu starten.

Ich versuche etwas ähnliches zu tun, ich habe einige PHP-Code geschrieben, um Shell-Befehle auszuführen. So starten Sie beispielsweise den sshd-Dienst neu:

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

und ich habe versucht, diesen Befehl über die exec-Funktion auszuführen, aber er benötigt root-Berechtigung, aber wir haben eine Apache-Benutzerberechtigung.

Ich habe einige Lösungen gefunden:

  1. "Apache mit root-Benutzer ausführen" ist wirklich unsicher. Ich möchte das nicht machen.
  2. "Apache ALL = NOPASSWD:/sbin/service to/etc/sudoers" Ich habe es versucht, aber immer noch ein Problem.

Irgendwelche anderen Lösungen? Danke für die Antworten.


jetzt .. es ist interessant. Ich habe versucht, @ refp post und es funktionierte mein lokaler Ubuntu-Server. Aber als ich das gleiche auf meinem cenOS vps Server ausprobiert habe. Es funktioniert nicht. Und das ist Apaches Fehlerprotokoll "rm:/var/lock/subsys/vsftpd kann nicht entfernt werden: Berechtigung verweigert".

50
Mehmet INCE

Lies diesen ganzen Beitrag, bevor du ihn ausprobierst, es gibt eine Auswahl.


Lösung mit einem binären Wrapper (mit suid bit)

1) Erstellen Sie ein Skript (vorzugsweise .sh), Das das enthält, was Sie als root ausführen möchten.

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

2) Diese Datei sollte Eigentum von root sein und da sie später mit root-Berechtigungen ausgeführt wird, stellen Sie sicher, dass nur root die Berechtigung hat, in die Datei zu schreiben.

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

) Um das Skript als root auszuführen, egal welcher Benutzer es ausführt, benötigen wir einen Binär-Wrapper. Erstellen Sie eine, die unseren php_Shell.sh Ausführt.

# 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) Kompiliere und setze die richtigen Berechtigungen, einschließlich des suid-Bits (das besagt, dass es mit root-Rechten ausgeführt werden soll):

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

php_root Wird jetzt mit Root-Berechtigungen ausgeführt und führt die in php_Shell.sh Angegebenen Befehle aus.


Wenn Sie die Option zum einfachen Ändern der auszuführenden Befehle nicht benötigen, empfehlen wir Ihnen, die Befehle direkt in wrapper.c Unter Schritt 4 zu schreiben. Dann brauchen Sie keine Binärdatei, die ein externes Skript ausführt, das die fraglichen Befehle ausführt.

Geben Sie in wrapper.c Mit system ("your Shell command here"); an, welche Befehle Sie ausführen möchten.

88

Ich hätte keine PHP) Sudo-Befehle ausführen müssen. Für mich klingt das so, als würde ich nach Problemen fragen. Stattdessen würde ich zwei separate Systeme erstellen.

Das erste System in PHP (der Webschicht)) würde Benutzeranforderungen verarbeiten. Wenn eine Anforderung gestellt wird, die einen Sudo-Befehl benötigt, würde ich diese Anforderung in eine Warteschlange stellen. Dies könnte eine Datenbank sein von irgendeiner Art oder Middleware wie ZeroMQ.

Das zweite System (die Business-Schicht) würde Nachrichten aus dieser Warteschlange lesen oder empfangen und könnte Sudo-Befehle ausführen, ist jedoch nicht Teil Ihres Webserver-Prozesses.

Ich weiß, dass dies etwas vage ist und mit verschiedenen Technologien auf unterschiedliche Weise gelöst werden kann, aber ich denke, dies ist der beste und sicherste Weg.

22
Luke

Warten Sie, bis der Benutzer www-data ausgeführt wird, um program1 und program2 ohne Kennwort auszuführen:

Sudo visudo

Zum Inhalt der sudoers-Datei hinzufügen:

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

Speichern.

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

8
harrrrrrry

Lösung mit einem binären Wrapper (mit suid bit) Einige Modifikationen von Filip Roséen - refp post.

Um einen Befehl auszuführen, muss wrapper.c geändert werden

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

Kompilieren Sie und legen Sie die richtigen Berechtigungen fest;

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

Rufen Sie nun von PHP aus auf. Führen Sie einen beliebigen Befehl aus.

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

Ich habe kürzlich ein Projekt veröffentlicht, das es PHP ermöglicht, eine echte Bash-Shell zu erhalten und mit ihr zu interagieren. Es gibt Ihnen leicht eine Shell, die als root angemeldet ist. Dann können Sie einfach die einzelnen Bash-Befehle ausführen anstatt Bündeln Sie dann in einem Skript. Auf diese Weise können Sie auch die Rückgabe erledigen. Laden Sie es hier herunter: https://github.com/merlinthemagic/MTS

Nach dem Download verwenden Sie einfach den folgenden 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  ]
2
MerlinTheMagic