CTF & Wargame(WEB)

level 3 XS-Search

KWAKBUMJUN 2025. 4. 22. 02:32

엔드 포인트 분석

notes = {
    (FLAG, True), 
    ("Hello World", False), 
    ("DreamHack", False), 
    ("carpe diem, quam minimum credula postero", False)
}

/search

@app.route('/search')
def search():
    query = request.args.get('query', None)
    if query == None:
        return render_template("search.html", query=None, result=None)
    for note, private in notes:
        if private == True and request.remote_addr != "127.0.0.1" and request.headers.get("HOST") != "127.0.0.1:8000":
            # private이 true고, 접속 ip가 127.0.0.1이 아니고 HOST가 127.0.0.1:8000가 아니라면 비공개
            continue # 넘어감
        if query != "" and query in note:
            return render_template("search.html", query=query, result=note)
    return render_template("search.html", query=query, result=None)

사용자에게 query를 입력 받는다. 만약 아무것도 입력하지 않았다면 search.html 반환

만약 private의 값이 true이고, 사용자의 ip가 localhost가 아니고, headers가 localhost가 아니라면 비공개로 판단하여 넘어감.

만약 query가 빈 문자열이 아니고 query의 값이 note와 같다면 해당 데이터 출력

 

search.html

{% extends "base.html" %}
{% block title %}Search{% endblock %}

{% block head %}
  {{ super() }}
{% endblock %}

{% block content %}
<h2>Search</h2><br/>
{% if result %}
  <h3>Searching "{{ query }}" found</h3>
  <iframe srcdoc="<pre>{{ result }}</pre>"></iframe>
{% elif query %}
  <h3> Searching "{{ query }}" not found</h3>
{% else %}
  <form method="GET" class="form-inline">
      <div class="form-group">
          <label class="sr-only" for="query">/</label>
          <div class="input-group">
              <div class="input-group-addon">Query: </div>
              <input type="text" class="form-control" id="query" name="query" placeholder="DreamHack">
          </div>
      </div>
      <button type="submit" class="btn btn-primary">Search</button>
  </form>
{% endif %}
{% endblock %}

result가 존재한다면 iframe을 생성한다. 그리고 검색 결과가 존재하지 않으면 query가 존재하지 않는다고 출력한다.

여기서 검색 결과가 존재할때와 존재하지 않을때의 frame 개수 차이가 존재함을 알 수 있다.(XS-Search)

 

/submit

@app.route("/submit", methods=["GET", "POST"])
def submit():
    if request.method == "GET":
        return render_template("submit.html")
    elif request.method == "POST":
        url = request.form.get("url", "")
        if not urlparse(url).scheme.startswith("http"):
            # http로 시작하지 않으면 wrong url
            return '<script>alert("wrong url");history.go(-1);</script>'
        if not read_url(url):
            # read_url의 반환값이 거짓이면 wrong?? 출력
            return '<script>alert("wrong??");history.go(-1);</script>'

        return '<script>alert("good");history.go(-1);</script>'

url이라는 파라미터를 입력 받고 해당 파라미터의 값이 http로 시작하지 않으면 wrong url, read_url의 반환이 거짓이면 wrong??

 

취약점 분석

/search 페이지를 이용하여 frame 개수를 파악하여 flag를 획득할수 있다.

 

귀찮음

'CTF & Wargame(WEB)' 카테고리의 다른 글

level 2 blind sql injection advanced  (0) 2025.04.22
level 2 DOM XSS  (0) 2025.04.22
level 2 Relative Path Overwrite Advanced  (0) 2025.04.21
RPO(Relative Path Overwrite) 이해하기  (0) 2025.04.21
level 2 Relative Path Overwrite  (1) 2025.04.18