Web Hacking/DreamHack

[DreamHack] Dream Gallery 풀이

프레딕 2024. 4. 16. 01:13
728x90

from flask import Flask, request, render_template, url_for, redirect
from urllib.request import urlopen
import base64, os

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

mini_database = []


@app.route('/')
def index():
    return redirect(url_for('view'))


@app.route('/request')
def url_request():
    url = request.args.get('url', '').lower()
    title = request.args.get('title', '')
    if url == '' or url.startswith("file://") or "flag" in url or title == '':
        return render_template('request.html')

    try:
        data = urlopen(url).read()
        mini_database.append({title: base64.b64encode(data).decode('utf-8')})
        return redirect(url_for('view'))
    except:
        return render_template("request.html")


@app.route('/view')
def view():
    return render_template('view.html', img_list=mini_database)


@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        f = request.files['file']
        title = request.form.get('title', '')
        if not f or title == '':
            return render_template('upload.html')

        en_data = base64.b64encode(f.read()).decode('utf-8')
        mini_database.append({title: en_data})
        return redirect(url_for('view'))
    else:
        return render_template('upload.html')


if __name__ == "__main__":
    img_list = [
        {'초록색 선글라스': "static/assetA#03.jpg"}, 
        {'분홍색 선글라스': "static/assetB#03.jpg"},
        {'보라색 선글라스': "static/assetC#03.jpg"}, 
        {'파란색 선글라스': "static/assetD#03.jpg"}
    ]
    for img in img_list:
        for k, v in img.items():
            data = open(v, 'rb').read()
            mini_database.append({k: base64.b64encode(data).decode('utf-8')})
    
    app.run(host="0.0.0.0", port=80, debug=False)

 

file:// 과 flag.txt를 우회하는 문제이다.

 

file://는 구글링해보니 여러가지 방법이 있었다.

1. 공백 + file://

앞에 공백을 넣어서 단순히 bypass 할수 있지만 내 컴퓨터 환경에서 %09를 넣어보고 공백 띄어보고 했는데도 작동하지 않았다.

 

2. < file:// >

양쪽에 괄호를 씌어쓰면 unwrap함수에서 자연스럽게 벗겨진다는데 역시 안됐다.

 

3. file:/

슬래쉬하나 쓰는건데 이건 작동해서 이걸 썼다.

 

그다음은 flag.txt 우회이다.

 

1. 16진수변환

이거는 그냥 안되는거 같다 http:// 이런거 뒤에 써야할거같다.

 

2. url인코딩

url 인코딩 작동은 했다. fl%61g.txt 이렇게 사용하면 된다. 

하지만 다른 사람들은 뭐 이중 인코딩해서 풀었다는데 이중인코딩하면 오히려 안돼서 안했다.

 

 

결론은 file:/fl%61g.txt

이렇게 작성하면 flag획득이 가능하다.

728x90
반응형