csrf-2 풀이

2021. 8. 17. 19:34Dreamhack Wargame

728x90

문제 제목
문제 정보
메인 페이지

#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for
from selenium import webdriver
import urllib
import os

app = Flask(__name__)
app.secret_key = os.urandom(32)

try:
    FLAG = open("./flag.txt", "r").read()
except:
    FLAG = "[**FLAG**]"

users = {
    'guest': 'guest',
    'admin': FLAG
}

session_storage = {}

def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome("/chromedriver", options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get("http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(url)
    except Exception as e:
        driver.quit()
        print(str(e))
        # return str(e)
        return False
    driver.quit()
    return True


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():
    session_id = request.cookies.get('sessionid', None)
    try:
        username = session_storage[session_id]
    except KeyError:
        return render_template('index.html', text='please login')

    return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not an admin"}')


@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", "")
        session_id = os.urandom(16).hex()
        session_storage[session_id] = 'admin'
        if not check_csrf(param, {"name":"sessionid", "value": session_id}):
            return '<script>alert("wrong??");history.go(-1);</script>'

        return '<script>alert("good");history.go(-1);</script>'


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            pw = users[username]
        except:
            return '<script>alert("not found user");history.go(-1);</script>'
        if pw == password:
            resp = make_response(redirect(url_for('index')) )
            session_id = os.urandom(8).hex()
            session_storage[session_id] = username
            resp.set_cookie('sessionid', session_id)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'


@app.route("/change_password")
def change_password():
    pw = request.args.get("pw", "")
    session_id = request.cookies.get('sessionid', None)
    try:
        username = session_storage[session_id]
    except KeyError:
        return render_template('index.html', text='please login')

    users[username] = pw
    return 'Done'

app.run(host="0.0.0.0", port=8000)

 

코드가 너무 길어서 코드 블록으로 첨부했습니다.

(이번 문제는 코드 해석보다는 풀이 중점으로 작성했습니다.)

 

우선, 메인 페이지에 login이 보입니다.

코드를 보면 

users = {
    'guest': 'guest',
    'admin': FLAG
}

라는 부분이 있습니다.

우선 guest로 로그인을 해보겠습니다.

 

guest login

Hello guest, you are not an admin이라는 문구가 뜹니다.

FLAG를 얻기 위해서는 admin 계정으로 로그인을 해야하는데, 코드를 보면 비밀번호가 FLAG로 되어있습니다.

패스워드를 알아낼 방법이 딱히 떠오르지 않으니 변조를 하는 식으로 접근을 해보겠습니다.

 

우선 img 태그를 활용해야 할 것 같습니다.

그리고 메인 페이지에는 나와있지 않지만, 코드를 보면 /change_password라는 페이지가 있습니다.

이 페이지에 접근해서 pw를 아무 값으로 변조하고, 변조한 비밀번호와 id인 admin으로 로그인을 해보겠습니다.

 

<img src=/change_password?pw=asdf>

 

FLAG 획득 완료
문제 풀이 성공

어떻게 풀지만 생각한다면 생각보다 간단하네요...?

728x90

'Dreamhack Wargame' 카테고리의 다른 글

web-ssrf 풀이  (0) 2021.08.25
blind-command 풀이  (0) 2021.08.18
xss-2 풀이  (0) 2021.08.17
proxy-1 풀이  (0) 2021.08.11
basic_exploitation_003 풀이  (0) 2021.08.04