index 페이지에서 session_id를 통해 session_storage에 저장된 username을 가져오고, 만약 username이 admin이면 FLAG를 출력해준다.
/login
GET으로 login 페이지를 가져옴
POST 요청에서 username, password 파라미터에서 값을 가져오고, users에 있는 사용자이면 사용자 입력의 password가 원래 pw와 동일한지 확인함. 이때 users에는 guest, admin만 있으며, admin의 pw는 FLAG 값임.
패스워드 인증이 되면, 랜덤값으로 session_id를 생성하고 session_id에 username을 저장해서 session_storage에 넣는다.
set_cookie로 sessionid는 session_id로 지정한다.
/flag
@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", "")
session_id = os.urandom(16).hex()
session_storage[session_id] = 'admin'
if not check_csrf(param, {"name":"sessionid", "value": session_id}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
POST 요청을 주는 경우, 이때 admin에 대한 session_id가 만들어진다.
이 부분에서 생성되는 admin에 대한 session_id를 탈취할 ㅜㅅ 있을듯..
def check_csrf(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)
일단 /vuln 요청이 가므로, vuln을 보면, xss_filter로 frame, script, on을 필터랑하고 해당되면 *으로 치환한 다음 처리한다.
다른 키워드는 사용할 수 있다.
일단 admin의 session_id를 가져와야 change_password를 하고, login해서 index에서 FLAG를 출력할 수 있다.
/change_password
pw 파라미터를 가져와서, 브라우저에 sessionid가 설정되어 있으면 이 값을 통해 session_storage에서 username을 가져오고, 해당 username에 대한 pw를 변경한다.
/flag에서 session_id가 admin의 것이므로, 여기서 /change_password로 admin의 pw를 변경한다.
<iframe> 태그는 막혔지만 <img>는 사용할 수 있으므로 <img> 태그를 사용한다.
<img src="/change_password?pw=asdf">


/flag 요청 시 xss_filter에서 필터링된 html 태그를 사용하지 않았기 때문에 정상적으로 요청이 수행된다.


이후 변경된 admin:asdf로 로그인 요청 시 session_id로 username인 admin을 저장하고, cookie에 해당 sessionid가 설정된 것을 확인할 수 있다.

| [Dreamhack] Hangul - Revenge (WEB) (0) | 2025.04.29 |
|---|---|
| [Dreamhack] web-ssrf (WEB) (0) | 2025.04.17 |
| Dreamhack CTF Season 7 Round #7 (🚩Div1) Pybrid write up (0) | 2025.04.07 |
| [Dreamhack] baby-ai (0) | 2025.04.01 |
| [Dreamhack] phpreg (WEB) (0) | 2025.03.28 |