csrf-2 풀이
2021. 8. 17. 19:34ㆍDreamhack 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로 로그인을 해보겠습니다.
Hello guest, you are not an admin이라는 문구가 뜹니다.
FLAG를 얻기 위해서는 admin 계정으로 로그인을 해야하는데, 코드를 보면 비밀번호가 FLAG로 되어있습니다.
패스워드를 알아낼 방법이 딱히 떠오르지 않으니 변조를 하는 식으로 접근을 해보겠습니다.
우선 img 태그를 활용해야 할 것 같습니다.
그리고 메인 페이지에는 나와있지 않지만, 코드를 보면 /change_password라는 페이지가 있습니다.
이 페이지에 접근해서 pw를 아무 값으로 변조하고, 변조한 비밀번호와 id인 admin으로 로그인을 해보겠습니다.
<img src=/change_password?pw=asdf>
어떻게 풀지만 생각한다면 생각보다 간단하네요...?
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 |