[LEVEL 1] csrf-1

yamewrong·2023년 1월 6일
0

웹해킹

목록 보기
10/12
post-thumbnail

Description

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.
CSRF 취약점을 이용해 플래그를 획득하세요.

문제 분석

check_csrf

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)

위 코드는 파라미터에 저장된 값을 합친 url 값과, cookie값을 반환해 준다.

vuln

def vuln():
    param = request.args.get("param", "").lower()
    xss_filter = ["frame", "script", "on"]
    for _ in xss_filter:
        param = param.replace(_, "*")
    return param

위 코드는 frame, script, on 키워드를 필터링 하고 있고, 대문자또한 필터링 하고 있음을 볼 수 있다.
또한 _ 문자도 필터링 하고 있다.
필터링 된 결과를 param에 저장해서 반환한다.

flag

def flag():
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param", "")
        if not check_csrf(param):
            return '<script>alert("wrong??");history.go(-1);</script>'
        return '<script>alert("good");history.go(-1);</script>'

위 코드는 check_csrf에 파라미터를 보내는 코드

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)

위 코드는 메모. 생략.

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"

위 코드는 127.0.0.1에서 보내고, userid가 admin이면flag를 메모에 저장해주겠다는 코드인듯

풀이

admin_notice_flag로 위 조건을 만족시켜서 접근할 수 있을까?
우선 flag 페이지를 보면
파라미터자체가 127.0.0.1에서 보내진다
1번조건 ok
이제 userid=admin을 맞춰주면된다
앞서 필터링에 꺽쇠는 없기 때문에 img 태그를 사용해서 주면 해당 페이지로 유도 가능

<img src="/admin/notice_flag?userid=admin">

0개의 댓글