Befehl asuführen
Janine
- perl
Hi
ich möchte mit ein perl-Programm, welches über ein Apache mit suid ausgeführt wird, die Shell eines Benutzers ändern
my $test =
/usr/bin/chsh -s /bin/false benutzer;``
Die Shell des Benutzers wird jedoch nicht geändert.
Wenn ich folgenden Befehl ausführe:
my $test =
touch /tmp/test;;
wird die Datei angelegt
-rw-r--r-- 1 root www 0 24. Mai 02:03 test
Was mache ich falsch?
Janine
Hi
ich möchte mit ein perl-Programm, welches über ein Apache mit suid ausgeführt wird, die Shell eines Benutzers ändern
my $test =
/usr/bin/chsh -s /bin/false benutzer;``
Die Shell des Benutzers wird jedoch nicht geändert.Wenn ich folgenden Befehl ausführe:
my $test =
touch /tmp/test;;
wird die Datei angelegt
-rw-r--r-- 1 root www 0 24. Mai 02:03 testWas mache ich falsch?
Mit google habe ich jetzt herausgefunden, dass sich das Problem mit ein C Wrapper lösen läßt
mein C Wrapper sieht wie folgt aus:
#define REAL_PATH "/absoluter/pfad/zur/perl/datei.pl"
int main(int argc, char **argv)
{
setegid(0);
seteuid(0);
setgid(0);
setuid(0);
execv(REAL_PATH, argv);
return 0;
}
Sollte/Muss ich noch auf etwas anderes achten?
Die Shell wird jetzt per chsh geändert.
Beispiel der perl-Datei
#!/usr/bin/perl -w
use warnings;
use strict;
my $test = `/usr/bin/chsh -s /bin/false benutzer;`;
print $test;
exit(0);
Janine
my $test =
/usr/bin/chsh -s /bin/false benutzer;``
Die Shell des Benutzers wird jedoch nicht geändert.
Was mache ich falsch?
Wenn Suid gesetzt ist, wird Perl mit Taint-Checks ausgeführt - ein Merkmal von Perl, welches sicheres Programmieren unterstützt. Das Programm muss speziell dafür geschrieben/angepasst werden. Leider hast du überhaupt keine Fehlerbehandlung eingebaut und auch die Meldungen im Webserverlog ignoriert, das hätte schon deutliche Hinweise auf die Problematik gegeben.
Sollte/Muss ich noch auf etwas anderes achten?
Suid ist ein Hack. Der C-Wrapper verschiebt das Problem auf eine höhere Abstraktionsebene, ist also ein Hack auf einem Hack. Es entspricht nicht der guten Praxis, die Komplexität zu erhöhen, wenn es um sicherheitsrelevante Programme geht.
Die korrekte Lösung benutzt Entkopplung vom Web, somit wird auch das Thema Suid/Taint am Webserver hinfällig. Statt einem Programm, das alles macht, spalte die Funktionalität auf, so dass jede Komponente genau eine Sache macht:
1. Ein Webprogramm, das Anfragen zur Shell-Änderung entgegennimmt und in eine Warteschlange einreiht.
2. Die Jobwarteschlange. Dies kann auch einfacherweise eine dumme Datei sein, wenn du korrektes Locking beherrschst.
3. Ein Systemprogramm, das aus der Warteschlange liest und die Shell-Änderung ausführt. Dieses kann dann mit normalen Root-Rechten laufen, wahlweise als Daemon oder regelmäßig (Cron).
Garniere mit Fehlerbehandlung und Logging. Es gibt für alles Module.
Hi
my $test =
/usr/bin/chsh -s /bin/false benutzer;``
Die Shell des Benutzers wird jedoch nicht geändert.
Was mache ich falsch?
Wenn Suid gesetzt ist, wird Perl mit Taint-Checks ausgeführt - ein Merkmal von Perl, welches sicheres Programmieren unterstützt. Das Programm muss speziell dafür geschrieben/angepasst werden. Leider hast du überhaupt keine Fehlerbehandlung eingebaut und auch die Meldungen im Webserverlog ignoriert, das hätte schon deutliche Hinweise auf die Problematik gegeben.
wie kann ich bei befehl
ein Fehler abfangen? Im error Log des Apachen hatte ich auch nichts aussergewöhnliches entdeckt.
Als ich das jedoch von der Konsole aus probiert hatte, wurde mir ein Fehler ausgegeben. Icdh sei nicht b erechtigt die Shell zu ändern.
Sollte/Muss ich noch auf etwas anderes achten?
Suid ist ein Hack. Der C-Wrapper verschiebt das Problem auf eine höhere Abstraktionsebene, ist also ein Hack auf einem Hack. Es entspricht nicht der guten Praxis, die Komplexität zu erhöhen, wenn es um sicherheitsrelevante Programme geht.Die korrekte Lösung benutzt Entkopplung vom Web, somit wird auch das Thema Suid/Taint am Webserver hinfällig. Statt einem Programm, das alles macht, spalte die Funktionalität auf, so dass jede Komponente genau eine Sache macht:
- Ein Webprogramm, das Anfragen zur Shell-Änderung entgegennimmt und in eine Warteschlange einreiht.
- Die Jobwarteschlange. Dies kann auch einfacherweise eine dumme Datei sein, wenn du korrektes Locking beherrschst.
- Ein Systemprogramm, das aus der Warteschlange liest und die Shell-Änderung ausführt. Dieses kann dann mit normalen Root-Rechten laufen, wahlweise als Daemon oder regelmäßig (Cron).
welches von den etlichen job+queue meinst Du genau. Wiue das genau ablaufen soll, habe ich leider nicht ganz verstanden.
Garniere mit Fehlerbehandlung und Logging. Es gibt für alles Module.
wie sollte man logging mit einer Logklasse über mehrere Klassen realisieren?
Muss/Sollte man immer das Object übergeben?
Janine
wie kann ich bei
befehl
ein Fehler abfangen?
Da chsh Meldungen nach STDERR schreibt, hilft dir `` gar nicht. Mache es am besten so:
use autodie qw(:all);
use Try::Tiny;
use Capture::Tiny qw(capture_merged);
my $output = capture_merged {
try {
system '/usr/bin/chsh', '-s /bin/false', $benutzer;
} catch {
warn $_; # z.B. "/usr/bin/chsh" unexpectedly returned exit value 1 at...
};
};
$output # z.B. chsh: Unbekannter Benutzer "foo".
welches von den etlichen job+queue meinst Du genau.
Nimm doch Qudo, das ist prima für kleine Zwecke.
Wiue das genau ablaufen soll, habe ich leider nicht ganz verstanden.
Die Synopsen sind ergiebig, das muss ich hier nicht nachprogrammieren. Das Schema für die Datenbank befindet sich im Verzeichnis doc der Distribution. Im Fehlerfalle machst du dann eben keine Warnung wie im Beispiel oben, sondern belässt den Job in der Warteschlange und schickst eine Benachrichtigung an den Systemadministrator, damit er die Ursache beheben kann.
wie sollte man logging mit einer Logklasse über mehrere Klassen realisieren?
Muss/Sollte man immer das Object übergeben?
Das ist eine schlechte Idee. Die Klasse sollte die Methoden bereits einkomponiert haben. Ganz leicht geht das mit dem standardmäßigen Importmechanismus, oder als Mixin (hier: Moose-Rolle).