alligator: CGI / Perl auf Sicherheit testen

Hallo zusammen,

ich würd gerne mal mein Perl-Script, die Usereingaben empfangen auf
Sicherheit testen. Deshalb wollt ich mal schauen, was man alles machen kann, wenn der Tainted-Modus nicht aktivert ist.
Dazu folgendes lokales Mini-Testproggi:
use CGI;
$q = new CGI;
$value = $q->param('foo');
print $value;
$value;
Leider hab ich bis jetzt nicht hinbekommen (trotz dieses offenen Scriptes) z.B. nen Systembefehl oder sowas abzusetzen. Ich teste auf Windows...
Z.B.
perl tt.pl foo=exec('dir');
oder
perl tt.pl foo=sleep+10;
hat alles nix gebracht, außer die Ausgaben: exec('dir') und sleep 10.

Hat jemand ne Idee, was ich da falsch mache ?

cya
alligator

  1. Hi,

    hat alles nix gebracht, außer die Ausgaben: exec('dir') und sleep 10.
    Hat jemand ne Idee, was ich da falsch mache ?

    Ja. exec() ist nicht dafür da, einen systembefehl auszuführen, sondern um ein anderes Programm auszuführen, das ist ein Unterschied. Was du suchst sind backticks `` oder besser system().

    Was fürs nächste auch mal wichtig wäre, dass du Fehlermeldungen hier auch postest. Da hilft es dir die Warunungen einzustellen (entweder mittels -w in der Shebang oder use warnings).

    Grüße Andres Freund.

    --
    ss:) zu:) ls:} fo:) de:] va:) ch:| n4:& rl:° br:^ js:( ie:% fl:( mo:|
  2. Halihallo alligator

    ich würd gerne mal mein Perl-Script, die Usereingaben empfangen auf
    Sicherheit testen. Deshalb wollt ich mal schauen, was man alles machen kann, wenn der Tainted-Modus nicht aktivert ist.

    Der Tainted-Modus erhöht die Sicherheit nicht, das kannst _alleine_ du. Er stellt nur
    sicher, dass du die externen Daten (eg. über Kommandozeile) über eine RegExp prüfst,
    ob der Inhalt "sinnvoll" ist (bezgl. der Sicherheit z.B. keine Pipes enthält, womit
    man sonst was tun könnte).

    Leider hab ich bis jetzt nicht hinbekommen (trotz dieses offenen Scriptes) z.B. nen Systembefehl oder sowas abzusetzen. Ich teste auf Windows...

    Ich halte das Script für sehr geschlossen. Wo siehst du hier eine Sicherheitslücke?
    Das Script ist IMHO so gut wie gar nicht angreifbar. Wenn es jemand angreifen wollte,
    müsste er den Quelltext haben und sehr, sehr viel über die internas von Perl verstehen,
    sodass er unfug treiben könnte (Bufferoverflows z.B.).

    perl tt.pl foo=exec('dir');
    oder
    perl tt.pl foo=sleep+10;
    hat alles nix gebracht, außer die Ausgaben: exec('dir') und sleep 10.

    Was hättest du erwartet? - Das das ausgeführt wird? - Ja, dann wäre es in der Tat eine
    Sicherheitslücke, aber dem ist nicht so. Solange du nicht im Programm selber mit
    Backticks, exec, system, open oder eval arbeitest und die Eingaben nicht überprüfst, dürfte es keine "wirklich grundlegenden" Sicherheitsprobleme geben.

    Hat jemand ne Idee, was ich da falsch mache ?

    _Wie_ erwartest du es denn richtig?

    Viele Grüsse

    Philipp

    --
    RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
    Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
    1. perl tt.pl foo=exec('dir');
      oder
      perl tt.pl foo=sleep+10;
      hat alles nix gebracht, außer die Ausgaben: exec('dir') und sleep 10.

      Was hättest du erwartet? - Das das ausgeführt wird? - Ja, dann wäre es in der Tat eine
      Sicherheitslücke, aber dem ist nicht so. Solange du nicht im Programm selber mit
      Backticks, exec, system, open oder eval arbeitest und die Eingaben nicht überprüfst, dürfte es keine "wirklich grundlegenden" Sicherheitsprobleme geben.

      Aha sehr gut zu wissen. D.h. also wenn ich die übergebenen Variablen nicht in einem Systemufruf benutze kann fast nix schief gehen...

      Hier aber mal ein Beispiel, welches afaik unfug macht, oder.
      Empfangen vom Formular
      $mailto = hans@hacker </etc/passwd

      Aufruf im Script
      open (MAIL, "| /usr/bin/sendmail $mailto");
      print MAIL "Blub";
      close MAIL

      Hat jemand ne Idee, was ich da falsch mache ?
      _Wie_ erwartest du es denn richtig?

      Naja richtig in meinem Fall wäre eine Sicherheitslücke gewesen, da ich ja diese testen wollte.

      So long ...
      alligator

      1. Halihallo alligator

        Aha sehr gut zu wissen. D.h. also wenn ich die übergebenen Variablen nicht in einem Systemufruf benutze kann fast nix schief gehen...

        Genau.

        Hier aber mal ein Beispiel, welches afaik unfug macht, oder.
        Empfangen vom Formular
        $mailto = hans@hacker </etc/passwd

        Genau.

        Aufruf im Script
        open (MAIL, "| /usr/bin/sendmail $mailto");
        print MAIL "Blub";
        close MAIL

        Und genau deshalb _sollte_ man sendmail mit -t Schalter
        verwenden! - Dann wird die Adresse über den Mailcontent übergeben und
        sendmail öffnet eben keine pipes sondern beschwert höchstens über
        eine nicht konforme E-Mail Adresse. Ansonsten empfehle ich ohnehin
        Net::SMTP.

        Viele Grüsse

        Philipp

        1. Halihallo nochmals

          Aha sehr gut zu wissen. D.h. also wenn ich die übergebenen Variablen nicht in einem Systemufruf benutze kann fast nix schief gehen...
          Genau.

          uha, das war böse! - "Genau" bezog sich auf den besprochenen Kontext. Ich hoffe, dass es
          jedem klar ist, dass diese Möglichkeit nur _eine unter vielen_ ist, um unfug zu
          betreiben, sprich Sicherheitslücken auszunutzen.
          Ich will jetzt nicht die ganze "Sicherheitsthematik" nochmals durchkauen, ich wollte
          nur darauf hinweisen, dass dies nur eine Möglichkeit unter sehr, sehr vielen ist.

          Leider gibt's auch keine "Perfekte Checkliste/Handbuch der Sicherheit", denn die
          Sicherheit hängt massgebend vom Programmierer und dem Server-Admin ab, beides sind
          Menschen, beide machen Fehler und es ist nicht möglich alle möglichen Fehler abzudecken
          bzw. in einer Checkliste zu vereinen.

          Viele Grüsse

          Philipp

          --
          RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
          Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
  3. use CGI;
    $q = new CGI;
    $value = $q->param('foo');
    print $value;
    $value;

    ^^^^^^^

    hättest du Warnungen aktiviert, bekämst du hier eine Warnung "Useless use of a variable in void context ...". Bitte, beginne deine Programme mit "use strict; use warnings;"!

    Perl ist nämlich keine Shell. Das einfach platzieren von $value bewirkt nicht, dass deren Inhalt ausgeführt wird. In dem Fall hättest du eine Sicherheitslücke.

    Folgendes Programm ist sicherheitskritisch und darf NIEMALS auf einem Webserver liegen!

    #!/usr/bin/perl
    use strict;
    use warnings;
    use CGI qw/:standard/;

    exec param('exec');
    __END__

    Aufruf:
    $ perl tt.pl "exec=echo Sicherheitslücke"

    Lies also perldoc warnings, perldoc strict, und unbedingt perldoc perlsec!

    1. use CGI;
      $q = new CGI;
      $value = $q->param('foo');
      print $value;
      $value;
        ^^^^^^^

      hättest du Warnungen aktiviert, bekämst du hier eine Warnung "Useless use of a variable in void context ...". Bitte, beginne deine Programme mit "use strict; use warnings;"!

      »»
      Hi,

      mach ich ja normalerweise auch, aber bei so nem Minitestprogramm hab
      ichs jetzt halt nicht gemacht. Die Faulheit läßt grüßen :o)

      Perl ist nämlich keine Shell. Das einfach platzieren von $value bewirkt nicht, dass deren Inhalt ausgeführt wird. In dem Fall hättest du eine Sicherheitslücke.

      Folgendes Programm ist sicherheitskritisch und darf NIEMALS auf einem Webserver liegen!

      #!/usr/bin/perl
      use strict;
      use warnings;
      use CGI qw/:standard/;

      exec param('exec');
      __END__

      Aufruf:
      $ perl tt.pl "exec=echo Sicherheitslücke"

      Aha, ok sowas hab ich gesucht. Danke.

      cya
      alligator