[DreamHack] [web] [Level 1] csrf-1 풀이

2025. 1. 27. 06:22Information Security 정보보안/DreamHack

728x90

배울내용 

dreamhack,

web hacking,

개발자도구,

dreamhack 풀이,

dreamhack csrf 문제,

dreamhack web 풀이 ,

cross-site request forgery,

Cross-Site Scripting, 

 

 

문제

 





 

들어가면 위와 같이 나와있고 이전문제랑 유사한 형태이다

그러면 한번 코드를 바로 보도록 하자

 

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)


@app.route("/")
def index():
    return render_template("index.html")


@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


@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_csrf(param):
            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", None)
    if text:
        memo_text += text
    return render_template("memo.html", memo=memo_text)


@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 이다 

그리고 flag 라는 곳을 가게 되면 아래와 같이 입력을할수있는데 여기서 어떠한 값을 넣으면 성공플레그를 뛰울수있을것 같다 . 

 

 

 

한가지 주의해야할점은 아래처럼 parameter 를 받을때 소문자로 바꾸고 frame, script, on 을 필터링 한다. 

이를 우회하면 성공플레그를 뛰울수있다. 

 


@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

 

다행히 태그는 필터링에 들어가있지 않으니 "<" , " >" 이를 이용해 script 를 만들면 될것같다.

주로 아래와 같이 img 태그를 많이 쓰고  위에 서 본 admin_notice_flag 에서  userid 가 admin 이면 성공플레그를 뛰울수있는걸로 봐서 flag 에 아래의 값만 넣어주면 된다 

 

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

 

 

 

 

 

그러면 good 이라고 뜨고 memo 에서 flag 를 확인할수있다

 

 

 

728x90