system () vs execve ()

8

Sowohl system() als auch execve() kann verwendet werden, um einen anderen Befehl innerhalb eines Programms auszuführen. Warum ist in Set-UID-Programmen system() gefährlich, während execve() sicher ist?

    
Jake 12.12.2014, 10:25
quelle

3 Antworten

12

System ruft die Shell auf (sh ), um den als Argument gesendeten Befehl auszuführen. Das Problem mit system , da das Shell-Verhalten vom Benutzer abhängt, der den Befehl ausführt. Ein kleines Beispiel:

Erstellen einer Datei test.c :

%Vor%

Dann:

%Vor%

Erstellen Sie ein Skript namens ls in Ihrem aktuellen Verzeichnis:

%Vor%

Jetzt:

%Vor%

Hoppla, Sie haben eine Shell mit root-Rechten.

execve ruft keine Shell auf. Es führt das als erstes Argument übergebene Programm aus. Das Programm muss eine binäre ausführbare Datei oder ein Skript-Start mit shebang Zeile sein.

    
cuonglm 12.12.2014 11:04
quelle
9

system() und execve() funktionieren auf verschiedene Arten. system() ruft immer die Shell auf und diese Shell führt den Befehl als separaten Prozess aus (deshalb können Sie bei Verwendung von system() Platzhalter und andere Shell-Funktionen in der Befehlszeile verwenden).

execve() (und die anderen Funktionen in der exec() -Familie) ersetzt den aktuellen Prozess durch den direkt erzeugten Prozess (die Funktion execve() kehrt nicht zurück, außer im Falle eines Fehlers). Tatsächlich sollte system() implementation eine Folge von fork() , execve() und wait() aufrufen, um ihre Funktion auszuführen.

Natürlich sind beide gefährlich, abhängig davon, was ausgeführt wird, wenn der Prozess Root-Rechte hat. system() bringt jedoch einige zusätzliche Gefahren mit sich, da die zusätzliche "Ebenen" -Schicht die Raumsicherheitsverletzungen öffnet, da sie eine Root-Shell aufruft, wie im Fall Ihrer Frage (dh der Prozess hat das suid-Bit) / p>     

Marcelo 12.12.2014 10:40
quelle
0

Abgesehen von den genannten Sicherheitsproblemen mit system() erbt der erzeugte Prozess die Umgebung des Hauptprogramms. Dies kann sehr problematisch sein, wenn suid verwendet wird, beispielsweise wenn der aufrufende Prozess LD_LIBRARY_PATH -environment-Variable festlegt.

Mit der exec() -Familie kann das aufrufende Programm die Umgebung auf genau das einstellen, was für das aufgerufene Programm benötigt wird (und sicher ist), bevor exec() aufgerufen wird.

Und natürlich kann die von system() aufgerufene Shell selbst Sicherheitsprobleme haben.

    
TBrandt 12.12.2014 12:42
quelle