문제 정보
- 여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.
- 플래그 형식은 DH{…} 입니다.
풀이
먼저 사이트에 접속해보면 이런 화면이 나온다.
vuln 페이지에 들어가보면 url에 써있는 <script>가 바로 화면에 나오는걸 알 수 있다.
문제에 보면 다음 코드가 있는데 이 코드는 param 값이 사용자의 입력으로 받기 때문에, 사용자가 삽입한 스크립트가 실행될 수 있다.
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param
memo 페이지에 들어가보면 hello가 나온다. 문제를 살펴보면 GET 요청으로 들어온 memo매개변수 값을 가져와서 text변수에 할당한다. memo_text 변수에 text값에 \n을 더하고 memo 변수에 memo_text값을 대입해서 memo.html을 반환한다. 따라서 memo 경로로 요청을 보내면 지금까지 입력한 메모 내용이 화면에 출력된다. memo_text는 /flag 쪽에서 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)
flag 페이지는 이렇게 생겼다. 악성 스크립트를 URL에 삽입하고 서버의 응답에 담겨오므로 Reflected XSS이라고 볼 수 있겠다.
/flag경로로 GET 요청이 들어오면, flag.html을 반환하고 POST 요청이 들어오면, "param" 변수를 추출한 후, check_xss()함수를 사용하여 해당 변수의 XSS 취약점 여부를 검사한다. 검사 결과에 따라, "good" 또는 "wrong??"라는 알림창이 뜬다.
@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 = ""
check_xss 함수를 보면 param 과 cookie를 인자로 받는다. 여기서 param은 url에 의해 바뀌면서 read_url 함수를 사용해 리턴된다.
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)
따라서 param에 쿠키가 있으면 name은 flag이고 value는 FLAG.strip()이라고 하는 flag값을 memo창에서 볼 수 있다.
해당 페이지에서 쿠키를 볼 수 있는 명령어는 document.cookie; 이고 위치를 이동하는 명령어는 location.href 이므로 <script>location.href="/memo?memo=" + document.cookie;</script> 를 param 값에 넣어주면 memo창에서 flag값을 찾을 수 있다.
'Web Hacking > Dreamhack 풀이' 카테고리의 다른 글
simple_sqli_chatgpt (0) | 2023.06.25 |
---|---|
CSRF-2 (0) | 2023.06.25 |
CSRF-1 (0) | 2023.06.25 |
XSS-2 (0) | 2023.06.25 |
Session-basic (0) | 2023.06.25 |