Ergebnis 1 bis 9 von 9

Thema: Kontrolle auf Injection

  1. #1
    TP-Veteran
    Registriert seit
    Apr 2004
    Ort
    NRW
    Beiträge
    1.045

    Kontrolle auf Injection

    Hallo Forumfreunde,

    habe mich ein wenig mit der Injection beschäftigt. Habe ein Formular erstellt und würde es gerne wissen ob das beschäftigen mit Injection geholfen hat oder immer noch der Code gefährdet ist. Hier mein Code dazu:

    PHP-Code:
    <link rel="stylesheet" type="text/css" href="/templates/big-garath/css/Verein.css"/>
    <?php
    $ordner 
    $_SERVER['DOCUMENT_ROOT'];
    require_once(
    $ordner '/Con/verb.inc.php');
    require_once(
    $ordner '/Con/probe.php');
    defined('_JEXEC') or die('Rufen Sie die Seite auf: => http://' $_SERVER['HTTP_HOST'] . '/index.php');
    ?>

    <?php
    $jetzt 
    "location: http://" $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $ausw "http://" $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . "?" $_SERVER['QUERY_STRING'];

    mysql_select_db($database_probe$probe);
    $query_anwender "SELECT benutzername, angemeldet, passwort, cookie_hash FROM `geeheim`
    WHERE `angemeldet`  ='1'"
    ;
    $anwender mysql_query($query_anwender$probe) or die(mysql_error());
    $mitgl mysql_fetch_assoc($anwender);
    $anzgl mysql_num_rows($anwender);
        

    if (isset(
    $_GET["mit"]) && is_numeric($_GET["mit"]))
    {
        
    // bei aufruf mit GET["mit"] dann hatte ich mich schon angemeldet
        // Hier das Array POST wiederherstellen
        
    $_POST['login']         = Anmelden;
        
    $anzgl                    $anzgl;    
        
    $_POST['benutzer']         = $_mitgl['benutzername'];
        
    $_POST['anzahl']         = $anzgl;
    }
    //hier wird die Tabelle auf null gestellt wenn erstes mal aufgerufen wird
    if (( ! isset( $_POST['login'])) )
    {
        
    // "first" alle Benutzer auf nicht angemeldet stellen
        
    mysql_select_db($database_probe$probe);
        
    $sql "UPDATE geeheim SET angemeldet = (NULL) WHERE angemeldet = 1";
        
    $anwender mysql_query ($sql$probe) or die(mysql_error());

    else
    {

        
    $ben $_POST['benutzer'];
        
    // "Angemeldet" ist Bentzer angemeldet dann wird auf 1 gestellt;
        
    mysql_select_db($database_probe$probe);
        
    $sql "UPDATE geeheim SET angemeldet = 1 WHERE benutzername ='" $ben "'";
        
    $anwender mysql_query ($sql$probe) or die(mysql_error());
    }

    // Hier die Datenbank aufrufen für die Zugangskontrolle
    mysql_select_db($database_probe$probe);
    $query_anwender "SELECT benutzername, angemeldet, passwort, cookie_hash FROM `geeheim`
        WHERE `angemeldet`  ='1'"
    ;
    $anwender mysql_query($query_anwender$probe) or die(mysql_error());
    $mitgl mysql_fetch_assoc($anwender);
    $anzgl mysql_num_rows($anwender);


    // Wenn Benutzer nicht angemeldet dann Formular einblenden
    if ( ! $anzgl == )
    {
    ?>
        <h2>Hier nur f&uuml;r autorisierte anwenderer!</h2>
        <p><form id="loginform" method="post" action="<?php echo $selber?>" name="loginform" >
            <label for="benutzer">Benutzer: </label><input type="text" name="benutzer" id="benutzer" value="" /><br /><br />
            <label for="passwort">Passwort: </label><input type="password" name="passwort" id="passwort" value="" /><br /><br />
            <input name="anzahl" type="hidden" value="1" />
            <input type="submit" name="login" id="login" value="Anmelden" />
        </form></p>
        <?php
    }
        
    if ( (! 
    $_POST['benutzer'] == $mitgl['benutzername']) && ( ! md5($_POST['passwort']) ==  $mitgl['passwort']))  
    {
        
    header ($jetzt);
        die;        
    }

    // Formular noch nicht ausgefüllt
    if ( ! $anzgl == 0  )
    {
        
    // Hier wenn angemeldet geht es weiter
        
    if (isset($_GET['mit']) && is_numeric($_GET['mit']) )
        {
            
    $ausw substr $ausw0, -);
        }
        
    // Text für die Links 
        
    $links = array("Neues anwender eintragen","&Uuml;bernahme""&Auml;ndern""L&ouml;schen""Listen");
        
    // die Datei für Include
        
    $links_F = array("Mitgl_neu","Mitgl_uebern""Mitgl_aend""Mitgl_del""Mitgl_sonst");
        
        
    // activen Link auswählen __ Anzahl der Einträge
        
    $anz count ($links) ; 
        
    // Anzahl der Einträge im Array
        
        
    $cln     "n" // nicht activer Link
        
    $cln_p     "n_active"// activer Link
        
    $x         0;

        if ( ! isset(
    $_POST['do_print']))
        {
            echo 
    "</style>";
            echo 
    '<ul class="u_vnavi" >';
            
            
    // Navigation für anwenderer anhand des Arrays
            
    for ( $x 0$x $anz$x++ )
            {
                if ( 
    $_GET['mit'] == $x+1
                {
                    
    $art $cln_p// active
                
    } else {
                    
    $art $cln// nicht active
                
    }
                echo 
    '<li class="vnavi"><a href="';
                echo 
    $ausw '&mit='  . ($x+1) . '"';
                echo 
    ' class="';
                echo 
    $art '">';
                echo 
    $links[$x]  . '</a>' '</li>' "\n";
            
            }
            echo 
    "</ul>";
        }
        
        if (isset(
    $_GET['mit']) & is_numeric$_GET['mit']))
        {
            
    $file_in $links_F[$_GET['mit']-1]. ".php";
            
            
            
    // je nach Wahl eines Menues Aufruf
            
    require_once( $file_in);
        }
    }
    ?>
    Vielen Dank im voraus. Ist noch Nachbesserung nötig?
    _____________________
    gruss
    reinhold

    _____________________
    meine Site:
    http://www.rkami.de



  2. #2
    TP-Moderator Avatar von maxi89
    Registriert seit
    Nov 2004
    Ort
    Mulpe an der Tunke
    Beiträge
    2.584
    Ich würde sagen: Nein, hat sich nicht genug gelohnt
    Ich habe im ganzen Code keine Stelle finden können, in der Benutzereingaben gefilert werden, bevor sie in SQL-Queries verwendet werden.
    Beispiel gefällig?

    Kopiere doch mal Folgendes in das Feld "benutzer" hinein:
    Code:
    benutzername'; UPDATE geheim SET passwort = 'geheim
    In das Passwortfeld trägst du irgendwas ein.
    Der Login wird fehlschlagen. Aber jetzt melde dich mal mit einem wirklich existierenden Benutzer an und verwende dabei das Passwort "geheim"
    Wenn es nicht funktioniert, hat dich vermutlich "Magic Quotes" von PHP gerettet - aber vernünftige Eingabenfilterung ist das immer noch nicht...

    Sieh dir das hier mal an: http://de.php.net/manual/de/function...ape-string.php
    Wenn du alle Benutzereingaben dadurch filtern lässt, würde diese SQL-Injection sofort an Wirkung verlieren, weil das Apostroph und noch ein paar andere "böse" Zeichen escaped, also unschädlich gemacht werden.

    Btw:
    $anzgl != 0 ist die Kurzform für ! $anzgl == 0

  3. #3
    TP-Veteran
    Registriert seit
    Apr 2004
    Ort
    NRW
    Beiträge
    1.045
    Hallo maxi89,

    habe mal das eingegeben....
    Ergebnis:
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE geheim SET passwort = 'geheim'' at line 1
    Im Code habe ich eine Weiche eingebaut
    ist der Name in der DB dann setze ein angemeldet.
    in $ben wird der Benutzer eingetragen
    PHP-Code:
    $ben $_POST['benutzer'];
    // "Angemeldet" ist Bentzer angemeldet dann wird auf 1 gestellt;
    mysql_select_db($database_probe$probe);
    $sql "UPDATE geeheim SET angemeldet = 1 WHERE benutzername ='" $ben "'";
    $anwender mysql_query ($sql$probe) or die(mysql_error()); 
    Es wird doch nur dann als angemeldet eingetragen wenn der Name mit der Anmeldung gleich ist. Wie kann ich das anders filtern?
    _____________________
    gruss
    reinhold

    _____________________
    meine Site:
    http://www.rkami.de



  4. #4
    TP-Moderator Avatar von maxi89
    Registriert seit
    Nov 2004
    Ort
    Mulpe an der Tunke
    Beiträge
    2.584
    Dann scheinen dich die magic_quotes gerettet zu haben - schade, wäre eindrucksvoll gewesen

    Mit mysql_real_escape_string fährt man am sichersten. Da ist eigentlich ein schönes Beispiel auf der PHP-Seite, auf deinen Code angewandt würde das so aussehen:

    PHP-Code:
    $ben $_POST['benutzer'];
    // "Angemeldet" ist Bentzer angemeldet dann wird auf 1 gestellt;
    mysql_select_db($database_probe$probe);
    $sql sprintf("UPDATE geeheim SET angemeldet = 1 WHERE benutzername = '%s' ",  mysql_real_escape_string($ben) );
    $anwender mysql_query ($sql$probe) or die(mysql_error()); 
    sprintf() ist... naja, wie soll man das erklären... Es nimmt einen String und ersetzt bestimmte Platzhalter darin.
    In dem Fall ist %s der Platzhalter für den Benutzernamen (%s ist genormt!).
    Als Parameter wird sprintf() dann immer mitgegeben, durch was der Platzhalter ersetzt werden soll - hier durch das was in das Feld "benutzer" eingegeben wurde, jedoch vorher durch mysql_real_escape_string() gefiltert wurde.

  5. #5
    TP-Veteran
    Registriert seit
    Apr 2004
    Ort
    NRW
    Beiträge
    1.045
    Hallo maxi89,

    sprintf () kenne ich.
    _____________________
    gruss
    reinhold

    _____________________
    meine Site:
    http://www.rkami.de



  6. #6
    TP-Veteran
    Registriert seit
    Apr 2004
    Ort
    NRW
    Beiträge
    1.045
    Ich würde fragen: "und warum nicht?". Bitte ein Beispiel. Wenn man noch nicht so bewandert ist mit der Injection, dann sieht man den Fehler nicht.
    _____________________
    gruss
    reinhold

    _____________________
    meine Site:
    http://www.rkami.de



  7. #7
    TP-Veteran
    Registriert seit
    May 2006
    Beiträge
    1.572
    Was hast Du denn über Injections gelesen? Ging es da überhaupt um SQL-Injections? Bsp.:

    PHP-Code:
    $ben $_POST['benutzer'];
    //...
    $sql "UPDATE geeheim SET angemeldet = 1 WHERE benutzername ='" $ben "'"
    maxi hat ziemlich deutlich gezeigt, was hier passieren kann. Wenn hier jemand statt einem Benutzernamen einen passenden SQL-Ausdruck benutzt und Du keine magic_quotes aktiviert hast, kann derjenige Deine Datenbank manipulieren, weil Du eben _keine_ Filterung durchführst.

    Richtiger wäre:
    [PHP]
    PHP-Code:
    $ben mysql_real_escape_string($_POST['benutzer']); 
    Noch richtiger wäre es, PDO o. ä. zu benutzen.
    ...Meine Meinung

  8. #8
    TP-Veteran
    Registriert seit
    Apr 2004
    Ort
    NRW
    Beiträge
    1.045
    Hallo marc22,

    danke für den Hinweis. PDO ist was "Feines". Ist aber, meine ich, eine Übungssache.
    Nun zu meinem Code. Der Benutzername wird nicht in eine Datenbank übernommen. Der ist ja schon in der DB. Bei der Anmeldung wird nur verglichen = ist der Benutzer schon in der DB vorhanden und ist das Passwort gleich mit dem Benutzer in der DB überein dann melde den Benutzer zur Freigabe. Passt es nicht, rufe das Formular wieder auf. Damit kann der Anmelde-Name nicht für SQL-Statement genutzt werden. So ist das doch richtig gedacht oder ist doch eine Injection möglich?
    _____________________
    gruss
    reinhold

    _____________________
    meine Site:
    http://www.rkami.de



  9. #9
    TP-Veteran
    Registriert seit
    Jan 2008
    Ort
    Hessen
    Beiträge
    1.033
    Zitat Zitat von kami Beitrag anzeigen
    Hallo marc22,
    Damit kann der Anmelde-Name nicht für SQL-Statement genutzt werden. So ist das doch richtig gedacht oder ist doch eine Injection möglich?
    Natürlich ist sie möglich. Denn egal was auch immer der Benutzer in das Feld "Benutzer" eingibt, es landet ungefiltert und ungeprüft in einem SQL-Statement übernimmst. Mit der Eingabe von bestimmten Sonderzeichen (z.Bsp Url-encoded) an passender Stelle könnte man in Deinem vorgegebenen Code einen Kommentar /* einleiten und somit Dein SQL-Statement verändern. Entsprechend dann den Kommentar beenden und "Drop Database; reinschreiben. Oder den SQL Befehl erweiteren mit Eingabe von "Hans OR 1 = 1", es gibt einige Möglichkeiten.

    Wenn es auf Deiner Testumgebung nicht funktioniert (wie z.Bsp. das Beispiel von maxi89), dann liegt dies an der vorhandenen PHP und MySQL-Konfiguration. Auf einem anderen Server kann das ganz vollkommen anders aussehen.

    Selbst wenn der Versuch die SQL Abfrage zu einer Fehlermeldung führt (die hast Du ja schon erwähnt) liefert diese Fehlermeldung dem potentiellen Angreifer weitere Informationen. (Datenbank-Tabellennamen, etc.)
    Auch die Ausgabe der Fehlermeldung an den Client muss unterbunden werden.


    Deshalb sind immer alle Eingaben vor der Verwendung in SQL-Statements prüfen und zu filtern.

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. FYI: Email Injection
    Von fettmme im Forum Traum-Dynamik
    Antworten: 89
    Letzter Beitrag: 03.04.2009, 16:00
  2. [Coding] exec_INSERTquery + SQL Injection
    Von alexf812 im Forum TYPO3
    Antworten: 6
    Letzter Beitrag: 07.07.2008, 19:53
  3. MySQL Injection
    Von webdepp im Forum Traum-Dynamik
    Antworten: 3
    Letzter Beitrag: 09.11.2007, 16:44
  4. Antworten: 4
    Letzter Beitrag: 17.02.2006, 11:51
  5. Sicherheitslücke via mysql-injection?
    Von Boris im Forum Traum-Dynamik
    Antworten: 1
    Letzter Beitrag: 10.02.2005, 12:53

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

     

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51