Dreamhack - xss-1 (XSS공격)

·2025년 7월 3일

Dreamhack-Writeups

목록 보기
11/52

xss-1

문제 링크

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

문제 설명

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.
XSS 취약점을 이용해 flag.txt, FLAG 변수에 있는 플래그를 획득하는 문제입니다.

풀이과정

  1. 생성된 서버에서 flag에 들어가면 입력 할 수 있는 url 칸이 나옵니다. 이 입력 칸을 이용해 xss 공격을 하는 문제입니다.

  2. memo 칸에 접속해 보았습니다. 그랬더니 hello 란 글이 작성된걸 확인할 수 있습니다.

  3. 이때 url을 확인해보면 http://host3.dreamhack.games:10952/memo?memo=hello 입니다.
    memo?memo=뒤에 들어간 값이 화면에 표시되는지 확인하기 위해 URL을 memo?memo=hi 로 변경해보았고, hi가 memo에 작성됨을 알 수 있습니다.
    이를 통해 플래그 값을 memo간에 작성되도록 유도하는 문제임을 유추해볼 수 있었습니다.

  4. 제시된 app.py 를 확인해 봅니다.

    def read_url(url, cookie={"name": "name", "value": "value"}):
     cookie.update({"domain": "127.0.0.1"})
     ...
     driver = webdriver.Chrome(service=service, options=options)
     ...
     driver.get("http://127.0.0.1:8000/")
     driver.add_cookie(cookie)
     driver.get(url)

    이 함수는

    • http://127.0.0.1:8000/ 에 먼저 접속합니다.
    • read_url 에 전달된 쿠키를 driver.add_cookie(cookie)를 통해 봇 브라우저에 심습니다.
    • 이후 제공한 URL로 접속합니다. (driver.get(url))
  5. read_url이 어떻게 호출되었는지 확인하기 위해 check_xss 함수를 확인합니다.

    def check_xss(param, cookie={"name": "name", "value": "value"}):
     url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
     return read_url(url, cookie)

    check_xss 에 전달되는 쿠키값이 read_url 에 그대로 전달되어 브라우저에 심어지는 구조임을 확인할 수 있습니다.

  6. check_xss 가 어떻게 호출되는지 확인하기 위해 /flag 라우트의 POST 부분을 확인합니다.

    @app.route("/flag", methods=["GET", "POST"])
     def flag():
         if request.method == "POST":
             param = request.form.get("param")
             if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
                 ...
             else:
                 ...

    여기에서 직접 {"name": "flag", "value": FLAG.strip()} 를 넘기고 있습니다.
    이를 통해 FLAG 값이 flag라는 이름의 쿠키로 봇 브라우저에 심어지는 구조임을 확인할 수 있습니다.

  7. flag에 접속해 <script>location.href="http://127.0.0.1:8000/memo?memo=hello"+document.cookie;</script> 로 XSS 공격을 시도합니다.

    • location.href="http://127.0.0.1:8000/memo?memo=hello 는 플래그 값을 쿠키로 이미 심어둔 봇 브라우저가 해당 URL로 이동해 플래그가 메모에 남도록 유도하는 역할을 합니다.
    • document.cookie 는 현재 브라우저의 쿠키 문자열을 반환합니다. 앞서 분석한 구조에 따라 flag=DH{...} 형태의 플래그가 쿠키에 담겨 있음을 알 수 있습니다.
    • +는 자바스크립트에서 문자열 이어붙이기 연산자이며, 최종적으로 http://127.0.0.1:8000/memo?memo=helloflag=DH{...}로 이동하게 만들어, 플래그가 메모 페이지에 기록되도록 합니다.
  8. memo 에 접속해보니 성공적으로 플래그 값을 획득할 수 있었습니다.


배운점

  • XSS의 실전 활용을 배워볼 수 있었습니다.
  • +는 자바스크립트에서 문자열 이어붙이기 연산자임을 알게 되었습니다.
  • document.cookie를 통해 브라우저의 쿠키를 탈취할 수 있다는 것을 확인할 수 있었습니다.
  • XSS를 활용하여 봇이 실행되게 만들고, 쿠키값을 읽어내도록 유도하는 법을 배웠습니다.

Summary (English)

  • The provided web service has multiple features and a bot that checks submitted URLs.
  • The goal is to use XSS to get the flag stored in flag.txt and the FLAG variable.
  • Accessed /flag and found a URL input field for the XSS payload.
  • Checked /memo and confirmed that values after ?memo= are displayed on the page.
  • Reviewed the provided app.py:
    • The bot uses Selenium to open http://127.0.0.1:8000/, sets a flag cookie with the flag value, and then visits the submitted URL.
  • Since the bot stores the flag as a cookie, used document.cookie in the payload to extract it.
  • Submitted:
      <script>location.href="http://127.0.0.1:8000/memo?memo=hello"+document.cookie;</script>

to send the flag to the memo page.

  • Accessed /memo and successfully retrieved the flag.
profile
CTF 풀이 및 실습 중심 학습을 기록합니다.

0개의 댓글