Hallo, On Wed, 10 Apr 2002 at 22:35 (+0200), Ratti wrote:
Am Mit, 2002-04-10 um 19.11 schrieb Bernhard Walle:
Folgendes "sollte" funktionieren:
=============== test_sec.cgi ==========================
Jepp. Mal abgesehen davon, daß ich figlet nicht installiert habe, tut es seinen Job im wesentlichen.
Ist doch ein cooles Programm ;) In der Praxis taucht sendmail häufig auf, und zwar irgendwie so: open (SENDMAIL, "| /usr/lib/sendmail $empfaenger") || die "Could ..."; Und da $empfaenger irgendwie vom Benutzer eingegeben wurde, haben wir hier schon eine fette Sicherheitslücke. In diesem Fall würde ich die Möglichkeit von Sendmail nutzen, den Empfänger aus der Nachricht zu entnehmen und damit zu verzichten, von der Kommandozeile zu lesen (Option: -t). Ab Perl 5.6.1 sollte auch folgendes gehen: open (SENDMAIL, "-|", /usr/lib/sendmail", $empfaenger) || die "Could ..."; Nicht getestet, da ich Perl 5.6.0 installiert habe, stand aber im Kamel-Buch so ähnlich drin.
(Interessanterweise geht perl -c test_sec.cgi nicht, weil er die gleichen Parameter wie im !# haben möchte, was aber nicht machbar ist, denn ich will ja (c)hecken und nicht starten...)
Sicher geht das: $ perl -cwT test_sec.cgi test_sec.cgi syntax OK Keine Angst, bevor ich was an die Liste poste lasse ich das schon durchlaufen :) Ich dachte auch einige Zeit, dass es nicht geht aber irgendwann habe ich es dann einfach mal probiert ...
Im wesentlichen liegt das Problem ja wohl hier:
my $ausgabe = qx(/usr/bin/figlet $wort);
"Irgendwas", in Form von $wort, vom Surfer übermittelt, wird dem System zur Ausführung übergeben.
Richtig.
Prinzipiell besteht diese Gefahr doch immer, wenn man auf diese Weise programmiert - nur, daß die Konsequenzen bei suidperl natürlich ungleich gewichtiger wären.
Eben. Und der Taint-Modus verhindert sowas z. B. wirkungsvoll (mit dem "Vergiftungsprinzip"), man ihn nicht bewusst umgeht wie ich. Damit wollte ich _auch_ demonstrieren, dass nicht alles was mit -T läuft auch sicher ist! Man kann aber zumindest nichts _vergessen_. Wenn man nicht qx() sondern system() verwendet, sollte ab Perl 5.6.0 [1] grundsätzlich folgendes gehen: system ("command", "arg1", "arg2"); Damit führt Perl das Kommando direkt aus und startet keine Shell. Somit gehen Spielchen wie && oder ; nicht und außerdem läuft es auch einen Tick schneller, da keine Shell benötigt wird. Test: $ perl -e 'system("figlet Bernhard && ls");' ____ _ _ | __ ) ___ _ __ _ __ | |__ __ _ _ __ __| | | _ \ / _ \ '__| '_ \| '_ \ / _` | '__/ _` | | |_) | __/ | | | | | | | | (_| | | | (_| | |____/ \___|_| |_| |_|_| |_|\__,_|_| \__,_| Eigene Mail News backup bin binarys office52 public_html src $ perl -e 'system("figlet", "Bernhard && ls");' ____ _ _ ___ ___ _ | __ ) ___ _ __ _ __ | |__ __ _ _ __ __| | ( _ ) ( _ ) | |___ | _ \ / _ \ '__| '_ \| '_ \ / _` | '__/ _` | / _ \/\/ _ \/\ | / __| | |_) | __/ | | | | | | | | (_| | | | (_| | | (_> < (_> < | \__ \ |____/ \___|_| |_| |_|_| |_|\__,_|_| \__,_| \___/\/\___/\/ |_|___/ Wie man das jetzt bei qx(), d. h. `` hinbekommt, weiß ich nicht. Da in der Praxis qx() aber wohl eher selten in CGIs auftaucht, ist das irrelevant. Für system() empfehle ich auf jeden Fall o. g. Methode, wenn es aufgrund der Perl-Version machbar ist. Wenn es möglich ist, sollte man _immer_ darauf verzichten, User-Eingaben irgendwie mit system() ins Spiel zu bringen. Bei Sendmail bietet sich z. B. -t an.
Es geht also nicht um ein "ausbrechen" aus htdocs/public_html äquivalent zu Nimda, oder daß in irgend einer Weise Löcher im Webserver auftauchen, sondern relevant ist, daß irgendwann mal das cgi dem System "etwas" zur Ausführung übergibt (Was ja auch durchaus nicht abwegig ist).
Genau. Das ist z. B. eine Sicherheitslücke, die ich kenne. Natürlich kann man sie erst richtig ausnutzen, wenn man an den Quellcode kommt, aber Try&Error hilft manchmal auch. Gruß, Bernhard [1] Ja, bei system() ist es 5.6.0, bei open ist es 5.6.1, war kein Tippfehler! Quelle: Kamel-Buch[2] (deutsch auf S. 443) + eigene Erfahrungen. [2] Programmieren in Perl, O'Reilly-Verlag, Dt. Übersetzung der 3. Auflage bzw. die 3. Auflage auf anderer Seite. Siehe auch http://www.bwalle.de -> "Buchtipps". PS: Ja, die Antwort ist umfangreicher ausgefallen als nötig, ich weiß. Sollte auch keine "Belehrung" gegenüber Dir sein sondern einfach nochmal ein paar Tipps an den einen oder anderen, wie man sichere CGI-Skripten in Perl programmiert. Zuviel Sicherheit kann _nie_ schaden! -- Ich sag's ja, ...diese abolut warmduschende Meute von "Vollquotern" steigt. -- Clemens Wohld in suse-linux