https://dreamhack.io/wargame/challenges/26/
초기화면이다. xss와 별 다를 것이 없는 것 같다.
/vuln페이지다. <script> 태그가 필터링 되고있는 것 같다.
/memo 페이지다. memo의 값을 출력한다.
/admin/notice_flag페이지다. 접근이 거부됐다. 특별한 조건이 필요한 것 같다.
익스플로잇 코드를 삽입할 수 있을 것 같은 페이지다. 이제 코드를 살펴보자.
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
아까 살펴 보았듯이 필터링이 적용돼 있다. xss공격은 어려울 것으로 보인다.
@app.route("/admin/notice_flag")
def admin_notice_flag():
global memo_text
if request.remote_addr != "127.0.0.1":
return "Access Denied"
if request.args.get("userid", "") != "admin":
return "Access Denied 2"
memo_text += f"[Notice] flag is {FLAG}\n"
return "Ok"
접근이 거부됐다고 했던 /admin/notice_flag 페이지 코드다. 호스트 아이피가 아니라면 우리가 봤던 Access Denied를 리턴한다. 또한 userid 매개변수의 값도 admin이어야 한다고 한다. 그러면 글로벌 변수인 memo_text의 값에 flag를 적어준다.
memo_text는 또 어디에 있을까?
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", None)
if text:
memo_text += text
return render_template("memo.html", memo=memo_text)
/memo 페이지다. 글로벌 변수 memo_text가 보인다. 앞서 살펴봤던 memo_text의 값을 리턴해주는 것을 볼 수 있다.
정리해보자면, /admin/notice_flag에 접속하면 /memo페이지에 플래그를 적어준다. 하지만
/admin/notice_flag에 접속하려면 아이피가 호스트여야 하며, userid의 값이 admin이어야 한다.
/vuln 페이지를 이용하여 서버가 직접 /admin/notice_flag 방문하게 하면 되겠다. 그렇다면 /vuln페이지를 어떻게 방문시킬까? 스크립트 태그와 onerror와 같은 방법도 다 막혀있다.
필자는 '<>'가 살아있는 것을 이용하여 <img>태그의 src로 접근시켜 보겠다.
<img src="/admin/notice_flag?userid=admin">
익스플로잇 코드다. 이것을 /flag 페이지에 넣어서 실행시켜 보자.
짜잔
'웹 해킹 > 드림핵' 카테고리의 다른 글
[드림핵]simple_sqli 풀이 (0) | 2023.03.11 |
---|---|
[드림핵]csrf-2 풀이 (0) | 2023.03.11 |
[드림핵]xss-2 풀이 (0) | 2023.03.11 |
[드림핵] xss-1 풀이 (0) | 2023.03.10 |
[드림핵] cookie 풀이 (1) | 2023.03.10 |