이발 Write-up

Ccr3t·2025년 10월 27일
0

Wargame

목록 보기
53/55

[Solved in under 14 minutes]

다들 행복하신가요.
요즘 바쁜 나날을 보내고 있습니다.
우리 모두 행복합시다.

가보자

로그인 하라고 하는데 SQLI도 연계해서 해야하는건가? 삽질 하다가 그냥 문제 파일을 보기로 한다.

from flask import Flask, request, redirect, url_for, send_file, render_template_string
import os, base64, secrets
app = Flask(__name__)
app.secret_key = os.urandom(24)
UF = './uploads'
os.makedirs(UF, exist_ok=True)
flag = open("../flag.txt").read().strip()
flag_name = secrets.token_hex(8) + '.txt'
with open(os.path.join(UF, flag_name), 'w') as f:
    f.write(base64.b64encode(flag.encode()).decode())
users = {"admin": "adminpass"}
sessions = {}
lp = """
<h2>Login</h2>
<form method="POST">
Username: <input name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="Login">
</form>
"""
up = """
<h2>Upload your profile image!</h2>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
"""
@app.route('/', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        u = request.form.get('username', '')
        p = request.form.get('password', '')
        if users.get(u) == p:
            token = secrets.token_hex(16)
            sessions[token] = u
            resp = redirect('/upload')
            resp.set_cookie('session', token)
            return resp
        else:
            return "Permission Deneid"
    return render_template_string(lp)
@app.route('/upload', methods=['GET', 'POST'])
def upload():
    session = request.cookies.get('session')
    if session not in sessions:
        return redirect('/')
    if request.method == 'POST':
        file = request.files['file']
        filename = file.filename
        if any(x in filename for x in ['.php', '.phtml', '.htaccess']):
            return "Permission Denied"
        filepath = os.path.join(UF, filename)
        file.save(filepath)
        with open(filepath, 'r') as f:
            code = f.read()
            try:
                result = eval(code)
            except Exception as e:
                result = f"Error: {e}"
            return f"{result}"
        return f"Uploaded {filename}"
    return render_template_string(up)
@app.route('/uploads/<filename>')
def get_file(filename):
    session = request.cookies.get('session')
    if session not in sessions or sessions[session] != 'admin':
        return "Forbidden"
    return send_file(os.path.join(UF, filename))
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

admin / adminpass 란다 진작에 볼걸.

로그인 하면 파일 업로드 하는 부분이 생기는데 파일 업로드 취약점인가?

해서 코드를 다시 보니
php, phtml, htaccess 는 막아뒀다.
저거를 우회하는 문제인가? 싶어서 또 우회 방법들을 해봤다.

안돼서 뭐지 하고 다시 코드를 제대로 읽는데 eval(code) 가 있는것이다.

아. Eval Injection을 노려야 하는거구나 싶어서 코드를 해석하면 필터링 되어 있는 확장자를 제외하고 올리면 그 코드를 eval() 함수로 읽는 형식이다.

그러니까 Python 에서 eval() 을 이용해서 파일을 읽도록 하자

open('flag.txt').read()

간단하게 열어서 읽도록 만들어주고

올리면~?

잘 뽑힌당

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 답 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

DH{c632b8109d5550f168bcc71ce1a0133854627119c6651fbf0994c9311f704d98}

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

요즘 모의침투 사업에 치여서 Wargame을 많이 못 푸는거 같지만 실무에서 실력이 굉장히 많이 늘고 있다는 것을 깨닫는다.

실력이 아주 좋은 동기(2년차 선배 but 같은 직급)가 있어서 버틸만하다.

여하튼!

DreamHack 이발 Write-up

이상 보고 끝!

profile
웹해킹을 잘 못 하지만 좋아 하려고 노력하는 한 젊은이.

0개의 댓글