
xss 문제를 풀어봄
여기서 selenium을 첨봤는데
-> 사람이 브라우저에서 하는 행동을 코드로 자동화해주는 도구
-> 웹크롤링, 웹테스트, 반복업무 자동화, 워게임의 victim봇으로 자주 사용됨
이런거라고 한다
위 문제는 reflected xss의 성격(?)을 보이는 xss 문제 같다는 생각을 했다
아래에서 코드랑 동작원리를 분석해볼것이지만,
일단 결론적으로 봤을 때 파라미터값에 들어간 값이 결국 서버에서 어떤 처리가 되지 않고, 그대로 응답으로 와서 브라우저에서 실행되면서 발생하는 xss취약점이기에 reflected xss라고 생각했다
문제 코드
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import urllib
import os
app = Flask(__name__)
app.secret_key = os.urandom(32)
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"})
driver = None
try:
service = Service(executable_path="/usr/local/bin/chromedriver")
options = webdriver.ChromeOptions()
options.binary_location = "/usr/bin/google-chrome"
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:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
# return str(e)
return False
finally:
if driver is not None:
driver.quit()
return True
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)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param")
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
memo_text = ""
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", "")
memo_text += text + "\n"
return render_template("memo.html", memo=memo_text)
app.run(host="0.0.0.0", port=8000)
read_url(), vuln(), check_xss(), flag(), memo() 이렇게 5개의 주요 함수들을 볼 수 있는데
먼저,
read_url()을 보면
def read_url(url, cookie={"name": "name", "value": "value"}):
...
driver.add_cookie(cookie)
driver.get(url)
url, cookie 값을 받고, cookie를 get, url을 get해서 접속(?)하는 걸 볼 수 있다,, 그럼 이 cookie랑 url를 추적해보면
check_css() 함수에서
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)
url을 생성하고 있는데, /vuln ~~ 이렇게 보인다
/vuln 을 보면
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param
param 값을 그대로 반환하는 걸 볼 수 있고
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param")
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
flag()를 보면,
post 요청일 때, param 값과 쿠키의 값을 flag로 check_xss을 실행하는 걸 볼 수 있다!
그리고 check_xss는 read_url로 반환하는 걸 볼 수 있다
그럼 만약

이렇게 flag 페이지에서 param값을 입력해서 요청하면 쿠키값은 flag로 넘어갈것이고,, 그 쿠키값을 이제 내가 보도록 만들어줘야할 거 같은데,, 내가 flag값을 보기위해 활용할 페이지가 /memo 인듯,,
memo_text = ""
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", "")
memo_text += text + "\n"
return render_template("memo.html", memo=memo_text)
이렇게 코드를 보면,
text에 "memo" 라는 파라미터값을 가져오는 걸 볼 수 있고, 또 memo_text는 누적되는 걸 볼 수 있음.
그럼 /memo 페이지로 리다이렉트 되면 저렇게 자동으로 텍스트가 기록되는 것이니까,
/flag에 <script>location.href = "/memo?memo"+document.cookie</script>
이렇게 작성해주면,

flag를 확인 가능하다..
음,, 뭔가 하나하나 분석한 걸 쓰다 보니까 복잡해보이는 감이 있는데,
차근차근 다시 적어보면,,
1. 사용자가 /flag 페이지에 XSS payload를 제출
2. /flag 에서 check_xss()를 호출
이때 flag 값이 쿠키 형태로 함께 전달된다.
3. check_xss()는 /vuln?param=payload 형태의 URL을 만듦
4. read_url()에서 Selenium 브라우저를 실행한다.
5. Selenium 브라우저에 flag 쿠키가 저장된다.
driver.add_cookie(cookie)
6. Selenium 브라우저가 /vuln?param=payload에 접속한다.
driver.get(url)
7. /vuln 페이지는 param 값을 그대로 반환한다.
8. 브라우저가 <script>location.href = "/memo?memo"+document.cookie</script>를 JavaScript로 실행한다.
9. document.cookie로 flag 쿠키를 읽는다.
10. location.href를 통해 /memo?memo=flag값 으로 이동한다.
11. /memo 페이지가 flag 값을 memo_text에 저장한다.
12. 사용자가 /memo에 접속해 flag를 확인한다.
이렇게 진행됐고,
핵심 취약점을 뽑자면
/vuln 에서 사용자의 입력값을 검증없이 그대로 반환해주는 부분이라고 생각한다 (reflected xss)
끝!
'워게임 > web2' 카테고리의 다른 글
| csrf-2 (0) | 2026.06.05 |
|---|---|
| csrf-1 (0) | 2026.06.04 |
| xss-2 (0) | 2026.06.02 |
| session-basic (dream hack) (0) | 2026.05.15 |
| 아주 쉬운 cookie 문제 (0) | 2026.05.14 |