
์๋
ํ์ญ๋๊น ์ฝ๋ฉ ํ์ธ์ ํ์
๋๋ค
์ด๋ฒ์๋ ๋๋ฆผ ๋ณ์ ๐ฑ์ ๊ดํด ํ์ด๋ณด๊ฒ ์ต๋๋ค.
https://dreamhack.io/wargame/challenges/2814
์ ํฌ ๋๋ฆผ ๋ณ์์ ํ์ ์ ๋ณด๋ฅผ ์์ ํ๊ฒ ๋ณดํธํ๊ณ ์์ต๋๋ค. ๐ฅ
...

import hashlib
import os
from flask import Flask, render_template, request, redirect, url_for, session, abort
app = Flask(__name__)
app.secret_key = os.urandom(24).hex()
health_records = {
1: {
"name": "๊น๊น๋ฐ",
"date": "2024-03-10",
"height": "175cm",
"weight": "70kg",
"blood_pressure": "120/80",
"diagnosis": "ํน์ด์ฌํญ ์์ (๊ฒ์ง์๋ฃ)",
"summary": "DH{This_is_fake_flag}", #โํ๋๊ทธ ์์น
"owner": "admin"
},
125: {
"name": "๊น๋๋ฆผ",
"date": "2024-03-25",
"height": "180cm",
"weight": "75kg",
"blood_pressure": "115/75",
"diagnosis": "๋นํ๋ฏผ D ๋ถ์กฑ ๊ถ๊ณ ",
"summary": "์ ๋ฐ์ ์ผ๋ก ์ํธํ๋ฉฐ ๊พธ์คํ ์ด๋์ ๊ถ์ฅํฉ๋๋ค.",
"owner": "guest"
}
}
def get_hash(uid):
return hashlib.md5(str(uid).encode()).hexdigest()
@app.route('/')
def index():
if 'user' in session:
return redirect(url_for('dashboard'))
return render_template('index.html')
@app.route('/auth/login', methods=['POST'])
def login():
if request.form.get('username') == 'guest' and request.form.get('password') == 'guest':
session['user'] = 'guest'
return redirect(url_for('dashboard'))
return "Login Failed", 401
@app.route('/auth/logout')
def logout():
session.pop('user', None)
return redirect(url_for('index'))
@app.route('/dashboard')
def dashboard():
if 'user' not in session:
return redirect(url_for('index'))
user_data = health_records[125]
return render_template('dashboard.html', user_hash=get_hash(125), name=user_data['name'])
@app.route('/report/view/<user_hash>')
def view_report(user_hash):
if 'user' not in session:
return redirect(url_for('index'))
for uid, data in health_records.items():
if get_hash(uid) == user_hash:
if data['owner'] != session['user']:
return "<h1>Access Denied</h1>", 403
return render_template('report.html', data=data, user_hash=user_hash)
return "Not Found", 404
@app.route('/report/download/<user_hash>')
def download_report(user_hash):
if 'user' not in session:
return redirect(url_for('index'))
for uid, data in health_records.items():
if get_hash(uid) == user_hash:
return render_template('print.html', data=data)
return "Not Found", 404
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)
์ผ๋จ guest/guest๋ฅผ ํตํด guest๋ก ๋ก๊ทธ์ธ ํด๋ด ์๋ค

์, ์ฝ๋๋ฅผ ์ดํด๋ด ์๋ค
์ฝ๋๋ฅผ ๋ณด์๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฌ์ค๋ฌ์ด ๋ถ๋ถ์ด ์กด์ฌํฉ๋๋ค
def get_hash(uid):
return hashlib.md5(str(uid).encode()).hexdigest()
...
@app.route('/report/view/<user_hash>')
def view_report(user_hash):
if 'user' not in session:
return redirect(url_for('index'))
for uid, data in health_records.items():
if get_hash(uid) == user_hash:
if data['owner'] != session['user']:
return "<h1>Access Denied</h1>", 403
return render_template('report.html', data=data, user_hash=user_hash)
return "Not Found", 404
์ด๋ ๊ฒ ๋ค์๊ณผ ๊ฐ์ด uid๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํ ๋ค MD5 ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ํด์ฑํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ 16์ง์ ๋ฌธ์์ด๋ก ๋ฐํํ๋ ๊ตฌ๋ฌธ์ url์ ๋ฃ์ด IDOR์ด ๊ฐ๋ฅํจ์ ์ ์ถํ ์ ์์ต๋๋ค.
report/view/3def184ad8f4755ff269862ea77393dd
guest๋ก ๋ก๊ทธ์ธํ์๋ฉด url์ด ๋ค์๊ณผ ๊ฐ์ด ๋์ค๋ ๊ฒ์ ์ ์ ์์ผ๋ฉฐ ์ด๋ 125์(health_record์ guest๋ฒํธ) get_hash() ๊ฐ์์ ์ ์ ์์ต๋๋ค
๋ฐ๋ผ์ ์ ํฌ๋ owner๊ฐ admin์ ๋ฒํธ๊ฐ ๋๋ 1์ get_hash()์ ๋ฃ์ด IDOR๋ฅผ ์๋ํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ด๊ฑธ ๊ณง์ด๊ณง๋๋ก /report/view/<user_hash> ์ ๋ฃ๊ฒ ๋๋ฉด ์ฝ๋์ฒ๋ผ 'Access Denied'๊ฐ ๋์ค๊ฒ ๋ฉ๋๋ค
๊ฒฐ๊ณผํ๊ฐ ๋๋ /report/download/<user_hash> ๋ ์ข ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋์ต๋๋ค
@app.route('/report/download/<user_hash>')
def download_report(user_hash):
if 'user' not in session:
return redirect(url_for('index'))
for uid, data in health_records.items():
if get_hash(uid) == user_hash:
return render_template('print.html', data=data)
return "Not Found", 404
/report/view/<user_hash>์๋ ๋ค๋ฅด๊ฒ ๋ก๊ทธ์ธ ํ์ธ ํ, ์ฐพ์ ๋ฐ์ดํฐ์ ์ฃผ์ธ๊ณผ ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ์ผ์นํ๋์ง ๋น๊ตํ์ง ์๊ธฐ์
(data['owner'] != session['user'])
/report/view/c4ca4238a0b923820dcc509a6f75849b
์ ํตํด ์ ๊ทผํ๋ฉด ํ๋๊ทธ๋ฅผ ํ๋ํ ์ ์๊ฒ ๋ฉ๋๋ค.
FLAG :

ํ๊ฐ :
