Notice
Recent Posts
Recent Comments
Link
«   2025/12   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

HW_chick hacker

[WEB] Red This - BYUCTF 2025 본문

CTF

[WEB] Red This - BYUCTF 2025

{{HW}} 2025. 5. 27. 22:17

 

💉 Exploit

🛠️ Step 1. main.py 분석

 

main.py

### IMPORTS ###
import flask, redis, os


### INITIALIZATIONS ###
app = flask.Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(32).hex()
HOST = "redthis-redis"


### HELPER FUNCTIONS ###
def getData(key):
    db = redis.Redis(host=HOST, port=6379, decode_responses=True)
    value = db.get(key)
    return value

def getAdminOptions(username):
    adminOptions = []
    if username != None and username == "admin":
        db = redis.Redis(host=HOST, port=6379, decode_responses=True)
        adminOptions = db.json().get("admin_options", "$")[0]
    return adminOptions



### ROUTES ###
@app.route('/', methods=['GET'])
def root():
    username = flask.session.get('username')
    adminOptions = getAdminOptions(username)
    return flask.render_template('index.html', adminOptions=adminOptions)


# get quote 
@app.route('/get_quote', methods=['POST'])
def getQuote():
    username = flask.session.get('username')
    person = flask.request.form.get('famous_person')
    quote = [person, '']
    if "flag" in person and username != "admin":
        quote[1] = "Nope"
    else: 
        quote[1] = getData(person)
    adminOptions = getAdminOptions(username)
    return flask.render_template('index.html', adminOptions=adminOptions, quote=quote)


@app.route('/register', methods=['POST', 'GET'])
def register():
    # return register page 
    if flask.request.method == 'GET':
        error = flask.request.args.get('error')
        return flask.render_template('register.html', error=error)

    username = flask.request.form.get("username").lower()
    password = flask.request.form.get("password")

    ## error check
    if not username or not password:
        return flask.redirect('/register?error=Missing+fields')

    ## if username already exists return error
    isUser = getData(username)
    if isUser:
        return flask.redirect('/register?error=Username+already+taken')
    else:
        # insert new user and password
        db = redis.Redis(host=HOST, port=6379, decode_responses=True)
        # db.set(username, "User") # nah, we don't want to let you write to the db :)
        passwordKey = username + "_password"
        # db.set(passwordKey, password) # nah, we don't want to let you write to the db :)
        flask.session['username'] = username
        return flask.redirect('/')

@app.route('/login', methods=['POST', 'GET'])
def login():
     # return register page 
    if flask.request.method == 'GET':
        error = flask.request.args.get('error')
        return flask.render_template('login.html', error=error)
    
    username = flask.request.form.get("username").lower()
    password = flask.request.form.get("password")

    ## error check
    if not username or not password:
        return flask.redirect('/login?error=Missing+fields')
    
    # check username and password
    dbUser = getData(username)
    dbPassword = getData(username + "_password")
    
    if dbUser == "User" and dbPassword == password:
        flask.session['username'] = username
        return flask.redirect('/')
    return flask.redirect('/login?error=Bad+login')


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=1337, debug=False, threaded=True)

 

- /register 경로에서 주석처리된 구문에 계정정보를 db에 저장하지 못하고 있음.

 

 

🛠️ Step 2. insert.redis 분석

set key value
set "FDR" "The only thing we have to fear is fear itself."
set "Shakespeare" "To be, or not to be, that is the question."
set "Mandela" "The greatest glory in living lies not in never falling, but in rising every time we fall."
set "Theodore Roosevelt" "Believe you can and you're halfway there."
set "Disney" "All our dreams can come true, if we have the courage to pursue them."

set "admin" "User"
set "admin_password" "prod_has_a_different_password"
set "fake_flag" "I told you"
set "flag_" "byuctf{test_flag}"
JSON.SET admin_options $ '["hints", "fake_flag", "flag_"]'

 

- /get_quote 경로 접근하여 파라미터 값에 대해 출력하는 내용이다.

- “admin_password”를 입력하면 "prod_has_a_different_password" 값에서 flag값이 노출 될 것이다.

 

🛠️ Step 3. flag

- admin, I_HopeYou4re8admin_iLoveTechn070g_9283910 로그인하면 admin 계정에 접근이 가능함.